diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Kconfig.debug.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Kconfig.debug.patch new file mode 100644 index 00000000..e430a610 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Kconfig.debug.patch @@ -0,0 +1,61 @@ +--- linux-4.9.37/arch/arm/Kconfig.debug 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/Kconfig.debug 2021-06-07 13:01:32.000000000 +0300 +@@ -287,6 +287,38 @@ + Say Y here if you want kernel low-level debugging support + on HI3620 UART. + ++ config DEBUG_GK7205V200_UART ++ bool "Goke GK7205V200 Debug UART" ++ depends on ARCH_GK7205V200 ++ select DEBUG_UART_PL01X ++ help ++ Say Y here if you want kernel low-level debugging support ++ on GK7205V200 UART. ++ ++ config DEBUG_GK7205V300_UART ++ bool "Goke GK7205V300 Debug UART" ++ depends on ARCH_GK7205V300 ++ select DEBUG_UART_PL01X ++ help ++ Say Y here if you want kernel low-level debugging support ++ on GK7205V300 UART. ++ ++ config DEBUG_GK7202V300_UART ++ bool "Goke GK7202V300 Debug UART" ++ depends on ARCH_GK7202V300 ++ select DEBUG_UART_PL01X ++ help ++ Say Y here if you want kernel low-level debugging support ++ on GK7202V300 UART. ++ ++ config DEBUG_GK7605V100_UART ++ bool "Goke GK7605V100 Debug UART" ++ depends on ARCH_GK7605V100 ++ select DEBUG_UART_PL01X ++ help ++ Say Y here if you want kernel low-level debugging support ++ on GK7605V100 UART. ++ + config DEBUG_HIGHBANK_UART + bool "Kernel low-level debugging messages via Highbank UART" + depends on ARCH_HIGHBANK +@@ -1530,6 +1562,9 @@ + default 0xf991e000 if DEBUG_QCOM_UARTDM + default 0xfc00c000 if DEBUG_AT91_SAMA5D4_USART3 + default 0xfcb00000 if DEBUG_HI3620_UART ++ default 0x12040000 if DEBUG_GK7205V200_UART ++ default 0x12040000 if DEBUG_GK7205V300_UART ++ default 0x12040000 if DEBUG_GK7202V300_UART + default 0xfd883000 if DEBUG_ALPINE_UART0 + default 0xfe800000 if ARCH_IOP32X + default 0xff690000 if DEBUG_RK32_UART2 +@@ -1619,6 +1654,9 @@ + default 0xfe300000 if DEBUG_BCM_KONA_UART + default 0xfe800000 if ARCH_IOP32X + default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HIX5HD2_UART ++ default 0xfe440000 if DEBUG_GK7205V200_UART ++ default 0xfe440000 if DEBUG_GK7205V300_UART ++ default 0xfe440000 if DEBUG_GK7202V300_UART + default 0xfeb24000 if DEBUG_RK3X_UART0 + default 0xfeb26000 if DEBUG_RK3X_UART1 + default 0xfeb30c00 if DEBUG_KEYSTONE_UART0 diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Kconfig.patch new file mode 100644 index 00000000..0290b04e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Kconfig.patch @@ -0,0 +1,20 @@ +--- linux-4.9.37/arch/arm/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/Kconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -330,7 +330,7 @@ + depends on MMU + select ARM_HAS_SG_CHAIN + select ARM_PATCH_PHYS_VIRT +- select AUTO_ZRELADDR ++ #select AUTO_ZRELADDR + select CLKSRC_OF + select COMMON_CLK + select GENERIC_CLOCKEVENTS +@@ -747,6 +747,8 @@ + + source "arch/arm/mach-hisi/Kconfig" + ++source "arch/arm/mach-goke/Kconfig" ++ + source "arch/arm/mach-integrator/Kconfig" + + source "arch/arm/mach-iop32x/Kconfig" diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Makefile.patch new file mode 100644 index 00000000..c6fd10e1 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-Makefile.patch @@ -0,0 +1,21 @@ +--- linux-4.9.37/arch/arm/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/Makefile 2021-06-07 13:01:32.000000000 +0300 +@@ -170,6 +170,7 @@ + machine-$(CONFIG_ARCH_GEMINI) += gemini + machine-$(CONFIG_ARCH_HIGHBANK) += highbank + machine-$(CONFIG_ARCH_HISI) += hisi ++machine-$(CONFIG_ARCH_GOKE) += goke + machine-$(CONFIG_ARCH_INTEGRATOR) += integrator + machine-$(CONFIG_ARCH_IOP13XX) += iop13xx + machine-$(CONFIG_ARCH_IOP32X) += iop32x +@@ -268,6 +269,10 @@ + endif + endif + ++ifeq ($(CONFIG_ARCH_GOKE),y) ++KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs)) ++endif ++ + export TEXT_OFFSET GZFLAGS MMUEXT + + # Do we have FASTFPE? diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-Makefile.patch new file mode 100644 index 00000000..f56a12c6 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-Makefile.patch @@ -0,0 +1,45 @@ +--- linux-4.9.37/arch/arm/boot/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/Makefile 2021-06-07 13:01:32.000000000 +0300 +@@ -16,6 +16,8 @@ + ifneq ($(MACHINE),) + include $(MACHINE)/Makefile.boot + endif ++include $(srctree)/arch/arm/mach-goke/Makefile.boot ++include $(srctree)/arch/arm/boot/dts/Makefile + + # Note: the following conditions must always be true: + # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) +@@ -24,10 +26,12 @@ + ZRELADDR := $(zreladdr-y) + PARAMS_PHYS := $(params_phys-y) + INITRD_PHYS := $(initrd_phys-y) ++DTB_OBJS ?= $(dtb-y) ++DTB_OBJS_FULL := $(addprefix $(obj)/dts/,$(DTB_OBJS)) + + export ZRELADDR INITRD_PHYS PARAMS_PHYS + +-targets := Image zImage xipImage bootpImage uImage ++targets := Image zImage xipImage bootpImage uImage zImage-dtb + + ifeq ($(CONFIG_XIP_KERNEL),y) + +@@ -55,6 +59,10 @@ + $(obj)/zImage: $(obj)/compressed/vmlinux FORCE + $(call if_changed,objcopy) + ++$(obj)/zImage-dtb: $(obj)/zImage $(DTB_OBJS_FULL) FORCE ++ @cat $(obj)/zImage $(DTB_OBJS_FULL) > $@ ++ @$(kecho) ' Kernel: $@ is ready' ++ + endif + + ifneq ($(LOADADDR),) +@@ -75,7 +83,7 @@ + false; \ + fi + +-$(obj)/uImage: $(obj)/zImage FORCE ++$(obj)/uImage: $(obj)/zImage-dtb FORCE + @$(check_for_multiple_loadaddr) + $(call if_changed,uimage) + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-compressed-head.S.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-compressed-head.S.patch new file mode 100644 index 00000000..9a9ccca7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-compressed-head.S.patch @@ -0,0 +1,24 @@ +--- linux-4.9.37/arch/arm/boot/compressed/head.S 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/compressed/head.S 2021-06-07 13:01:32.000000000 +0300 +@@ -218,6 +218,21 @@ + addcc r0, r0, pc + cmpcc r4, r0 + orrcc r4, r4, #1 @ remember we skipped cache_on ++ ++/*TODO all the Cortex-A7 Single Core must fix this bug */ ++#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) \ ++ || defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) ++/* ++ * This is a bug on Cortex-A7 MPCORE. see buglist of Cortex-A7 ++ * The D-caches are disabled when ACTLR.SMP is set to 0 regardless of the ++ * value of the cache enable bit. so we must set SMP bit of ACTLR register ++ * before enable D cache ++ */ ++ mrc p15, 0, r0, c1, c0, 1 ++ orr r0, #(1 << 6) ++ mcr p15, 0, r0, c1, c0, 1 ++#endif ++ + blcs cache_on + + restart: adr r0, LC0 diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-Makefile.patch new file mode 100644 index 00000000..c2a35a3c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-Makefile.patch @@ -0,0 +1,17 @@ +--- linux-4.9.37/arch/arm/boot/dts/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/Makefile 2021-06-07 13:01:32.000000000 +0300 +@@ -174,6 +174,14 @@ + hi3519-demb.dtb + dtb-$(CONFIG_ARCH_HIX5HD2) += \ + hisi-x5hd2-dkb.dtb ++dtb-$(CONFIG_ARCH_GK7205V200) += \ ++ gk7205v200-demb.dtb ++dtb-$(CONFIG_ARCH_GK7205V300) += \ ++ gk7205v300-demb.dtb ++dtb-$(CONFIG_ARCH_GK7202V300) += \ ++ gk7202v300-demb.dtb ++dtb-$(CONFIG_ARCH_GK7605V100) += \ ++ gk7605v100-demb.dtb + dtb-$(CONFIG_ARCH_INTEGRATOR) += \ + integratorap.dtb \ + integratorcp.dtb diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7202v300-demb.dts.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7202v300-demb.dts.patch new file mode 100644 index 00000000..b54884cd --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7202v300-demb.dts.patch @@ -0,0 +1,154 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7202v300-demb.dts 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7202v300-demb.dts 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,151 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++/dts-v1/; ++#include "gk7202v300.dtsi" ++ ++/ { ++ model = "Goke GK7202V300 DEMO Board"; ++ compatible = "goke,gk7202v300"; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x40000000 0x20000000>; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "disabled"; ++}; ++ ++&uart2 { ++ status = "disabled"; ++}; ++ ++&i2c_bus0 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus1 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus2 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&spi_bus0{ ++ status = "okay"; ++ num-cs = <1>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&spi_bus1{ ++ status = "okay"; ++ num-cs = <2>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++ spidev@1 { ++ compatible = "rohm,dh2228fv"; ++ reg = <1>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&dual_timer0 { ++ status = "okay"; ++}; ++ ++&mdio0 { ++ goke,phy-reset-delays-us = <10000 20000 150000>; ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&femac { ++ mac-address = [00 00 00 00 00 00]; ++ phy-mode = "mii"; ++ phy-handle = <&phy0>; ++ status = "okay"; ++}; ++ ++&sfc { ++ sfc { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&snfc { ++ nand { ++ compatible = "jedec,spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&mmc0 { ++ status = "okay"; ++}; ++ ++&mmc1 { ++ status = "okay"; ++}; ++ ++&gpio_chip0 { ++ status = "okay"; ++}; ++ ++&gpio_chip1 { ++ status = "okay"; ++}; ++ ++&gpio_chip2 { ++ status = "okay"; ++}; ++ ++&gpio_chip4 { ++ status = "okay"; ++}; ++ ++&gpio_chip5 { ++ status = "okay"; ++}; ++ ++&gpio_chip6 { ++ status = "okay"; ++}; ++ ++&gpio_chip7 { ++ status = "okay"; ++}; ++ ++&gpio_chip8 { ++ status = "okay"; ++}; ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7202v300.dtsi.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7202v300.dtsi.patch new file mode 100644 index 00000000..8d77f2b7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7202v300.dtsi.patch @@ -0,0 +1,628 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7202v300.dtsi 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7202v300.dtsi 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,625 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include "skeleton.dtsi" ++#include ++/ { ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ i2c0 = &i2c_bus0; ++ i2c1 = &i2c_bus1; ++ i2c2 = &i2c_bus2; ++ spi0 = &spi_bus0; ++ spi1 = &spi_bus1; ++ gpio0 = &gpio_chip0; ++ gpio1 = &gpio_chip1; ++ gpio2 = &gpio_chip2; ++ gpio4 = &gpio_chip4; ++ gpio5 = &gpio_chip5; ++ gpio6 = &gpio_chip6; ++ gpio7 = &gpio_chip7; ++ gpio8 = &gpio_chip8; ++ }; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ enable-method = "goke,gk7202v300"; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ clock-frequency = ; ++ reg = <0>; ++ }; ++ }; ++ ++ pmu { ++ compatible = "arm,armv7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ clock: clock@12010000 { ++ compatible = "goke,gk7202v300-clock", "syscon"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ #clock-cells = <1>; ++ #reset-cells = <2>; ++ reg = <0x12010000 0x1000>; ++ }; ++ ++ gic: interrupt-controller@10300000 { ++ compatible = "arm,cortex-a7-gic"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ /* gic dist base, gic cpu base , no virtual support */ ++ reg = <0x10301000 0x1000>, <0x10302000 0x100>; ++ }; ++ ++ syscounter { ++ compatible = "arm,armv7-timer"; ++ interrupt-parent = <&gic>; ++ interrupts = <1 13 0xf08>, ++ <1 14 0xf08>; ++ clock-frequency = <50000000>; ++ }; ++ ++ soc { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ clk_3m: clk_3m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <3000000>; ++ }; ++ ++ clk_apb: clk_apb { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <50000000>; ++ }; ++ ++ pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ sysctrl: system-controller@12020000 { ++ compatible = "goke,sysctrl"; ++ reg = <0x12020000 0x1000>; ++ reboot-offset = <0x4>; ++ #clock-cells = <1>; ++ }; ++ ++ iocfg_ctrl: iocfg-controller@100c0000 { ++ compatible = "syscon"; ++ reg = <0x100C0000 0x10000>; ++ }; ++ ++ iocfg_ctrl2: iocfg-controller2@112c0000 { ++ compatible = "syscon"; ++ reg = <0x112C0000 0x10000>; ++ }; ++ ++#ifdef CONFIG_EDMAC ++ edmac: edma-controller@100B0000 { ++ compatible = "goke,edmac"; ++ reg = <0x100B0000 0x1000>; ++ interrupts = <0 38 4>; ++ clocks = <&clock GK7202V300_EDMAC_CLK>, <&clock GK7202V300_EDMAC_AXICLK>; ++ clock-names = "apb_pclk", "axi_aclk"; ++ clock-cells = <2>; ++ resets = <&clock 0x194 0>; ++ reset-names = "dma-reset"; ++ dma-requests = <32>; ++ dma-channels = <4>; ++ devid = <0>; ++ #dma-cells = <2>; ++ status = "okay"; ++ }; ++#endif ++ amba { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "arm,amba-bus"; ++ ranges; ++ ++ dual_timer0: dual_timer@12000000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer0 & timer1 */ ++ interrupts = <0 5 4>; ++ reg = <0x12000000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer00", "timer01", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dual_timer1: dual_timer@12001000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer2 & timer3 */ ++ interrupts = <0 6 4>; ++ reg = <0x12001000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer10", "timer11", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart0: uart@12040000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12040000 0x1000>; ++ interrupts = <0 7 4>; ++ clocks = <&clock GK7202V300_UART0_CLK>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart1: uart@12041000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12041000 0x1000>; ++ interrupts = <0 8 4>; ++ clocks = <&clock GK7202V300_UART1_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 19 19>, <&edmac 18 18>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ uart2: uart@12042000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12042000 0x1000>; ++ interrupts = <0 9 4>; ++ clocks = <&clock GK7202V300_UART2_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 21 21>, <&edmac 20 20>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ }; ++ ++ i2c_bus0: i2c@12060000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12060000 0x1000>; ++ clocks = <&clock GK7202V300_I2C0_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus1: i2c@12061000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12061000 0x1000>; ++ clocks = <&clock GK7202V300_I2C1_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus2: i2c@12062000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12062000 0x1000>; ++ clocks = <&clock GK7202V300_I2C2_CLK>; ++ status = "disabled"; ++ }; ++ ++ spi_bus0: spi@12070000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12070000 0x1000>; ++ interrupts = <0 14 4>; ++ clocks = <&clock GK7202V300_SPI0_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 27 27>, <&edmac 26 26>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ spi_bus1: spi@12071000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12071000 0x1000>, <0x12028000 0x4>; ++ interrupts = <0 15 4>; ++ clocks = <&clock GK7202V300_SPI1_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ num-cs = <2>; ++ spi_cs_sb = <2>; ++ spi_cs_mask_bit = <0x4>;//0100 ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 29 29>, <&edmac 28 28>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ mdio0: mdio@10041100 { ++ compatible = "goke,femac-mdio"; ++ reg = <0x10041100 0x10>,<0x12028024 0x4>; ++ clocks = <&clock GK7202V300_ETH0_CLK>; ++ clock-names = "mdio"; ++ resets = <&clock 0x16c 3>; ++ reset-names = "internal-phy"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ femac: ethernet@10040000 { ++ compatible = "goke,femac"; ++ reg = <0x10040000 0x1000>,<0x10041300 0x200>; ++ interrupts = <0 33 4>; ++ clocks = <&clock GK7202V300_ETH0_CLK>; ++ resets = <&clock 0x16c 0>; ++ reset-names = "mac"; ++ }; ++ ++ fmc: flash-memory-controller@10000000 { ++ compatible = "goke,fmc"; ++ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; ++ reg-names = "control", "memory"; ++ clocks = <&clock GK7202V300_FMC_CLK>; ++ max-dma-size = <0x2000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sfc:spi-nor@0 { ++ compatible = "goke,fmc-spi-nor"; ++ assigned-clocks = <&clock GK7202V300_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ snfc:spi-nand@0 { ++ compatible = "goke,fmc-spi-nand"; ++ assigned-clocks = <&clock GK7202V300_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ ++ mmc0: sdhci@0x10010000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10010000 0x1000>; ++ interrupts = <0 30 4>; ++ clocks = <&clock GK7202V300_MMC0_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <150000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl>; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ cap-sd-highspeed; ++ mmc-hs200-1_8v; ++ full-pwr-cycle; ++ devid = <0>; ++ status = "enable"; ++ }; ++ ++ mmc1: sdhci@0x10020000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10020000 0x1000>; ++ interrupts = <0 31 4>; ++ clocks = <&clock GK7202V300_MMC1_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <50000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl2>; ++ bus-width = <4>; ++ cap-sd-highspeed; ++ full-pwr-cycle; ++ devid = <2>; ++ status = "enable"; ++ }; ++ ++ usb2_phy0: phy2-0 { ++ compatible = "goke,usbp2-phy"; ++ reg = <0x100D0000 0x1000>, ++ <0x12010000 0x1000>, ++ <0x100c0000 0x1000>; ++ clocks = <&clock GK7202V300_USB2_PHY_APB_CLK>, ++ <&clock GK7202V300_USB2_PHY_PLL_CLK>, ++ <&clock GK7202V300_USB2_PHY_XO_CLK>; ++ clock-names = "clk_u2phy_apb_ref", ++ "clk_u2phy_pll_ref", ++ "clk_u2phy_xo_ref"; ++ resets = <&clock 0x140 0>, ++ <&clock 0x140 1>; ++ reset-names = "phy_por_reset", ++ "phy_tpor_reset"; ++ phy_pll_offset = <0x14>; ++ phy_pll_mask = <0x03>; ++ phy_pll_val = <0x00>; ++ crg_offset = <0x140>; ++ crg_defal_mask = <0x0c07>; ++ crg_defal_val = <0x0807>; ++ vbus_offset = <0x7c>; ++ vbus_val = <0x0531>; ++ pwren_offset = <0x80>; ++ pwren_val = <0x1>; ++ ana_cfg_0_eye_val = <0x0433cc23>; ++ ana_cfg_0_offset = <0x00>; ++ ana_cfg_2_eye_val = <0x00320f0f>; ++ ana_cfg_2_offset = <0x08>; ++ ana_cfg_4_eye_val = <0x655>; ++ ana_cfg_4_offset = <0x10>; ++ trim_otp_addr = <0x12028004>; ++ trim_otp_mask = <0x1f>; ++ trim_otp_bit_offset = <0x00>; ++ trim_otp_min = <0x09>; ++ trim_otp_max = <0x1d>; ++ #phy-cells = <0>; ++ }; ++ ++ usbdrd3_0: usb3-0{ ++ compatible = "goke,dwusb2"; ++ reg = <0x10030000 0x10000>, ++ <0x12010000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ crg_offset = <0x140>; ++ crg_ctrl_def_mask = <0x3308>; ++ crg_ctrl_def_val = <0x1308>; ++ clocks = <&clock GK7202V300_USB2_BUS_CLK>, ++ <&clock GK7202V300_USB2_REF_CLK>, ++ <&clock GK7202V300_USB2_UTMI_CLK>; ++ clock-names = "usb2_bus_clk", ++ "usb2_ref_clk", ++ "usb2_utmi_clk"; ++ resets = <&clock 0x140 3>; ++ reset-names = "vcc_reset"; ++ ranges; ++ ++ dwc3@0x100e0000 { ++ compatible = "snps,dwc3"; ++ reg = <0x10030000 0x10000>; ++ interrupts = <0 39 4>; ++ interrupt-names = "peripheral"; ++ phys = <&usb2_phy0>; ++ phy-names = "usb2-phy"; ++ maximum-speed = "high-speed"; ++ dr_mode = "peripheral"; ++ eps_directions = <0x6a>; ++ snps,eps_new_init; ++ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; ++ snps,usb2-lpm-disable; ++ }; ++ }; ++ ++ gpio_chip0: gpio_chip@120b0000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b0000 0x1000>; ++ interrupts = <0 16 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip1: gpio_chip@120b1000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b1000 0x1000>; ++ interrupts = <0 17 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip2: gpio_chip@120b2000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b2000 0x1000>; ++ interrupts = <0 18 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip4: gpio_chip@120b4000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b4000 0x1000>; ++ interrupts = <0 20 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip5: gpio_chip@120b5000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b5000 0x1000>; ++ interrupts = <0 21 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip6: gpio_chip@120b6000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b6000 0x1000>; ++ interrupts = <0 22 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip7: gpio_chip@120b7000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b7000 0x1000>; ++ interrupts = <0 23 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip8: gpio_chip@120b8000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b8000 0x1000>; ++ interrupts = <0 24 4>; ++ clocks = <&clock GK7202V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ rtc: rtc@120e0000 { ++ compatible = "goke,rtc"; ++ reg = <0x120e0000 0x1000>; ++ interrupts = <0 0 4>; ++ }; ++ ++ cipher: cipher@0x10050000 { ++ compatible = "goke,cipher"; ++ reg = <0x10050000 0x10000>; ++ reg-names = "cipher"; ++ interrupts = <0 34 4>, <0 34 4>; ++ interrupt-names = "cipher", "hash"; ++ }; ++ ++ adc: adc@120a0000 { ++ compatible = "goke,lsadc"; ++ reg = <0x120a0000 0x1000>; ++ interrupts = <0 4 4>; ++ interrupt-names = "adc"; ++ resets = <&clock 0x1bc 2>; ++ reset-names = "lsadc-crg"; ++ status = "okay"; ++ }; ++ ++ wdg: wdg@0x12030000 { ++ compatible = "goke,wdg"; ++ reg = <0x12030000 0x1000>; ++ reg-names = "wdg"; ++ interrupts = <0 2 4>; ++ interrupt-names = "wdg"; ++ }; ++ }; ++ ++ media { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ osal: osal { ++ compatible = "goke,osal"; ++ }; ++ ++ sys: sys@12010000 { ++ compatible = "goke,sys"; ++ }; ++ ++ mipi: mipi@0x11240000 { ++ compatible = "goke,mipi"; ++ reg = <0x11240000 0x10000>; ++ reg-names = "mipi_rx"; ++ interrupts = <0 45 4>; ++ interrupt-names = "mipi_rx"; ++ }; ++ ++ vi: vi@11000000 { ++ compatible = "goke,vi"; ++ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; ++ reg-names = "VI_CAP0", "VI_PROC0"; ++ interrupts = <0 43 4>, <0 44 4>; ++ interrupt-names = "VI_CAP0", "VI_PROC0"; ++ }; ++ ++ isp: isp@11220000 { ++ compatible = "goke,isp"; ++ reg = <0x11220000 0x20000>; ++ reg-names = "ISP"; ++ interrupts = <0 43 4>; ++ interrupt-names = "ISP"; ++ }; ++ ++ vpss: vpss@11400000 { ++ compatible = "goke,vpss"; ++ reg = <0x11400000 0x10000>; ++ reg-names = "vpss0"; ++ interrupts = <0 46 4>; ++ interrupt-names = "vpss0"; ++ }; ++ ++ vo: vo@11280000 { ++ compatible = "goke,vo"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "vo"; ++ interrupts = <0 40 4>; ++ interrupt-names = "vo"; ++ }; ++ ++ gfbg: gfbg@11280000 { ++ compatible = "goke,gfbg"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "gfbg"; ++ interrupts = <0 41 4>; ++ interrupt-names = "gfbg"; ++ }; ++ ++ vgs: vgs@11300000 { ++ compatible = "goke,vgs"; ++ reg = <0x11300000 0x10000>; ++ reg-names = "vgs0"; ++ interrupts = <0 49 4>; ++ interrupt-names = "vgs0"; ++ }; ++ ++ gzip: gzip@11310000 { ++ compatible = "goke,gzip"; ++ reg = <0x11310000 0x10000>; ++ reg-names = "gzip"; ++ interrupts = <0 50 4>; ++ interrupt-names = "gzip"; ++ }; ++ ++ vedu: vedu@11410000 { ++ compatible = "goke,vedu"; ++ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; ++ reg-names = "vedu0", "jpge"; ++ interrupts = <0 47 4>, <0 48 4>; ++ interrupt-names = "vedu0","jpge"; ++ }; ++ ++ venc: venc { ++ compatible = "goke,venc"; ++ }; ++ ++ aiao: aiao@100e0000 { ++ compatible = "goke,aiao"; ++ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; ++ reg-names = "aiao","acodec"; ++ interrupts = <0 42 4>; ++ interrupt-names = "AIO"; ++ }; ++ ++ ive: ive@11320000 { ++ compatible = "goke,ive"; ++ reg = <0x11320000 0x10000>; ++ reg-names = "ive"; ++ interrupts = <0 51 4>; ++ interrupt-names = "ive"; ++ }; ++ }; ++}; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v200-demb.dts.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v200-demb.dts.patch new file mode 100644 index 00000000..fd51c8aa --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v200-demb.dts.patch @@ -0,0 +1,154 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7205v200-demb.dts 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7205v200-demb.dts 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,151 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++/dts-v1/; ++#include "gk7205v200.dtsi" ++ ++/ { ++ model = "Goke GK7205V200 DEMO Board"; ++ compatible = "goke,gk7205v200"; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x40000000 0x20000000>; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "disabled"; ++}; ++ ++&uart2 { ++ status = "disabled"; ++}; ++ ++&i2c_bus0 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus1 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus2 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&spi_bus0{ ++ status = "okay"; ++ num-cs = <1>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&spi_bus1{ ++ status = "okay"; ++ num-cs = <2>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++ spidev@1 { ++ compatible = "rohm,dh2228fv"; ++ reg = <1>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&dual_timer0 { ++ status = "okay"; ++}; ++ ++&mdio0 { ++ goke,phy-reset-delays-us = <10000 20000 150000>; ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&femac { ++ mac-address = [00 00 00 00 00 00]; ++ phy-mode = "mii"; ++ phy-handle = <&phy0>; ++ status = "okay"; ++}; ++ ++&sfc { ++ sfc { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&snfc { ++ nand { ++ compatible = "jedec,spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&mmc0 { ++ status = "okay"; ++}; ++ ++&mmc1 { ++ status = "okay"; ++}; ++ ++&gpio_chip0 { ++ status = "okay"; ++}; ++ ++&gpio_chip1 { ++ status = "okay"; ++}; ++ ++&gpio_chip2 { ++ status = "okay"; ++}; ++ ++&gpio_chip4 { ++ status = "okay"; ++}; ++ ++&gpio_chip5 { ++ status = "okay"; ++}; ++ ++&gpio_chip6 { ++ status = "okay"; ++}; ++ ++&gpio_chip7 { ++ status = "okay"; ++}; ++ ++&gpio_chip8 { ++ status = "okay"; ++}; ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v200.dtsi.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v200.dtsi.patch new file mode 100644 index 00000000..08c6f384 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v200.dtsi.patch @@ -0,0 +1,628 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7205v200.dtsi 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7205v200.dtsi 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,625 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include "skeleton.dtsi" ++#include ++/ { ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ i2c0 = &i2c_bus0; ++ i2c1 = &i2c_bus1; ++ i2c2 = &i2c_bus2; ++ spi0 = &spi_bus0; ++ spi1 = &spi_bus1; ++ gpio0 = &gpio_chip0; ++ gpio1 = &gpio_chip1; ++ gpio2 = &gpio_chip2; ++ gpio4 = &gpio_chip4; ++ gpio5 = &gpio_chip5; ++ gpio6 = &gpio_chip6; ++ gpio7 = &gpio_chip7; ++ gpio8 = &gpio_chip8; ++ }; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ enable-method = "goke,gk7205v200"; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ clock-frequency = ; ++ reg = <0>; ++ }; ++ }; ++ ++ pmu { ++ compatible = "arm,armv7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ clock: clock@12010000 { ++ compatible = "goke,gk7205v200-clock", "syscon"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ #clock-cells = <1>; ++ #reset-cells = <2>; ++ reg = <0x12010000 0x1000>; ++ }; ++ ++ gic: interrupt-controller@10300000 { ++ compatible = "arm,cortex-a7-gic"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ /* gic dist base, gic cpu base , no virtual support */ ++ reg = <0x10301000 0x1000>, <0x10302000 0x100>; ++ }; ++ ++ syscounter { ++ compatible = "arm,armv7-timer"; ++ interrupt-parent = <&gic>; ++ interrupts = <1 13 0xf08>, ++ <1 14 0xf08>; ++ clock-frequency = <50000000>; ++ }; ++ ++ soc { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ clk_3m: clk_3m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <3000000>; ++ }; ++ ++ clk_apb: clk_apb { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <50000000>; ++ }; ++ ++ pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ sysctrl: system-controller@12020000 { ++ compatible = "goke,sysctrl"; ++ reg = <0x12020000 0x1000>; ++ reboot-offset = <0x4>; ++ #clock-cells = <1>; ++ }; ++ ++ iocfg_ctrl: iocfg-controller@100c0000 { ++ compatible = "syscon"; ++ reg = <0x100C0000 0x10000>; ++ }; ++ ++ iocfg_ctrl2: iocfg-controller2@112c0000 { ++ compatible = "syscon"; ++ reg = <0x112C0000 0x10000>; ++ }; ++ ++#ifdef CONFIG_EDMAC ++ edmac: edma-controller@100B0000 { ++ compatible = "goke,edmac"; ++ reg = <0x100B0000 0x1000>; ++ interrupts = <0 38 4>; ++ clocks = <&clock GK7205V200_EDMAC_CLK>, <&clock GK7205V200_EDMAC_AXICLK>; ++ clock-names = "apb_pclk", "axi_aclk"; ++ clock-cells = <2>; ++ resets = <&clock 0x194 0>; ++ reset-names = "dma-reset"; ++ dma-requests = <32>; ++ dma-channels = <4>; ++ devid = <0>; ++ #dma-cells = <2>; ++ status = "okay"; ++ }; ++#endif ++ amba { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "arm,amba-bus"; ++ ranges; ++ ++ dual_timer0: dual_timer@12000000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer0 & timer1 */ ++ interrupts = <0 5 4>; ++ reg = <0x12000000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer00", "timer01", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dual_timer1: dual_timer@12001000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer2 & timer3 */ ++ interrupts = <0 6 4>; ++ reg = <0x12001000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer10", "timer11", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart0: uart@12040000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12040000 0x1000>; ++ interrupts = <0 7 4>; ++ clocks = <&clock GK7205V200_UART0_CLK>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart1: uart@12041000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12041000 0x1000>; ++ interrupts = <0 8 4>; ++ clocks = <&clock GK7205V200_UART1_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 19 19>, <&edmac 18 18>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ uart2: uart@12042000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12042000 0x1000>; ++ interrupts = <0 9 4>; ++ clocks = <&clock GK7205V200_UART2_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 21 21>, <&edmac 20 20>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ }; ++ ++ i2c_bus0: i2c@12060000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12060000 0x1000>; ++ clocks = <&clock GK7205V200_I2C0_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus1: i2c@12061000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12061000 0x1000>; ++ clocks = <&clock GK7205V200_I2C1_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus2: i2c@12062000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12062000 0x1000>; ++ clocks = <&clock GK7205V200_I2C2_CLK>; ++ status = "disabled"; ++ }; ++ ++ spi_bus0: spi@12070000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12070000 0x1000>; ++ interrupts = <0 14 4>; ++ clocks = <&clock GK7205V200_SPI0_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 27 27>, <&edmac 26 26>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ spi_bus1: spi@12071000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12071000 0x1000>, <0x12028000 0x4>; ++ interrupts = <0 15 4>; ++ clocks = <&clock GK7205V200_SPI1_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ num-cs = <2>; ++ spi_cs_sb = <2>; ++ spi_cs_mask_bit = <0x4>;//0100 ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 29 29>, <&edmac 28 28>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ mdio0: mdio@10041100 { ++ compatible = "goke,femac-mdio"; ++ reg = <0x10041100 0x10>,<0x12028024 0x4>; ++ clocks = <&clock GK7205V200_ETH0_CLK>; ++ clock-names = "mdio"; ++ resets = <&clock 0x16c 3>; ++ reset-names = "internal-phy"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ femac: ethernet@10040000 { ++ compatible = "goke,femac"; ++ reg = <0x10040000 0x1000>,<0x10041300 0x200>; ++ interrupts = <0 33 4>; ++ clocks = <&clock GK7205V200_ETH0_CLK>; ++ resets = <&clock 0x16c 0>; ++ reset-names = "mac"; ++ }; ++ ++ fmc: flash-memory-controller@10000000 { ++ compatible = "goke,fmc"; ++ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; ++ reg-names = "control", "memory"; ++ clocks = <&clock GK7205V200_FMC_CLK>; ++ max-dma-size = <0x2000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sfc:spi-nor@0 { ++ compatible = "goke,fmc-spi-nor"; ++ assigned-clocks = <&clock GK7205V200_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ snfc:spi-nand@0 { ++ compatible = "goke,fmc-spi-nand"; ++ assigned-clocks = <&clock GK7205V200_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ ++ mmc0: sdhci@0x10010000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10010000 0x1000>; ++ interrupts = <0 30 4>; ++ clocks = <&clock GK7205V200_MMC0_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <150000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl>; ++ bus-width = <4>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ cap-sd-highspeed; ++ mmc-hs200-1_8v; ++ full-pwr-cycle; ++ devid = <0>; ++ status = "enable"; ++ }; ++ ++ mmc1: sdhci@0x10020000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10020000 0x1000>; ++ interrupts = <0 31 4>; ++ clocks = <&clock GK7205V200_MMC1_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <50000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl2>; ++ bus-width = <4>; ++ cap-sd-highspeed; ++ full-pwr-cycle; ++ devid = <2>; ++ status = "enable"; ++ }; ++ ++ usb2_phy0: phy2-0 { ++ compatible = "goke,usbp2-phy"; ++ reg = <0x100D0000 0x1000>, ++ <0x12010000 0x1000>, ++ <0x100c0000 0x1000>; ++ clocks = <&clock GK7205V200_USB2_PHY_APB_CLK>, ++ <&clock GK7205V200_USB2_PHY_PLL_CLK>, ++ <&clock GK7205V200_USB2_PHY_XO_CLK>; ++ clock-names = "clk_u2phy_apb_ref", ++ "clk_u2phy_pll_ref", ++ "clk_u2phy_xo_ref"; ++ resets = <&clock 0x140 0>, ++ <&clock 0x140 1>; ++ reset-names = "phy_por_reset", ++ "phy_tpor_reset"; ++ phy_pll_offset = <0x14>; ++ phy_pll_mask = <0x03>; ++ phy_pll_val = <0x00>; ++ crg_offset = <0x140>; ++ crg_defal_mask = <0x0c07>; ++ crg_defal_val = <0x0807>; ++ vbus_offset = <0x7c>; ++ vbus_val = <0x0531>; ++ pwren_offset = <0x80>; ++ pwren_val = <0x01>; ++ ana_cfg_0_eye_val = <0x0433cc23>; ++ ana_cfg_0_offset = <0x00>; ++ ana_cfg_2_eye_val = <0x00320f0f>; ++ ana_cfg_2_offset = <0x08>; ++ ana_cfg_4_eye_val = <0x655>; ++ ana_cfg_4_offset = <0x10>; ++ trim_otp_addr = <0x12028004>; ++ trim_otp_mask = <0x1f>; ++ trim_otp_bit_offset = <0x00>; ++ trim_otp_min = <0x09>; ++ trim_otp_max = <0x1d>; ++ #phy-cells = <0>; ++ }; ++ ++ usbdrd3_0: usb3-0{ ++ compatible = "goke,dwusb2"; ++ reg = <0x10030000 0x10000>, ++ <0x12010000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ crg_offset = <0x140>; ++ crg_ctrl_def_mask = <0x3308>; ++ crg_ctrl_def_val = <0x1308>; ++ clocks = <&clock GK7205V200_USB2_BUS_CLK>, ++ <&clock GK7205V200_USB2_REF_CLK>, ++ <&clock GK7205V200_USB2_UTMI_CLK>; ++ clock-names = "usb2_bus_clk", ++ "usb2_ref_clk", ++ "usb2_utmi_clk"; ++ resets = <&clock 0x140 3>; ++ reset-names = "vcc_reset"; ++ ranges; ++ ++ dwc3@0x100e0000 { ++ compatible = "snps,dwc3"; ++ reg = <0x10030000 0x10000>; ++ interrupts = <0 39 4>; ++ interrupt-names = "peripheral"; ++ phys = <&usb2_phy0>; ++ phy-names = "usb2-phy"; ++ maximum-speed = "high-speed"; ++ dr_mode = "host"; ++ eps_directions = <0x6a>; ++ snps,eps_new_init; ++ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; ++ snps,usb2-lpm-disable; ++ }; ++ }; ++ ++ gpio_chip0: gpio_chip@120b0000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b0000 0x1000>; ++ interrupts = <0 16 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip1: gpio_chip@120b1000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b1000 0x1000>; ++ interrupts = <0 17 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip2: gpio_chip@120b2000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b2000 0x1000>; ++ interrupts = <0 18 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip4: gpio_chip@120b4000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b4000 0x1000>; ++ interrupts = <0 20 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip5: gpio_chip@120b5000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b5000 0x1000>; ++ interrupts = <0 21 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip6: gpio_chip@120b6000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b6000 0x1000>; ++ interrupts = <0 22 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip7: gpio_chip@120b7000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b7000 0x1000>; ++ interrupts = <0 23 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip8: gpio_chip@120b8000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b8000 0x1000>; ++ interrupts = <0 24 4>; ++ clocks = <&clock GK7205V200_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ rtc: rtc@120e0000 { ++ compatible = "goke,rtc"; ++ reg = <0x120e0000 0x1000>; ++ interrupts = <0 0 4>; ++ }; ++ ++ cipher: cipher@0x10050000 { ++ compatible = "goke,cipher"; ++ reg = <0x10050000 0x10000>; ++ reg-names = "cipher"; ++ interrupts = <0 34 4>, <0 34 4>; ++ interrupt-names = "cipher", "hash"; ++ }; ++ ++ adc: adc@120a0000 { ++ compatible = "goke,lsadc"; ++ reg = <0x120a0000 0x1000>; ++ interrupts = <0 4 4>; ++ interrupt-names = "adc"; ++ resets = <&clock 0x1bc 2>; ++ reset-names = "lsadc-crg"; ++ status = "okay"; ++ }; ++ ++ wdg: wdg@0x12030000 { ++ compatible = "goke,wdg"; ++ reg = <0x12030000 0x1000>; ++ reg-names = "wdg"; ++ interrupts = <0 2 4>; ++ interrupt-names = "wdg"; ++ }; ++ }; ++ ++ media { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ osal: osal { ++ compatible = "goke,osal"; ++ }; ++ ++ sys: sys@12010000 { ++ compatible = "goke,sys"; ++ }; ++ ++ mipi: mipi@0x11240000 { ++ compatible = "goke,mipi"; ++ reg = <0x11240000 0x10000>; ++ reg-names = "mipi_rx"; ++ interrupts = <0 45 4>; ++ interrupt-names = "mipi_rx"; ++ }; ++ ++ vi: vi@11000000 { ++ compatible = "goke,vi"; ++ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; ++ reg-names = "VI_CAP0", "VI_PROC0"; ++ interrupts = <0 43 4>, <0 44 4>; ++ interrupt-names = "VI_CAP0", "VI_PROC0"; ++ }; ++ ++ isp: isp@11220000 { ++ compatible = "goke,isp"; ++ reg = <0x11220000 0x20000>; ++ reg-names = "ISP"; ++ interrupts = <0 43 4>; ++ interrupt-names = "ISP"; ++ }; ++ ++ vpss: vpss@11400000 { ++ compatible = "goke,vpss"; ++ reg = <0x11400000 0x10000>; ++ reg-names = "vpss0"; ++ interrupts = <0 46 4>; ++ interrupt-names = "vpss0"; ++ }; ++ ++ vo: vo@11280000 { ++ compatible = "goke,vo"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "vo"; ++ interrupts = <0 40 4>; ++ interrupt-names = "vo"; ++ }; ++ ++ gfbg: gfbg@11280000 { ++ compatible = "goke,gfbg"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "gfbg"; ++ interrupts = <0 41 4>; ++ interrupt-names = "gfbg"; ++ }; ++ ++ vgs: vgs@11300000 { ++ compatible = "goke,vgs"; ++ reg = <0x11300000 0x10000>; ++ reg-names = "vgs0"; ++ interrupts = <0 49 4>; ++ interrupt-names = "vgs0"; ++ }; ++ ++ gzip: gzip@11310000 { ++ compatible = "goke,gzip"; ++ reg = <0x11310000 0x10000>; ++ reg-names = "gzip"; ++ interrupts = <0 50 4>; ++ interrupt-names = "gzip"; ++ }; ++ ++ vedu: vedu@11410000 { ++ compatible = "goke,vedu"; ++ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; ++ reg-names = "vedu0", "jpge"; ++ interrupts = <0 47 4>, <0 48 4>; ++ interrupt-names = "vedu0","jpge"; ++ }; ++ ++ venc: venc { ++ compatible = "goke,venc"; ++ }; ++ ++ aiao: aiao@100e0000 { ++ compatible = "goke,aiao"; ++ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; ++ reg-names = "aiao","acodec"; ++ interrupts = <0 42 4>; ++ interrupt-names = "AIO"; ++ }; ++ ++ ive: ive@11320000 { ++ compatible = "goke,ive"; ++ reg = <0x11320000 0x10000>; ++ reg-names = "ive"; ++ interrupts = <0 51 4>; ++ interrupt-names = "ive"; ++ }; ++ }; ++}; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v300-demb.dts.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v300-demb.dts.patch new file mode 100644 index 00000000..d60e6b00 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v300-demb.dts.patch @@ -0,0 +1,162 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7205v300-demb.dts 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7205v300-demb.dts 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++/dts-v1/; ++#include "gk7205v300.dtsi" ++ ++/ { ++ model = "Goke GK7205V300 DEMO Board"; ++ compatible = "goke,gk7205v300"; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x40000000 0x20000000>; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "disabled"; ++}; ++ ++&uart2 { ++ status = "disabled"; ++}; ++ ++&i2c_bus0 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus1 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus2 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&spi_bus0{ ++ status = "okay"; ++ num-cs = <1>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&spi_bus1{ ++ status = "okay"; ++ num-cs = <2>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++ spidev@1 { ++ compatible = "rohm,dh2228fv"; ++ reg = <1>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&dual_timer0 { ++ status = "okay"; ++}; ++ ++&mdio0 { ++ goke,phy-reset-delays-us = <10000 20000 150000>; ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&femac { ++ mac-address = [00 00 00 00 00 00]; ++ phy-mode = "mii"; ++ phy-handle = <&phy0>; ++ status = "okay"; ++}; ++ ++&sfc { ++ sfc { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&snfc { ++ nand { ++ compatible = "jedec,spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&mmc0 { ++ status = "okay"; ++}; ++ ++&mmc1 { ++ status = "okay"; ++}; ++ ++&gpio_chip0 { ++ status = "okay"; ++}; ++ ++&gpio_chip1 { ++ status = "okay"; ++}; ++ ++&gpio_chip2 { ++ status = "okay"; ++}; ++ ++&gpio_chip3 { ++ status = "okay"; ++}; ++ ++&gpio_chip4 { ++ status = "okay"; ++}; ++ ++&gpio_chip5 { ++ status = "okay"; ++}; ++ ++&gpio_chip6 { ++ status = "okay"; ++}; ++ ++&gpio_chip7 { ++ status = "okay"; ++}; ++ ++&gpio_chip8 { ++ status = "okay"; ++}; ++ ++&gpio_chip9 { ++ status = "okay"; ++}; ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v300.dtsi.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v300.dtsi.patch new file mode 100644 index 00000000..16cb3baf --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7205v300.dtsi.patch @@ -0,0 +1,647 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7205v300.dtsi 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7205v300.dtsi 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,644 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include "skeleton.dtsi" ++#include ++/ { ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ i2c0 = &i2c_bus0; ++ i2c1 = &i2c_bus1; ++ i2c2 = &i2c_bus2; ++ spi0 = &spi_bus0; ++ spi1 = &spi_bus1; ++ gpio0 = &gpio_chip0; ++ gpio1 = &gpio_chip1; ++ gpio2 = &gpio_chip2; ++ gpio3 = &gpio_chip3; ++ gpio4 = &gpio_chip4; ++ gpio5 = &gpio_chip5; ++ gpio6 = &gpio_chip6; ++ gpio7 = &gpio_chip7; ++ gpio8 = &gpio_chip8; ++ gpio9 = &gpio_chip9; ++ }; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ enable-method = "goke,gk7205v300"; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ clock-frequency = ; ++ reg = <0>; ++ }; ++ }; ++ ++ pmu { ++ compatible = "arm,armv7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ clock: clock@12010000 { ++ compatible = "goke,gk7205v300-clock", "syscon"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ #clock-cells = <1>; ++ #reset-cells = <2>; ++ reg = <0x12010000 0x1000>; ++ }; ++ ++ gic: interrupt-controller@10300000 { ++ compatible = "arm,cortex-a7-gic"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ /* gic dist base, gic cpu base , no virtual support */ ++ reg = <0x10301000 0x1000>, <0x10302000 0x100>; ++ }; ++ ++ syscounter { ++ compatible = "arm,armv7-timer"; ++ interrupt-parent = <&gic>; ++ interrupts = <1 13 0xf08>, ++ <1 14 0xf08>; ++ clock-frequency = <50000000>; ++ }; ++ ++ soc { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ clk_3m: clk_3m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <3000000>; ++ }; ++ ++ clk_apb: clk_apb { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <50000000>; ++ }; ++ ++ pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ sysctrl: system-controller@12020000 { ++ compatible = "goke,sysctrl"; ++ reg = <0x12020000 0x1000>; ++ reboot-offset = <0x4>; ++ #clock-cells = <1>; ++ }; ++ ++ iocfg_ctrl: iocfg-controller@100c0000 { ++ compatible = "syscon"; ++ reg = <0x100C0000 0x10000>; ++ }; ++ ++#ifdef CONFIG_EDMAC ++ edmac: edma-controller@100B0000 { ++ compatible = "goke,edmac"; ++ reg = <0x100B0000 0x1000>; ++ interrupts = <0 38 4>; ++ clocks = <&clock GK7205V300_EDMAC_CLK>, <&clock GK7205V300_EDMAC_AXICLK>; ++ clock-names = "apb_pclk", "axi_aclk"; ++ clock-cells = <2>; ++ resets = <&clock 0x194 0>; ++ reset-names = "dma-reset"; ++ dma-requests = <32>; ++ dma-channels = <4>; ++ devid = <0>; ++ #dma-cells = <2>; ++ status = "okay"; ++ }; ++#endif ++ amba { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "arm,amba-bus"; ++ ranges; ++ ++ dual_timer0: dual_timer@12000000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer0 & timer1 */ ++ interrupts = <0 5 4>; ++ reg = <0x12000000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer00", "timer01", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dual_timer1: dual_timer@12001000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer2 & timer3 */ ++ interrupts = <0 6 4>; ++ reg = <0x12001000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer10", "timer11", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart0: uart@12040000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12040000 0x1000>; ++ interrupts = <0 7 4>; ++ clocks = <&clock GK7205V300_UART0_CLK>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart1: uart@12041000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12041000 0x1000>; ++ interrupts = <0 8 4>; ++ clocks = <&clock GK7205V300_UART1_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 19 19>, <&edmac 18 18>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ uart2: uart@12042000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12042000 0x1000>; ++ interrupts = <0 9 4>; ++ clocks = <&clock GK7205V300_UART2_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 21 21>, <&edmac 20 20>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ }; ++ ++ i2c_bus0: i2c@12060000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12060000 0x1000>; ++ clocks = <&clock GK7205V300_I2C0_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus1: i2c@12061000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12061000 0x1000>; ++ clocks = <&clock GK7205V300_I2C1_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus2: i2c@12062000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12062000 0x1000>; ++ clocks = <&clock GK7205V300_I2C2_CLK>; ++ status = "disabled"; ++ }; ++ ++ spi_bus0: spi@12070000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12070000 0x1000>; ++ interrupts = <0 14 4>; ++ clocks = <&clock GK7205V300_SPI0_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 27 27>, <&edmac 26 26>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ spi_bus1: spi@12071000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12071000 0x1000>, <0x12028000 0x4>; ++ interrupts = <0 15 4>; ++ clocks = <&clock GK7205V300_SPI1_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ num-cs = <2>; ++ spi_cs_sb = <2>; ++ spi_cs_mask_bit = <0x4>;//0100 ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 29 29>, <&edmac 28 28>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ mdio0: mdio@10041100 { ++ compatible = "goke,femac-mdio"; ++ reg = <0x10041100 0x10>,<0x12028024 0x4>; ++ clocks = <&clock GK7205V300_ETH0_CLK>; ++ clock-names = "mdio"; ++ resets = <&clock 0x16c 3>; ++ reset-names = "internal-phy"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ femac: ethernet@10040000 { ++ compatible = "goke,femac"; ++ reg = <0x10040000 0x1000>,<0x10041300 0x200>; ++ interrupts = <0 33 4>; ++ clocks = <&clock GK7205V300_ETH0_CLK>; ++ resets = <&clock 0x16c 0>; ++ reset-names = "mac"; ++ }; ++ ++ fmc: flash-memory-controller@10000000 { ++ compatible = "goke,fmc"; ++ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; ++ reg-names = "control", "memory"; ++ clocks = <&clock GK7205V300_FMC_CLK>; ++ max-dma-size = <0x2000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sfc:spi-nor@0 { ++ compatible = "goke,fmc-spi-nor"; ++ assigned-clocks = <&clock GK7205V300_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ snfc:spi-nand@0 { ++ compatible = "goke,fmc-spi-nand"; ++ assigned-clocks = <&clock GK7205V300_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ ++ mmc0: sdhci@0x10010000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10010000 0x1000>; ++ interrupts = <0 30 4>; ++ clocks = <&clock GK7205V300_MMC0_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <90000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl>; ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ cap-sd-highspeed; ++ mmc-hs200-1_8v; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ full-pwr-cycle; ++ devid = <0>; ++ status = "enable"; ++ }; ++ ++ mmc1: sdhci@0x10020000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10020000 0x1000>; ++ interrupts = <0 31 4>; ++ clocks = <&clock GK7205V300_MMC1_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <50000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl>; ++ bus-width = <4>; ++ cap-sd-highspeed; ++ full-pwr-cycle; ++ devid = <2>; ++ status = "enable"; ++ }; ++ ++ usb2_phy0: phy2-0 { ++ compatible = "goke,usbp2-phy"; ++ reg = <0x100D0000 0x1000>, ++ <0x12010000 0x1000>, ++ <0x100c0000 0x1000>; ++ clocks = <&clock GK7205V300_USB2_PHY_APB_CLK>, ++ <&clock GK7205V300_USB2_PHY_PLL_CLK>, ++ <&clock GK7205V300_USB2_PHY_XO_CLK>; ++ clock-names = "clk_u2phy_apb_ref", ++ "clk_u2phy_pll_ref", ++ "clk_u2phy_xo_ref"; ++ resets = <&clock 0x140 0>, ++ <&clock 0x140 1>; ++ reset-names = "phy_por_reset", ++ "phy_tpor_reset"; ++ phy_pll_offset = <0x14>; ++ phy_pll_mask = <0x03>; ++ phy_pll_val = <0x00>; ++ crg_offset = <0x140>; ++ crg_defal_mask = <0x0c07>; ++ crg_defal_val = <0x0807>; ++ vbus_offset = <0x7c>; ++ vbus_val = <0x0431>; ++ pwren_offset = <0x80>; ++ pwren_val = <0x1>; ++ ana_cfg_0_eye_val = <0x0433cc23>; ++ ana_cfg_0_offset = <0x00>; ++ ana_cfg_2_eye_val = <0x00320f0f>; ++ ana_cfg_2_offset = <0x08>; ++ ana_cfg_4_eye_val = <0x655>; ++ ana_cfg_4_offset = <0x10>; ++ trim_otp_addr = <0x12028004>; ++ trim_otp_mask = <0x1f>; ++ trim_otp_bit_offset = <0x00>; ++ trim_otp_min = <0x09>; ++ trim_otp_max = <0x1d>; ++ #phy-cells = <0>; ++ }; ++ ++ usbdrd3_0: usb3-0{ ++ compatible = "goke,dwusb2"; ++ reg = <0x10030000 0x10000>, ++ <0x12010000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ crg_offset = <0x140>; ++ crg_ctrl_def_mask = <0x3308>; ++ crg_ctrl_def_val = <0x1308>; ++ clocks = <&clock GK7205V300_USB2_BUS_CLK>, ++ <&clock GK7205V300_USB2_REF_CLK>, ++ <&clock GK7205V300_USB2_UTMI_CLK>; ++ clock-names = "usb2_bus_clk", ++ "usb2_ref_clk", ++ "usb2_utmi_clk"; ++ resets = <&clock 0x140 3>; ++ reset-names = "vcc_reset"; ++ ranges; ++ ++ dwc3@0x100e0000 { ++ compatible = "snps,dwc3"; ++ reg = <0x10030000 0x10000>; ++ interrupts = <0 39 4>; ++ interrupt-names = "peripheral"; ++ phys = <&usb2_phy0>; ++ phy-names = "usb2-phy"; ++ maximum-speed = "high-speed"; ++ dr_mode = "host"; ++ eps_directions = <0x6a>; ++ snps,eps_new_init; ++ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; ++ snps,usb2-lpm-disable; ++ }; ++ }; ++ ++ gpio_chip0: gpio_chip@120b0000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b0000 0x1000>; ++ interrupts = <0 16 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip1: gpio_chip@120b1000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b1000 0x1000>; ++ interrupts = <0 17 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip2: gpio_chip@120b2000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b2000 0x1000>; ++ interrupts = <0 18 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip3: gpio_chip@120b3000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b3000 0x1000>; ++ interrupts = <0 19 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip4: gpio_chip@120b4000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b4000 0x1000>; ++ interrupts = <0 20 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip5: gpio_chip@120b5000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b5000 0x1000>; ++ interrupts = <0 21 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip6: gpio_chip@120b6000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b6000 0x1000>; ++ interrupts = <0 22 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip7: gpio_chip@120b7000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b7000 0x1000>; ++ interrupts = <0 23 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip8: gpio_chip@120b8000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b8000 0x1000>; ++ interrupts = <0 24 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip9: gpio_chip@120b9000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b9000 0x1000>; ++ interrupts = <0 25 4>; ++ clocks = <&clock GK7205V300_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ rtc: rtc@120e0000 { ++ compatible = "goke,rtc"; ++ reg = <0x120e0000 0x1000>; ++ interrupts = <0 0 4>; ++ }; ++ ++ cipher: cipher@0x10050000 { ++ compatible = "goke,cipher"; ++ reg = <0x10050000 0x10000>; ++ reg-names = "cipher"; ++ interrupts = <0 34 4>, <0 34 4>; ++ interrupt-names = "cipher", "hash"; ++ }; ++ ++ adc: adc@120a0000 { ++ compatible = "goke,lsadc"; ++ reg = <0x120a0000 0x1000>; ++ interrupts = <0 4 4>; ++ interrupt-names = "adc"; ++ resets = <&clock 0x1bc 2>; ++ reset-names = "lsadc-crg"; ++ status = "okay"; ++ }; ++ ++ wdg: wdg@0x12030000 { ++ compatible = "goke,wdg"; ++ reg = <0x12030000 0x1000>; ++ reg-names = "wdg"; ++ interrupts = <0 2 4>; ++ interrupt-names = "wdg"; ++ }; ++ }; ++ ++ media { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ osal: osal { ++ compatible = "goke,osal"; ++ }; ++ ++ sys: sys@12010000 { ++ compatible = "goke,sys"; ++ }; ++ ++ mipi: mipi@0x11240000 { ++ compatible = "goke,mipi"; ++ reg = <0x11240000 0x10000>; ++ reg-names = "mipi_rx"; ++ interrupts = <0 45 4>; ++ interrupt-names = "mipi_rx"; ++ }; ++ ++ vi: vi@11000000 { ++ compatible = "goke,vi"; ++ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; ++ reg-names = "VI_CAP0", "VI_PROC0"; ++ interrupts = <0 43 4>, <0 44 4>; ++ interrupt-names = "VI_CAP0", "VI_PROC0"; ++ }; ++ ++ isp: isp@11220000 { ++ compatible = "goke,isp"; ++ reg = <0x11220000 0x20000>; ++ reg-names = "ISP"; ++ interrupts = <0 43 4>; ++ interrupt-names = "ISP"; ++ }; ++ ++ vpss: vpss@11400000 { ++ compatible = "goke,vpss"; ++ reg = <0x11400000 0x10000>; ++ reg-names = "vpss0"; ++ interrupts = <0 46 4>; ++ interrupt-names = "vpss0"; ++ }; ++ ++ vo: vo@11280000 { ++ compatible = "goke,vo"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "vo"; ++ interrupts = <0 40 4>; ++ interrupt-names = "vo"; ++ }; ++ ++ gfbg: gfbg@11280000 { ++ compatible = "goke,gfbg"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "gfbg"; ++ interrupts = <0 41 4>; ++ interrupt-names = "gfbg"; ++ }; ++ ++ vgs: vgs@11300000 { ++ compatible = "goke,vgs"; ++ reg = <0x11300000 0x10000>; ++ reg-names = "vgs0"; ++ interrupts = <0 49 4>; ++ interrupt-names = "vgs0"; ++ }; ++ ++ gzip: gzip@11310000 { ++ compatible = "goke,gzip"; ++ reg = <0x11310000 0x10000>; ++ reg-names = "gzip"; ++ interrupts = <0 50 4>; ++ interrupt-names = "gzip"; ++ }; ++ ++ vedu: vedu@11410000 { ++ compatible = "goke,vedu"; ++ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; ++ reg-names = "vedu0", "jpge"; ++ interrupts = <0 47 4>, <0 48 4>; ++ interrupt-names = "vedu0","jpge"; ++ }; ++ ++ venc: venc { ++ compatible = "goke,venc"; ++ }; ++ ++ aiao: aiao@100e0000 { ++ compatible = "goke,aiao"; ++ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; ++ reg-names = "aiao","acodec"; ++ interrupts = <0 42 4>; ++ interrupt-names = "AIO"; ++ }; ++ ++ ive: ive@11320000 { ++ compatible = "goke,ive"; ++ reg = <0x11320000 0x10000>; ++ reg-names = "ive"; ++ interrupts = <0 51 4>; ++ interrupt-names = "ive"; ++ }; ++ }; ++}; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7605v100-demb.dts.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7605v100-demb.dts.patch new file mode 100644 index 00000000..ee09a3c8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7605v100-demb.dts.patch @@ -0,0 +1,162 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7605v100-demb.dts 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7605v100-demb.dts 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++/dts-v1/; ++#include "gk7605v100.dtsi" ++ ++/ { ++ model = "Goke GK7605V100 DEMO Board"; ++ compatible = "goke,gk7605v100"; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x40000000 0x20000000>; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "disabled"; ++}; ++ ++&uart2 { ++ status = "disabled"; ++}; ++ ++&i2c_bus0 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus1 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&i2c_bus2 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&spi_bus0{ ++ status = "okay"; ++ num-cs = <1>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&spi_bus1{ ++ status = "okay"; ++ num-cs = <2>; ++ ++ spidev@0 { ++ compatible = "rohm,dh2228fv"; ++ reg = <0>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++ spidev@1 { ++ compatible = "rohm,dh2228fv"; ++ reg = <1>; ++ pl022,interface = <0>; ++ pl022,com-mode = <0>; ++ spi-max-frequency = <50000000>; ++ }; ++}; ++ ++&dual_timer0 { ++ status = "okay"; ++}; ++ ++&mdio0 { ++ goke,phy-reset-delays-us = <10000 20000 150000>; ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&femac { ++ mac-address = [00 00 00 00 00 00]; ++ phy-mode = "mii"; ++ phy-handle = <&phy0>; ++ status = "okay"; ++}; ++ ++&sfc { ++ sfc { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&snfc { ++ nand { ++ compatible = "jedec,spi-nand"; ++ reg = <0>; ++ spi-max-frequency = <160000000>; ++ }; ++}; ++ ++&mmc0 { ++ status = "okay"; ++}; ++ ++&mmc1 { ++ status = "okay"; ++}; ++ ++&gpio_chip0 { ++ status = "okay"; ++}; ++ ++&gpio_chip1 { ++ status = "okay"; ++}; ++ ++&gpio_chip2 { ++ status = "okay"; ++}; ++ ++&gpio_chip3 { ++ status = "okay"; ++}; ++ ++&gpio_chip4 { ++ status = "okay"; ++}; ++ ++&gpio_chip5 { ++ status = "okay"; ++}; ++ ++&gpio_chip6 { ++ status = "okay"; ++}; ++ ++&gpio_chip7 { ++ status = "okay"; ++}; ++ ++&gpio_chip8 { ++ status = "okay"; ++}; ++ ++&gpio_chip9 { ++ status = "okay"; ++}; ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7605v100.dtsi.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7605v100.dtsi.patch new file mode 100644 index 00000000..23cde51a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-boot-dts-gk7605v100.dtsi.patch @@ -0,0 +1,647 @@ +--- linux-4.9.37/arch/arm/boot/dts/gk7605v100.dtsi 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/boot/dts/gk7605v100.dtsi 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,644 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include "skeleton.dtsi" ++#include ++/ { ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ i2c0 = &i2c_bus0; ++ i2c1 = &i2c_bus1; ++ i2c2 = &i2c_bus2; ++ spi0 = &spi_bus0; ++ spi1 = &spi_bus1; ++ gpio0 = &gpio_chip0; ++ gpio1 = &gpio_chip1; ++ gpio2 = &gpio_chip2; ++ gpio3 = &gpio_chip3; ++ gpio4 = &gpio_chip4; ++ gpio5 = &gpio_chip5; ++ gpio6 = &gpio_chip6; ++ gpio7 = &gpio_chip7; ++ gpio8 = &gpio_chip8; ++ gpio9 = &gpio_chip9; ++ }; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ enable-method = "goke,gk7605v100"; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ clock-frequency = ; ++ reg = <0>; ++ }; ++ }; ++ ++ pmu { ++ compatible = "arm,armv7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ clock: clock@12010000 { ++ compatible = "goke,gk7605v100-clock", "syscon"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ #clock-cells = <1>; ++ #reset-cells = <2>; ++ reg = <0x12010000 0x1000>; ++ }; ++ ++ gic: interrupt-controller@10300000 { ++ compatible = "arm,cortex-a7-gic"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ /* gic dist base, gic cpu base , no virtual support */ ++ reg = <0x10301000 0x1000>, <0x10302000 0x100>; ++ }; ++ ++ syscounter { ++ compatible = "arm,armv7-timer"; ++ interrupt-parent = <&gic>; ++ interrupts = <1 13 0xf08>, ++ <1 14 0xf08>; ++ clock-frequency = <50000000>; ++ }; ++ ++ soc { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ clk_3m: clk_3m { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <3000000>; ++ }; ++ ++ clk_apb: clk_apb { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <50000000>; ++ }; ++ ++ pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = <0 58 4>; ++ }; ++ ++ sysctrl: system-controller@12020000 { ++ compatible = "goke,sysctrl"; ++ reg = <0x12020000 0x1000>; ++ reboot-offset = <0x4>; ++ #clock-cells = <1>; ++ }; ++ ++ iocfg_ctrl: iocfg-controller@100c0000 { ++ compatible = "syscon"; ++ reg = <0x100C0000 0x10000>; ++ }; ++ ++#ifdef CONFIG_EDMAC ++ edmac: edma-controller@100B0000 { ++ compatible = "goke,edmac"; ++ reg = <0x100B0000 0x1000>; ++ interrupts = <0 38 4>; ++ clocks = <&clock GK7605V100_EDMAC_CLK>, <&clock GK7605V100_EDMAC_AXICLK>; ++ clock-names = "apb_pclk", "axi_aclk"; ++ clock-cells = <2>; ++ resets = <&clock 0x194 0>; ++ reset-names = "dma-reset"; ++ dma-requests = <32>; ++ dma-channels = <4>; ++ devid = <0>; ++ #dma-cells = <2>; ++ status = "okay"; ++ }; ++#endif ++ amba { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "arm,amba-bus"; ++ ranges; ++ ++ dual_timer0: dual_timer@12000000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer0 & timer1 */ ++ interrupts = <0 5 4>; ++ reg = <0x12000000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer00", "timer01", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dual_timer1: dual_timer@12001000 { ++ compatible = "arm,sp804", "arm,primecell"; ++ /* timer2 & timer3 */ ++ interrupts = <0 6 4>; ++ reg = <0x12001000 0x1000>; ++ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; ++ clock-names = "timer10", "timer11", "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart0: uart@12040000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12040000 0x1000>; ++ interrupts = <0 7 4>; ++ clocks = <&clock GK7605V100_UART0_CLK>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ uart1: uart@12041000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12041000 0x1000>; ++ interrupts = <0 8 4>; ++ clocks = <&clock GK7605V100_UART1_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 19 19>, <&edmac 18 18>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ uart2: uart@12042000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x12042000 0x1000>; ++ interrupts = <0 9 4>; ++ clocks = <&clock GK7605V100_UART2_CLK>; ++ clock-names = "apb_pclk"; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 21 21>, <&edmac 20 20>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ }; ++ ++ i2c_bus0: i2c@12060000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12060000 0x1000>; ++ clocks = <&clock GK7605V100_I2C0_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus1: i2c@12061000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12061000 0x1000>; ++ clocks = <&clock GK7605V100_I2C1_CLK>; ++ status = "disabled"; ++ }; ++ ++ i2c_bus2: i2c@12062000 { ++ compatible = "goke,goke-i2c"; ++ reg = <0x12062000 0x1000>; ++ clocks = <&clock GK7605V100_I2C2_CLK>; ++ status = "disabled"; ++ }; ++ ++ spi_bus0: spi@12070000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12070000 0x1000>; ++ interrupts = <0 14 4>; ++ clocks = <&clock GK7605V100_SPI0_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 27 27>, <&edmac 26 26>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ spi_bus1: spi@12071000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ arm,primecell-periphid = <0x00041022>; ++ reg = <0x12071000 0x1000>, <0x12028000 0x4>; ++ interrupts = <0 15 4>; ++ clocks = <&clock GK7605V100_SPI1_CLK>; ++ clock-names = "apb_pclk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ num-cs = <2>; ++ spi_cs_sb = <2>; ++ spi_cs_mask_bit = <0x4>;//0100 ++#ifdef CONFIG_EDMAC ++ dmas = <&edmac 29 29>, <&edmac 28 28>; ++ dma-names = "tx","rx"; ++#endif ++ status = "disabled"; ++ }; ++ ++ mdio0: mdio@10041100 { ++ compatible = "goke,femac-mdio"; ++ reg = <0x10041100 0x10>,<0x12028024 0x4>; ++ clocks = <&clock GK7605V100_ETH0_CLK>; ++ clock-names = "mdio"; ++ resets = <&clock 0x16c 3>; ++ reset-names = "internal-phy"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ femac: ethernet@10040000 { ++ compatible = "goke,femac"; ++ reg = <0x10040000 0x1000>,<0x10041300 0x200>; ++ interrupts = <0 33 4>; ++ clocks = <&clock GK7605V100_ETH0_CLK>; ++ resets = <&clock 0x16c 0>; ++ reset-names = "mac"; ++ }; ++ ++ fmc: flash-memory-controller@10000000 { ++ compatible = "goke,fmc"; ++ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; ++ reg-names = "control", "memory"; ++ clocks = <&clock GK7605V100_FMC_CLK>; ++ max-dma-size = <0x2000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sfc:spi-nor@0 { ++ compatible = "goke,fmc-spi-nor"; ++ assigned-clocks = <&clock GK7605V100_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ snfc:spi-nand@0 { ++ compatible = "goke,fmc-spi-nand"; ++ assigned-clocks = <&clock GK7605V100_FMC_CLK>; ++ assigned-clock-rates = <24000000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ ++ mmc0: sdhci@0x10010000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10010000 0x1000>; ++ interrupts = <0 30 4>; ++ clocks = <&clock GK7605V100_MMC0_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <90000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl>; ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ cap-mmc-hw-reset; ++ cap-sd-highspeed; ++ mmc-hs200-1_8v; ++ mmc-hs400-1_8v; ++ mmc-hs400-enhanced-strobe; ++ full-pwr-cycle; ++ devid = <0>; ++ status = "enable"; ++ }; ++ ++ mmc1: sdhci@0x10020000 { ++ compatible = "goke,sdhci"; ++ reg = <0x10020000 0x1000>; ++ interrupts = <0 31 4>; ++ clocks = <&clock GK7605V100_MMC1_CLK>; ++ clock-names = "mmc_clk"; ++ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; ++ reset-names = "crg_reset", "dll_reset"; ++ max-frequency = <50000000>; ++ crg_regmap = <&clock>; ++ iocfg_regmap = <&iocfg_ctrl>; ++ bus-width = <4>; ++ cap-sd-highspeed; ++ full-pwr-cycle; ++ devid = <2>; ++ status = "enable"; ++ }; ++ ++ usb2_phy0: phy2-0 { ++ compatible = "goke,usbp2-phy"; ++ reg = <0x100D0000 0x1000>, ++ <0x12010000 0x1000>, ++ <0x100c0000 0x1000>; ++ clocks = <&clock GK7605V100_USB2_PHY_APB_CLK>, ++ <&clock GK7605V100_USB2_PHY_PLL_CLK>, ++ <&clock GK7605V100_USB2_PHY_XO_CLK>; ++ clock-names = "clk_u2phy_apb_ref", ++ "clk_u2phy_pll_ref", ++ "clk_u2phy_xo_ref"; ++ resets = <&clock 0x140 0>, ++ <&clock 0x140 1>; ++ reset-names = "phy_por_reset", ++ "phy_tpor_reset"; ++ phy_pll_offset = <0x14>; ++ phy_pll_mask = <0x03>; ++ phy_pll_val = <0x00>; ++ crg_offset = <0x140>; ++ crg_defal_mask = <0x0c07>; ++ crg_defal_val = <0x0807>; ++ vbus_offset = <0x7c>; ++ vbus_val = <0x0431>; ++ pwren_offset = <0x80>; ++ pwren_val = <0x1>; ++ ana_cfg_0_eye_val = <0x0433cc23>; ++ ana_cfg_0_offset = <0x00>; ++ ana_cfg_2_eye_val = <0x00320f0f>; ++ ana_cfg_2_offset = <0x08>; ++ ana_cfg_4_eye_val = <0x655>; ++ ana_cfg_4_offset = <0x10>; ++ trim_otp_addr = <0x12028004>; ++ trim_otp_mask = <0x1f>; ++ trim_otp_bit_offset = <0x00>; ++ trim_otp_min = <0x09>; ++ trim_otp_max = <0x1d>; ++ #phy-cells = <0>; ++ }; ++ ++ usbdrd3_0: usb3-0{ ++ compatible = "goke,dwusb2"; ++ reg = <0x10030000 0x10000>, ++ <0x12010000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ crg_offset = <0x140>; ++ crg_ctrl_def_mask = <0x3308>; ++ crg_ctrl_def_val = <0x1308>; ++ clocks = <&clock GK7605V100_USB2_BUS_CLK>, ++ <&clock GK7605V100_USB2_REF_CLK>, ++ <&clock GK7605V100_USB2_UTMI_CLK>; ++ clock-names = "usb2_bus_clk", ++ "usb2_ref_clk", ++ "usb2_utmi_clk"; ++ resets = <&clock 0x140 3>; ++ reset-names = "vcc_reset"; ++ ranges; ++ ++ dwc3@0x100e0000 { ++ compatible = "snps,dwc3"; ++ reg = <0x10030000 0x10000>; ++ interrupts = <0 39 4>; ++ interrupt-names = "peripheral"; ++ phys = <&usb2_phy0>; ++ phy-names = "usb2-phy"; ++ maximum-speed = "high-speed"; ++ dr_mode = "host"; ++ eps_directions = <0x6a>; ++ snps,eps_new_init; ++ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; ++ snps,usb2-lpm-disable; ++ }; ++ }; ++ ++ gpio_chip0: gpio_chip@120b0000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b0000 0x1000>; ++ interrupts = <0 16 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip1: gpio_chip@120b1000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b1000 0x1000>; ++ interrupts = <0 17 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip2: gpio_chip@120b2000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b2000 0x1000>; ++ interrupts = <0 18 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip3: gpio_chip@120b3000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b3000 0x1000>; ++ interrupts = <0 19 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip4: gpio_chip@120b4000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b4000 0x1000>; ++ interrupts = <0 20 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip5: gpio_chip@120b5000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b5000 0x1000>; ++ interrupts = <0 21 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip6: gpio_chip@120b6000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b6000 0x1000>; ++ interrupts = <0 22 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip7: gpio_chip@120b7000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b7000 0x1000>; ++ interrupts = <0 23 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip8: gpio_chip@120b8000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b8000 0x1000>; ++ interrupts = <0 24 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_chip9: gpio_chip@120b9000 { ++ compatible = "arm,pl061", "arm,primecell"; ++ reg = <0x120b9000 0x1000>; ++ interrupts = <0 25 4>; ++ clocks = <&clock GK7605V100_SYSAPB_CLK>; ++ clock-names = "apb_pclk"; ++ #gpio-cells = <2>; ++ status = "disabled"; ++ }; ++ ++ rtc: rtc@120e0000 { ++ compatible = "goke,rtc"; ++ reg = <0x120e0000 0x1000>; ++ interrupts = <0 0 4>; ++ }; ++ ++ cipher: cipher@0x10050000 { ++ compatible = "goke,cipher"; ++ reg = <0x10050000 0x10000>; ++ reg-names = "cipher"; ++ interrupts = <0 34 4>, <0 34 4>; ++ interrupt-names = "cipher", "hash"; ++ }; ++ ++ adc: adc@120a0000 { ++ compatible = "goke,lsadc"; ++ reg = <0x120a0000 0x1000>; ++ interrupts = <0 4 4>; ++ interrupt-names = "adc"; ++ resets = <&clock 0x1bc 2>; ++ reset-names = "lsadc-crg"; ++ status = "okay"; ++ }; ++ ++ wdg: wdg@0x12030000 { ++ compatible = "goke,wdg"; ++ reg = <0x12030000 0x1000>; ++ reg-names = "wdg"; ++ interrupts = <0 2 4>; ++ interrupt-names = "wdg"; ++ }; ++ }; ++ ++ media { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ interrupt-parent = <&gic>; ++ ranges; ++ ++ osal: osal { ++ compatible = "goke,osal"; ++ }; ++ ++ sys: sys@12010000 { ++ compatible = "goke,sys"; ++ }; ++ ++ mipi: mipi@0x11240000 { ++ compatible = "goke,mipi"; ++ reg = <0x11240000 0x10000>; ++ reg-names = "mipi_rx"; ++ interrupts = <0 45 4>; ++ interrupt-names = "mipi_rx"; ++ }; ++ ++ vi: vi@11000000 { ++ compatible = "goke,vi"; ++ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; ++ reg-names = "VI_CAP0", "VI_PROC0"; ++ interrupts = <0 43 4>, <0 44 4>; ++ interrupt-names = "VI_CAP0", "VI_PROC0"; ++ }; ++ ++ isp: isp@11220000 { ++ compatible = "goke,isp"; ++ reg = <0x11220000 0x20000>; ++ reg-names = "ISP"; ++ interrupts = <0 43 4>; ++ interrupt-names = "ISP"; ++ }; ++ ++ vpss: vpss@11400000 { ++ compatible = "goke,vpss"; ++ reg = <0x11400000 0x10000>; ++ reg-names = "vpss0"; ++ interrupts = <0 46 4>; ++ interrupt-names = "vpss0"; ++ }; ++ ++ vo: vo@11280000 { ++ compatible = "goke,vo"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "vo"; ++ interrupts = <0 40 4>; ++ interrupt-names = "vo"; ++ }; ++ ++ gfbg: gfbg@11280000 { ++ compatible = "goke,gfbg"; ++ reg = <0x11280000 0x40000>; ++ reg-names = "gfbg"; ++ interrupts = <0 41 4>; ++ interrupt-names = "gfbg"; ++ }; ++ ++ vgs: vgs@11300000 { ++ compatible = "goke,vgs"; ++ reg = <0x11300000 0x10000>; ++ reg-names = "vgs0"; ++ interrupts = <0 49 4>; ++ interrupt-names = "vgs0"; ++ }; ++ ++ gzip: gzip@11310000 { ++ compatible = "goke,gzip"; ++ reg = <0x11310000 0x10000>; ++ reg-names = "gzip"; ++ interrupts = <0 50 4>; ++ interrupt-names = "gzip"; ++ }; ++ ++ vedu: vedu@11410000 { ++ compatible = "goke,vedu"; ++ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; ++ reg-names = "vedu0", "jpge"; ++ interrupts = <0 47 4>, <0 48 4>; ++ interrupt-names = "vedu0","jpge"; ++ }; ++ ++ venc: venc { ++ compatible = "goke,venc"; ++ }; ++ ++ aiao: aiao@100e0000 { ++ compatible = "goke,aiao"; ++ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; ++ reg-names = "aiao","acodec"; ++ interrupts = <0 42 4>; ++ interrupt-names = "AIO"; ++ }; ++ ++ ive: ive@11320000 { ++ compatible = "goke,ive"; ++ reg = <0x11320000 0x10000>; ++ reg-names = "ive"; ++ interrupts = <0 51 4>; ++ interrupt-names = "ive"; ++ }; ++ }; ++}; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_emmc_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_emmc_defconfig.patch new file mode 100644 index 00000000..06a1e97e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_emmc_defconfig.patch @@ -0,0 +1,2861 @@ +--- linux-4.9.37/arch/arm/configs/gk7202v300_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7202v300_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2858 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++# CONFIG_ARCH_GK7205V200 is not set ++# CONFIG_ARCH_GK7205V300 is not set ++CONFIG_ARCH_GK7202V300=y ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++# CONFIG_NETDEVICES is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=y ++CONFIG_USB_U_ETHER=y ++CONFIG_USB_F_ECM=y ++CONFIG_USB_F_RNDIS=y ++CONFIG_USB_CONFIGFS=y ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++# CONFIG_USB_CONFIGFS_ACM is not set ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7202V300=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_full_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_full_defconfig.patch new file mode 100644 index 00000000..6728cd8c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_full_defconfig.patch @@ -0,0 +1,2861 @@ +--- linux-4.9.37/arch/arm/configs/gk7202v300_full_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7202v300_full_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2858 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++# CONFIG_ARCH_GK7205V200 is not set ++# CONFIG_ARCH_GK7205V300 is not set ++CONFIG_ARCH_GK7202V300=y ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++# CONFIG_NETDEVICES is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=y ++CONFIG_USB_U_ETHER=y ++CONFIG_USB_F_ECM=y ++CONFIG_USB_F_RNDIS=y ++CONFIG_USB_CONFIGFS=y ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++# CONFIG_USB_CONFIGFS_ACM is not set ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7202V300=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_mini_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_mini_defconfig.patch new file mode 100644 index 00000000..729ed5db --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7202v300_mini_defconfig.patch @@ -0,0 +1,1794 @@ +--- linux-4.9.37/arch/arm/configs/gk7202v300_mini_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7202v300_mini_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,1791 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++# CONFIG_KERNEL_GZIP is not set ++# CONFIG_KERNEL_LZMA is not set ++CONFIG_KERNEL_XZ=y ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++# CONFIG_CGROUP_FREEZER is not set ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++# CONFIG_BLK_DEV_INITRD is not set ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++# CONFIG_ARCH_GK7205V200 is not set ++# CONFIG_ARCH_GK7205V300 is not set ++CONFIG_ARCH_GK7202V300=y ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++# CONFIG_ARM_THUMB is not set ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++# CONFIG_VDSO is not set ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++# CONFIG_ARM_PATCH_IDIV is not set ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++# CONFIG_PACKET is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++# CONFIG_NET_KEY is not set ++# CONFIG_INET is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_STREAM_PARSER is not set ++# CONFIG_WIRELESS is not set ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++# CONFIG_UEVENT_HELPER is not set ++# CONFIG_DEVTMPFS is not set ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++# CONFIG_FIRMWARE_IN_KERNEL is not set ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_MMIO=y ++# CONFIG_DMA_SHARED_BUFFER is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++# CONFIG_MTD_NAND is not set ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++CONFIG_CLOSE_SPI_8PIN_4IO=y ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++# CONFIG_MTD_UBI is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++ ++# ++# DRBD disabled because PROC_FS or INET not selected ++# ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_DMA is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_NETDEVICES is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_TAOS_EVM is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_FSL_SPI is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_SINGLE is not set ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++# CONFIG_GPIOLIB is not set ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++# CONFIG_MEDIA_SUPPORT is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++# CONFIG_HID is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_UWB is not set ++# CONFIG_MMC is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++# CONFIG_RTC_CLASS is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7202V300=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++# CONFIG_GENERIC_PHY is not set ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++# CONFIG_PHY_GOKE_USBP2 is not set ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++# CONFIG_EXT4_FS is not set ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++# CONFIG_FS_POSIX_ACL is not set ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++# CONFIG_MANDATORY_FILE_LOCKING is not set ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++# CONFIG_ISO9660_FS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++# CONFIG_MSDOS_FS is not set ++# CONFIG_VFAT_FS is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_TMPFS_XATTR is not set ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++# CONFIG_YAFFS_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++# CONFIG_LOGFS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++# CONFIG_NLS_CODEPAGE_437 is not set ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++# CONFIG_NLS_ISO8859_1 is not set ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++# CONFIG_NLS_UTF8 is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++# CONFIG_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC_T10DIF is not set ++# CONFIG_CRC_ITU_T is not set ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++# CONFIG_LIBCRC32C is not set ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++# CONFIG_SG_SPLIT is not set ++# CONFIG_SG_POOL is not set ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_emmc_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_emmc_defconfig.patch new file mode 100644 index 00000000..e0d20d03 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_emmc_defconfig.patch @@ -0,0 +1,2978 @@ +--- linux-4.9.37/arch/arm/configs/gk7205v200_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7205v200_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2975 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++CONFIG_ARCH_GK7205V200=y ++# CONFIG_ARCH_GK7205V300 is not set ++# CONFIG_ARCH_GK7202V300 is not set ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++CONFIG_NETDEVICES=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_VXLAN is not set ++# CONFIG_MACSEC is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_VETH is not set ++# CONFIG_NLMON is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_GOKE=y ++CONFIG_GOKE_FEMAC=y ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++CONFIG_NET_VENDOR_MICROCHIP=y ++# CONFIG_ENC28J60 is not set ++# CONFIG_ENCX24J600 is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++ ++# ++# MDIO bus device drivers ++# ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++CONFIG_MDIO_GOKE_FEMAC=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_USB_NET_DRIVERS is not set ++# CONFIG_WLAN is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=m ++CONFIG_USB_F_ACM=m ++CONFIG_USB_U_SERIAL=m ++CONFIG_USB_U_ETHER=m ++CONFIG_USB_F_ECM=m ++CONFIG_USB_F_RNDIS=m ++CONFIG_USB_F_MASS_STORAGE=m ++CONFIG_USB_CONFIGFS=m ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++CONFIG_USB_CONFIGFS_ACM=y ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7205V200=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_full_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_full_defconfig.patch new file mode 100644 index 00000000..b01747b0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_full_defconfig.patch @@ -0,0 +1,2984 @@ +--- linux-4.9.37/arch/arm/configs/gk7205v200_full_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7205v200_full_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2981 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++CONFIG_ARCH_GK7205V200=y ++# CONFIG_ARCH_GK7205V300 is not set ++# CONFIG_ARCH_GK7202V300 is not set ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++CONFIG_NETDEVICES=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_VXLAN is not set ++# CONFIG_MACSEC is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_VETH is not set ++# CONFIG_NLMON is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_GOKE=y ++CONFIG_GOKE_FEMAC=y ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++CONFIG_NET_VENDOR_MICROCHIP=y ++# CONFIG_ENC28J60 is not set ++# CONFIG_ENCX24J600 is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++ ++# ++# MDIO bus device drivers ++# ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++CONFIG_MDIO_GOKE_FEMAC=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_USB_NET_DRIVERS is not set ++# CONFIG_WLAN is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_PWM_BEEPER is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=m ++CONFIG_USB_F_ACM=m ++CONFIG_USB_U_SERIAL=m ++CONFIG_USB_U_ETHER=m ++CONFIG_USB_F_ECM=m ++CONFIG_USB_F_RNDIS=m ++CONFIG_USB_F_MASS_STORAGE=m ++CONFIG_USB_CONFIGFS=m ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++CONFIG_USB_CONFIGFS_ACM=y ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PWM is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7205V200=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++CONFIG_PWM=y ++CONFIG_PWM_SYSFS=y ++# CONFIG_PWM_FSL_FTM is not set ++CONFIG_PWM_GOKE=y ++# CONFIG_PWM_PCA9685 is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_mini_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_mini_defconfig.patch new file mode 100644 index 00000000..4c6dfc42 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v200_mini_defconfig.patch @@ -0,0 +1,2053 @@ +--- linux-4.9.37/arch/arm/configs/gk7205v200_mini_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7205v200_mini_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2050 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++# CONFIG_KERNEL_GZIP is not set ++# CONFIG_KERNEL_LZMA is not set ++CONFIG_KERNEL_XZ=y ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++# CONFIG_CGROUP_FREEZER is not set ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++# CONFIG_BLK_DEV_INITRD is not set ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++CONFIG_ARCH_GK7205V200=y ++# CONFIG_ARCH_GK7205V300 is not set ++# CONFIG_ARCH_GK7202V300 is not set ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++# CONFIG_ARM_THUMB is not set ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++# CONFIG_VDSO is not set ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++# CONFIG_ARM_PATCH_IDIV is not set ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++# CONFIG_PACKET is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++# CONFIG_XFRM_USER is not set ++# CONFIG_NET_KEY is not set ++CONFIG_INET=y ++# CONFIG_IP_MULTICAST is not set ++# CONFIG_IP_ADVANCED_ROUTER is not set ++# CONFIG_IP_PNP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++# CONFIG_SYN_COOKIES is not set ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++# CONFIG_TCP_MD5SIG is not set ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++# CONFIG_WIRELESS is not set ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++# CONFIG_UEVENT_HELPER is not set ++# CONFIG_DEVTMPFS is not set ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++# CONFIG_FIRMWARE_IN_KERNEL is not set ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_MMIO=y ++# CONFIG_DMA_SHARED_BUFFER is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++# CONFIG_MTD_NAND is not set ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++# CONFIG_SPI_GOKE_SFC is not set ++CONFIG_CLOSE_SPI_8PIN_4IO=y ++# CONFIG_MTD_UBI is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_DMA is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++CONFIG_NETDEVICES=y ++# CONFIG_NET_CORE is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_GOKE=y ++CONFIG_GOKE_FEMAC=y ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++# CONFIG_NET_VENDOR_MICROCHIP is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++ ++# ++# MDIO bus device drivers ++# ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++CONFIG_MDIO_GOKE_FEMAC=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++ ++# ++# Host-side USB support is needed for USB Network Adapter support ++# ++# CONFIG_WLAN is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_TAOS_EVM is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_FSL_SPI is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_SINGLE is not set ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++# CONFIG_GPIOLIB is not set ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++# CONFIG_MFD_CORE is not set ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++# CONFIG_MFD_GOKE_FMC is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++# CONFIG_MEDIA_SUPPORT is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++# CONFIG_HID is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_UWB is not set ++# CONFIG_MMC is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++# CONFIG_RTC_CLASS is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7205V200=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++# CONFIG_GENERIC_PHY is not set ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++# CONFIG_PHY_GOKE_USBP2 is not set ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++# CONFIG_EXT4_FS is not set ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++# CONFIG_FS_POSIX_ACL is not set ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++# CONFIG_MANDATORY_FILE_LOCKING is not set ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++# CONFIG_ISO9660_FS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++# CONFIG_MSDOS_FS is not set ++# CONFIG_VFAT_FS is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_TMPFS_XATTR is not set ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++# CONFIG_YAFFS_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++# CONFIG_LOGFS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++# CONFIG_NFS_FS is not set ++# CONFIG_NFSD is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++# CONFIG_NLS_CODEPAGE_437 is not set ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++# CONFIG_NLS_ISO8859_1 is not set ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++# CONFIG_NLS_UTF8 is not set ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++# CONFIG_CRYPTO_MANAGER is not set ++# CONFIG_CRYPTO_MANAGER2 is not set ++# CONFIG_CRYPTO_USER is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++# CONFIG_CRYPTO_CCM is not set ++# CONFIG_CRYPTO_GCM is not set ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++# CONFIG_CRYPTO_SEQIV is not set ++# CONFIG_CRYPTO_ECHAINIV is not set ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++# CONFIG_CRYPTO_CTR is not set ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++# CONFIG_CRYPTO_HMAC is not set ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++# CONFIG_CRYPTO_GHASH is not set ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++# CONFIG_CRYPTO_MD5 is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_LZO is not set ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_DRBG_MENU is not set ++# CONFIG_CRYPTO_JITTERENTROPY is not set ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC_T10DIF is not set ++# CONFIG_CRC_ITU_T is not set ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++# CONFIG_LIBCRC32C is not set ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++# CONFIG_SG_SPLIT is not set ++# CONFIG_SG_POOL is not set ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v300_emmc_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v300_emmc_defconfig.patch new file mode 100644 index 00000000..f52cee54 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v300_emmc_defconfig.patch @@ -0,0 +1,2978 @@ +--- linux-4.9.37/arch/arm/configs/gk7205v300_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7205v300_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2975 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++# CONFIG_ARCH_GK7205V200 is not set ++CONFIG_ARCH_GK7205V300=y ++# CONFIG_ARCH_GK7202V300 is not set ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++CONFIG_NETDEVICES=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_VXLAN is not set ++# CONFIG_MACSEC is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_VETH is not set ++# CONFIG_NLMON is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_GOKE=y ++CONFIG_GOKE_FEMAC=y ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++CONFIG_NET_VENDOR_MICROCHIP=y ++# CONFIG_ENC28J60 is not set ++# CONFIG_ENCX24J600 is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++ ++# ++# MDIO bus device drivers ++# ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++CONFIG_MDIO_GOKE_FEMAC=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_USB_NET_DRIVERS is not set ++# CONFIG_WLAN is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=m ++CONFIG_USB_F_ACM=m ++CONFIG_USB_U_SERIAL=m ++CONFIG_USB_U_ETHER=m ++CONFIG_USB_F_ECM=m ++CONFIG_USB_F_RNDIS=m ++CONFIG_USB_F_MASS_STORAGE=m ++CONFIG_USB_CONFIGFS=m ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++CONFIG_USB_CONFIGFS_ACM=y ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7205V300=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v300_full_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v300_full_defconfig.patch new file mode 100644 index 00000000..6998c957 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7205v300_full_defconfig.patch @@ -0,0 +1,2978 @@ +--- linux-4.9.37/arch/arm/configs/gk7205v300_full_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7205v300_full_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2975 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++# CONFIG_ARCH_GK7205V200 is not set ++CONFIG_ARCH_GK7205V300=y ++# CONFIG_ARCH_GK7202V300 is not set ++# CONFIG_ARCH_GK7605V100 is not set ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++CONFIG_NETDEVICES=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_VXLAN is not set ++# CONFIG_MACSEC is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_VETH is not set ++# CONFIG_NLMON is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_GOKE=y ++CONFIG_GOKE_FEMAC=y ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++CONFIG_NET_VENDOR_MICROCHIP=y ++# CONFIG_ENC28J60 is not set ++# CONFIG_ENCX24J600 is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++ ++# ++# MDIO bus device drivers ++# ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++CONFIG_MDIO_GOKE_FEMAC=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_USB_NET_DRIVERS is not set ++# CONFIG_WLAN is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=m ++CONFIG_USB_F_ACM=m ++CONFIG_USB_U_SERIAL=m ++CONFIG_USB_U_ETHER=m ++CONFIG_USB_F_ECM=m ++CONFIG_USB_F_RNDIS=m ++CONFIG_USB_F_MASS_STORAGE=m ++CONFIG_USB_CONFIGFS=m ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++CONFIG_USB_CONFIGFS_ACM=y ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7205V300=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7605v100_emmc_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7605v100_emmc_defconfig.patch new file mode 100644 index 00000000..daef83c0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7605v100_emmc_defconfig.patch @@ -0,0 +1,2978 @@ +--- linux-4.9.37/arch/arm/configs/gk7605v100_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7605v100_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2975 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++# CONFIG_ARCH_GK7205V200 is not set ++# CONFIG_ARCH_GK7205V300 is not set ++# CONFIG_ARCH_GK7202V300 is not set ++CONFIG_ARCH_GK7605V100=y ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++CONFIG_NETDEVICES=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_VXLAN is not set ++# CONFIG_MACSEC is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_VETH is not set ++# CONFIG_NLMON is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_GOKE=y ++CONFIG_GOKE_FEMAC=y ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++CONFIG_NET_VENDOR_MICROCHIP=y ++# CONFIG_ENC28J60 is not set ++# CONFIG_ENCX24J600 is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++ ++# ++# MDIO bus device drivers ++# ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++CONFIG_MDIO_GOKE_FEMAC=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_USB_NET_DRIVERS is not set ++# CONFIG_WLAN is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=m ++CONFIG_USB_F_ACM=m ++CONFIG_USB_U_SERIAL=m ++CONFIG_USB_U_ETHER=m ++CONFIG_USB_F_ECM=m ++CONFIG_USB_F_RNDIS=m ++CONFIG_USB_F_MASS_STORAGE=m ++CONFIG_USB_CONFIGFS=m ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++CONFIG_USB_CONFIGFS_ACM=y ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7605V100=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7605v100_full_defconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7605v100_full_defconfig.patch new file mode 100644 index 00000000..49c715f7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-configs-gk7605v100_full_defconfig.patch @@ -0,0 +1,2978 @@ +--- linux-4.9.37/arch/arm/configs/gk7605v100_full_defconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/configs/gk7605v100_full_defconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,2975 @@ ++# ++# Automatically generated file; DO NOT EDIT. ++# Linux/arm 4.9.37 Kernel Configuration ++# ++CONFIG_ARM=y ++CONFIG_ARM_HAS_SG_CHAIN=y ++CONFIG_MIGHT_HAVE_PCI=y ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_HAVE_PROC_CPU=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++CONFIG_RWSEM_XCHGADD_ALGORITHM=y ++CONFIG_FIX_EARLYCON_MEM=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_ARCH_SUPPORTS_UPROBES=y ++CONFIG_VECTORS_BASE=0xffff0000 ++CONFIG_ARM_PATCH_PHYS_VIRT=y ++CONFIG_GENERIC_BUG=y ++CONFIG_PGTABLE_LEVELS=2 ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++CONFIG_IRQ_WORK=y ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++ ++# ++# General setup ++# ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_CROSS_COMPILE="" ++# CONFIG_COMPILE_TEST is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_HAVE_KERNEL_GZIP=y ++CONFIG_HAVE_KERNEL_LZMA=y ++CONFIG_HAVE_KERNEL_XZ=y ++CONFIG_HAVE_KERNEL_LZO=y ++CONFIG_HAVE_KERNEL_LZ4=y ++CONFIG_KERNEL_GZIP=y ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_XZ is not set ++# CONFIG_KERNEL_LZO is not set ++# CONFIG_KERNEL_LZ4 is not set ++CONFIG_DEFAULT_HOSTNAME="(none)" ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_CROSS_MEMORY_ATTACH=y ++CONFIG_FHANDLE=y ++CONFIG_USELIB=y ++# CONFIG_AUDIT is not set ++CONFIG_HAVE_ARCH_AUDITSYSCALL=y ++ ++# ++# IRQ subsystem ++# ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_IRQ_SHOW=y ++CONFIG_GENERIC_IRQ_SHOW_LEVEL=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_ARCH_CLOCKSOURCE_DATA=y ++CONFIG_GENERIC_TIME_VSYSCALL=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++ ++# ++# Timers subsystem ++# ++CONFIG_HZ_PERIODIC=y ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++ ++# ++# CPU/Task time and stats accounting ++# ++CONFIG_TICK_CPU_ACCOUNTING=y ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_TASKSTATS is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_TINY_RCU=y ++# CONFIG_RCU_EXPERT is not set ++CONFIG_SRCU=y ++# CONFIG_TASKS_RCU is not set ++# CONFIG_RCU_STALL_COMMON is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++# CONFIG_BUILD_BIN2C is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++CONFIG_GENERIC_SCHED_CLOCK=y ++CONFIG_CGROUPS=y ++# CONFIG_MEMCG is not set ++# CONFIG_BLK_CGROUP is not set ++# CONFIG_CGROUP_SCHED is not set ++# CONFIG_CGROUP_PIDS is not set ++CONFIG_CGROUP_FREEZER=y ++# CONFIG_CPUSETS is not set ++# CONFIG_CGROUP_DEVICE is not set ++# CONFIG_CGROUP_CPUACCT is not set ++# CONFIG_CGROUP_DEBUG is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++CONFIG_NAMESPACES=y ++CONFIG_UTS_NS=y ++CONFIG_IPC_NS=y ++# CONFIG_USER_NS is not set ++CONFIG_PID_NS=y ++CONFIG_NET_NS=y ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_RELAY is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_RD_GZIP=y ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_LZO is not set ++CONFIG_RD_LZ4=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_HAVE_UID16=y ++CONFIG_BPF=y ++# CONFIG_EXPERT is not set ++CONFIG_UID16=y ++CONFIG_MULTIUSER=y ++# CONFIG_SGETMASK_SYSCALL is not set ++CONFIG_SYSFS_SYSCALL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++CONFIG_PRINTK=y ++CONFIG_PRINTK_NMI=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++CONFIG_SIGNALFD=y ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++# CONFIG_BPF_SYSCALL is not set ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_USERFAULTFD is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_EMBEDDED is not set ++CONFIG_HAVE_PERF_EVENTS=y ++CONFIG_PERF_USE_VMALLOC=y ++ ++# ++# Kernel Performance Events And Counters ++# ++# CONFIG_PERF_EVENTS is not set ++CONFIG_VM_EVENT_COUNTERS=y ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_PROFILING is not set ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_UPROBES is not set ++# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set ++CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y ++CONFIG_ARCH_USE_BUILTIN_BSWAP=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HAVE_OPTPROBES=y ++CONFIG_HAVE_NMI=y ++CONFIG_HAVE_ARCH_TRACEHOOK=y ++CONFIG_HAVE_DMA_CONTIGUOUS=y ++CONFIG_GENERIC_SMP_IDLE_THREAD=y ++CONFIG_GENERIC_IDLE_POLL_SETUP=y ++CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y ++CONFIG_HAVE_CLK=y ++CONFIG_HAVE_DMA_API_DEBUG=y ++CONFIG_HAVE_PERF_REGS=y ++CONFIG_HAVE_PERF_USER_STACK_DUMP=y ++CONFIG_HAVE_ARCH_JUMP_LABEL=y ++CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y ++CONFIG_HAVE_ARCH_SECCOMP_FILTER=y ++CONFIG_HAVE_GCC_PLUGINS=y ++# CONFIG_GCC_PLUGINS is not set ++CONFIG_HAVE_CC_STACKPROTECTOR=y ++CONFIG_CC_STACKPROTECTOR=y ++# CONFIG_CC_STACKPROTECTOR_NONE is not set ++# CONFIG_CC_STACKPROTECTOR_REGULAR is not set ++CONFIG_CC_STACKPROTECTOR_STRONG=y ++CONFIG_HAVE_CONTEXT_TRACKING=y ++CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y ++CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y ++CONFIG_HAVE_MOD_ARCH_SPECIFIC=y ++CONFIG_MODULES_USE_ELF_REL=y ++CONFIG_ARCH_HAS_ELF_RANDOMIZE=y ++CONFIG_HAVE_ARCH_MMAP_RND_BITS=y ++CONFIG_HAVE_EXIT_THREAD=y ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS=8 ++# CONFIG_HAVE_ARCH_HASH is not set ++# CONFIG_ISA_BUS_API is not set ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_OLD_SIGSUSPEND3=y ++CONFIG_OLD_SIGACTION=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++# CONFIG_HAVE_ARCH_VMAP_STACK is not set ++ ++# ++# GCOV-based kernel profiling ++# ++CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y ++CONFIG_HAVE_GENERIC_DMA_COHERENT=y ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++CONFIG_BLOCK=y ++CONFIG_LBDAF=y ++CONFIG_BLK_DEV_BSG=y ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++CONFIG_BLK_CMDLINE_PARSER=y ++ ++# ++# Partition Types ++# ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_OSF_PARTITION is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_MAC_PARTITION is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_LDM_PARTITION is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_KARMA_PARTITION is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_CMDLINE_PARTITION=y ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++CONFIG_DEFAULT_DEADLINE=y ++# CONFIG_DEFAULT_CFQ is not set ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_INLINE_SPIN_UNLOCK_IRQ=y ++CONFIG_INLINE_READ_UNLOCK=y ++CONFIG_INLINE_READ_UNLOCK_IRQ=y ++CONFIG_INLINE_WRITE_UNLOCK=y ++CONFIG_INLINE_WRITE_UNLOCK_IRQ=y ++CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y ++CONFIG_FREEZER=y ++ ++# ++# System Type ++# ++CONFIG_MMU=y ++CONFIG_ARCH_MULTIPLATFORM=y ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_OMAP1 is not set ++ ++# ++# Multiple platform selection ++# ++ ++# ++# CPU Core family selection ++# ++# CONFIG_ARCH_MULTI_V6 is not set ++CONFIG_ARCH_MULTI_V7=y ++CONFIG_ARCH_MULTI_V6_V7=y ++# CONFIG_ARCH_MULTI_CPU_AUTO is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BERLIN is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++CONFIG_ARCH_GOKE=y ++ ++# ++# Goke platform type ++# ++# CONFIG_ARCH_GK7205V200 is not set ++# CONFIG_ARCH_GK7205V300 is not set ++# CONFIG_ARCH_GK7202V300 is not set ++CONFIG_ARCH_GK7605V100=y ++# CONFIG_GOKE_MC is not set ++CONFIG_BSP_ZRELADDR=0x40008000 ++CONFIG_BSP_PARAMS_PHYS=0x00000100 ++CONFIG_BSP_INITRD_PHYS=0x00800000 ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MEDIATEK is not set ++ ++# ++# TI OMAP/AM/DM/DRA Family ++# ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_EXYNOS is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++ ++# ++# Processor Type ++# ++CONFIG_CPU_V7=y ++CONFIG_CPU_32v6K=y ++CONFIG_CPU_32v7=y ++CONFIG_CPU_ABRT_EV7=y ++CONFIG_CPU_PABRT_V7=y ++CONFIG_CPU_CACHE_V7=y ++CONFIG_CPU_CACHE_VIPT=y ++CONFIG_CPU_COPY_V6=y ++CONFIG_CPU_TLB_V7=y ++CONFIG_CPU_HAS_ASID=y ++CONFIG_CPU_CP15=y ++CONFIG_CPU_CP15_MMU=y ++ ++# ++# Processor Features ++# ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set ++CONFIG_ARM_THUMB=y ++# CONFIG_ARM_THUMBEE is not set ++CONFIG_ARM_VIRT_EXT=y ++# CONFIG_SWP_EMULATE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++CONFIG_KUSER_HELPERS=y ++CONFIG_VDSO=y ++CONFIG_MIGHT_HAVE_CACHE_L2X0=y ++# CONFIG_CACHE_L2X0 is not set ++CONFIG_ARM_L1_CACHE_SHIFT_6=y ++CONFIG_ARM_L1_CACHE_SHIFT=6 ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_DEBUG_RODATA is not set ++CONFIG_MULTI_IRQ_HANDLER=y ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++ ++# ++# Bus support ++# ++# CONFIG_PCI is not set ++# CONFIG_PCI_DOMAINS_GENERIC is not set ++# CONFIG_PCI_SYSCALL is not set ++# CONFIG_PCCARD is not set ++ ++# ++# Kernel Features ++# ++CONFIG_HAVE_SMP=y ++# CONFIG_SMP is not set ++CONFIG_HAVE_ARM_ARCH_TIMER=y ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_1G is not set ++CONFIG_PAGE_OFFSET=0xC0000000 ++# CONFIG_ARM_PSCI is not set ++CONFIG_ARCH_NR_GPIO=0 ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_HZ_FIXED=0 ++CONFIG_HZ_100=y ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++# CONFIG_THUMB2_KERNEL is not set ++CONFIG_ARM_PATCH_IDIV=y ++CONFIG_AEABI=y ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set ++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set ++CONFIG_HAVE_ARCH_PFN_VALID=y ++# CONFIG_HIGHMEM is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_ARCH_WANT_GENERAL_HUGETLB=y ++# CONFIG_ARM_MODULE_PLTS is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_HAVE_MEMBLOCK=y ++CONFIG_NO_BOOTMEM=y ++# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++CONFIG_COMPACTION=y ++CONFIG_MIGRATION=y ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_KSM is not set ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++CONFIG_NEED_PER_CPU_KM=y ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CMA is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZSMALLOC is not set ++CONFIG_GENERIC_EARLY_IOREMAP=y ++# CONFIG_IDLE_PAGE_TRACKING is not set ++CONFIG_FRAME_VECTOR=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_ALIGNMENT_TRAP=y ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SWIOTLB=y ++CONFIG_IOMMU_HELPER=y ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_XEN is not set ++ ++# ++# Boot options ++# ++CONFIG_USE_OF=y ++CONFIG_ATAGS=y ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++CONFIG_ZBOOT_ROM_TEXT=0 ++CONFIG_ZBOOT_ROM_BSS=0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_ARM_ATAG_DTB_COMPAT=y ++CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++CONFIG_CMDLINE="" ++# CONFIG_KEXEC is not set ++# CONFIG_CRASH_DUMP is not set ++CONFIG_AUTO_ZRELADDR=y ++# CONFIG_EFI is not set ++ ++# ++# CPU Power Management ++# ++ ++# ++# CPU Frequency scaling ++# ++# CONFIG_CPU_FREQ is not set ++ ++# ++# CPU Idle ++# ++# CONFIG_CPU_IDLE is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++ ++# ++# Floating point emulation ++# ++ ++# ++# At least one emulation must be selected ++# ++CONFIG_VFP=y ++CONFIG_VFPv3=y ++CONFIG_NEON=y ++# CONFIG_KERNEL_MODE_NEON is not set ++ ++# ++# Userspace binary formats ++# ++CONFIG_BINFMT_ELF=y ++CONFIG_ELFCORE=y ++CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y ++CONFIG_BINFMT_SCRIPT=y ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_COREDUMP=y ++ ++# ++# Power management options ++# ++CONFIG_SUSPEND=y ++CONFIG_SUSPEND_FREEZER=y ++CONFIG_PM_SLEEP=y ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_WAKELOCKS is not set ++CONFIG_PM=y ++# CONFIG_PM_DEBUG is not set ++# CONFIG_APM_EMULATION is not set ++CONFIG_PM_CLK=y ++# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set ++CONFIG_CPU_PM=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM_CPU_SUSPEND=y ++CONFIG_ARCH_HIBERNATION_POSSIBLE=y ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++CONFIG_UNIX=y ++# CONFIG_UNIX_DIAG is not set ++CONFIG_XFRM=y ++CONFIG_XFRM_ALGO=y ++CONFIG_XFRM_USER=y ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_FIB_TRIE_STATS is not set ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++# CONFIG_IP_PNP_DHCP is not set ++# CONFIG_IP_PNP_BOOTP is not set ++# CONFIG_IP_PNP_RARP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IP_TUNNEL is not set ++CONFIG_IP_MROUTE=y ++# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++# CONFIG_NET_UDP_TUNNEL is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++CONFIG_INET_DIAG=y ++CONFIG_INET_TCP_DIAG=y ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_DIAG_DESTROY is not set ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_BIC=m ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_TCP_CONG_WESTWOOD=m ++CONFIG_TCP_CONG_HTCP=m ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_CDG is not set ++# CONFIG_TCP_CONG_BBR is not set ++CONFIG_DEFAULT_CUBIC=y ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_TCP_MD5SIG=y ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_L2TP is not set ++# CONFIG_BRIDGE is not set ++CONFIG_HAVE_NET_DSA=y ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_PHONET is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++CONFIG_DNS_RESOLVER=y ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_MPLS is not set ++# CONFIG_HSR is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_CGROUP_NET_PRIO is not set ++# CONFIG_CGROUP_NET_CLASSID is not set ++CONFIG_NET_RX_BUSY_POLL=y ++CONFIG_BQL=y ++# CONFIG_BPF_JIT is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_STREAM_PARSER is not set ++CONFIG_FIB_RULES=y ++CONFIG_WIRELESS=y ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PROC=y ++CONFIG_CFG80211=m ++# CONFIG_NL80211_TESTMODE is not set ++# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set ++CONFIG_CFG80211_DEFAULT_PS=y ++# CONFIG_CFG80211_INTERNAL_REGDB is not set ++CONFIG_CFG80211_CRDA_SUPPORT=y ++CONFIG_CFG80211_WEXT=y ++# CONFIG_LIB80211 is not set ++CONFIG_MAC80211=m ++CONFIG_MAC80211_HAS_RC=y ++CONFIG_MAC80211_RC_MINSTREL=y ++CONFIG_MAC80211_RC_MINSTREL_HT=y ++# CONFIG_MAC80211_RC_MINSTREL_VHT is not set ++CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y ++CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" ++CONFIG_MAC80211_MESH=y ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++# CONFIG_MAC80211_DEBUG_MENU is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++# CONFIG_CAIF is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_NFC is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_NET_DEVLINK is not set ++CONFIG_MAY_USE_DEVLINK=y ++CONFIG_HAVE_CBPF_JIT=y ++ ++# ++# Device Drivers ++# ++CONFIG_ARM_AMBA=y ++ ++# ++# Generic Driver Options ++# ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_STANDALONE=y ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++CONFIG_FW_LOADER=y ++CONFIG_FIRMWARE_IN_KERNEL=y ++CONFIG_EXTRA_FIRMWARE="" ++# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y ++CONFIG_REGMAP_SPI=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_DMA_SHARED_BUFFER=y ++# CONFIG_FENCE_TRACE is not set ++ ++# ++# Bus devices ++# ++# CONFIG_BRCMSTB_GISB_ARB is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AFS_PARTS is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++# CONFIG_MTD_CFI is not set ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_M25P80 is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_NAND_ECC=y ++# CONFIG_MTD_NAND_ECC_SMC is not set ++CONFIG_MTD_NAND=y ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++# CONFIG_MTD_NAND_MTK is not set ++CONFIG_MTD_SPI_NAND_GOKE=y ++# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set ++# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set ++CONFIG_MTD_SPI_NAND_FMC100=y ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR & LPDDR2 PCM memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++CONFIG_SPI_GOKE_SFC=y ++# CONFIG_CLOSE_SPI_8PIN_4IO is not set ++CONFIG_GOKE_SPI_BLOCK_PROTECT=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UBI_BLOCK is not set ++CONFIG_DTC=y ++CONFIG_OF=y ++# CONFIG_OF_UNITTEST is not set ++CONFIG_OF_FLATTREE=y ++CONFIG_OF_EARLY_FLATTREE=y ++CONFIG_OF_ADDRESS=y ++CONFIG_OF_IRQ=y ++CONFIG_OF_NET=y ++CONFIG_OF_MDIO=y ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_OVERLAY is not set ++CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=65536 ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_NVME_TARGET is not set ++ ++# ++# Misc devices ++# ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_DS1682 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++# CONFIG_SRAM is not set ++# CONFIG_C2PORT is not set ++ ++# ++# EEPROM support ++# ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++ ++# ++# Texas Instruments shared transport line discipline ++# ++# CONFIG_TI_ST is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++ ++# ++# Altera FPGA firmware download module ++# ++# CONFIG_ALTERA_STAPL is not set ++ ++# ++# Intel MIC Bus Driver ++# ++ ++# ++# SCIF Bus Driver ++# ++ ++# ++# VOP Bus Driver ++# ++ ++# ++# Intel MIC Host Driver ++# ++ ++# ++# Intel MIC Card Driver ++# ++ ++# ++# SCIF Driver ++# ++ ++# ++# Intel MIC Coprocessor State Management (COSM) Drivers ++# ++ ++# ++# VOP Driver ++# ++# CONFIG_ECHO is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++ ++# ++# SCSI device support ++# ++CONFIG_SCSI_MOD=y ++# CONFIG_RAID_ATTRS is not set ++CONFIG_SCSI=y ++CONFIG_SCSI_DMA=y ++CONFIG_SCSI_NETLINK=y ++# CONFIG_SCSI_MQ_DEFAULT is not set ++CONFIG_SCSI_PROC_FS=y ++ ++# ++# SCSI support type (disk, tape, CD-ROM) ++# ++CONFIG_BLK_DEV_SD=y ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CHR_DEV_OSST is not set ++CONFIG_BLK_DEV_SR=y ++# CONFIG_BLK_DEV_SR_VENDOR is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_LOGGING is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++ ++# ++# SCSI Transports ++# ++# CONFIG_SCSI_SPI_ATTRS is not set ++CONFIG_SCSI_FC_ATTRS=y ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_ISCSI_TCP is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_LIBFC is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++# CONFIG_TARGET_CORE is not set ++CONFIG_NETDEVICES=y ++CONFIG_NET_CORE=y ++# CONFIG_BONDING is not set ++# CONFIG_DUMMY is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_VXLAN is not set ++# CONFIG_MACSEC is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_VETH is not set ++# CONFIG_NLMON is not set ++ ++# ++# CAIF transport drivers ++# ++ ++# ++# Distributed Switch Architecture drivers ++# ++CONFIG_ETHERNET=y ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_NET_VENDOR_AMAZON is not set ++# CONFIG_NET_VENDOR_ARC is not set ++# CONFIG_NET_VENDOR_AURORA is not set ++# CONFIG_NET_CADENCE is not set ++# CONFIG_NET_VENDOR_BROADCOM is not set ++# CONFIG_NET_VENDOR_CIRRUS is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DNET is not set ++# CONFIG_NET_VENDOR_EZCHIP is not set ++# CONFIG_NET_VENDOR_FARADAY is not set ++# CONFIG_NET_VENDOR_HISILICON is not set ++CONFIG_NET_VENDOR_GOKE=y ++CONFIG_GOKE_FEMAC=y ++# CONFIG_NET_VENDOR_INTEL is not set ++# CONFIG_NET_VENDOR_MARVELL is not set ++# CONFIG_NET_VENDOR_MICREL is not set ++CONFIG_NET_VENDOR_MICROCHIP=y ++# CONFIG_ENC28J60 is not set ++# CONFIG_ENCX24J600 is not set ++# CONFIG_NET_VENDOR_NATSEMI is not set ++# CONFIG_NET_VENDOR_NETRONOME is not set ++# CONFIG_ETHOC is not set ++# CONFIG_NET_VENDOR_QUALCOMM is not set ++# CONFIG_NET_VENDOR_RENESAS is not set ++# CONFIG_NET_VENDOR_ROCKER is not set ++# CONFIG_NET_VENDOR_SAMSUNG is not set ++# CONFIG_NET_VENDOR_SEEQ is not set ++# CONFIG_NET_VENDOR_SMSC is not set ++# CONFIG_NET_VENDOR_STMICRO is not set ++# CONFIG_NET_VENDOR_SYNOPSYS is not set ++# CONFIG_NET_VENDOR_VIA is not set ++# CONFIG_NET_VENDOR_WIZNET is not set ++CONFIG_PHYLIB=y ++CONFIG_SWPHY=y ++ ++# ++# MDIO bus device drivers ++# ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++CONFIG_MDIO_GOKE_FEMAC=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++ ++# ++# MII PHY device drivers ++# ++# CONFIG_AMD_PHY is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BROADCOM_PHY is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++CONFIG_FIXED_PHY=y ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_STE10XP is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_USB_NET_DRIVERS is not set ++# CONFIG_WLAN is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_ISDN is not set ++# CONFIG_NVM is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++ ++# ++# Userland interfaces ++# ++CONFIG_INPUT_MOUSEDEV=y ++CONFIG_INPUT_MOUSEDEV_PSAUX=y ++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 ++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++CONFIG_INPUT_KEYBOARD=y ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++CONFIG_KEYBOARD_ATKBD=y ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_BCM is not set ++CONFIG_INPUT_MOUSE=y ++CONFIG_MOUSE_PS2=y ++CONFIG_MOUSE_PS2_ALPS=y ++CONFIG_MOUSE_PS2_BYD=y ++CONFIG_MOUSE_PS2_LOGIPS2PP=y ++CONFIG_MOUSE_PS2_SYNAPTICS=y ++CONFIG_MOUSE_PS2_CYPRESS=y ++CONFIG_MOUSE_PS2_TRACKPOINT=y ++# CONFIG_MOUSE_PS2_ELANTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_PS2_TOUCHKIT is not set ++CONFIG_MOUSE_PS2_FOCALTECH=y ++# CONFIG_MOUSE_SERIAL is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_BCM5974 is not set ++# CONFIG_MOUSE_CYAPA is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_VSXXXAA is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INPUT_CM109 is not set ++CONFIG_INPUT_UINPUT=y ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_RMI4_CORE is not set ++ ++# ++# Hardware I/O ports ++# ++CONFIG_SERIO=y ++CONFIG_SERIO_SERPORT=y ++# CONFIG_SERIO_AMBAKMI is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_USERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_TTY=y ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_VT_CONSOLE_SLEEP=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_UNIX98_PTYS=y ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_N_GSM is not set ++# CONFIG_TRACE_SINK is not set ++CONFIG_DEVMEM=y ++# CONFIG_DEVKMEM is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_8250 is not set ++ ++# ++# Non-8250 serial port support ++# ++# CONFIG_SERIAL_AMBA_PL010 is not set ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_UARTLITE is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_XILLYBUS is not set ++ ++# ++# I2C support ++# ++CONFIG_I2C=y ++CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_COMPAT=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_MUX=y ++ ++# ++# Multiplexer I2C Chip support ++# ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++CONFIG_I2C_HELPER_AUTO=y ++ ++# ++# I2C Hardware Bus support ++# ++ ++# ++# I2C system bus drivers (mostly embedded / system-on-chip) ++# ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++CONFIG_I2C_GOKE=y ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_XILINX is not set ++ ++# ++# External I2C/SMBus adapter drivers ++# ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_TINY_USB is not set ++ ++# ++# Other I2C/SMBus bus drivers ++# ++CONFIG_DMA_MSG_MIN_LEN=5 ++CONFIG_DMA_MSG_MAX_LEN=4090 ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++CONFIG_SPI=y ++# CONFIG_SPI_DEBUG is not set ++CONFIG_SPI_MASTER=y ++ ++# ++# SPI Master Controller Drivers ++# ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_OC_TINY is not set ++CONFIG_SPI_PL022=y ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++ ++# ++# SPI Protocol Masters ++# ++CONFIG_SPI_SPIDEV=y ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPMI is not set ++# CONFIG_HSI is not set ++ ++# ++# PPS support ++# ++# CONFIG_PPS is not set ++ ++# ++# PPS generators support ++# ++ ++# ++# PTP clock support ++# ++# CONFIG_PTP_1588_CLOCK is not set ++ ++# ++# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. ++# ++CONFIG_PINCTRL=y ++ ++# ++# Pin controllers ++# ++CONFIG_PINMUX=y ++CONFIG_PINCONF=y ++CONFIG_GENERIC_PINCONF=y ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++CONFIG_PINCTRL_SINGLE=y ++CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y ++CONFIG_GPIOLIB=y ++CONFIG_OF_GPIO=y ++CONFIG_GPIOLIB_IRQCHIP=y ++# CONFIG_DEBUG_GPIO is not set ++CONFIG_GPIO_SYSFS=y ++ ++# ++# Memory mapped GPIO drivers ++# ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++CONFIG_GPIO_PL061=y ++# CONFIG_GPIO_SYSCON is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++ ++# ++# I2C GPIO expanders ++# ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++ ++# ++# MFD GPIO expanders ++# ++# CONFIG_HTC_EGPIO is not set ++ ++# ++# SPI GPIO expanders ++# ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_PISOSR is not set ++ ++# ++# SPI or I2C GPIO expanders ++# ++# CONFIG_GPIO_MCP23S08 is not set ++ ++# ++# USB GPIO expanders ++# ++# CONFIG_W1 is not set ++# CONFIG_POWER_AVS is not set ++CONFIG_POWER_RESET=y ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++CONFIG_POWER_RESET_GOKE=y ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_POWER_SUPPLY=y ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++CONFIG_BCMA_POSSIBLE=y ++ ++# ++# Broadcom specific AMBA ++# ++# CONFIG_BCMA is not set ++ ++# ++# Multifunction device drivers ++# ++CONFIG_MFD_CORE=y ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++CONFIG_MFD_GOKE_FMC=y ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_MFD_STMPE is not set ++CONFIG_MFD_SYSCON=y ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_REGULATOR is not set ++CONFIG_MEDIA_SUPPORT=y ++ ++# ++# Multimedia core support ++# ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++CONFIG_VIDEO_DEV=y ++CONFIG_VIDEO_V4L2=y ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++CONFIG_VIDEOBUF2_CORE=y ++CONFIG_VIDEOBUF2_MEMOPS=y ++CONFIG_VIDEOBUF2_VMALLOC=y ++# CONFIG_TTPCI_EEPROM is not set ++ ++# ++# Media drivers ++# ++CONFIG_MEDIA_USB_SUPPORT=y ++ ++# ++# Webcam devices ++# ++CONFIG_USB_VIDEO_CLASS=y ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++CONFIG_USB_GSPCA=m ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_PWC is not set ++# CONFIG_VIDEO_CPIA2 is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_S2255 is not set ++ ++# ++# Webcam, TV (analog/digital) USB devices ++# ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++ ++# ++# Supported MMC/SDIO adapters ++# ++# CONFIG_CYPRESS_FIRMWARE is not set ++ ++# ++# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) ++# ++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y ++ ++# ++# Audio decoders, processors and mixers ++# ++ ++# ++# RDS decoders ++# ++ ++# ++# Video decoders ++# ++ ++# ++# Video and audio decoders ++# ++ ++# ++# Video encoders ++# ++ ++# ++# Camera sensor devices ++# ++ ++# ++# Flash devices ++# ++ ++# ++# Video improvement chips ++# ++ ++# ++# Audio/Video compression chips ++# ++ ++# ++# Miscellaneous helper chips ++# ++ ++# ++# Sensors used on soc_camera driver ++# ++ ++# ++# Tools to develop new frontends ++# ++# CONFIG_DVB_DUMMY_FE is not set ++ ++# ++# Graphics support ++# ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_DRM is not set ++ ++# ++# ACP (Audio CoProcessor) Configuration ++# ++ ++# ++# Frame buffer Devices ++# ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++CONFIG_FB_CMDLINE=y ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_VGASTATE is not set ++ ++# ++# Console display driver support ++# ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_LOGO is not set ++# CONFIG_SOUND is not set ++ ++# ++# HID support ++# ++CONFIG_HID=y ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_UHID is not set ++CONFIG_HID_GENERIC=y ++ ++# ++# Special HID drivers ++# ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_MAGICMOUSE is not set ++CONFIG_HID_MICROSOFT=y ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_ALPS is not set ++ ++# ++# USB HID support ++# ++CONFIG_USB_HID=y ++# CONFIG_HID_PID is not set ++# CONFIG_USB_HIDDEV is not set ++ ++# ++# I2C HID support ++# ++# CONFIG_I2C_HID is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++ ++# ++# Miscellaneous USB options ++# ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_WUSB_CBAF is not set ++ ++# ++# USB Host Controller Drivers ++# ++# CONFIG_USB_C67X00_HCD is not set ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++ ++# ++# USB Device Class drivers ++# ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_TMC is not set ++ ++# ++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may ++# ++ ++# ++# also be needed; see USB_STORAGE Help for more info ++# ++CONFIG_USB_STORAGE=y ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_UAS is not set ++ ++# ++# USB Imaging devices ++# ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USBIP_CORE is not set ++# CONFIG_USB_MUSB_HDRC is not set ++CONFIG_USB_DWC3=y ++# CONFIG_USB_DWC3_HOST is not set ++# CONFIG_USB_DWC3_GADGET is not set ++CONFIG_USB_DWC3_DUAL_ROLE=y ++ ++# ++# Platform Glue Driver Support ++# ++CONFIG_USB_DWC3_OF_SIMPLE=y ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_ISP1760 is not set ++ ++# ++# USB port drivers ++# ++# CONFIG_USB_SERIAL is not set ++ ++# ++# USB Miscellaneous drivers ++# ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++ ++# ++# USB Physical Layer drivers ++# ++# CONFIG_USB_PHY is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ULPI is not set ++CONFIG_USB_GADGET=y ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++ ++# ++# USB Peripheral Controller ++# ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_BDC_UDC is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_DUMMY_HCD is not set ++CONFIG_USB_LIBCOMPOSITE=m ++CONFIG_USB_F_ACM=m ++CONFIG_USB_U_SERIAL=m ++CONFIG_USB_U_ETHER=m ++CONFIG_USB_F_ECM=m ++CONFIG_USB_F_RNDIS=m ++CONFIG_USB_F_MASS_STORAGE=m ++CONFIG_USB_CONFIGFS=m ++# CONFIG_USB_CONFIGFS_SERIAL is not set ++CONFIG_USB_CONFIGFS_ACM=y ++# CONFIG_USB_CONFIGFS_OBEX is not set ++# CONFIG_USB_CONFIGFS_NCM is not set ++CONFIG_USB_CONFIGFS_ECM=y ++# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set ++CONFIG_USB_CONFIGFS_RNDIS=y ++# CONFIG_USB_CONFIGFS_EEM is not set ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++# CONFIG_USB_CONFIGFS_F_LB_SS is not set ++# CONFIG_USB_CONFIGFS_F_FS is not set ++# CONFIG_USB_CONFIGFS_F_HID is not set ++# CONFIG_USB_CONFIGFS_F_UVC is not set ++# CONFIG_USB_CONFIGFS_F_PRINTER is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_UWB is not set ++CONFIG_MMC=y ++# CONFIG_MMC_DEBUG is not set ++CONFIG_PWRSEQ_EMMC=y ++CONFIG_PWRSEQ_SIMPLE=y ++ ++# ++# MMC/SD/SDIO Card Drivers ++# ++CONFIG_MMC_BLOCK=y ++CONFIG_MMC_BLOCK_MINORS=8 ++CONFIG_MMC_BLOCK_BOUNCE=y ++# CONFIG_SDIO_UART is not set ++# CONFIG_MMC_TEST is not set ++ ++# ++# MMC/SD/SDIO Host Controller Drivers ++# ++# CONFIG_MMC_ARMMMCI is not set ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++CONFIG_MMC_SDHCI_GOKE=y ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_CQ_HCI is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_EDAC_ATOMIC_SCRUB=y ++CONFIG_EDAC_SUPPORT=y ++# CONFIG_EDAC is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# I2C RTC drivers ++# ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++ ++# ++# SPI RTC drivers ++# ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++CONFIG_RTC_I2C_AND_SPI=y ++ ++# ++# SPI and I2C RTC drivers ++# ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++ ++# ++# Platform RTC drivers ++# ++CONFIG_RTC_DRV_GOKE=y ++# CONFIG_RTC_DRV_CMOS is not set ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++ ++# ++# on-CPU RTC drivers ++# ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++ ++# ++# HID Sensor RTC drivers ++# ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_DMADEVICES is not set ++ ++# ++# DMABUF options ++# ++# CONFIG_SYNC_FILE is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_UIO is not set ++# CONFIG_VIRT_DRIVERS is not set ++ ++# ++# Virtio drivers ++# ++# CONFIG_VIRTIO_MMIO is not set ++ ++# ++# Microsoft Hyper-V guest support ++# ++# CONFIG_STAGING is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_CHROME_PLATFORMS is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_HAVE_CLK_PREPARE=y ++CONFIG_COMMON_CLK=y ++ ++# ++# Common Clock Framework ++# ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++CONFIG_COMMON_CLK_GK7605V100=y ++CONFIG_RESET_GOKE=y ++ ++# ++# Hardware Spinlock drivers ++# ++ ++# ++# Clock Source drivers ++# ++CONFIG_CLKSRC_OF=y ++CONFIG_CLKSRC_PROBE=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set ++CONFIG_ARM_TIMER_SP804=y ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_MAILBOX is not set ++# CONFIG_IOMMU_SUPPORT is not set ++ ++# ++# Remoteproc drivers ++# ++# CONFIG_STE_MODEM_RPROC is not set ++ ++# ++# Rpmsg drivers ++# ++ ++# ++# SOC (System On Chip) specific Drivers ++# ++ ++# ++# Broadcom SoC drivers ++# ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_EXTCON is not set ++# CONFIG_MEMORY is not set ++# CONFIG_IIO is not set ++# CONFIG_PWM is not set ++CONFIG_IRQCHIP=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_IPACK_BUS is not set ++CONFIG_RESET_CONTROLLER=y ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_FMC is not set ++ ++# ++# PHY Subsystem ++# ++CONFIG_GENERIC_PHY=y ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++CONFIG_PHY_GOKE_USBP2=y ++# CONFIG_USB_MODE_OPTION is not set ++# CONFIG_POWERCAP is not set ++# CONFIG_MCB is not set ++ ++# ++# Performance monitor support ++# ++# CONFIG_RAS is not set ++ ++# ++# Android ++# ++# CONFIG_ANDROID is not set ++# CONFIG_NVMEM is not set ++# CONFIG_STM is not set ++# CONFIG_INTEL_TH is not set ++ ++# ++# FPGA Configuration Support ++# ++# CONFIG_FPGA is not set ++ ++# ++# goke driver support ++# ++ ++# ++# Firmware Drivers ++# ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_HAVE_ARM_SMCCC=y ++ ++# ++# File systems ++# ++CONFIG_DCACHE_WORD_ACCESS=y ++# CONFIG_EXT2_FS is not set ++# CONFIG_EXT3_FS is not set ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_DEBUG is not set ++CONFIG_JBD2=y ++# CONFIG_JBD2_DEBUG is not set ++CONFIG_FS_MBCACHE=y ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_F2FS_FS is not set ++CONFIG_FS_POSIX_ACL=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++CONFIG_FILE_LOCKING=y ++CONFIG_MANDATORY_FILE_LOCKING=y ++# CONFIG_FS_ENCRYPTION is not set ++CONFIG_FSNOTIFY=y ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_FANOTIFY is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_OVERLAY_FS is not set ++ ++# ++# Caches ++# ++# CONFIG_FSCACHE is not set ++ ++# ++# CD-ROM/DVD Filesystems ++# ++CONFIG_ISO9660_FS=y ++# CONFIG_JOLIET is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++CONFIG_PROC_SYSCTL=y ++CONFIG_PROC_PAGE_MONITOR=y ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_KERNFS=y ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS_XATTR=y ++# CONFIG_HUGETLB_PAGE is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_YAFFS_FS=y ++CONFIG_YAFFS_YAFFS1=y ++# CONFIG_YAFFS_9BYTE_TAGS is not set ++# CONFIG_YAFFS_DOES_ECC is not set ++CONFIG_YAFFS_YAFFS2=y ++CONFIG_YAFFS_AUTO_YAFFS2=y ++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set ++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set ++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set ++# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set ++# CONFIG_YAFFS_DISABLE_BACKGROUND is not set ++# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set ++CONFIG_YAFFS_XATTR=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++# CONFIG_JFFS2_LZMA is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_UBIFS_FS=y ++# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set ++CONFIG_UBIFS_FS_LZO=y ++CONFIG_UBIFS_FS_ZLIB=y ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_LOGFS is not set ++CONFIG_CRAMFS=y ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_PSTORE is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V2=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V4_1 is not set ++CONFIG_ROOT_NFS=y ++# CONFIG_NFS_USE_LEGACY_DNS is not set ++CONFIG_NFS_USE_KERNEL_DNS=y ++# CONFIG_NFSD is not set ++CONFIG_GRACE_PERIOD=y ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_ACL_SUPPORT=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++CONFIG_SUNRPC_GSS=y ++# CONFIG_SUNRPC_DEBUG is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_737=m ++CONFIG_NLS_CODEPAGE_775=m ++CONFIG_NLS_CODEPAGE_850=m ++CONFIG_NLS_CODEPAGE_852=m ++CONFIG_NLS_CODEPAGE_855=m ++CONFIG_NLS_CODEPAGE_857=m ++CONFIG_NLS_CODEPAGE_860=m ++CONFIG_NLS_CODEPAGE_861=m ++CONFIG_NLS_CODEPAGE_862=m ++CONFIG_NLS_CODEPAGE_863=m ++CONFIG_NLS_CODEPAGE_864=m ++CONFIG_NLS_CODEPAGE_865=m ++CONFIG_NLS_CODEPAGE_866=m ++CONFIG_NLS_CODEPAGE_869=m ++CONFIG_NLS_CODEPAGE_936=y ++CONFIG_NLS_CODEPAGE_950=m ++CONFIG_NLS_CODEPAGE_932=m ++CONFIG_NLS_CODEPAGE_949=m ++CONFIG_NLS_CODEPAGE_874=m ++CONFIG_NLS_ISO8859_8=m ++CONFIG_NLS_CODEPAGE_1250=m ++CONFIG_NLS_CODEPAGE_1251=m ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_ISO8859_2=m ++CONFIG_NLS_ISO8859_3=m ++CONFIG_NLS_ISO8859_4=m ++CONFIG_NLS_ISO8859_5=m ++CONFIG_NLS_ISO8859_6=m ++CONFIG_NLS_ISO8859_7=m ++CONFIG_NLS_ISO8859_9=m ++CONFIG_NLS_ISO8859_13=m ++CONFIG_NLS_ISO8859_14=m ++CONFIG_NLS_ISO8859_15=m ++CONFIG_NLS_KOI8_R=m ++CONFIG_NLS_KOI8_U=m ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++CONFIG_NLS_UTF8=y ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++ ++# ++# printk and dmesg options ++# ++# CONFIG_PRINTK_TIME is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_BOOT_PRINTK_DELAY is not set ++ ++# ++# Compile-time checks and compiler options ++# ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_STRIP_ASM_SYMS is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_DEBUG_FS is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++CONFIG_FRAME_POINTER=y ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_DEBUG_KERNEL=y ++ ++# ++# Memory Debugging ++# ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_HAVE_DEBUG_KMEMLEAK=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_VM is not set ++CONFIG_DEBUG_MEMORY_INIT=y ++# CONFIG_DEBUG_SHIRQ is not set ++ ++# ++# Debug Lockups and Hangs ++# ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_PANIC_ON_OOPS is not set ++CONFIG_PANIC_ON_OOPS_VALUE=0 ++CONFIG_PANIC_TIMEOUT=0 ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_SCHED_INFO is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_TIMER_STATS is not set ++ ++# ++# Lock Debugging (spinlocks, mutexes, etc...) ++# ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_BUGVERBOSE=y ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++ ++# ++# RCU Debugging ++# ++# CONFIG_PROVE_RCU is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_HAVE_FUNCTION_TRACER=y ++CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y ++CONFIG_HAVE_DYNAMIC_FTRACE=y ++CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y ++CONFIG_HAVE_SYSCALL_TRACEPOINTS=y ++CONFIG_HAVE_C_RECORDMCOUNT=y ++CONFIG_TRACING_SUPPORT=y ++# CONFIG_FTRACE is not set ++ ++# ++# Runtime Testing ++# ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_DMA_API_DEBUG is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set ++# CONFIG_UBSAN is not set ++CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y ++CONFIG_STRICT_DEVMEM=y ++# CONFIG_IO_STRICT_DEVMEM is not set ++# CONFIG_ARM_PTDUMP is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_LL is not set ++CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" ++# CONFIG_DEBUG_UART_8250 is not set ++CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_DEBUG_SET_MODULE_RONX is not set ++# CONFIG_CORESIGHT is not set ++ ++# ++# Security options ++# ++CONFIG_KEYS=y ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_SECURITY_DMESG_RESTRICT is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y ++CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY is not set ++CONFIG_DEFAULT_SECURITY_DAC=y ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++CONFIG_CRYPTO_AEAD=m ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_BLKCIPHER=y ++CONFIG_CRYPTO_BLKCIPHER2=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_RNG=m ++CONFIG_CRYPTO_RNG2=y ++CONFIG_CRYPTO_RNG_DEFAULT=m ++CONFIG_CRYPTO_AKCIPHER2=y ++CONFIG_CRYPTO_KPP2=y ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_ECDH is not set ++CONFIG_CRYPTO_MANAGER=m ++CONFIG_CRYPTO_MANAGER2=y ++# CONFIG_CRYPTO_USER is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++CONFIG_CRYPTO_GF128MUL=m ++CONFIG_CRYPTO_NULL=m ++CONFIG_CRYPTO_NULL2=y ++CONFIG_CRYPTO_WORKQUEUE=y ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++CONFIG_CRYPTO_CCM=m ++CONFIG_CRYPTO_GCM=m ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++CONFIG_CRYPTO_SEQIV=m ++CONFIG_CRYPTO_ECHAINIV=m ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++CONFIG_CRYPTO_CTR=m ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_CMAC is not set ++CONFIG_CRYPTO_HMAC=m ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set ++ ++# ++# Digest ++# ++CONFIG_CRYPTO_CRC32C=y ++# CONFIG_CRYPTO_CRC32 is not set ++CONFIG_CRYPTO_CRCT10DIF=y ++CONFIG_CRYPTO_GHASH=m ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_MD4 is not set ++CONFIG_CRYPTO_MD5=y ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++CONFIG_CRYPTO_SHA1=y ++CONFIG_CRYPTO_SHA256=y ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_ANUBIS is not set ++CONFIG_CRYPTO_ARC4=y ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++CONFIG_CRYPTO_DRBG_MENU=m ++CONFIG_CRYPTO_DRBG_HMAC=y ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++CONFIG_CRYPTO_DRBG=m ++CONFIG_CRYPTO_JITTERENTROPY=m ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++ ++# ++# Certificates for signature checking ++# ++# CONFIG_ARM_CRYPTO is not set ++# CONFIG_BINARY_PRINTF is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_HAVE_ARCH_BITREVERSE=y ++CONFIG_RATIONAL=y ++CONFIG_GENERIC_STRNCPY_FROM_USER=y ++CONFIG_GENERIC_STRNLEN_USER=y ++CONFIG_GENERIC_NET_UTILS=y ++CONFIG_GENERIC_PCI_IOMAP=y ++CONFIG_GENERIC_IO=y ++CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y ++CONFIG_CRC_CCITT=y ++CONFIG_CRC16=y ++CONFIG_CRC_T10DIF=y ++CONFIG_CRC_ITU_T=y ++CONFIG_CRC32=y ++# CONFIG_CRC32_SELFTEST is not set ++CONFIG_CRC32_SLICEBY8=y ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SARWATE is not set ++# CONFIG_CRC32_BIT is not set ++# CONFIG_CRC7 is not set ++CONFIG_LIBCRC32C=y ++# CONFIG_CRC8 is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_LZO_COMPRESS=y ++CONFIG_LZO_DECOMPRESS=y ++CONFIG_LZ4_DECOMPRESS=y ++CONFIG_XZ_DEC=y ++CONFIG_XZ_DEC_X86=y ++CONFIG_XZ_DEC_POWERPC=y ++CONFIG_XZ_DEC_IA64=y ++CONFIG_XZ_DEC_ARM=y ++CONFIG_XZ_DEC_ARMTHUMB=y ++CONFIG_XZ_DEC_SPARC=y ++CONFIG_XZ_DEC_BCJ=y ++# CONFIG_XZ_DEC_TEST is not set ++CONFIG_DECOMPRESS_GZIP=y ++CONFIG_DECOMPRESS_LZ4=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_ASSOCIATIVE_ARRAY=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HAS_DMA=y ++CONFIG_DQL=y ++CONFIG_NLATTR=y ++# CONFIG_CORDIC is not set ++# CONFIG_DDR is not set ++# CONFIG_IRQ_POLL is not set ++CONFIG_LIBFDT=y ++CONFIG_OID_REGISTRY=y ++# CONFIG_SG_SPLIT is not set ++CONFIG_SG_POOL=y ++CONFIG_ARCH_HAS_SG_CHAIN=y ++CONFIG_SBITMAP=y ++# CONFIG_VIRTUALIZATION is not set diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-kvm-handle_exit.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-kvm-handle_exit.c.patch new file mode 100644 index 00000000..0ac90a7a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-kvm-handle_exit.c.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/arch/arm/kvm/handle_exit.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/kvm/handle_exit.c 2021-06-07 13:01:32.000000000 +0300 +@@ -21,7 +21,7 @@ + #include + #include + #include +-#include ++#include + #include + + #include "trace.h" diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Kconfig.patch new file mode 100644 index 00000000..910917d6 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Kconfig.patch @@ -0,0 +1,74 @@ +--- linux-4.9.37/arch/arm/mach-goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/Kconfig 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,71 @@ ++config ARCH_GOKE ++ bool "Goke SoC Support" ++ select ARM_AMBA ++ select ARM_GIC if ARCH_MULTI_V7 ++ select ARM_VIC if ARCH_MULTI_V5 ++ select ARM_TIMER_SP804 ++ select POWER_RESET ++ select POWER_RESET_GOKE ++ select POWER_SUPPLY ++ ++if ARCH_GOKE ++ ++menu "Goke platform type" ++ ++config ARCH_GK7205V200 ++ bool "Goke GK7205V200 Cortex-A7 family" ++ depends on ARCH_MULTI_V7 ++ select HAVE_ARM_ARCH_TIMER ++ select PINCTRL ++ select POWER_RESET_GOKE ++ help ++ Support for Goke GK7205V200 Soc family. ++ ++config ARCH_GK7205V300 ++ bool "Goke GK7205V300 Cortex-A7 family" ++ depends on ARCH_MULTI_V7 ++ select HAVE_ARM_ARCH_TIMER ++ select PINCTRL ++ select POWER_RESET_GOKE ++ help ++ Support for Goke GK7205V300 Soc family. ++ ++config ARCH_GK7202V300 ++ bool "Goke GK7202V300 Cortex-A7 family" ++ depends on ARCH_MULTI_V7 ++ select HAVE_ARM_ARCH_TIMER ++ select PINCTRL ++ select POWER_RESET_GOKE ++ help ++ Support for Goke GK7202V300 Soc family. ++ ++config ARCH_GK7605V100 ++ bool "Goke GK7605V100 Cortex-A7 family" ++ depends on ARCH_MULTI_V7 ++ select HAVE_ARM_ARCH_TIMER ++ select PINCTRL ++ select POWER_RESET_GOKE ++ help ++ Support for Goke GK7605V100 Soc family. ++ ++config GOKE_MC ++ bool "Goke mc platform solution" ++ default n ++ help ++ support for Goke mc platform solution ++ ++config BSP_ZRELADDR ++ hex 'zreladdr' ++ default "0x40008000" if ARCH_GK7205V200 || ARCH_GK7205V300 || ARCH_GK7202V300 || ARCH_GK7605V100 ++ ++config BSP_PARAMS_PHYS ++ hex 'params_phys' ++ default "0x00000100" ++ ++config BSP_INITRD_PHYS ++ hex 'initrd_phys' ++ default "0x00800000" ++ ++endmenu ++ ++endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Makefile.boot.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Makefile.boot.patch new file mode 100644 index 00000000..43f6117b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Makefile.boot.patch @@ -0,0 +1,6 @@ +--- linux-4.9.37/arch/arm/mach-goke/Makefile.boot 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/Makefile.boot 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,3 @@ ++zreladdr-$(CONFIG_ARCH_GOKE) := $(CONFIG_BSP_ZRELADDR) ++params_phys-$(CONFIG_ARCH_GOKE) := $(CONFIG_BSP_PARAMS_PHYS) ++initrd_phys-$(CONFIG_ARCH_GOKE) := $(CONFIG_BSP_INITRD_PHYS) diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Makefile.patch new file mode 100644 index 00000000..7b2fb687 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-Makefile.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/arch/arm/mach-goke/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/Makefile 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,8 @@ ++# ++# Makefile for Goke processors family ++# ++ ++obj-$(CONFIG_ARCH_GK7205V200) += mach-gk7205v200.o ++obj-$(CONFIG_ARCH_GK7205V300) += mach-gk7205v300.o ++obj-$(CONFIG_ARCH_GK7202V300) += mach-gk7202v300.o ++obj-$(CONFIG_ARCH_GK7605V100) += mach-gk7605v100.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-include-mach-io.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-include-mach-io.h.patch new file mode 100644 index 00000000..392821eb --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-include-mach-io.h.patch @@ -0,0 +1,9 @@ +--- linux-4.9.37/arch/arm/mach-goke/include/mach/io.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/include/mach/io.h 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,6 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#ifndef __ASM_ARM_ARCH_IO_H ++#define __ASM_ARM_ARCH_IO_H ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-include-mach-platform.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-include-mach-platform.h.patch new file mode 100644 index 00000000..a6fa704b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-include-mach-platform.h.patch @@ -0,0 +1,9 @@ +--- linux-4.9.37/arch/arm/mach-goke/include/mach/platform.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/include/mach/platform.h 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,6 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#ifndef __GOKE_PLATFORM_H__ ++#define __GOKE_PLATFORM_H__ ++#endif /* End of __GOKE_PLATFORM_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-common.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-common.h.patch new file mode 100644 index 00000000..c3c2d1cb --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-common.h.patch @@ -0,0 +1,15 @@ +--- linux-4.9.37/arch/arm/mach-goke/mach-common.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/mach-common.h 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,12 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#ifndef __SMP_COMMON_H ++#define __SMP_COMMON_H ++ ++#ifdef CONFIG_SMP ++void bsp_set_cpu(unsigned int cpu, bool enable); ++void __init bsp_smp_prepare_cpus(unsigned int max_cpus); ++int bsp_boot_secondary(unsigned int cpu, struct task_struct *idle); ++#endif /* CONFIG_SMP */ ++#endif /* __SMP_COMMON_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7202v300.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7202v300.c.patch new file mode 100644 index 00000000..ce8de095 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7202v300.c.patch @@ -0,0 +1,55 @@ +--- linux-4.9.37/arch/arm/mach-goke/mach-gk7202v300.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/mach-gk7202v300.c 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++ ++#include "mach-common.h" ++ ++#ifdef CONFIG_SMP ++ ++#define REG_CPU_SRST_CRG 0x78 ++#define CPU1_SRST_REQ BIT(2) ++#define DBG1_SRST_REQ BIT(4) ++ ++void bsp_set_cpu(unsigned int cpu, bool enable) ++{ ++ struct device_node *np = NULL; ++ unsigned int regval; ++ void __iomem *crg_base; ++ ++ np = of_find_compatible_node(NULL, NULL, "goke,gk7202v300-clock"); ++ if (!np) { ++ pr_err("failed to find goke clock node\n"); ++ return; ++ } ++ ++ crg_base = of_iomap(np, 0); ++ if (!crg_base) { ++ pr_err("failed to map address\n"); ++ return; ++ } ++ ++ if (enable) { ++ /* clear the slave cpu reset */ ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval &= ~CPU1_SRST_REQ; ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } else { ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } ++} ++ ++static const struct smp_operations bsp_smp_ops __initconst = { ++ .smp_prepare_cpus = bsp_smp_prepare_cpus, ++ .smp_boot_secondary = bsp_boot_secondary, ++}; ++ ++CPU_METHOD_OF_DECLARE(gk7202v300_smp, "goke,gk7202v300-smp", &bsp_smp_ops); ++#endif /* CONFIG_SMP */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7205v200.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7205v200.c.patch new file mode 100644 index 00000000..d660714b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7205v200.c.patch @@ -0,0 +1,55 @@ +--- linux-4.9.37/arch/arm/mach-goke/mach-gk7205v200.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/mach-gk7205v200.c 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++ ++#include "mach-common.h" ++ ++#ifdef CONFIG_SMP ++ ++#define REG_CPU_SRST_CRG 0x78 ++#define CPU1_SRST_REQ BIT(2) ++#define DBG1_SRST_REQ BIT(4) ++ ++void bsp_set_cpu(unsigned int cpu, bool enable) ++{ ++ struct device_node *np = NULL; ++ unsigned int regval; ++ void __iomem *crg_base; ++ ++ np = of_find_compatible_node(NULL, NULL, "goke,gk7205v200-clock"); ++ if (!np) { ++ pr_err("failed to find goke clock node\n"); ++ return; ++ } ++ ++ crg_base = of_iomap(np, 0); ++ if (!crg_base) { ++ pr_err("failed to map address\n"); ++ return; ++ } ++ ++ if (enable) { ++ /* clear the slave cpu reset */ ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval &= ~CPU1_SRST_REQ; ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } else { ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } ++} ++ ++static const struct smp_operations bsp_smp_ops __initconst = { ++ .smp_prepare_cpus = bsp_smp_prepare_cpus, ++ .smp_boot_secondary = bsp_boot_secondary, ++}; ++ ++CPU_METHOD_OF_DECLARE(gk7205v200_smp, "goke,gk7205v200-smp", &bsp_smp_ops); ++#endif /* CONFIG_SMP */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7205v300.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7205v300.c.patch new file mode 100644 index 00000000..4feeaaa4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7205v300.c.patch @@ -0,0 +1,55 @@ +--- linux-4.9.37/arch/arm/mach-goke/mach-gk7205v300.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/mach-gk7205v300.c 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++ ++#include "mach-common.h" ++ ++#ifdef CONFIG_SMP ++ ++#define REG_CPU_SRST_CRG 0x78 ++#define CPU1_SRST_REQ BIT(2) ++#define DBG1_SRST_REQ BIT(4) ++ ++void bsp_set_cpu(unsigned int cpu, bool enable) ++{ ++ struct device_node *np = NULL; ++ unsigned int regval; ++ void __iomem *crg_base; ++ ++ np = of_find_compatible_node(NULL, NULL, "goke,gk7205v300-clock"); ++ if (!np) { ++ pr_err("failed to find goke clock node\n"); ++ return; ++ } ++ ++ crg_base = of_iomap(np, 0); ++ if (!crg_base) { ++ pr_err("failed to map address\n"); ++ return; ++ } ++ ++ if (enable) { ++ /* clear the slave cpu reset */ ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval &= ~CPU1_SRST_REQ; ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } else { ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } ++} ++ ++static const struct smp_operations bsp_smp_ops __initconst = { ++ .smp_prepare_cpus = bsp_smp_prepare_cpus, ++ .smp_boot_secondary = bsp_boot_secondary, ++}; ++ ++CPU_METHOD_OF_DECLARE(gk7205v300_smp, "goke,gk7205v300-smp", &bsp_smp_ops); ++#endif /* CONFIG_SMP */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7605v100.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7605v100.c.patch new file mode 100644 index 00000000..44c282a1 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mach-goke-mach-gk7605v100.c.patch @@ -0,0 +1,55 @@ +--- linux-4.9.37/arch/arm/mach-goke/mach-gk7605v100.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/arch/arm/mach-goke/mach-gk7605v100.c 2021-06-07 13:01:32.000000000 +0300 +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++ ++#include "mach-common.h" ++ ++#ifdef CONFIG_SMP ++ ++#define REG_CPU_SRST_CRG 0x78 ++#define CPU1_SRST_REQ BIT(2) ++#define DBG1_SRST_REQ BIT(4) ++ ++void bsp_set_cpu(unsigned int cpu, bool enable) ++{ ++ struct device_node *np = NULL; ++ unsigned int regval; ++ void __iomem *crg_base; ++ ++ np = of_find_compatible_node(NULL, NULL, "goke,gk7605v100-clock"); ++ if (!np) { ++ pr_err("failed to find goke clock node\n"); ++ return; ++ } ++ ++ crg_base = of_iomap(np, 0); ++ if (!crg_base) { ++ pr_err("failed to map address\n"); ++ return; ++ } ++ ++ if (enable) { ++ /* clear the slave cpu reset */ ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval &= ~CPU1_SRST_REQ; ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } else { ++ regval = readl(crg_base + REG_CPU_SRST_CRG); ++ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); ++ writel(regval, (crg_base + REG_CPU_SRST_CRG)); ++ } ++} ++ ++static const struct smp_operations bsp_smp_ops __initconst = { ++ .smp_prepare_cpus = bsp_smp_prepare_cpus, ++ .smp_boot_secondary = bsp_boot_secondary, ++}; ++ ++CPU_METHOD_OF_DECLARE(gk7605v100_smp, "goke,gk7605v100-smp", &bsp_smp_ops); ++#endif /* CONFIG_SMP */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mm-dma-mapping.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mm-dma-mapping.c.patch new file mode 100644 index 00000000..7f693180 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mm-dma-mapping.c.patch @@ -0,0 +1,43 @@ +--- linux-4.9.37/arch/arm/mm/dma-mapping.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/mm/dma-mapping.c 2021-06-07 13:01:32.000000000 +0300 +@@ -275,7 +275,7 @@ + return mask; + } + +-static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) ++void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) + { + /* + * Ensure that the allocated pages are zeroed, and that any data +@@ -304,6 +304,7 @@ + } + } + } ++EXPORT_SYMBOL(__dma_clear_buffer); + + /* + * Allocate a DMA buffer for 'dev' of size 'size' using the +@@ -528,6 +529,12 @@ + flush_tlb_kernel_range(start, end); + } + ++void bsp_flush_tlb_kernel_range(unsigned long start, unsigned long end) ++{ ++ flush_tlb_kernel_range(start, end); ++} ++EXPORT_SYMBOL(bsp_flush_tlb_kernel_range); ++ + static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, + pgprot_t prot, struct page **ret_page, + const void *caller, bool want_vaddr) +@@ -2397,3 +2404,10 @@ + { + arm_teardown_iommu_dma_ops(dev); + } ++ ++void bsp_dmac_map_area(const void *kaddr, size_t size, ++ enum dma_data_direction dir) ++{ ++ dmac_map_area(kaddr, size, dir); ++} ++EXPORT_SYMBOL(bsp_dmac_map_area); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mm-init.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mm-init.c.patch new file mode 100644 index 00000000..f3831354 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-mm-init.c.patch @@ -0,0 +1,15 @@ +--- linux-4.9.37/arch/arm/mm/init.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/mm/init.c 2021-06-07 13:01:32.000000000 +0300 +@@ -268,6 +268,12 @@ + /* reserve any platform specific memblock areas */ + if (mdesc->reserve) + mdesc->reserve(); ++#if defined CONFIG_CMA && defined CONFIG_ARCH_GOKE ++ else { ++ extern int goke_declare_heap_memory(void); ++ goke_declare_heap_memory(); ++ } ++#endif + + early_init_fdt_reserve_self(); + early_init_fdt_scan_reserved_mem(); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-vdso-vgettimeofday.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-vdso-vgettimeofday.c.patch new file mode 100644 index 00000000..7603e494 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-arm-vdso-vgettimeofday.c.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/arch/arm/vdso/vgettimeofday.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/arm/vdso/vgettimeofday.c 2021-06-07 13:01:32.000000000 +0300 +@@ -115,7 +115,7 @@ + return 0; + } + +-#ifdef CONFIG_ARM_ARCH_TIMER ++#if defined (CONFIG_ARM_ARCH_TIMER) && defined(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS) + + static notrace u64 get_ns(struct vdso_data *vdata) + { diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-sh-boot-compressed-vmlinux.scr.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-sh-boot-compressed-vmlinux.scr.patch new file mode 100644 index 00000000..28a9592a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-sh-boot-compressed-vmlinux.scr.patch @@ -0,0 +1,13 @@ +--- linux-4.9.37/arch/sh/boot/compressed/vmlinux.scr 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/sh/boot/compressed/vmlinux.scr 1970-01-01 03:00:00.000000000 +0300 +@@ -1,10 +0,0 @@ +-SECTIONS +-{ +- .rodata..compressed : { +- input_len = .; +- LONG(input_data_end - input_data) input_data = .; +- *(.data) +- output_len = . - 4; +- input_data_end = .; +- } +-} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-sh-boot-romimage-vmlinux.scr.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-sh-boot-romimage-vmlinux.scr.patch new file mode 100644 index 00000000..0897ccd7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_arch-sh-boot-romimage-vmlinux.scr.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/arch/sh/boot/romimage/vmlinux.scr 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/arch/sh/boot/romimage/vmlinux.scr 1970-01-01 03:00:00.000000000 +0300 +@@ -1,8 +0,0 @@ +-SECTIONS +-{ +- .text : { +- zero_page_pos = .; +- *(.data) +- end_data = .; +- } +-} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-Kconfig.patch new file mode 100644 index 00000000..4c2b27d0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-Kconfig.patch @@ -0,0 +1,9 @@ +--- linux-4.9.37/drivers/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -202,4 +202,6 @@ + + source "drivers/fpga/Kconfig" + ++source "drivers/goke/Kconfig" ++ + endmenu diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-Makefile.patch new file mode 100644 index 00000000..a52cb8ea --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-Makefile.patch @@ -0,0 +1,15 @@ +--- linux-4.9.37/drivers/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -70,6 +70,7 @@ + obj-$(CONFIG_LIBNVDIMM) += nvdimm/ + obj-$(CONFIG_DEV_DAX) += dax/ + obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/ ++obj-$(CONFIG_SYNC_FILE) += fence/ + obj-$(CONFIG_NUBUS) += nubus/ + obj-y += macintosh/ + obj-$(CONFIG_IDE) += ide/ +@@ -174,3 +175,4 @@ + obj-$(CONFIG_ANDROID) += android/ + obj-$(CONFIG_NVMEM) += nvmem/ + obj-$(CONFIG_FPGA) += fpga/ ++obj-$(CONFIG_ARCH_GOKE) += goke/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-base-dma-contiguous.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-base-dma-contiguous.c.patch new file mode 100644 index 00000000..ab5164f7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-base-dma-contiguous.c.patch @@ -0,0 +1,18 @@ +--- linux-4.9.37/drivers/base/dma-contiguous.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/base/dma-contiguous.c 2021-06-07 13:01:33.000000000 +0300 +@@ -195,6 +195,7 @@ + + return cma_alloc(dev_get_cma_area(dev), count, align); + } ++EXPORT_SYMBOL(dma_alloc_from_contiguous); + + /** + * dma_release_from_contiguous() - release allocated pages +@@ -211,6 +212,7 @@ + { + return cma_release(dev_get_cma_area(dev), pages, count); + } ++EXPORT_SYMBOL(dma_release_from_contiguous); + + /* + * Support for reserved memory regions defined in device tree diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-char-random.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-char-random.c.patch new file mode 100644 index 00000000..7fdaf27a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-char-random.c.patch @@ -0,0 +1,29 @@ +--- linux-4.9.37/drivers/char/random.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/char/random.c 2021-06-07 13:01:33.000000000 +0300 +@@ -812,7 +812,7 @@ + if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { + crng_init = 1; + wake_up_interruptible(&crng_init_wait); +- pr_notice("random: fast init done\n"); ++ printk_once("random: fast init done\n"); + } + spin_unlock_irqrestore(&primary_crng.lock, flags); + return 1; +@@ -850,7 +850,7 @@ + crng_init = 2; + process_random_ready_list(); + wake_up_interruptible(&crng_init_wait); +- pr_notice("random: crng init done\n"); ++ printk_once("random: crng init done\n"); + } + spin_unlock_irqrestore(&primary_crng.lock, flags); + } +@@ -1744,7 +1744,7 @@ + + if (!crng_ready() && maxwarn > 0) { + maxwarn--; +- printk(KERN_NOTICE "random: %s: uninitialized urandom read " ++ printk_once(KERN_NOTICE "random: %s: uninitialized urandom read " + "(%zd bytes read)\n", + current->comm, nbytes); + spin_lock_irqsave(&primary_crng.lock, flags); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-Kconfig.patch new file mode 100644 index 00000000..40b80352 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-Kconfig.patch @@ -0,0 +1,9 @@ +--- linux-4.9.37/drivers/clk/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/clk/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -210,5 +210,6 @@ + source "drivers/clk/tegra/Kconfig" + source "drivers/clk/ti/Kconfig" + source "drivers/clk/uniphier/Kconfig" ++source "drivers/clk/goke/Kconfig" + + endmenu diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-Makefile.patch new file mode 100644 index 00000000..50d6af5e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-Makefile.patch @@ -0,0 +1,8 @@ +--- linux-4.9.37/drivers/clk/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/clk/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -92,3 +92,4 @@ + endif + obj-$(CONFIG_ARCH_ZX) += zte/ + obj-$(CONFIG_ARCH_ZYNQ) += zynq/ ++obj-$(CONFIG_ARCH_GOKE) += goke/ +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-Kconfig.patch new file mode 100644 index 00000000..f5965adf --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-Kconfig.patch @@ -0,0 +1,42 @@ +--- linux-4.9.37/drivers/clk/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,39 @@ ++config COMMON_CLK_GK7205V200 ++ tristate "GK7205V200 Clock Driver" ++ depends on ARCH_GK7205V200 || COMPILE_TEST ++ select RESET_GOKE ++ default ARCH_GOKE ++ help ++ Build the clock driver for GK7205V200. ++ ++config COMMON_CLK_GK7205V300 ++ tristate "GK7205V300 Clock Driver" ++ depends on ARCH_GK7205V300 || COMPILE_TEST ++ select RESET_GOKE ++ default ARCH_GOKE ++ help ++ Build the clock driver for GK7205V300. ++ ++config COMMON_CLK_GK7202V300 ++ tristate "GK7202V300 Clock Driver" ++ depends on ARCH_GK7202V300 || COMPILE_TEST ++ select RESET_GOKE ++ default ARCH_GOKE ++ help ++ Build the clock driver for GK7202V300. ++ ++config COMMON_CLK_GK7605V100 ++ tristate "GK7605V100 Clock Driver" ++ depends on ARCH_GK7605V100 || COMPILE_TEST ++ select RESET_GOKE ++ default ARCH_GOKE ++ help ++ Build the clock driver for GK7605V100. ++ ++config RESET_GOKE ++ bool "Goke Reset Controller Driver" ++ depends on ARCH_GOKE || COMPILE_TEST || ARCH_GOKE ++ select RESET_CONTROLLER ++ help ++ Build reset controller driver for Goke device chipsets. ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-Makefile.patch new file mode 100644 index 00000000..196b2ea8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-Makefile.patch @@ -0,0 +1,13 @@ +--- linux-4.9.37/drivers/clk/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,10 @@ ++# ++# Goke Clock specific Makefile ++# ++ ++obj-y += clk.o ++obj-$(CONFIG_COMMON_CLK_GK7205V200) += clk-gk7205v200.o ++obj-$(CONFIG_COMMON_CLK_GK7205V300) += clk-gk7205v300.o ++obj-$(CONFIG_COMMON_CLK_GK7202V300) += clk-gk7202v300.o ++obj-$(CONFIG_COMMON_CLK_GK7605V100) += clk-gk7605v100.o ++obj-$(CONFIG_RESET_GOKE) += reset.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7202v300.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7202v300.c.patch new file mode 100644 index 00000000..c2eb570f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7202v300.c.patch @@ -0,0 +1,236 @@ +--- linux-4.9.37/drivers/clk/goke/clk-gk7202v300.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/clk-gk7202v300.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,233 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk.h" ++#include "reset.h" ++ ++static struct gk_fixed_rate_clock gk7202v300_fixed_rate_clks[] __initdata = { ++ { GK7202V300_FIXED_100K, "100k", NULL, 0, 100000, }, ++ { GK7202V300_FIXED_400K, "400k", NULL, 0, 400000, }, ++ { GK7202V300_FIXED_3M, "3m", NULL, 0, 3000000, }, ++ { GK7202V300_FIXED_6M, "6m", NULL, 0, 6000000, }, ++ { GK7202V300_FIXED_12M, "12m", NULL, 0, 12000000, }, ++ { GK7202V300_FIXED_24M, "24m", NULL, 0, 24000000, }, ++ { GK7202V300_FIXED_25M, "25m", NULL, 0, 25000000, }, ++ { GK7202V300_FIXED_50M, "50m", NULL, 0, 50000000, }, ++ { GK7202V300_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, ++ { GK7202V300_FIXED_90M, "90m", NULL, 0, 90000000, }, ++ { GK7202V300_FIXED_100M, "100m", NULL, 0, 100000000, }, ++ { GK7202V300_FIXED_112M, "112m", NULL, 0, 112000000, }, ++ { GK7202V300_FIXED_125M, "125m", NULL, 0, 125000000, }, ++ { GK7202V300_FIXED_150M, "150m", NULL, 0, 150000000, }, ++ { GK7202V300_FIXED_200M, "200m", NULL, 0, 200000000, }, ++ { GK7202V300_FIXED_250M, "250m", NULL, 0, 250000000, }, ++ { GK7202V300_FIXED_300M, "300m", NULL, 0, 300000000, }, ++ { GK7202V300_FIXED_324M, "324m", NULL, 0, 324000000, }, ++ { GK7202V300_FIXED_342M, "342m", NULL, 0, 342000000, }, ++ { GK7202V300_FIXED_342M, "375m", NULL, 0, 375000000, }, ++ { GK7202V300_FIXED_400M, "400m", NULL, 0, 400000000, }, ++ { GK7202V300_FIXED_448M, "448m", NULL, 0, 448000000, }, ++ { GK7202V300_FIXED_500M, "500m", NULL, 0, 500000000, }, ++ { GK7202V300_FIXED_540M, "540m", NULL, 0, 540000000, }, ++ { GK7202V300_FIXED_600M, "600m", NULL, 0, 600000000, }, ++ { GK7202V300_FIXED_750M, "750m", NULL, 0, 750000000, }, ++ { GK7202V300_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, ++ { GK7202V300_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, ++}; ++ ++static const char *sysaxi_mux_p[] __initconst = { ++ "24m", "200m" ++}; ++static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; ++static const char *uart_mux_p[] __initconst = {"24m", "6m"}; ++static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "200m", "300m", "360m"}; ++static const char *mmc_mux_p[] __initdata = { ++ "100k", "400k", "25m", "50m", "90m", "112m", "150m" ++}; ++static const char *eth_mux_p[] __initconst = {"100m", "54m"}; ++static const char *usb_mux_p[] __initdata = {"phy", "crg",}; ++ ++static u32 sysaxi_mux_table[] = {0, 1}; ++static u32 sysapb_mux_table[] = {0, 1}; ++static u32 uart_mux_table[] = {0, 1}; ++static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; ++static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; ++static u32 eth_mux_table[] = {0, 1}; ++static u32 usb_mux_table[] = {0, 1}; ++ ++static struct gk_mux_clock gk7202v300_mux_clks[] __initdata = { ++ { ++ GK7202V300_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, ++ ARRAY_SIZE(sysaxi_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, ++ }, ++ { ++ GK7202V300_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, ++ ARRAY_SIZE(sysapb_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, ++ }, ++ { ++ GK7202V300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, ++ }, ++ { ++ GK7202V300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7202V300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7202V300_UART_MUX, "uart_mux0", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7202V300_UART_MUX, "uart_mux1", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7202V300_UART_MUX, "uart_mux2", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7202V300_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), ++ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, ++ }, ++ { ++ GK7202V300_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), ++ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table ++ }, ++}; ++ ++static struct gk_fixed_factor_clock gk7202v300_fixed_factor_clks[] __initdata = { ++ { ++ GK7202V300_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, ++ CLK_SET_RATE_PARENT ++ }, ++}; ++ ++static struct gk_gate_clock gk7202v300_gate_clks[] __initdata = { ++ /* fmc */ ++ { ++ GK7202V300_FMC_CLK, "clk_fmc", "fmc_mux", ++ CLK_SET_RATE_PARENT, 0x144, 1, 0, ++ }, ++ /* mmc */ ++ { ++ GK7202V300_MMC0_CLK, "clk_mmc0", "mmc0_mux", ++ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, ++ }, ++ { ++ GK7202V300_MMC1_CLK, "clk_mmc1", "mmc1_mux", ++ CLK_SET_RATE_PARENT, 0x22c, 28, 0, ++ }, ++ /* uart */ ++ { ++ GK7202V300_UART0_CLK, "clk_uart0", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, ++ }, ++ { ++ GK7202V300_UART1_CLK, "clk_uart1", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, ++ }, ++ { ++ GK7202V300_UART2_CLK, "clk_uart2", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, ++ }, ++ /* spi */ ++ { ++ GK7202V300_SPI0_CLK, "clk_spi0", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, ++ }, ++ { ++ GK7202V300_SPI1_CLK, "clk_spi1", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, ++ }, ++ /* i2c */ ++ { ++ GK7202V300_I2C0_CLK, "clk_i2c0", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, ++ }, ++ { ++ GK7202V300_I2C1_CLK, "clk_i2c1", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, ++ }, ++ { ++ GK7202V300_I2C2_CLK, "clk_i2c2", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, ++ }, ++ /* ethernet mac */ ++ { ++ GK7202V300_ETH0_CLK, "clk_eth0", "eth_mux", ++ CLK_SET_RATE_PARENT, 0x16c, 1, 0, ++ }, ++ /* edmac */ ++ { ++ GK7202V300_EDMAC_AXICLK, "axi_clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 2, 0, ++ }, ++ { ++ GK7202V300_EDMAC_CLK, "clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 1, 0, ++ }, ++ /* usb */ ++ { ++ GK7202V300_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 8, 0, ++ }, ++ { ++ GK7202V300_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 9, 0, ++ }, ++ { ++ GK7202V300_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 12, 0, ++ }, ++ { ++ GK7202V300_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 11, 0, ++ }, ++ { ++ GK7202V300_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 4, 0, ++ }, ++ { ++ GK7202V300_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 2, 0, ++ }, ++}; ++ ++static void __init gk7202v300_clk_init(struct device_node *np) ++{ ++ struct gk_clock_data *clk_data; ++ ++ clk_data = gk_clk_init(np, GK7202V300_NR_CLKS); ++ if (!clk_data) ++ return; ++ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) ++ gk_reset_init(np, GK7202V300_NR_RSTS); ++ ++ gk_clk_register_fixed_rate(gk7202v300_fixed_rate_clks, ++ ARRAY_SIZE(gk7202v300_fixed_rate_clks), ++ clk_data); ++ gk_clk_register_mux(gk7202v300_mux_clks, ARRAY_SIZE(gk7202v300_mux_clks), ++ clk_data); ++ gk_clk_register_fixed_factor(gk7202v300_fixed_factor_clks, ++ ARRAY_SIZE(gk7202v300_fixed_factor_clks), clk_data); ++ gk_clk_register_gate(gk7202v300_gate_clks, ++ ARRAY_SIZE(gk7202v300_gate_clks), clk_data); ++ ++} ++ ++CLK_OF_DECLARE(gk7202v300_clk, "goke,gk7202v300-clock", gk7202v300_clk_init); ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7205v200.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7205v200.c.patch new file mode 100644 index 00000000..57744edb --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7205v200.c.patch @@ -0,0 +1,238 @@ +--- linux-4.9.37/drivers/clk/goke/clk-gk7205v200.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/clk-gk7205v200.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,235 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk.h" ++#include "reset.h" ++ ++static struct gk_fixed_rate_clock gk7205v200_fixed_rate_clks[] __initdata = { ++ { GK7205V200_FIXED_100K, "100k", NULL, 0, 100000, }, ++ { GK7205V200_FIXED_400K, "400k", NULL, 0, 400000, }, ++ { GK7205V200_FIXED_3M, "3m", NULL, 0, 3000000, }, ++ { GK7205V200_FIXED_6M, "6m", NULL, 0, 6000000, }, ++ { GK7205V200_FIXED_12M, "12m", NULL, 0, 12000000, }, ++ { GK7205V200_FIXED_24M, "24m", NULL, 0, 24000000, }, ++ { GK7205V200_FIXED_25M, "25m", NULL, 0, 25000000, }, ++ { GK7205V200_FIXED_50M, "50m", NULL, 0, 50000000, }, ++ { GK7205V200_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, ++ { GK7205V200_FIXED_90M, "90m", NULL, 0, 90000000, }, ++ { GK7205V200_FIXED_100M, "100m", NULL, 0, 100000000, }, ++ { GK7205V200_FIXED_112M, "112m", NULL, 0, 112000000, }, ++ { GK7205V200_FIXED_125M, "125m", NULL, 0, 125000000, }, ++ { GK7205V200_FIXED_150M, "150m", NULL, 0, 150000000, }, ++ { GK7205V200_FIXED_200M, "200m", NULL, 0, 200000000, }, ++ { GK7205V200_FIXED_250M, "250m", NULL, 0, 250000000, }, ++ { GK7205V200_FIXED_300M, "300m", NULL, 0, 300000000, }, ++ { GK7205V200_FIXED_324M, "324m", NULL, 0, 324000000, }, ++ { GK7205V200_FIXED_342M, "342m", NULL, 0, 342000000, }, ++ { GK7205V200_FIXED_342M, "375m", NULL, 0, 375000000, }, ++ { GK7205V200_FIXED_400M, "400m", NULL, 0, 400000000, }, ++ { GK7205V200_FIXED_448M, "448m", NULL, 0, 448000000, }, ++ { GK7205V200_FIXED_500M, "500m", NULL, 0, 500000000, }, ++ { GK7205V200_FIXED_540M, "540m", NULL, 0, 540000000, }, ++ { GK7205V200_FIXED_600M, "600m", NULL, 0, 600000000, }, ++ { GK7205V200_FIXED_750M, "750m", NULL, 0, 750000000, }, ++ { GK7205V200_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, ++ { GK7205V200_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, ++}; ++ ++static const char *sysaxi_mux_p[] __initconst = { ++ "24m", "200m" ++}; ++static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; ++static const char *uart_mux_p[] __initconst = {"24m", "6m"}; ++static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "200m", "300m", "360m"}; ++static const char *mmc_mux_p[] __initdata = { ++ "100k", "400k", "25m", "50m", "90m", "112m", "150m" ++}; ++static const char *eth_mux_p[] __initconst = {"100m", "54m"}; ++static const char *usb_mux_p[] __initdata = {"phy", "crg",}; ++ ++static u32 sysaxi_mux_table[] = {0, 1}; ++static u32 sysapb_mux_table[] = {0, 1}; ++static u32 uart_mux_table[] = {0, 1}; ++static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; ++static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; ++static u32 eth_mux_table[] = {0, 1}; ++static u32 usb_mux_table[] = {0, 1}; ++ ++static struct gk_mux_clock gk7205v200_mux_clks[] __initdata = { ++ { ++ GK7205V200_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, ++ ARRAY_SIZE(sysaxi_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, ++ }, ++ { ++ GK7205V200_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, ++ ARRAY_SIZE(sysapb_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, ++ }, ++ { ++ GK7205V200_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, ++ }, ++ { ++ GK7205V200_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7205V200_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7205V200_UART_MUX, "uart_mux0", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7205V200_UART_MUX, "uart_mux1", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7205V200_UART_MUX, "uart_mux2", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7205V200_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), ++ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, ++ }, ++ { ++ GK7205V200_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), ++ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table ++ }, ++}; ++ ++#if 1 ++static struct gk_fixed_factor_clock gk7205v200_fixed_factor_clks[] __initdata = { ++ { ++ GK7205V200_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, ++ CLK_SET_RATE_PARENT ++ }, ++}; ++#endif ++ ++static struct gk_gate_clock gk7205v200_gate_clks[] __initdata = { ++ /* fmc */ ++ { ++ GK7205V200_FMC_CLK, "clk_fmc", "fmc_mux", ++ CLK_SET_RATE_PARENT, 0x144, 1, 0, ++ }, ++ /* mmc */ ++ { ++ GK7205V200_MMC0_CLK, "clk_mmc0", "mmc0_mux", ++ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, ++ }, ++ { ++ GK7205V200_MMC1_CLK, "clk_mmc1", "mmc1_mux", ++ CLK_SET_RATE_PARENT, 0x22c, 28, 0, ++ }, ++ /* uart */ ++ { ++ GK7205V200_UART0_CLK, "clk_uart0", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, ++ }, ++ { ++ GK7205V200_UART1_CLK, "clk_uart1", "uart_mux1", ++ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, ++ }, ++ { ++ GK7205V200_UART2_CLK, "clk_uart2", "uart_mux2", ++ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, ++ }, ++ /* spi */ ++ { ++ GK7205V200_SPI0_CLK, "clk_spi0", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, ++ }, ++ { ++ GK7205V200_SPI1_CLK, "clk_spi1", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, ++ }, ++ /* i2c */ ++ { ++ GK7205V200_I2C0_CLK, "clk_i2c0", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, ++ }, ++ { ++ GK7205V200_I2C1_CLK, "clk_i2c1", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, ++ }, ++ { ++ GK7205V200_I2C2_CLK, "clk_i2c2", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, ++ }, ++ /* ethernet mac */ ++ { ++ GK7205V200_ETH0_CLK, "clk_eth0", "eth_mux", ++ CLK_SET_RATE_PARENT, 0x16c, 1, 0, ++ }, ++ /* edmac */ ++ { ++ GK7205V200_EDMAC_AXICLK, "axi_clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 2, 0, ++ }, ++ { ++ GK7205V200_EDMAC_CLK, "clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 1, 0, ++ }, ++ /* usb */ ++ { ++ GK7205V200_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 8, 0, ++ }, ++ { ++ GK7205V200_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 9, 0, ++ }, ++ { ++ GK7205V200_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 12, 0, ++ }, ++ { ++ GK7205V200_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 11, 0, ++ }, ++ { ++ GK7205V200_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 4, 0, ++ }, ++ { ++ GK7205V200_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 2, 0, ++ }, ++}; ++ ++static void __init gk7205v200_clk_init(struct device_node *np) ++{ ++ struct gk_clock_data *clk_data; ++ ++ clk_data = gk_clk_init(np, GK7205V200_NR_CLKS); ++ if (!clk_data) ++ return; ++ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) ++ gk_reset_init(np, GK7205V200_NR_RSTS); ++ ++ gk_clk_register_fixed_rate(gk7205v200_fixed_rate_clks, ++ ARRAY_SIZE(gk7205v200_fixed_rate_clks), ++ clk_data); ++ gk_clk_register_mux(gk7205v200_mux_clks, ARRAY_SIZE(gk7205v200_mux_clks), ++ clk_data); ++ gk_clk_register_fixed_factor(gk7205v200_fixed_factor_clks, ++ ARRAY_SIZE(gk7205v200_fixed_factor_clks), clk_data); ++ gk_clk_register_gate(gk7205v200_gate_clks, ++ ARRAY_SIZE(gk7205v200_gate_clks), clk_data); ++ ++} ++ ++CLK_OF_DECLARE(gk7205v200_clk, "goke,gk7205v200-clock", gk7205v200_clk_init); ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7205v300.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7205v300.c.patch new file mode 100644 index 00000000..52827467 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7205v300.c.patch @@ -0,0 +1,236 @@ +--- linux-4.9.37/drivers/clk/goke/clk-gk7205v300.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/clk-gk7205v300.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,233 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk.h" ++#include "reset.h" ++ ++static struct gk_fixed_rate_clock gk7205v300_fixed_rate_clks[] __initdata = { ++ { GK7205V300_FIXED_100K, "100k", NULL, 0, 100000, }, ++ { GK7205V300_FIXED_400K, "400k", NULL, 0, 400000, }, ++ { GK7205V300_FIXED_3M, "3m", NULL, 0, 3000000, }, ++ { GK7205V300_FIXED_6M, "6m", NULL, 0, 6000000, }, ++ { GK7205V300_FIXED_12M, "12m", NULL, 0, 12000000, }, ++ { GK7205V300_FIXED_24M, "24m", NULL, 0, 24000000, }, ++ { GK7205V300_FIXED_25M, "25m", NULL, 0, 25000000, }, ++ { GK7205V300_FIXED_50M, "50m", NULL, 0, 50000000, }, ++ { GK7205V300_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, ++ { GK7205V300_FIXED_90M, "90m", NULL, 0, 90000000, }, ++ { GK7205V300_FIXED_100M, "100m", NULL, 0, 100000000, }, ++ { GK7205V300_FIXED_112M, "112m", NULL, 0, 112000000, }, ++ { GK7205V300_FIXED_125M, "125m", NULL, 0, 125000000, }, ++ { GK7205V300_FIXED_150M, "150m", NULL, 0, 150000000, }, ++ { GK7205V300_FIXED_200M, "200m", NULL, 0, 200000000, }, ++ { GK7205V300_FIXED_250M, "250m", NULL, 0, 250000000, }, ++ { GK7205V300_FIXED_300M, "300m", NULL, 0, 300000000, }, ++ { GK7205V300_FIXED_324M, "324m", NULL, 0, 324000000, }, ++ { GK7205V300_FIXED_342M, "342m", NULL, 0, 342000000, }, ++ { GK7205V300_FIXED_342M, "375m", NULL, 0, 375000000, }, ++ { GK7205V300_FIXED_400M, "400m", NULL, 0, 400000000, }, ++ { GK7205V300_FIXED_448M, "448m", NULL, 0, 448000000, }, ++ { GK7205V300_FIXED_500M, "500m", NULL, 0, 500000000, }, ++ { GK7205V300_FIXED_540M, "540m", NULL, 0, 540000000, }, ++ { GK7205V300_FIXED_600M, "600m", NULL, 0, 600000000, }, ++ { GK7205V300_FIXED_750M, "750m", NULL, 0, 750000000, }, ++ { GK7205V300_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, ++ { GK7205V300_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, ++}; ++ ++static const char *sysaxi_mux_p[] __initconst = { ++ "24m", "200m" ++}; ++static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; ++static const char *uart_mux_p[] __initconst = {"24m", "6m"}; ++static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "200m", "300m", "360m"}; ++static const char *mmc_mux_p[] __initdata = { ++ "100k", "400k", "25m", "50m", "90m", "112m", "150m" ++}; ++static const char *eth_mux_p[] __initconst = {"100m", "54m"}; ++static const char *usb_mux_p[] __initdata = {"phy", "crg",}; ++ ++static u32 sysaxi_mux_table[] = {0, 1}; ++static u32 sysapb_mux_table[] = {0, 1}; ++static u32 uart_mux_table[] = {0, 1}; ++static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; ++static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; ++static u32 eth_mux_table[] = {0, 1}; ++static u32 usb_mux_table[] = {0, 1}; ++ ++static struct gk_mux_clock gk7205v300_mux_clks[] __initdata = { ++ { ++ GK7205V300_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, ++ ARRAY_SIZE(sysaxi_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, ++ }, ++ { ++ GK7205V300_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, ++ ARRAY_SIZE(sysapb_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, ++ }, ++ { ++ GK7205V300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, ++ }, ++ { ++ GK7205V300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7205V300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7205V300_UART_MUX, "uart_mux0", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7205V300_UART_MUX, "uart_mux1", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7205V300_UART_MUX, "uart_mux2", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7205V300_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), ++ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, ++ }, ++ { ++ GK7205V300_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), ++ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table ++ }, ++}; ++ ++static struct gk_fixed_factor_clock gk7205v300_fixed_factor_clks[] __initdata = { ++ { ++ GK7205V300_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, ++ CLK_SET_RATE_PARENT ++ }, ++}; ++ ++static struct gk_gate_clock gk7205v300_gate_clks[] __initdata = { ++ /* fmc */ ++ { ++ GK7205V300_FMC_CLK, "clk_fmc", "fmc_mux", ++ CLK_SET_RATE_PARENT, 0x144, 1, 0, ++ }, ++ /* mmc */ ++ { ++ GK7205V300_MMC0_CLK, "clk_mmc0", "mmc0_mux", ++ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, ++ }, ++ { ++ GK7205V300_MMC1_CLK, "clk_mmc1", "mmc1_mux", ++ CLK_SET_RATE_PARENT, 0x22c, 28, 0, ++ }, ++ /* uart */ ++ { ++ GK7205V300_UART0_CLK, "clk_uart0", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, ++ }, ++ { ++ GK7205V300_UART1_CLK, "clk_uart1", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, ++ }, ++ { ++ GK7205V300_UART2_CLK, "clk_uart2", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, ++ }, ++ /* spi */ ++ { ++ GK7205V300_SPI0_CLK, "clk_spi0", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, ++ }, ++ { ++ GK7205V300_SPI1_CLK, "clk_spi1", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, ++ }, ++ /* i2c */ ++ { ++ GK7205V300_I2C0_CLK, "clk_i2c0", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, ++ }, ++ { ++ GK7205V300_I2C1_CLK, "clk_i2c1", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, ++ }, ++ { ++ GK7205V300_I2C2_CLK, "clk_i2c2", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, ++ }, ++ /* ethernet mac */ ++ { ++ GK7205V300_ETH0_CLK, "clk_eth0", "eth_mux", ++ CLK_SET_RATE_PARENT, 0x16c, 1, 0, ++ }, ++ /* edmac */ ++ { ++ GK7205V300_EDMAC_AXICLK, "axi_clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 2, 0, ++ }, ++ { ++ GK7205V300_EDMAC_CLK, "clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 1, 0, ++ }, ++ /* usb */ ++ { ++ GK7205V300_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 8, 0, ++ }, ++ { ++ GK7205V300_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 9, 0, ++ }, ++ { ++ GK7205V300_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 12, 0, ++ }, ++ { ++ GK7205V300_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 11, 0, ++ }, ++ { ++ GK7205V300_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 4, 0, ++ }, ++ { ++ GK7205V300_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 2, 0, ++ }, ++}; ++ ++static void __init gk7205v300_clk_init(struct device_node *np) ++{ ++ struct gk_clock_data *clk_data; ++ ++ clk_data = gk_clk_init(np, GK7205V300_NR_CLKS); ++ if (!clk_data) ++ return; ++ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) ++ gk_reset_init(np, GK7205V300_NR_RSTS); ++ ++ gk_clk_register_fixed_rate(gk7205v300_fixed_rate_clks, ++ ARRAY_SIZE(gk7205v300_fixed_rate_clks), ++ clk_data); ++ gk_clk_register_mux(gk7205v300_mux_clks, ARRAY_SIZE(gk7205v300_mux_clks), ++ clk_data); ++ gk_clk_register_fixed_factor(gk7205v300_fixed_factor_clks, ++ ARRAY_SIZE(gk7205v300_fixed_factor_clks), clk_data); ++ gk_clk_register_gate(gk7205v300_gate_clks, ++ ARRAY_SIZE(gk7205v300_gate_clks), clk_data); ++ ++} ++ ++CLK_OF_DECLARE(gk7205v300_clk, "goke,gk7205v300-clock", gk7205v300_clk_init); ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7605v100.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7605v100.c.patch new file mode 100644 index 00000000..a205c4ba --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk-gk7605v100.c.patch @@ -0,0 +1,236 @@ +--- linux-4.9.37/drivers/clk/goke/clk-gk7605v100.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/clk-gk7605v100.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,233 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "clk.h" ++#include "reset.h" ++ ++static struct gk_fixed_rate_clock gk7605v100_fixed_rate_clks[] __initdata = { ++ { GK7605V100_FIXED_100K, "100k", NULL, 0, 100000, }, ++ { GK7605V100_FIXED_400K, "400k", NULL, 0, 400000, }, ++ { GK7605V100_FIXED_3M, "3m", NULL, 0, 3000000, }, ++ { GK7605V100_FIXED_6M, "6m", NULL, 0, 6000000, }, ++ { GK7605V100_FIXED_12M, "12m", NULL, 0, 12000000, }, ++ { GK7605V100_FIXED_24M, "24m", NULL, 0, 24000000, }, ++ { GK7605V100_FIXED_25M, "25m", NULL, 0, 25000000, }, ++ { GK7605V100_FIXED_50M, "50m", NULL, 0, 50000000, }, ++ { GK7605V100_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, ++ { GK7605V100_FIXED_90M, "90m", NULL, 0, 90000000, }, ++ { GK7605V100_FIXED_100M, "100m", NULL, 0, 100000000, }, ++ { GK7605V100_FIXED_112M, "112m", NULL, 0, 112000000, }, ++ { GK7605V100_FIXED_125M, "125m", NULL, 0, 125000000, }, ++ { GK7605V100_FIXED_150M, "150m", NULL, 0, 150000000, }, ++ { GK7605V100_FIXED_200M, "200m", NULL, 0, 200000000, }, ++ { GK7605V100_FIXED_250M, "250m", NULL, 0, 250000000, }, ++ { GK7605V100_FIXED_300M, "300m", NULL, 0, 300000000, }, ++ { GK7605V100_FIXED_324M, "324m", NULL, 0, 324000000, }, ++ { GK7605V100_FIXED_342M, "342m", NULL, 0, 342000000, }, ++ { GK7605V100_FIXED_342M, "375m", NULL, 0, 375000000, }, ++ { GK7605V100_FIXED_400M, "400m", NULL, 0, 400000000, }, ++ { GK7605V100_FIXED_448M, "448m", NULL, 0, 448000000, }, ++ { GK7605V100_FIXED_500M, "500m", NULL, 0, 500000000, }, ++ { GK7605V100_FIXED_540M, "540m", NULL, 0, 540000000, }, ++ { GK7605V100_FIXED_600M, "600m", NULL, 0, 600000000, }, ++ { GK7605V100_FIXED_750M, "750m", NULL, 0, 750000000, }, ++ { GK7605V100_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, ++ { GK7605V100_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, ++}; ++ ++static const char *sysaxi_mux_p[] __initconst = { ++ "24m", "200m" ++}; ++static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; ++static const char *uart_mux_p[] __initconst = {"24m", "6m"}; ++static const char *fmc_mux_p[] __initconst = {"24m", "100", "150m", "200m", "300m", "360m"}; ++static const char *mmc_mux_p[] __initdata = { ++ "100k", "400k", "25m", "50m", "90m", "112m", "150m" ++}; ++static const char *eth_mux_p[] __initconst = {"100m", "54m"}; ++static const char *usb_mux_p[] __initdata = {"phy", "crg",}; ++ ++static u32 sysaxi_mux_table[] = {0, 1}; ++static u32 sysapb_mux_table[] = {0, 1}; ++static u32 uart_mux_table[] = {0, 1}; ++static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; ++static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; ++static u32 eth_mux_table[] = {0, 1}; ++static u32 usb_mux_table[] = {0, 1}; ++ ++static struct gk_mux_clock gk7605v100_mux_clks[] __initdata = { ++ { ++ GK7605V100_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, ++ ARRAY_SIZE(sysaxi_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, ++ }, ++ { ++ GK7605V100_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, ++ ARRAY_SIZE(sysapb_mux_p), ++ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, ++ }, ++ { ++ GK7605V100_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, ++ }, ++ { ++ GK7605V100_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7605V100_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), ++ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, ++ }, ++ { ++ GK7605V100_UART_MUX, "uart_mux0", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7605V100_UART_MUX, "uart_mux1", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7605V100_UART_MUX, "uart_mux2", uart_mux_p, ++ ARRAY_SIZE(uart_mux_p), ++ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, ++ }, ++ { ++ GK7605V100_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), ++ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, ++ }, ++ { ++ GK7605V100_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), ++ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table ++ }, ++}; ++ ++static struct gk_fixed_factor_clock gk7605v100_fixed_factor_clks[] __initdata = { ++ { ++ GK7605V100_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, ++ CLK_SET_RATE_PARENT ++ }, ++}; ++ ++static struct gk_gate_clock gk7605v100_gate_clks[] __initdata = { ++ /* fmc */ ++ { ++ GK7605V100_FMC_CLK, "clk_fmc", "fmc_mux", ++ CLK_SET_RATE_PARENT, 0x144, 1, 0, ++ }, ++ /* mmc */ ++ { ++ GK7605V100_MMC0_CLK, "clk_mmc0", "mmc0_mux", ++ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, ++ }, ++ { ++ GK7605V100_MMC1_CLK, "clk_mmc1", "mmc1_mux", ++ CLK_SET_RATE_PARENT, 0x22c, 28, 0, ++ }, ++ /* uart */ ++ { ++ GK7605V100_UART0_CLK, "clk_uart0", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, ++ }, ++ { ++ GK7605V100_UART1_CLK, "clk_uart1", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, ++ }, ++ { ++ GK7605V100_UART2_CLK, "clk_uart2", "24m", ++ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, ++ }, ++ /* spi */ ++ { ++ GK7605V100_SPI0_CLK, "clk_spi0", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, ++ }, ++ { ++ GK7605V100_SPI1_CLK, "clk_spi1", "100m", ++ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, ++ }, ++ /* i2c */ ++ { ++ GK7605V100_I2C0_CLK, "clk_i2c0", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, ++ }, ++ { ++ GK7605V100_I2C1_CLK, "clk_i2c1", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, ++ }, ++ { ++ GK7605V100_I2C2_CLK, "clk_i2c2", "50m", ++ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, ++ }, ++ /* ethernet mac */ ++ { ++ GK7605V100_ETH0_CLK, "clk_eth0", "eth_mux", ++ CLK_SET_RATE_PARENT, 0x16c, 1, 0, ++ }, ++ /* edmac */ ++ { ++ GK7605V100_EDMAC_AXICLK, "axi_clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 2, 0, ++ }, ++ { ++ GK7605V100_EDMAC_CLK, "clk_edmac", NULL, ++ CLK_SET_RATE_PARENT, 0x194, 1, 0, ++ }, ++ /* usb */ ++ { ++ GK7605V100_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 8, 0, ++ }, ++ { ++ GK7605V100_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 9, 0, ++ }, ++ { ++ GK7605V100_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", ++ CLK_SET_RATE_PARENT, 0x140, 12, 0, ++ }, ++ { ++ GK7605V100_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 11, 0, ++ }, ++ { ++ GK7605V100_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 4, 0, ++ }, ++ { ++ GK7605V100_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, ++ CLK_SET_RATE_PARENT, 0x140, 2, 0, ++ }, ++}; ++ ++static void __init gk7605v100_clk_init(struct device_node *np) ++{ ++ struct gk_clock_data *clk_data; ++ ++ clk_data = gk_clk_init(np, GK7605V100_NR_CLKS); ++ if (!clk_data) ++ return; ++ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) ++ gk_reset_init(np, GK7605V100_NR_RSTS); ++ ++ gk_clk_register_fixed_rate(gk7605v100_fixed_rate_clks, ++ ARRAY_SIZE(gk7605v100_fixed_rate_clks), ++ clk_data); ++ gk_clk_register_mux(gk7605v100_mux_clks, ARRAY_SIZE(gk7605v100_mux_clks), ++ clk_data); ++ gk_clk_register_fixed_factor(gk7605v100_fixed_factor_clks, ++ ARRAY_SIZE(gk7605v100_fixed_factor_clks), clk_data); ++ gk_clk_register_gate(gk7605v100_gate_clks, ++ ARRAY_SIZE(gk7605v100_gate_clks), clk_data); ++ ++} ++ ++CLK_OF_DECLARE(gk7605v100_clk, "goke,gk7605v100-clock", gk7605v100_clk_init); ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk.c.patch new file mode 100644 index 00000000..5ed272aa --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk.c.patch @@ -0,0 +1,192 @@ +--- linux-4.9.37/drivers/clk/goke/clk.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/clk.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,188 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk.h" ++ ++static DEFINE_SPINLOCK(gk_clk_lock); ++ ++struct gk_clock_data *gk_clk_init(struct device_node *np, ++ int nr_clks) ++{ ++ struct gk_clock_data *clk_data; ++ struct clk **clk_table; ++ void __iomem *base; ++ ++ base = of_iomap(np, 0); ++ if (!base) { ++ pr_err("%s: failed to map clock registers\n", __func__); ++ goto err; ++ } ++ ++ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); ++ if (!clk_data) { ++ pr_err("%s: could not allocate clock data\n", __func__); ++ goto err; ++ } ++ clk_data->base = base; ++ ++ clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); ++ if (!clk_table) { ++ pr_err("%s: could not allocate clock lookup table\n", __func__); ++ goto err_data; ++ } ++ clk_data->clk_data.clks = clk_table; ++ clk_data->clk_data.clk_num = nr_clks; ++ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data); ++ return clk_data; ++err_data: ++ kfree(clk_data); ++err: ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(gk_clk_init); ++ ++int gk_clk_register_fixed_rate(const struct gk_fixed_rate_clock *clks, ++ int nums, struct gk_clock_data *data) ++{ ++ struct clk *clk; ++ int i; ++ ++ for (i = 0; i < nums; i++) { ++ clk = clk_register_fixed_rate(NULL, clks[i].name, ++ clks[i].parent_name, ++ clks[i].flags, ++ clks[i].fixed_rate); ++ if (IS_ERR(clk)) { ++ pr_err("%s: failed to register clock %s\n", ++ __func__, clks[i].name); ++ goto err; ++ } ++ data->clk_data.clks[clks[i].id] = clk; ++ } ++ ++ return 0; ++ ++err: ++ while (i--) ++ clk_unregister_fixed_rate(data->clk_data.clks[clks[i].id]); ++ ++ return PTR_ERR(clk); ++} ++EXPORT_SYMBOL_GPL(gk_clk_register_fixed_rate); ++ ++int gk_clk_register_fixed_factor(const struct gk_fixed_factor_clock *clks, ++ int nums, ++ struct gk_clock_data *data) ++{ ++ struct clk *clk; ++ int i; ++ ++ for (i = 0; i < nums; i++) { ++ clk = clk_register_fixed_factor(NULL, clks[i].name, ++ clks[i].parent_name, ++ clks[i].flags, clks[i].mult, ++ clks[i].div); ++ if (IS_ERR(clk)) { ++ pr_err("%s: failed to register clock %s\n", ++ __func__, clks[i].name); ++ goto err; ++ } ++ data->clk_data.clks[clks[i].id] = clk; ++ } ++ ++ return 0; ++ ++err: ++ while (i--) ++ clk_unregister_fixed_factor(data->clk_data.clks[clks[i].id]); ++ ++ return PTR_ERR(clk); ++} ++EXPORT_SYMBOL_GPL(gk_clk_register_fixed_factor); ++ ++int gk_clk_register_mux(const struct gk_mux_clock *clks, ++ int nums, struct gk_clock_data *data) ++{ ++ struct clk *clk; ++ void __iomem *base = data->base; ++ int i; ++ ++ for (i = 0; i < nums; i++) { ++ u32 mask = BIT(clks[i].width) - 1; ++ ++ clk = clk_register_mux_table(NULL, clks[i].name, ++ clks[i].parent_names, ++ clks[i].num_parents, clks[i].flags, ++ base + clks[i].offset, clks[i].shift, ++ mask, clks[i].mux_flags, ++ clks[i].table, &gk_clk_lock); ++ if (IS_ERR(clk)) { ++ pr_err("%s: failed to register clock %s\n", ++ __func__, clks[i].name); ++ goto err; ++ } ++ ++ if (clks[i].alias) ++ clk_register_clkdev(clk, clks[i].alias, NULL); ++ ++ data->clk_data.clks[clks[i].id] = clk; ++ } ++ ++ return 0; ++ ++err: ++ while (i--) ++ clk_unregister_mux(data->clk_data.clks[clks[i].id]); ++ ++ return PTR_ERR(clk); ++} ++EXPORT_SYMBOL_GPL(gk_clk_register_mux); ++ ++ ++int gk_clk_register_gate(const struct gk_gate_clock *clks, ++ int nums, struct gk_clock_data *data) ++{ ++ struct clk *clk; ++ void __iomem *base = data->base; ++ int i; ++ ++ for (i = 0; i < nums; i++) { ++ clk = clk_register_gate(NULL, clks[i].name, ++ clks[i].parent_name, ++ clks[i].flags, ++ base + clks[i].offset, ++ clks[i].bit_idx, ++ clks[i].gate_flags, ++ &gk_clk_lock); ++ if (IS_ERR(clk)) { ++ pr_err("%s: failed to register clock %s\n", ++ __func__, clks[i].name); ++ goto err; ++ } ++ ++ if (clks[i].alias) ++ clk_register_clkdev(clk, clks[i].alias, NULL); ++ ++ data->clk_data.clks[clks[i].id] = clk; ++ } ++ ++ return 0; ++ ++err: ++ while (i--) ++ clk_unregister_gate(data->clk_data.clks[clks[i].id]); ++ ++ return PTR_ERR(clk); ++} ++EXPORT_SYMBOL_GPL(gk_clk_register_gate); +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk.h.patch new file mode 100644 index 00000000..d1dfcd5d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-clk.h.patch @@ -0,0 +1,93 @@ +--- linux-4.9.37/drivers/clk/goke/clk.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/clk.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __GOKE_CLK_H ++#define __GOKE_CLK_H ++ ++#include ++#include ++#include ++ ++struct platform_device; ++ ++struct gk_clock_data { ++ struct clk_onecell_data clk_data; ++ void __iomem *base; ++}; ++ ++struct gk_fixed_rate_clock { ++ unsigned int id; ++ char *name; ++ const char *parent_name; ++ unsigned long flags; ++ unsigned long fixed_rate; ++}; ++ ++struct gk_fixed_factor_clock { ++ unsigned int id; ++ char *name; ++ const char *parent_name; ++ unsigned long mult; ++ unsigned long div; ++ unsigned long flags; ++}; ++ ++struct gk_mux_clock { ++ unsigned int id; ++ const char *name; ++ const char *const *parent_names; ++ u8 num_parents; ++ unsigned long flags; ++ unsigned long offset; ++ u8 shift; ++ u8 width; ++ u8 mux_flags; ++ u32 *table; ++ const char *alias; ++}; ++ ++struct gk_gate_clock { ++ unsigned int id; ++ const char *name; ++ const char *parent_name; ++ unsigned long flags; ++ unsigned long offset; ++ u8 bit_idx; ++ u8 gate_flags; ++ const char *alias; ++}; ++ ++struct gk_clock_data *gk_clk_init(struct device_node *, int); ++int gk_clk_register_fixed_rate(const struct gk_fixed_rate_clock *, ++ int, struct gk_clock_data *); ++int gk_clk_register_fixed_factor(const struct gk_fixed_factor_clock *, ++ int, struct gk_clock_data *); ++int gk_clk_register_mux(const struct gk_mux_clock *, int, ++ struct gk_clock_data *); ++int gk_clk_register_gate(const struct gk_gate_clock *, ++ int, struct gk_clock_data *); ++ ++#define gk_clk_unregister(type) \ ++static inline \ ++void gk_clk_unregister_##type(const struct gk_##type##_clock *clks, \ ++ int nums, struct gk_clock_data *data) \ ++{ \ ++ struct clk **clocks = data->clk_data.clks; \ ++ int i; \ ++ for (i = 0; i < nums; i++) { \ ++ int id = clks[i].id; \ ++ if (clocks[id]) \ ++ clk_unregister_##type(clocks[id]); \ ++ } \ ++} ++ ++gk_clk_unregister(fixed_rate) ++gk_clk_unregister(fixed_factor) ++gk_clk_unregister(mux) ++gk_clk_unregister(gate) ++ ++#endif /* __GOKE_CLK_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-reset.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-reset.c.patch new file mode 100644 index 00000000..98014a01 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-reset.c.patch @@ -0,0 +1,116 @@ +--- linux-4.9.37/drivers/clk/goke/reset.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/reset.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "reset.h" ++ ++#define GOKE_RESET_BIT_MASK 0x1f ++#define GOKE_RESET_OFFSET_SHIFT 8 ++#define GOKE_RESET_OFFSET_MASK 0xffff00 ++ ++struct gk_reset_controller { ++ spinlock_t lock; ++ void __iomem *membase; ++ struct reset_controller_dev rcdev; ++}; ++ ++ ++#define to_gk_reset_controller(rcdev) \ ++ container_of(rcdev, struct gk_reset_controller, rcdev) ++ ++static int gk_reset_of_xlate(struct reset_controller_dev *rcdev, ++ const struct of_phandle_args *reset_spec) ++{ ++ u32 offset; ++ u8 bit; ++ ++ offset = (reset_spec->args[0] << GOKE_RESET_OFFSET_SHIFT) ++ & GOKE_RESET_OFFSET_MASK; ++ bit = reset_spec->args[1] & GOKE_RESET_BIT_MASK; ++ ++ return (offset | bit); ++} ++ ++static int gk_reset_assert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct gk_reset_controller *rstc = to_gk_reset_controller(rcdev); ++ unsigned long flags; ++ u32 offset, reg; ++ u8 bit; ++ ++ offset = (id & GOKE_RESET_OFFSET_MASK) >> GOKE_RESET_OFFSET_SHIFT; ++ bit = id & GOKE_RESET_BIT_MASK; ++ ++ spin_lock_irqsave(&rstc->lock, flags); ++ ++ reg = readl(rstc->membase + offset); ++ writel(reg | BIT(bit), rstc->membase + offset); ++ ++ spin_unlock_irqrestore(&rstc->lock, flags); ++ ++ return 0; ++} ++ ++static int gk_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct gk_reset_controller *rstc = to_gk_reset_controller(rcdev); ++ unsigned long flags; ++ u32 offset, reg; ++ u8 bit; ++ ++ offset = (id & GOKE_RESET_OFFSET_MASK) >> GOKE_RESET_OFFSET_SHIFT; ++ bit = id & GOKE_RESET_BIT_MASK; ++ ++ spin_lock_irqsave(&rstc->lock, flags); ++ ++ reg = readl(rstc->membase + offset); ++ writel(reg & ~BIT(bit), rstc->membase + offset); ++ ++ spin_unlock_irqrestore(&rstc->lock, flags); ++ ++ return 0; ++} ++ ++static const struct reset_control_ops gk_reset_ops = { ++ .assert = gk_reset_assert, ++ .deassert = gk_reset_deassert, ++}; ++ ++int __init gk_reset_init(struct device_node *np, ++ int nr_rsts) ++{ ++ struct gk_reset_controller *rstc; ++ ++ rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); ++ if (!rstc) ++ return -ENOMEM; ++ ++ rstc->membase = of_iomap(np, 0); ++ if (!rstc->membase){ ++ kfree(rstc); ++ return -EINVAL; ++ } ++ ++ spin_lock_init(&rstc->lock); ++ ++ rstc->rcdev.owner = THIS_MODULE; ++ rstc->rcdev.nr_resets = nr_rsts; ++ rstc->rcdev.ops = &gk_reset_ops; ++ rstc->rcdev.of_node = np; ++ rstc->rcdev.of_reset_n_cells = 2; ++ rstc->rcdev.of_xlate = gk_reset_of_xlate; ++ ++ return reset_controller_register(&rstc->rcdev); ++} ++EXPORT_SYMBOL_GPL(gk_reset_init); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-reset.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-reset.h.patch new file mode 100644 index 00000000..143ecb46 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clk-goke-reset.h.patch @@ -0,0 +1,18 @@ +--- linux-4.9.37/drivers/clk/goke/reset.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/clk/goke/reset.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,15 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __GOKE_RESET_H ++#define __GOKE_RESET_H ++ ++struct device_node; ++struct gk_reset_controller; ++ ++#ifdef CONFIG_RESET_CONTROLLER ++int __init gk_reset_init(struct device_node *np, int nr_rsts); ++#endif ++ ++#endif /* __GOKE_RESET_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-Kconfig.patch new file mode 100644 index 00000000..e7c0dbfe --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-Kconfig.patch @@ -0,0 +1,17 @@ +--- linux-4.9.37/drivers/clocksource/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/clocksource/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -305,6 +305,14 @@ + This must be disabled for hardware validation purposes to detect any + hardware anomalies of missing events. + ++config ARM_ARCH_TIMER_VCT_ACCESS ++ bool "Support for ARM architected timer virtual counter access in userspace" ++ default n ++ depends on ARM_ARCH_TIMER ++ help ++ This option enables support for reading the ARM architected timer's ++ virtual counter in userspace. ++ + config FSL_ERRATUM_A008585 + bool "Workaround for Freescale/NXP Erratum A-008585" + default y diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-arm_arch_timer.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-arm_arch_timer.c.patch new file mode 100644 index 00000000..60ef0bd1 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-arm_arch_timer.c.patch @@ -0,0 +1,14 @@ +--- linux-4.9.37/drivers/clocksource/arm_arch_timer.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/clocksource/arm_arch_timer.c 2021-06-07 13:01:33.000000000 +0300 +@@ -449,7 +449,10 @@ + | ARCH_TIMER_USR_PCT_ACCESS_EN); + + /* Enable user access to the virtual counter */ +- cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; ++ if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)) ++ cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; ++ else ++ cntkctl &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; + + arch_timer_set_cntkctl(cntkctl); + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-timer-sp804.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-timer-sp804.c.patch new file mode 100644 index 00000000..1052bb26 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-clocksource-timer-sp804.c.patch @@ -0,0 +1,13 @@ +--- linux-4.9.37/drivers/clocksource/timer-sp804.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/clocksource/timer-sp804.c 2021-06-07 13:01:33.000000000 +0300 +@@ -235,6 +235,10 @@ + writel(0, base + TIMER_CTRL); + writel(0, base + TIMER_2_BASE + TIMER_CTRL); + ++ /* Ensure timer interrupts are clear */ ++ writel(1, base + TIMER_INTCLR); ++ writel(1, base + TIMER_2_BASE + TIMER_INTCLR); ++ + if (initialized || !of_device_is_available(np)) { + ret = -EINVAL; + goto err; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-Kconfig.patch new file mode 100644 index 00000000..85b106df --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-Kconfig.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/drivers/dma/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/dma/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -564,6 +564,19 @@ + help + Support the DMA engine for ZTE ZX296702 platform devices. + ++config EDMAC ++ tristate "Goke EDMAC Controller support" ++ depends on (ARCH_GK7205V300 || ARCH_GK7205V200 || ARCH_GK7202V300 || ARCH_GK7605V100) ++ select DMA_ENGINE ++ select DMA_VIRTUAL_CHANNELS ++ help ++ The Direction Memory Access(EDMA) is a high-speed data transfer ++ operation. It supports data read/write between peripherals and ++ memories without using the CPU. ++ Goke EDMA Controller(EDMAC) directly transfers data between ++ a memory and a peripheral, between peripherals, or between memories. ++ This avoids the CPU intervention and reduces the interrupt handling ++ overhead of the CPU. + + # driver files + source "drivers/dma/bestcomm/Kconfig" diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-Makefile.patch new file mode 100644 index 00000000..71f73fbf --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/dma/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/dma/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -67,6 +67,7 @@ + obj-$(CONFIG_TI_EDMA) += edma.o + obj-$(CONFIG_XGENE_DMA) += xgene-dma.o + obj-$(CONFIG_ZX_DMA) += zx296702_dma.o ++obj-$(CONFIG_EDMAC) += edmac_goke.o + + obj-y += qcom/ + obj-y += xilinx/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-_sw_sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-_sw_sync.h.patch new file mode 100644 index 00000000..2025fb13 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-_sw_sync.h.patch @@ -0,0 +1,35 @@ +--- linux-4.9.37/drivers/dma-buf/_sw_sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/_sw_sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _UAPI_LINUX_SW_SYNC_H ++#define _UAPI_LINUX_SW_SYNC_H ++ ++#include ++ ++struct sw_sync_create_fence_data { ++ __u32 value; ++ char name[32]; ++ __s32 fence; /* fd of new fence */ ++}; ++ ++#define SW_SYNC_IOC_MAGIC 'W' ++ ++#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ ++ struct sw_sync_create_fence_data) ++#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) ++ ++#endif /* _UAPI_LINUX_SW_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-_sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-_sync.h.patch new file mode 100644 index 00000000..a5bb1f5a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-_sync.h.patch @@ -0,0 +1,100 @@ +--- linux-4.9.37/drivers/dma-buf/_sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/_sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _UAPI_LINUX_SYNC_H ++#define _UAPI_LINUX_SYNC_H ++ ++#include ++#include ++ ++/** ++ * struct sync_merge_data - data passed to merge ioctl ++ * @fd2: file descriptor of second fence ++ * @name: name of new fence ++ * @fence: returns the fd of the new fence to userspace ++ */ ++struct sync_merge_data { ++ __s32 fd2; /* fd of second fence */ ++ char name[32]; /* name of new fence */ ++ __s32 fence; /* fd on newly created fence */ ++}; ++ ++/** ++ * struct sync_pt_info - detailed sync_pt information ++ * @len: length of sync_pt_info including any driver_data ++ * @obj_name: name of parent sync_timeline ++ * @driver_name: name of driver implementing the parent ++ * @status: status of the sync_pt 0:active 1:signaled <0:error ++ * @timestamp_ns: timestamp of status change in nanoseconds ++ * @driver_data: any driver dependent data ++ */ ++struct sync_pt_info { ++ __u32 len; ++ char obj_name[32]; ++ char driver_name[32]; ++ __s32 status; ++ __u64 timestamp_ns; ++ ++ __u8 driver_data[0]; ++}; ++ ++/** ++ * struct sync_fence_info_data - data returned from fence info ioctl ++ * @len: ioctl caller writes the size of the buffer its passing in. ++ * ioctl returns length of sync_fence_data returned to userspace ++ * including pt_info. ++ * @name: name of fence ++ * @status: status of fence. 1: signaled 0:active <0:error ++ * @pt_info: a sync_pt_info struct for every sync_pt in the fence ++ */ ++struct sync_fence_info_data { ++ __u32 len; ++ char name[32]; ++ __s32 status; ++ ++ __u8 pt_info[0]; ++}; ++ ++#define SYNC_IOC_MAGIC '>' ++ ++/** ++ * DOC: SYNC_IOC_WAIT - wait for a fence to signal ++ * ++ * pass timeout in milliseconds. Waits indefinitely timeout < 0. ++ */ ++#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) ++ ++/** ++ * DOC: SYNC_IOC_MERGE - merge two fences ++ * ++ * Takes a struct sync_merge_data. Creates a new fence containing copies of ++ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the ++ * new fence's fd in sync_merge_data.fence ++ */ ++#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) ++ ++/** ++ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence ++ * ++ * Takes a struct sync_fence_info_data with extra space allocated for pt_info. ++ * Caller should write the size of the buffer into len. On return, len is ++ * updated to reflect the total size of the sync_fence_info_data including ++ * pt_info. ++ * ++ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. ++ * To iterate over the sync_pt_infos, use the sync_pt_info.len field. ++ */ ++#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ ++ struct sync_fence_info_data) ++ ++#endif /* _UAPI_LINUX_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-fence.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-fence.c.patch new file mode 100644 index 00000000..b2ddcbc2 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-fence.c.patch @@ -0,0 +1,35 @@ +--- linux-4.9.37/drivers/dma-buf/fence.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/fence.c 2021-06-07 13:01:33.000000000 +0300 +@@ -68,6 +68,8 @@ + struct fence_cb *cur, *tmp; + int ret = 0; + ++ lockdep_assert_held(fence->lock); ++ + if (WARN_ON(!fence)) + return -EINVAL; + +@@ -159,9 +161,6 @@ + if (WARN_ON(timeout < 0)) + return -EINVAL; + +- if (timeout == 0) +- return fence_is_signaled(fence); +- + trace_fence_wait_start(fence); + ret = fence->ops->wait(fence, intr, timeout); + trace_fence_wait_end(fence); +@@ -304,8 +303,12 @@ + spin_lock_irqsave(fence->lock, flags); + + ret = !list_empty(&cb->node); +- if (ret) ++ if (ret) { + list_del_init(&cb->node); ++ if (list_empty(&fence->cb_list)) ++ if (fence->ops->disable_signaling) ++ fence->ops->disable_signaling(fence); ++ } + + spin_unlock_irqrestore(fence->lock, flags); + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-reservation.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-reservation.c.patch new file mode 100644 index 00000000..cc995959 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-reservation.c.patch @@ -0,0 +1,219 @@ +--- linux-4.9.37/drivers/dma-buf/reservation.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/reservation.c 2021-06-07 13:01:33.000000000 +0300 +@@ -280,18 +280,24 @@ + unsigned *pshared_count, + struct fence ***pshared) + { +- unsigned shared_count = 0; +- unsigned retry = 1; +- struct fence **shared = NULL, *fence_excl = NULL; +- int ret = 0; ++ struct fence **shared = NULL; ++ struct fence *fence_excl; ++ unsigned int shared_count; ++ int ret = 1; + +- while (retry) { ++ do { + struct reservation_object_list *fobj; + unsigned seq; ++ unsigned int i; + +- seq = read_seqcount_begin(&obj->seq); ++ shared_count = i = 0; + + rcu_read_lock(); ++ seq = read_seqcount_begin(&obj->seq); ++ ++ fence_excl = rcu_dereference(obj->fence_excl); ++ if (fence_excl && !fence_get_rcu(fence_excl)) ++ goto unlock; + + fobj = rcu_dereference(obj->fence); + if (fobj) { +@@ -309,52 +315,37 @@ + } + + ret = -ENOMEM; +- shared_count = 0; + break; + } + shared = nshared; +- memcpy(shared, fobj->shared, sz); + shared_count = fobj->shared_count; +- } else +- shared_count = 0; +- fence_excl = rcu_dereference(obj->fence_excl); +- +- retry = read_seqcount_retry(&obj->seq, seq); +- if (retry) +- goto unlock; +- +- if (!fence_excl || fence_get_rcu(fence_excl)) { +- unsigned i; + + for (i = 0; i < shared_count; ++i) { +- if (fence_get_rcu(shared[i])) +- continue; +- +- /* uh oh, refcount failed, abort and retry */ +- while (i--) +- fence_put(shared[i]); +- +- if (fence_excl) { +- fence_put(fence_excl); +- fence_excl = NULL; +- } +- +- retry = 1; +- break; ++ shared[i] = rcu_dereference(fobj->shared[i]); ++ if (!fence_get_rcu(shared[i])) ++ break; + } +- } else +- retry = 1; ++ } ++ ++ if ((i > 0) && (i != shared_count || read_seqcount_retry(&obj->seq, seq))) { ++ while (i--) ++ fence_put(shared[i]); ++ fence_put(fence_excl); ++ goto unlock; ++ } + ++ ret = 0; + unlock: + rcu_read_unlock(); +- } +- *pshared_count = shared_count; +- if (shared_count) +- *pshared = shared; +- else { +- *pshared = NULL; ++ } while (ret); ++ ++ if (!shared_count) { + kfree(shared); ++ shared = NULL; + } ++ ++ *pshared_count = shared_count; ++ *pshared = shared; + *pfence_excl = fence_excl; + + return ret; +@@ -379,10 +370,7 @@ + { + struct fence *fence; + unsigned seq, shared_count, i = 0; +- long ret = timeout; +- +- if (!timeout) +- return reservation_object_test_signaled_rcu(obj, wait_all); ++ long ret = timeout ? timeout : 1; + + retry: + fence = NULL; +@@ -397,9 +385,6 @@ + if (fobj) + shared_count = fobj->shared_count; + +- if (read_seqcount_retry(&obj->seq, seq)) +- goto unlock_retry; +- + for (i = 0; i < shared_count; ++i) { + struct fence *lfence = rcu_dereference(fobj->shared[i]); + +@@ -422,9 +407,6 @@ + if (!shared_count) { + struct fence *fence_excl = rcu_dereference(obj->fence_excl); + +- if (read_seqcount_retry(&obj->seq, seq)) +- goto unlock_retry; +- + if (fence_excl && + !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence_excl->flags)) { + if (!fence_get_rcu(fence_excl)) +@@ -439,6 +421,11 @@ + + rcu_read_unlock(); + if (fence) { ++ if (read_seqcount_retry(&obj->seq, seq)) { ++ fence_put(fence); ++ goto retry; ++ } ++ + ret = fence_wait_timeout(fence, intr, ret); + fence_put(fence); + if (ret > 0 && wait_all && (i + 1 < shared_count)) +@@ -484,12 +471,13 @@ + bool test_all) + { + unsigned seq, shared_count; +- int ret = true; ++ int ret; + ++ rcu_read_lock(); + retry: ++ ret = true; + shared_count = 0; + seq = read_seqcount_begin(&obj->seq); +- rcu_read_lock(); + + if (test_all) { + unsigned i; +@@ -500,46 +488,35 @@ + if (fobj) + shared_count = fobj->shared_count; + +- if (read_seqcount_retry(&obj->seq, seq)) +- goto unlock_retry; +- + for (i = 0; i < shared_count; ++i) { + struct fence *fence = rcu_dereference(fobj->shared[i]); + + ret = reservation_object_test_signaled_single(fence); + if (ret < 0) +- goto unlock_retry; ++ goto retry; + else if (!ret) + break; + } + +- /* +- * There could be a read_seqcount_retry here, but nothing cares +- * about whether it's the old or newer fence pointers that are +- * signaled. That race could still have happened after checking +- * read_seqcount_retry. If you care, use ww_mutex_lock. +- */ ++ if (read_seqcount_retry(&obj->seq, seq)) ++ goto retry; + } + + if (!shared_count) { + struct fence *fence_excl = rcu_dereference(obj->fence_excl); + +- if (read_seqcount_retry(&obj->seq, seq)) +- goto unlock_retry; +- + if (fence_excl) { + ret = reservation_object_test_signaled_single( + fence_excl); + if (ret < 0) +- goto unlock_retry; ++ goto retry; ++ ++ if (read_seqcount_retry(&obj->seq, seq)) ++ goto retry; + } + } + + rcu_read_unlock(); + return ret; +- +-unlock_retry: +- rcu_read_unlock(); +- goto retry; + } + EXPORT_SYMBOL_GPL(reservation_object_test_signaled_rcu); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sw_sync.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sw_sync.c.patch new file mode 100644 index 00000000..7dbff46d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sw_sync.c.patch @@ -0,0 +1,34 @@ +--- linux-4.9.37/drivers/dma-buf/sw_sync.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/sw_sync.c 2021-06-07 13:01:33.000000000 +0300 +@@ -234,6 +234,13 @@ + return true; + } + ++static void timeline_fence_disable_signaling(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ ++ list_del_init(&pt->active_list); ++} ++ + static void timeline_fence_value_str(struct fence *fence, + char *str, int size) + { +@@ -252,6 +259,7 @@ + .get_driver_name = timeline_fence_get_driver_name, + .get_timeline_name = timeline_fence_get_timeline_name, + .enable_signaling = timeline_fence_enable_signaling, ++ .disable_signaling = timeline_fence_disable_signaling, + .signaled = timeline_fence_signaled, + .wait = fence_default_wait, + .release = timeline_fence_release, +@@ -316,8 +324,8 @@ + } + + sync_file = sync_file_create(&pt->base); ++ fence_put(&pt->base); + if (!sync_file) { +- fence_put(&pt->base); + err = -ENOMEM; + goto err; + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sw_sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sw_sync.h.patch new file mode 100644 index 00000000..0556eac3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sw_sync.h.patch @@ -0,0 +1,46 @@ +--- linux-4.9.37/drivers/dma-buf/sw_sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/sw_sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,43 @@ ++/* ++ * include/linux/sw_sync.h ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_SW_SYNC_H ++#define _LINUX_SW_SYNC_H ++ ++#include ++#include ++#include "sync.h" ++#include "_sw_sync.h" ++#include ++ ++struct sw_sync_timeline { ++ struct sync_timeline obj; ++ ++ u32 value; ++}; ++ ++struct sw_sync_pt { ++ struct sync_pt pt; ++ ++ u32 value; ++}; ++ ++struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name); ++void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); ++ ++struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); ++ ++#endif /* _LINUX_SW_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync.c.patch new file mode 100644 index 00000000..af42f358 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync.c.patch @@ -0,0 +1,741 @@ +--- linux-4.9.37/drivers/dma-buf/sync.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/sync.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,738 @@ ++/* ++ * drivers/base/sync.c ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sync.h" ++ ++#include ++ ++static const struct fence_ops android_fence_ops; ++static const struct file_operations sync_fence_fops; ++ ++struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, ++ int size, const char *name) ++{ ++ struct sync_timeline *obj = NULL; ++ ++ if (size < sizeof(struct sync_timeline)) ++ return NULL; ++ ++ obj = kzalloc(size, GFP_KERNEL); ++ if (obj == NULL) ++ return NULL; ++ ++ kref_init(&obj->kref); ++ obj->ops = ops; ++ obj->context = fence_context_alloc(1); ++ strlcpy(obj->name, name, sizeof(obj->name)); ++ ++ INIT_LIST_HEAD(&obj->child_list_head); ++ INIT_LIST_HEAD(&obj->active_list_head); ++ spin_lock_init(&obj->child_list_lock); ++#if 0 ++ bsp_sync_timeline_debug_add(obj); ++#endif ++ ++ return obj; ++} ++EXPORT_SYMBOL(bsp_sync_timeline_create); ++ ++static void sync_timeline_free(struct kref *kref) ++{ ++ struct sync_timeline *obj = ++ container_of(kref, struct sync_timeline, kref); ++#if 0 ++ bsp_sync_timeline_debug_remove(obj); ++#endif ++ if (obj->ops->release_obj) ++ obj->ops->release_obj(obj); ++ ++ kfree(obj); ++} ++ ++static void sync_timeline_get(struct sync_timeline *obj) ++{ ++ kref_get(&obj->kref); ++} ++ ++static void sync_timeline_put(struct sync_timeline *obj) ++{ ++ kref_put(&obj->kref, sync_timeline_free); ++} ++ ++void bsp_sync_timeline_destroy(struct sync_timeline *obj) ++{ ++ obj->destroyed = true; ++ /* ++ * Ensure timeline is marked as destroyed before ++ * changing timeline's fences status. ++ */ ++ smp_wmb(); ++ ++ /* ++ * signal any children that their parent is going away. ++ */ ++ bsp_sync_timeline_signal(obj); ++ sync_timeline_put(obj); ++} ++EXPORT_SYMBOL(bsp_sync_timeline_destroy); ++ ++void bsp_sync_timeline_signal(struct sync_timeline *obj) ++{ ++ unsigned long flags; ++ LIST_HEAD(signaled_pts); ++ struct sync_pt *pt = NULL; ++ struct sync_pt *next = NULL; ++ ++ spin_lock_irqsave(&obj->child_list_lock, flags); ++ ++ list_for_each_entry_safe(pt, next, &obj->active_list_head, ++ active_list) { ++ if (fence_is_signaled_locked(&pt->base)) { ++ list_del_init(&pt->active_list); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) ++ fence_put(&pt->base); ++#endif ++ } ++ } ++ ++ spin_unlock_irqrestore(&obj->child_list_lock, flags); ++} ++EXPORT_SYMBOL(bsp_sync_timeline_signal); ++ ++struct sync_pt *bsp_sync_pt_create(struct sync_timeline *obj, int size) ++{ ++ unsigned long flags; ++ struct sync_pt *pt = NULL; ++ ++ if (size < sizeof(struct sync_pt)) ++ return NULL; ++ ++ pt = kzalloc(size, GFP_KERNEL); ++ if (pt == NULL) ++ return NULL; ++ ++ spin_lock_irqsave(&obj->child_list_lock, flags); ++ sync_timeline_get(obj); ++ fence_init(&pt->base, &android_fence_ops, &obj->child_list_lock, ++ obj->context, ++obj->value); ++ list_add_tail(&pt->child_list, &obj->child_list_head); ++ INIT_LIST_HEAD(&pt->active_list); ++ spin_unlock_irqrestore(&obj->child_list_lock, flags); ++ return pt; ++} ++EXPORT_SYMBOL(bsp_sync_pt_create); ++ ++void bsp_sync_pt_free(struct sync_pt *pt) ++{ ++ fence_put(&pt->base); ++} ++EXPORT_SYMBOL(bsp_sync_pt_free); ++ ++#if 0 ++static struct sync_fence *sync_fence_alloc(int size, const char *name) ++{ ++ struct sync_fence *fence; ++ ++ fence = kzalloc(size, GFP_KERNEL); ++ if (fence == NULL) ++ return NULL; ++ ++ fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, ++ fence, 0); ++ if (IS_ERR(fence->file)) ++ goto err; ++ ++ kref_init(&fence->kref); ++ strlcpy(fence->name, name, sizeof(fence->name)); ++ ++ init_waitqueue_head(&fence->wq); ++ ++ return fence; ++ ++err: ++ kfree(fence); ++ return NULL; ++} ++ ++static void fence_check_cb_func(struct fence *f, struct fence_cb *cb) ++{ ++ struct sync_fence_cb *check; ++ struct sync_fence *fence; ++ ++ check = container_of(cb, struct sync_fence_cb, cb); ++ fence = check->fence; ++ ++ if (atomic_dec_and_test(&fence->status)) ++ wake_up_all(&fence->wq); ++} ++ ++/* TODO: implement a create which takes more that one sync_pt */ ++struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt) ++{ ++ struct sync_fence *fence; ++ ++ fence = sync_fence_alloc(offsetof(struct sync_fence, cbs[1]), name); ++ if (fence == NULL) ++ return NULL; ++ ++ fence->num_fences = 1; ++ atomic_set(&fence->status, 1); ++ ++ fence->cbs[0].sync_pt = &pt->base; ++ fence->cbs[0].fence = fence; ++ if (fence_add_callback(&pt->base, &fence->cbs[0].cb, ++ fence_check_cb_func)) ++ atomic_dec(&fence->status); ++#if 0 ++ bsp_sync_fence_debug_add(fence); ++#endif ++ ++ return fence; ++} ++EXPORT_SYMBOL(bsp_sync_fence_create); ++ ++struct sync_fence *bsp_sync_fence_fdget(int fd) ++{ ++ struct file *file = fget(fd); ++ ++ if (file == NULL) ++ return NULL; ++ ++ if (file->f_op != &sync_fence_fops) ++ goto err; ++ ++ return file->private_data; ++ ++err: ++ fput(file); ++ return NULL; ++} ++EXPORT_SYMBOL(bsp_sync_fence_fdget); ++ ++void bsp_sync_fence_put(struct sync_fence *fence) ++{ ++ fput(fence->file); ++} ++EXPORT_SYMBOL(bsp_sync_fence_put); ++ ++void bsp_sync_fence_install(struct sync_fence *fence, int fd) ++{ ++ printk("<%s> Line %d: fd =%d, fence=%p, name=%s\n", __func__, __LINE__, fd, fence, fence->name); ++ fd_install(fd, fence->file); ++} ++EXPORT_SYMBOL(bsp_sync_fence_install); ++ ++static void sync_fence_add_pt(struct sync_fence *fence, ++ int *i, struct fence *pt) ++{ ++ fence->cbs[*i].sync_pt = pt; ++ fence->cbs[*i].fence = fence; ++ ++ if (!fence_add_callback(pt, &fence->cbs[*i].cb, fence_check_cb_func)) { ++ fence_get(pt); ++ (*i)++; ++ } ++} ++ ++struct sync_fence *bsp_sync_fence_merge(const char *name, ++ struct sync_fence *a, struct sync_fence *b) ++{ ++ int num_fences = a->num_fences + b->num_fences; ++ struct sync_fence *fence; ++ int i, i_a, i_b; ++ unsigned long size = offsetof(struct sync_fence, cbs[num_fences]); ++ ++ fence = sync_fence_alloc(size, name); ++ if (fence == NULL) ++ return NULL; ++ ++ atomic_set(&fence->status, num_fences); ++ ++ /* ++ * Assume sync_fence a and b are both ordered and have no ++ * duplicates with the same context. ++ * ++ * If a sync_fence can only be created with sync_fence_merge ++ * and sync_fence_create, this is a reasonable assumption. ++ */ ++ for (i = i_a = i_b = 0; i_a < a->num_fences && i_b < b->num_fences; ) { ++ struct fence *pt_a = a->cbs[i_a].sync_pt; ++ struct fence *pt_b = b->cbs[i_b].sync_pt; ++ ++ if (pt_a->context < pt_b->context) { ++ sync_fence_add_pt(fence, &i, pt_a); ++ ++ i_a++; ++ } else if (pt_a->context > pt_b->context) { ++ sync_fence_add_pt(fence, &i, pt_b); ++ ++ i_b++; ++ } else { ++ if (pt_a->seqno - pt_b->seqno <= INT_MAX) ++ sync_fence_add_pt(fence, &i, pt_a); ++ else ++ sync_fence_add_pt(fence, &i, pt_b); ++ ++ i_a++; ++ i_b++; ++ } ++ } ++ ++ for (; i_a < a->num_fences; i_a++) ++ sync_fence_add_pt(fence, &i, a->cbs[i_a].sync_pt); ++ ++ for (; i_b < b->num_fences; i_b++) ++ sync_fence_add_pt(fence, &i, b->cbs[i_b].sync_pt); ++ ++ if (num_fences > i) ++ atomic_sub(num_fences - i, &fence->status); ++ fence->num_fences = i; ++#if 0 ++ bsp_sync_fence_debug_add(fence); ++#endif ++ return fence; ++} ++EXPORT_SYMBOL(bsp_sync_fence_merge); ++ ++int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, ++ int wake_flags, void *key) ++{ ++ struct sync_fence_waiter *wait; ++ ++ wait = container_of(curr, struct sync_fence_waiter, work); ++ list_del_init(&wait->work.task_list); ++ ++ wait->callback(wait->work.private, wait); ++ return 1; ++} ++ ++int bsp_sync_fence_wait_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter) ++{ ++ int err = atomic_read(&fence->status); ++ unsigned long flags; ++ ++ if (err < 0) ++ return err; ++ ++ if (!err) ++ return 1; ++ ++ init_waitqueue_func_entry(&waiter->work, bsp_sync_fence_wake_up_wq); ++ waiter->work.private = fence; ++ ++ spin_lock_irqsave(&fence->wq.lock, flags); ++ err = atomic_read(&fence->status); ++ if (err > 0) ++ __add_wait_queue_tail(&fence->wq, &waiter->work); ++ spin_unlock_irqrestore(&fence->wq.lock, flags); ++ ++ if (err < 0) ++ return err; ++ ++ return !err; ++} ++EXPORT_SYMBOL(bsp_sync_fence_wait_async); ++ ++int bsp_sync_fence_cancel_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter) ++{ ++ unsigned long flags; ++ int ret = 0; ++ ++ spin_lock_irqsave(&fence->wq.lock, flags); ++ if (!list_empty(&waiter->work.task_list)) ++ list_del_init(&waiter->work.task_list); ++ else ++ ret = -ENOENT; ++ spin_unlock_irqrestore(&fence->wq.lock, flags); ++ return ret; ++} ++EXPORT_SYMBOL(bsp_sync_fence_cancel_async); ++ ++int bsp_sync_fence_wait(struct sync_fence *fence, long timeout) ++{ ++ long ret; ++ ++ if (timeout < 0) ++ timeout = MAX_SCHEDULE_TIMEOUT; ++ else ++ timeout = msecs_to_jiffies(timeout); ++ ++ ret = wait_event_interruptible_timeout(fence->wq, ++ atomic_read(&fence->status) <= 0, ++ timeout); ++ ++ if (ret < 0) { ++ return ret; ++ } else if (ret == 0) { ++ if (timeout) { ++ pr_info("fence timeout on [%p] after %dms\n", fence, ++ jiffies_to_msecs(timeout)); ++ bsp_sync_dump(); ++ } ++ return -ETIME; ++ } ++ ++ ret = atomic_read(&fence->status); ++ if (ret) { ++ pr_info("fence error %ld on [%p]\n", ret, fence); ++ bsp_sync_dump(); ++ } ++ return ret; ++} ++EXPORT_SYMBOL(bsp_sync_fence_wait); ++ ++#endif ++static const char *android_fence_get_driver_name(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ return parent->ops->driver_name; ++} ++ ++static const char *android_fence_get_timeline_name(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ return parent->name; ++} ++ ++static void android_fence_release(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ unsigned long flags; ++ ++ spin_lock_irqsave(fence->lock, flags); ++ list_del(&pt->child_list); ++ if (WARN_ON_ONCE(!list_empty(&pt->active_list))) ++ list_del(&pt->active_list); ++ spin_unlock_irqrestore(fence->lock, flags); ++ ++ if (parent->ops->free_pt) ++ parent->ops->free_pt(pt); ++ ++ sync_timeline_put(parent); ++ fence_free(&pt->base); ++} ++ ++static bool android_fence_signaled(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ int ret; ++ ++ ret = parent->ops->has_signaled(pt); ++ if (ret < 0) ++ fence->status = ret; ++ return ret; ++} ++ ++static bool android_fence_enable_signaling(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (android_fence_signaled(fence)) ++ return false; ++ ++ list_add_tail(&pt->active_list, &parent->active_list_head); ++ return true; ++} ++ ++static void android_fence_disable_signaling(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ ++ list_del_init(&pt->active_list); ++} ++ ++static int android_fence_fill_driver_data(struct fence *fence, ++ void *data, int size) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (!parent->ops->fill_driver_data) ++ return 0; ++ return parent->ops->fill_driver_data(pt, data, size); ++} ++ ++static void android_fence_value_str(struct fence *fence, ++ char *str, int size) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (!parent->ops->pt_value_str) { ++ if (size) ++ *str = 0; ++ return; ++ } ++ parent->ops->pt_value_str(pt, str, size); ++} ++ ++static void android_fence_timeline_value_str(struct fence *fence, ++ char *str, int size) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (!parent->ops->timeline_value_str) { ++ if (size) ++ *str = 0; ++ return; ++ } ++ parent->ops->timeline_value_str(parent, str, size); ++} ++ ++static const struct fence_ops android_fence_ops = { ++ .get_driver_name = android_fence_get_driver_name, ++ .get_timeline_name = android_fence_get_timeline_name, ++ .enable_signaling = android_fence_enable_signaling, ++ .signaled = android_fence_signaled, ++ .wait = fence_default_wait, ++ .release = android_fence_release, ++ .fill_driver_data = android_fence_fill_driver_data, ++ .fence_value_str = android_fence_value_str, ++ .timeline_value_str = android_fence_timeline_value_str, ++}; ++#if 0 ++static void sync_fence_free(struct kref *kref) ++{ ++ struct sync_fence *fence = container_of(kref, struct sync_fence, kref); ++ int i; ++ ++ for (i = 0; i < fence->num_fences; ++i) { ++ fence_remove_callback(fence->cbs[i].sync_pt, &fence->cbs[i].cb); ++ fence_put(fence->cbs[i].sync_pt); ++ } ++ ++ kfree(fence); ++} ++ ++static int sync_fence_release(struct inode *inode, struct file *file) ++{ ++ struct sync_fence *fence = file->private_data; ++ ++ bsp_sync_fence_debug_remove(fence); ++ ++ kref_put(&fence->kref, sync_fence_free); ++ return 0; ++} ++ ++static unsigned int sync_fence_poll(struct file *file, poll_table *wait) ++{ ++ struct sync_fence *fence = file->private_data; ++ int status; ++ ++ poll_wait(file, &fence->wq, wait); ++ ++ status = atomic_read(&fence->status); ++ ++ if (!status) ++ return POLLIN; ++ else if (status < 0) ++ return POLLERR; ++ return 0; ++} ++ ++static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) ++{ ++ __s32 value; ++ ++ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) ++ return -EFAULT; ++ ++ return bsp_sync_fence_wait(fence, value); ++} ++ ++static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) ++{ ++ int fd = get_unused_fd_flags(O_CLOEXEC); ++ int err; ++ struct sync_fence *fence2, *fence3; ++ struct sync_merge_data data; ++ ++ if (fd < 0) ++ return fd; ++ ++ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { ++ err = -EFAULT; ++ goto err_put_fd; ++ } ++ ++ fence2 = bsp_sync_fence_fdget(data.fd2); ++ if (fence2 == NULL) { ++ err = -ENOENT; ++ goto err_put_fd; ++ } ++ ++ data.name[sizeof(data.name) - 1] = '\0'; ++ fence3 = bsp_sync_fence_merge(data.name, fence, fence2); ++ if (fence3 == NULL) { ++ err = -ENOMEM; ++ goto err_put_fence2; ++ } ++ ++ data.fence = fd; ++ if (copy_to_user((void __user *)arg, &data, sizeof(data))) { ++ err = -EFAULT; ++ goto err_put_fence3; ++ } ++ ++ bsp_sync_fence_install(fence3, fd); ++ bsp_sync_fence_put(fence2); ++ return 0; ++ ++err_put_fence3: ++ bsp_sync_fence_put(fence3); ++ ++err_put_fence2: ++ bsp_sync_fence_put(fence2); ++ ++err_put_fd: ++ put_unused_fd(fd); ++ return err; ++} ++ ++static int sync_fill_pt_info(struct fence *fence, void *data, int size) ++{ ++ struct sync_pt_info *info = data; ++ int ret; ++ ++ if (size < sizeof(struct sync_pt_info)) ++ return -ENOMEM; ++ ++ info->len = sizeof(struct sync_pt_info); ++ ++ if (fence->ops->fill_driver_data) { ++ ret = fence->ops->fill_driver_data(fence, info->driver_data, ++ size - sizeof(*info)); ++ if (ret < 0) ++ return ret; ++ ++ info->len += ret; ++ } ++ ++ strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), ++ sizeof(info->obj_name)); ++ strlcpy(info->driver_name, fence->ops->get_driver_name(fence), ++ sizeof(info->driver_name)); ++ if (fence_is_signaled(fence)) ++ info->status = fence->status >= 0 ? 1 : fence->status; ++ else ++ info->status = 0; ++ info->timestamp_ns = ktime_to_ns(fence->timestamp); ++ ++ return info->len; ++} ++ ++static long sync_fence_ioctl_fence_info(struct sync_fence *fence, ++ unsigned long arg) ++{ ++ struct sync_fence_info_data *data; ++ __u32 size; ++ __u32 len = 0; ++ int ret, i; ++ ++ if (copy_from_user(&size, (void __user *)arg, sizeof(size))) ++ return -EFAULT; ++ ++ if (size < sizeof(struct sync_fence_info_data)) ++ return -EINVAL; ++ ++ if (size > 4096) ++ size = 4096; ++ ++ data = kzalloc(size, GFP_KERNEL); ++ if (data == NULL) ++ return -ENOMEM; ++ ++ strlcpy(data->name, fence->name, sizeof(data->name)); ++ data->status = atomic_read(&fence->status); ++ if (data->status >= 0) ++ data->status = !data->status; ++ ++ len = sizeof(struct sync_fence_info_data); ++ ++ for (i = 0; i < fence->num_fences; ++i) { ++ struct fence *pt = fence->cbs[i].sync_pt; ++ ++ ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len); ++ ++ if (ret < 0) ++ goto out; ++ ++ len += ret; ++ } ++ ++ data->len = len; ++ ++ if (copy_to_user((void __user *)arg, data, len)) ++ ret = -EFAULT; ++ else ++ ret = 0; ++ ++out: ++ kfree(data); ++ ++ return ret; ++} ++ ++static long sync_fence_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct sync_fence *fence = file->private_data; ++ ++ switch (cmd) { ++ case SYNC_IOC_WAIT: ++ return sync_fence_ioctl_wait(fence, arg); ++ ++ case SYNC_IOC_MERGE: ++ return sync_fence_ioctl_merge(fence, arg); ++ ++ case SYNC_IOC_FENCE_INFO: ++ return sync_fence_ioctl_fence_info(fence, arg); ++ ++ default: ++ return -ENOTTY; ++ } ++} ++ ++static const struct file_operations sync_fence_fops = { ++ .release = sync_fence_release, ++ .poll = sync_fence_poll, ++ .unlocked_ioctl = sync_fence_ioctl, ++ .compat_ioctl = sync_fence_ioctl, ++}; ++#endif ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync.h.patch new file mode 100644 index 00000000..206acfe5 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync.h.patch @@ -0,0 +1,366 @@ +--- linux-4.9.37/drivers/dma-buf/sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,363 @@ ++/* ++ * include/linux/sync.h ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_SYNC_H ++#define _LINUX_SYNC_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "_sync.h" ++ ++struct sync_timeline; ++struct sync_pt; ++#if 0 ++struct sync_fence; ++#endif ++ ++/** ++ * struct sync_timeline_ops - sync object implementation ops ++ * @driver_name: name of the implementation ++ * @dup: duplicate a sync_pt ++ * @has_signaled: returns: ++ * 1 if pt has signaled ++ * 0 if pt has not signaled ++ * <0 on error ++ * @compare: returns: ++ * 1 if b will signal before a ++ * 0 if a and b will signal at the same time ++ * -1 if a will signal before b ++ * @free_pt: called before sync_pt is freed ++ * @release_obj: called before sync_timeline is freed ++ * @fill_driver_data: write implementation specific driver data to data. ++ * should return an error if there is not enough room ++ * as specified by size. This information is returned ++ * to userspace by SYNC_IOC_FENCE_INFO. ++ * @timeline_value_str: fill str with the value of the sync_timeline's counter ++ * @pt_value_str: fill str with the value of the sync_pt ++ */ ++struct sync_timeline_ops { ++ const char *driver_name; ++ ++ /* required */ ++ struct sync_pt * (*dup)(struct sync_pt *pt); ++ ++ /* required */ ++ int (*has_signaled)(struct sync_pt *pt); ++ ++ /* required */ ++ int (*compare)(struct sync_pt *a, struct sync_pt *b); ++ ++ /* optional */ ++ void (*free_pt)(struct sync_pt *sync_pt); ++ ++ /* optional */ ++ void (*release_obj)(struct sync_timeline *sync_timeline); ++ ++ /* optional */ ++ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size); ++ ++ /* optional */ ++ void (*timeline_value_str)(struct sync_timeline *timeline, char *str, ++ int size); ++ ++ /* optional */ ++ void (*pt_value_str)(struct sync_pt *pt, char *str, int size); ++}; ++ ++/** ++ * struct sync_timeline - sync object ++ * @kref: reference count on fence. ++ * @ops: ops that define the implementation of the sync_timeline ++ * @name: name of the sync_timeline. Useful for debugging ++ * @destroyed: set when sync_timeline is destroyed ++ * @child_list_head: list of children sync_pts for this sync_timeline ++ * @child_list_lock: lock protecting @child_list_head, destroyed, and ++ * sync_pt.status ++ * @active_list_head: list of active (unsignaled/errored) sync_pts ++ * @sync_timeline_list: membership in global sync_timeline_list ++ */ ++struct sync_timeline { ++ struct kref kref; ++ const struct sync_timeline_ops *ops; ++ char name[32]; ++ ++ /* protected by child_list_lock */ ++ bool destroyed; ++ int context, value; ++ ++ struct list_head child_list_head; ++ spinlock_t child_list_lock; ++ ++ struct list_head active_list_head; ++ ++#ifdef CONFIG_DEBUG_FS ++ struct list_head sync_timeline_list; ++#endif ++}; ++ ++/** ++ * struct sync_pt - sync point ++ * @fence: base fence class ++ * @child_list: membership in sync_timeline.child_list_head ++ * @active_list: membership in sync_timeline.active_list_head ++ * @signaled_list: membership in temporary signaled_list on stack ++ * @fence: sync_fence to which the sync_pt belongs ++ * @pt_list: membership in sync_fence.pt_list_head ++ * @status: 1: signaled, 0:active, <0: error ++ * @timestamp: time which sync_pt status transitioned from active to ++ * signaled or error. ++ */ ++struct sync_pt { ++ struct fence base; ++ ++ struct list_head child_list; ++ struct list_head active_list; ++}; ++ ++static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt) ++{ ++ return container_of(pt->base.lock, struct sync_timeline, ++ child_list_lock); ++} ++ ++#if 0 ++struct sync_fence_cb { ++ struct fence_cb cb; ++ struct fence *sync_pt; ++ struct sync_fence *fence; ++}; ++ ++/** ++ * struct sync_fence - sync fence ++ * @file: file representing this fence ++ * @kref: reference count on fence. ++ * @name: name of sync_fence. Useful for debugging ++ * @pt_list_head: list of sync_pts in the fence. immutable once fence ++ * is created ++ * @status: 0: signaled, >0:active, <0: error ++ * ++ * @wq: wait queue for fence signaling ++ * @sync_fence_list: membership in global fence list ++ */ ++struct sync_fence { ++ struct file *file; ++ struct kref kref; ++ char name[32]; ++#ifdef CONFIG_DEBUG_FS ++ struct list_head sync_fence_list; ++#endif ++ int num_fences; ++ ++ wait_queue_head_t wq; ++ atomic_t status; ++ ++ struct sync_fence_cb cbs[]; ++}; ++ ++struct sync_fence_waiter; ++typedef void (*sync_callback_t)(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter); ++ ++/** ++ * struct sync_fence_waiter - metadata for asynchronous waiter on a fence ++ * @waiter_list: membership in sync_fence.waiter_list_head ++ * @callback: function pointer to call when fence signals ++ * @callback_data: pointer to pass to @callback ++ */ ++struct sync_fence_waiter { ++ wait_queue_t work; ++ sync_callback_t callback; ++}; ++ ++static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter, ++ sync_callback_t callback) ++{ ++ INIT_LIST_HEAD(&waiter->work.task_list); ++ waiter->callback = callback; ++} ++#endif ++ ++/* ++ * API for sync_timeline implementers ++ */ ++ ++/** ++ * sync_timeline_create() - creates a sync object ++ * @ops: specifies the implementation ops for the object ++ * @size: size to allocate for this obj ++ * @name: sync_timeline name ++ * ++ * Creates a new sync_timeline which will use the implementation specified by ++ * @ops. @size bytes will be allocated allowing for implementation specific ++ * data to be kept after the generic sync_timeline struct. ++ */ ++struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, ++ int size, const char *name); ++ ++/** ++ * sync_timeline_destroy() - destroys a sync object ++ * @obj: sync_timeline to destroy ++ * ++ * A sync implementation should call this when the @obj is going away ++ * (i.e. module unload.) @obj won't actually be freed until all its children ++ * sync_pts are freed. ++ */ ++void bsp_sync_timeline_destroy(struct sync_timeline *obj); ++ ++/** ++ * sync_timeline_signal() - signal a status change on a sync_timeline ++ * @obj: sync_timeline to signal ++ * ++ * A sync implementation should call this any time one of it's sync_pts ++ * has signaled or has an error condition. ++ */ ++void bsp_sync_timeline_signal(struct sync_timeline *obj); ++ ++/** ++ * sync_pt_create() - creates a sync pt ++ * @parent: sync_pt's parent sync_timeline ++ * @size: size to allocate for this pt ++ * ++ * Creates a new sync_pt as a child of @parent. @size bytes will be ++ * allocated allowing for implementation specific data to be kept after ++ * the generic sync_timeline struct. ++ */ ++struct sync_pt *bsp_sync_pt_create(struct sync_timeline *parent, int size); ++ ++/** ++ * sync_pt_free() - frees a sync pt ++ * @pt: sync_pt to free ++ * ++ * This should only be called on sync_pts which have been created but ++ * not added to a fence. ++ */ ++void bsp_sync_pt_free(struct sync_pt *pt); ++ ++#if 0 ++/** ++ * sync_fence_create() - creates a sync fence ++ * @name: name of fence to create ++ * @pt: sync_pt to add to the fence ++ * ++ * Creates a fence containg @pt. Once this is called, the fence takes ++ * ownership of @pt. ++ */ ++struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt); ++ ++/* ++ * API for sync_fence consumers ++ */ ++ ++/** ++ * sync_fence_merge() - merge two fences ++ * @name: name of new fence ++ * @a: fence a ++ * @b: fence b ++ * ++ * Creates a new fence which contains copies of all the sync_pts in both ++ * @a and @b. @a and @b remain valid, independent fences. ++ */ ++struct sync_fence *bsp_sync_fence_merge(const char *name, ++ struct sync_fence *a, struct sync_fence *b); ++ ++/** ++ * sync_fence_fdget() - get a fence from an fd ++ * @fd: fd referencing a fence ++ * ++ * Ensures @fd references a valid fence, increments the refcount of the backing ++ * file, and returns the fence. ++ */ ++struct sync_fence *bsp_sync_fence_fdget(int fd); ++ ++/** ++ * sync_fence_put() - puts a reference of a sync fence ++ * @fence: fence to put ++ * ++ * Puts a reference on @fence. If this is the last reference, the fence and ++ * all it's sync_pts will be freed ++ */ ++void bsp_sync_fence_put(struct sync_fence *fence); ++ ++/** ++ * sync_fence_install() - installs a fence into a file descriptor ++ * @fence: fence to install ++ * @fd: file descriptor in which to install the fence ++ * ++ * Installs @fence into @fd. @fd's should be acquired through ++ * get_unused_fd_flags(O_CLOEXEC). ++ */ ++void bsp_sync_fence_install(struct sync_fence *fence, int fd); ++ ++/** ++ * sync_fence_wait_async() - registers and async wait on the fence ++ * @fence: fence to wait on ++ * @waiter: waiter callback struck ++ * ++ * Returns 1 if @fence has already signaled. ++ * ++ * Registers a callback to be called when @fence signals or has an error. ++ * @waiter should be initialized with sync_fence_waiter_init(). ++ */ ++int bsp_sync_fence_wait_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter); ++ ++/** ++ * sync_fence_cancel_async() - cancels an async wait ++ * @fence: fence to wait on ++ * @waiter: waiter callback struck ++ * ++ * returns 0 if waiter was removed from fence's async waiter list. ++ * returns -ENOENT if waiter was not found on fence's async waiter list. ++ * ++ * Cancels a previously registered async wait. Will fail gracefully if ++ * @waiter was never registered or if @fence has already signaled @waiter. ++ */ ++int bsp_sync_fence_cancel_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter); ++ ++/** ++ * sync_fence_wait() - wait on fence ++ * @fence: fence to wait on ++ * @tiemout: timeout in ms ++ * ++ * Wait for @fence to be signaled or have an error. Waits indefinitely ++ * if @timeout < 0 ++ */ ++int bsp_sync_fence_wait(struct sync_fence *fence, long timeout); ++ ++#ifdef CONFIG_DEBUG_FS ++ ++void bsp_sync_timeline_debug_add(struct sync_timeline *obj); ++void bsp_sync_timeline_debug_remove(struct sync_timeline *obj); ++void bsp_sync_fence_debug_add(struct sync_fence *fence); ++void bsp_sync_fence_debug_remove(struct sync_fence *fence); ++void bsp_sync_dump(void); ++ ++#else ++# define bsp_sync_timeline_debug_add(obj) ++# define bsp_sync_timeline_debug_remove(obj) ++# define bsp_sync_fence_debug_add(fence) ++# define bsp_sync_fence_debug_remove(fence) ++# define bsp_sync_dump() ++#endif ++int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, ++ int wake_flags, void *key); ++ ++#endif ++ ++#endif /* _LINUX_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync_file.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync_file.c.patch new file mode 100644 index 00000000..50a3a81e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-buf-sync_file.c.patch @@ -0,0 +1,143 @@ +--- linux-4.9.37/drivers/dma-buf/sync_file.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/dma-buf/sync_file.c 2021-06-07 13:01:33.000000000 +0300 +@@ -67,9 +67,10 @@ + * sync_file_create() - creates a sync file + * @fence: fence to add to the sync_fence + * +- * Creates a sync_file containg @fence. Once this is called, the sync_file +- * takes ownership of @fence. The sync_file can be released with +- * fput(sync_file->file). Returns the sync_file or NULL in case of error. ++ * Creates a sync_file containg @fence. This function acquires and additional ++ * reference of @fence for the newly-created &sync_file, if it succeeds. The ++ * sync_file can be released with fput(sync_file->file). Returns the ++ * sync_file or NULL in case of error. + */ + struct sync_file *sync_file_create(struct fence *fence) + { +@@ -79,7 +80,7 @@ + if (!sync_file) + return NULL; + +- sync_file->fence = fence; ++ sync_file->fence = fence_get(fence); + + snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d", + fence->ops->get_driver_name(fence), +@@ -90,14 +91,7 @@ + } + EXPORT_SYMBOL(sync_file_create); + +-/** +- * sync_file_fdget() - get a sync_file from an fd +- * @fd: fd referencing a fence +- * +- * Ensures @fd references a valid sync_file, increments the refcount of the +- * backing file. Returns the sync_file or NULL in case of error. +- */ +-static struct sync_file *sync_file_fdget(int fd) ++struct sync_file *sync_file_fdget(int fd) + { + struct file *file = fget(fd); + +@@ -114,6 +108,8 @@ + return NULL; + } + ++EXPORT_SYMBOL(sync_file_fdget); ++ + /** + * sync_file_get_fence - get the fence related to the sync_file fd + * @fd: sync_file fd to get the fence from +@@ -305,10 +301,9 @@ + + poll_wait(file, &sync_file->wq, wait); + +- if (!poll_does_not_wait(wait) && +- !test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) { ++ if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) { + if (fence_add_callback(sync_file->fence, &sync_file->cb, +- fence_check_cb_func) < 0) ++ fence_check_cb_func) < 0) + wake_up_all(&sync_file->wq); + } + +@@ -370,7 +365,7 @@ + return err; + } + +-static void sync_fill_fence_info(struct fence *fence, ++static int sync_fill_fence_info(struct fence *fence, + struct sync_fence_info *info) + { + strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), +@@ -382,6 +377,8 @@ + else + info->status = 0; + info->timestamp_ns = ktime_to_ns(fence->timestamp); ++ ++ return info->status; + } + + static long sync_file_ioctl_fence_info(struct sync_file *sync_file, +@@ -407,8 +404,12 @@ + * sync_fence_info and return the actual number of fences on + * info->num_fences. + */ +- if (!info.num_fences) ++ if (!info.num_fences) { ++ info.status = fence_is_signaled(sync_file->fence); + goto no_fences; ++ } else { ++ info.status = 1; ++ } + + if (info.num_fences < num_fences) + return -EINVAL; +@@ -418,8 +419,10 @@ + if (!fence_info) + return -ENOMEM; + +- for (i = 0; i < num_fences; i++) +- sync_fill_fence_info(fences[i], &fence_info[i]); ++ for (i = 0; i < num_fences; i++) { ++ int status = sync_fill_fence_info(fences[i], &fence_info[i]); ++ info.status = info.status <= 0 ? info.status : status; ++ } + + if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info, + size)) { +@@ -429,7 +432,6 @@ + + no_fences: + strlcpy(info.name, sync_file->name, sizeof(info.name)); +- info.status = fence_is_signaled(sync_file->fence); + info.num_fences = num_fences; + + if (copy_to_user((void __user *)arg, &info, sizeof(info))) +@@ -443,12 +445,26 @@ + return ret; + } + ++#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) ++static long sync_fence_ioctl_wait(struct sync_file *sync_file, unsigned long arg) ++{ ++ __s32 value; ++ ++ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) ++ return -EFAULT; ++ if(value <= 0) ++ value = MAX_SCHEDULE_TIMEOUT; ++ return fence_wait_timeout(sync_file->fence, true, value); ++} ++ + static long sync_file_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) + { + struct sync_file *sync_file = file->private_data; + + switch (cmd) { ++ case SYNC_IOC_WAIT: ++ return sync_fence_ioctl_wait(sync_file, arg); + case SYNC_IOC_MERGE: + return sync_file_ioctl_merge(sync_file, arg); + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-edmac_goke.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-edmac_goke.c.patch new file mode 100644 index 00000000..6b6d1a0d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-edmac_goke.c.patch @@ -0,0 +1,1289 @@ +--- linux-4.9.37/drivers/dma/edmac_goke.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/dma/edmac_goke.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,1286 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "edmac_goke.h" ++#include "dmaengine.h" ++#include "virt-dma.h" ++ ++#define DRIVER_NAME "edmac-goke" ++ ++int edmac_trace_level = EDMAC_TRACE_LEVEL; ++ ++typedef struct edmac_lli { ++ u64 next_lli; ++ u32 reserved[5]; ++ u32 count; ++ u64 src_addr; ++ u64 dest_addr; ++ u32 config; ++ u32 pad[3]; ++} edmac_lli; ++ ++struct edmac_sg { ++ dma_addr_t src_addr; ++ dma_addr_t dst_addr; ++ size_t len; ++ struct list_head node; ++}; ++ ++struct transfer_desc { ++ struct virt_dma_desc virt_desc; ++ ++ dma_addr_t llis_busaddr; ++ u64 *llis_vaddr; ++ u32 ccfg; ++ size_t size; ++ bool done; ++ bool cyclic; ++}; ++ ++enum edmac_dma_chan_state { ++ EDMAC_CHAN_IDLE, ++ EDMAC_CHAN_RUNNING, ++ EDMAC_CHAN_PAUSED, ++ EDMAC_CHAN_WAITING, ++}; ++ ++struct edmac_dma_chan { ++ bool slave; ++ int signal; ++ int id; ++ struct virt_dma_chan virt_chan; ++ struct edmac_phy_chan *phychan; ++ struct dma_slave_config cfg; ++ struct transfer_desc *at; ++ struct edmac_driver_data *host; ++ enum edmac_dma_chan_state state; ++}; ++ ++struct edmac_phy_chan { ++ unsigned int id; ++ void __iomem *base; ++ spinlock_t lock; ++ struct edmac_dma_chan *serving; ++}; ++ ++struct edmac_driver_data { ++ struct platform_device *dev; ++ struct dma_device slave; ++ struct dma_device memcpy; ++ void __iomem *base; ++ struct regmap *misc_regmap; ++ void __iomem *crg_ctrl; ++ struct edmac_phy_chan *phy_chans; ++ struct dma_pool *pool; ++ unsigned int misc_ctrl_base; ++ int irq; ++ unsigned int id; ++ struct clk *clk; ++ struct clk *axi_clk; ++ struct reset_control *rstc; ++ unsigned int channels; ++ unsigned int slave_requests; ++ unsigned int max_transfer_size; ++}; ++ ++#ifdef DEBUG_EDMAC ++void dump_lli(u64 *llis_vaddr, unsigned int num) ++{ ++ ++ edmac_lli *plli = (edmac_lli *)llis_vaddr; ++ unsigned int i; ++ ++ edmac_trace(3, "lli num = 0%d\n", num); ++ for (i = 0; i < num; i++) { ++ printk("lli%d:lli_L: 0x%llx\n", i, plli[i].next_lli & 0xffffffff); ++ printk("lli%d:lli_H: 0x%llx\n", i, plli[i].next_lli >> 32 & 0xffffffff); ++ printk("lli%d:count: 0x%llx\n", i, plli[i].count); ++ printk("lli%d:src_addr_L: 0x%llx\n", i, plli[i].src_addr & 0xffffffff); ++ printk("lli%d:src_addr_H: 0x%llx\n", i, plli[i].src_addr >> 32 & 0xffffffff); ++ printk("lli%d:dst_addr_L: 0x%llx\n", i, plli[i].dest_addr & 0xffffffff); ++ printk("lli%d:dst_addr_H: 0x%llx\n", i, plli[i].dest_addr >> 32 & 0xffffffff); ++ printk("lli%d:CONFIG: 0x%llx\n", i, plli[i].config); ++ } ++} ++ ++#else ++void dump_lli(u64 *llis_vaddr, unsigned int num) ++{ ++} ++#endif ++ ++static inline struct edmac_dma_chan *to_edamc_chan(struct dma_chan *chan) ++{ ++ return container_of(chan, struct edmac_dma_chan, virt_chan.chan); ++} ++ ++static inline struct transfer_desc *to_edmac_transfer_desc(struct dma_async_tx_descriptor *tx) ++{ ++ return container_of(tx, struct transfer_desc, virt_desc.tx); ++} ++ ++static struct dma_chan *edmac_find_chan_id(struct edmac_driver_data *edmac, ++ int request_num) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = NULL; ++ ++ list_for_each_entry(edmac_dma_chan, &edmac->slave.channels, virt_chan.chan.device_node) { ++ if (edmac_dma_chan->id == request_num) { ++ return &edmac_dma_chan->virt_chan.chan; ++ } ++ } ++ return NULL; ++} ++ ++static struct dma_chan *edma_of_xlate(struct of_phandle_args *dma_spec, ++ struct of_dma *ofdma) ++{ ++ struct edmac_driver_data *edmac = ofdma->of_dma_data; ++ struct edmac_dma_chan *edmac_dma_chan = NULL; ++ struct dma_chan *dma_chan = NULL; ++ struct regmap *misc = NULL; ++ unsigned int signal = 0, request_num = 0; ++ unsigned int reg = 0, offset = 0; ++ ++ if (!edmac) { ++ return NULL; ++ } ++ ++ misc = edmac->misc_regmap; ++ ++ if (dma_spec->args_count != 2) { ++ edmac_error("args count not true!\n"); ++ return NULL; ++ } ++ ++ request_num = dma_spec->args[0]; ++ signal = dma_spec->args[1]; ++ ++ edmac_trace(3, "host->id = %d,signal = %d, request_num = %d\n", edmac->id, signal, request_num); ++ ++ if (misc != NULL) { ++#ifdef CONFIG_ACCESS_M7_DEV ++ offset = edmac->misc_ctrl_base; ++ reg = 0xc0; ++ regmap_write(misc, offset, reg); ++#else ++ offset = edmac->misc_ctrl_base + (request_num & (~0x3)); ++ regmap_read(misc, offset, ®); ++ reg &= ~(0x3f << ((request_num & 0x3) << 3)); ++ reg |= signal << ((request_num & 0x3) << 3); ++ regmap_write(misc, offset, reg); ++#endif ++ } ++ ++ edmac_trace(3, "offset = 0x%x, reg = 0x%x\n", offset, reg); ++ ++ dma_chan = edmac_find_chan_id(edmac, request_num); ++ if (!dma_chan) { ++ edmac_error("DMA slave channel is not found!\n"); ++ return NULL; ++ } ++ ++ edmac_dma_chan = to_edamc_chan(dma_chan); ++ edmac_dma_chan->signal = request_num; ++ ++ return dma_get_slave_channel(dma_chan); ++} ++ ++ ++static int get_of_probe(struct edmac_driver_data *edmac) ++{ ++ struct resource *res = NULL; ++ struct platform_device *platdev = edmac->dev; ++ struct device_node *np = platdev->dev.of_node; ++ int ret; ++ ++ ret = of_property_read_u32((&platdev->dev)->of_node, ++ "devid", &(edmac->id)); ++ if (ret) { ++ edmac_error("get edmac id fail\n"); ++ return -ENODEV; ++ } ++ ++ edmac->clk = devm_clk_get(&(platdev->dev), "apb_pclk"); ++ if (IS_ERR(edmac->clk)) { ++ return PTR_ERR(edmac->clk); ++ } ++ ++ edmac->axi_clk = devm_clk_get(&(platdev->dev), "axi_aclk"); ++ if (IS_ERR(edmac->axi_clk)) { ++ return PTR_ERR(edmac->axi_clk); ++ } ++ ++ edmac->rstc = devm_reset_control_get(&(platdev->dev), "dma-reset"); ++ if (IS_ERR(edmac->rstc)) { ++ return PTR_ERR(edmac->rstc); ++ } ++ ++ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ edmac_error("no reg resource\n"); ++ return -ENODEV; ++ } ++ ++ edmac->base = devm_ioremap_resource(&(platdev->dev), res); ++ if (IS_ERR(edmac->base)) { ++ return PTR_ERR(edmac->base); ++ } ++#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) || \ ++ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) ++ edmac->misc_regmap = 0; ++ (void)np; ++#else ++ edmac->misc_regmap = syscon_regmap_lookup_by_phandle(np, "misc_regmap"); ++ if (IS_ERR(edmac->misc_regmap)) { ++ return PTR_ERR(edmac->misc_regmap); ++ } ++ ++ ret = of_property_read_u32((&platdev->dev)->of_node, ++ "misc_ctrl_base", &(edmac->misc_ctrl_base)); ++ if (ret) { ++ edmac_error( "get dma-misc_ctrl_base fail\n"); ++ return -ENODEV; ++ } ++#endif ++ edmac->irq = platform_get_irq(platdev, 0); ++ if (unlikely(edmac->irq < 0)) { ++ return -ENODEV; ++ } ++ ++ ret = of_property_read_u32((&platdev->dev)->of_node, ++ "dma-channels", &(edmac->channels)); ++ if (ret) { ++ edmac_error( "get dma-channels fail\n"); ++ return -ENODEV; ++ } ++ ret = of_property_read_u32((&platdev->dev)->of_node, ++ "dma-requests", &(edmac->slave_requests)); ++ if (ret) { ++ edmac_error( "get dma-requests fail\n"); ++ return -ENODEV; ++ } ++ edmac_trace(2, "dma-channels = %d, dma-requests = %d\n", ++ edmac->channels, edmac->slave_requests); ++ return of_dma_controller_register(platdev->dev.of_node, edma_of_xlate, edmac); ++} ++ ++static void edmac_free_chan_resources(struct dma_chan *chan) ++{ ++ vchan_free_chan_resources(to_virt_chan(chan)); ++} ++ ++static enum dma_status edmac_tx_status(struct dma_chan *chan, ++ dma_cookie_t cookie, struct dma_tx_state *txstate) ++{ ++ enum dma_status ret = DMA_COMPLETE; ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct virt_dma_desc *vd = NULL; ++ struct transfer_desc *tsf_desc = NULL; ++ unsigned long flags; ++ size_t bytes = 0; ++ u64 curr_lli = 0, curr_residue_bytes = 0, temp = 0; ++ edmac_lli *plli = NULL; ++ unsigned int i = 0, index = 0; ++ ++ ret = dma_cookie_status(chan, cookie, txstate); ++ if (ret == DMA_COMPLETE) { ++ return ret; ++ } ++ ++ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); ++ vd = vchan_find_desc(&edmac_dma_chan->virt_chan, cookie); ++ if (vd) { ++ /* no been trasfer */ ++ tsf_desc = to_edmac_transfer_desc(&vd->tx); ++ bytes = tsf_desc->size; ++ } else { ++ /* trasfering */ ++ tsf_desc = edmac_dma_chan->at; ++ ++ if (!phychan || !tsf_desc) { ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ goto out; ++ } ++ curr_lli = (edmac_readl(edmac->base + EDMAC_Cx_LLI_L(phychan->id)) & (~(EDMAC_LLI_ALIGN - 1))); ++ curr_lli |= ((u64)(edmac_readl(edmac->base + EDMAC_Cx_LLI_H(phychan->id)) & 0xffffffff) << 32); ++ curr_residue_bytes = edmac_readl(edmac->base + EDMAC_Cx_CURR_CNT0(phychan->id)); ++ if (curr_lli == 0) { ++ /* It means non-lli mode */ ++ bytes = curr_residue_bytes; ++ } else { ++ /* It means lli mode */ ++ index = (curr_lli - tsf_desc->llis_busaddr) / sizeof(edmac_lli) - 1; ++ plli = (edmac_lli *)(tsf_desc->llis_vaddr); ++ for (i = 0; i < index; i++) { ++ temp += plli[i].count; ++ } ++ temp += plli[i].count - curr_residue_bytes; ++ bytes = tsf_desc->size - temp; ++ } ++ } ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ ++ dma_set_residue(txstate, bytes); ++ ++ if (edmac_dma_chan->state == EDMAC_CHAN_PAUSED && ret == DMA_IN_PROGRESS) { ++ ret = DMA_PAUSED; ++ return ret; ++ } ++ ++out: ++ return ret; ++} ++ ++static struct edmac_phy_chan *edmac_get_phy_channel( ++ struct edmac_driver_data *edmac, ++ struct edmac_dma_chan *edmac_dma_chan) ++{ ++ struct edmac_phy_chan *ch = NULL; ++ unsigned long flags; ++ int i; ++ ++ for (i = 0; i < edmac->channels; i++) { ++ ch = &edmac->phy_chans[i]; ++ ++ spin_lock_irqsave(&ch->lock, flags); ++ ++ if (!ch->serving) { ++ ch->serving = edmac_dma_chan; ++ spin_unlock_irqrestore(&ch->lock, flags); ++ break; ++ } ++ spin_unlock_irqrestore(&ch->lock, flags); ++ } ++ ++ if (i == edmac->channels) { ++ return NULL; ++ } ++ ++ return ch; ++} ++ ++static void edmac_write_lli(struct edmac_driver_data *edmac, ++ struct edmac_phy_chan *phychan, ++ struct transfer_desc *tsf_desc) ++{ ++ ++ edmac_lli *plli = (edmac_lli *)tsf_desc->llis_vaddr; ++ ++ if (plli->next_lli != 0x0) { ++ edmac_writel((plli->next_lli & 0xffffffff) | EDMAC_LLI_ENABLE, edmac->base + EDMAC_Cx_LLI_L(phychan->id)); ++ } else { ++ edmac_writel((plli->next_lli & 0xffffffff), edmac->base + EDMAC_Cx_LLI_L(phychan->id)); ++ } ++ ++ edmac_writel(((plli->next_lli >> 32) & 0xffffffff), edmac->base + EDMAC_Cx_LLI_H(phychan->id)); ++ edmac_writel(plli->count, edmac->base + EDMAC_Cx_CNT0(phychan->id)); ++ edmac_writel(plli->src_addr & 0xffffffff, edmac->base + EDMAC_Cx_SRC_ADDR_L(phychan->id)); ++ edmac_writel((plli->src_addr >> 32) & 0xffffffff, edmac->base + EDMAC_Cx_SRC_ADDR_H(phychan->id)); ++ edmac_writel(plli->dest_addr & 0xffffffff, edmac->base + EDMAC_Cx_DEST_ADDR_L(phychan->id)); ++ edmac_writel((plli->dest_addr >> 32) & 0xffffffff, edmac->base + EDMAC_Cx_DEST_ADDR_H(phychan->id)); ++ edmac_writel(plli->config, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++} ++ ++static void edmac_start_next_txd(struct edmac_dma_chan *edmac_dma_chan) ++{ ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; ++ struct virt_dma_desc *vd = vchan_next_desc(&edmac_dma_chan->virt_chan); ++ struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx); ++ unsigned int val = 0; ++ ++ list_del(&tsf_desc->virt_desc.node); ++ ++ edmac_dma_chan->at = tsf_desc; ++ ++ edmac_write_lli(edmac, phychan, tsf_desc); ++ ++ val = edmac_readl(edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++ ++ edmac_trace(2, " EDMAC_Cx_CONFIG = 0x%x\n", val); ++ edmac_writel(val | EDMAC_CxCONFIG_LLI_START, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++} ++ ++static void edmac_start(struct edmac_dma_chan * edmac_dma_chan) ++{ ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct edmac_phy_chan *ch; ++ ++ ch = edmac_get_phy_channel(edmac, edmac_dma_chan); ++ if (!ch) { ++ edmac_error("no phy channel available !\n"); ++ edmac_dma_chan->state = EDMAC_CHAN_WAITING; ++ return; ++ } ++ ++ edmac_dma_chan->phychan = ch; ++ edmac_dma_chan->state = EDMAC_CHAN_RUNNING; ++ ++ edmac_start_next_txd(edmac_dma_chan); ++} ++ ++static void edmac_issue_pending(struct dma_chan *chan) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); ++ if (vchan_issue_pending(&edmac_dma_chan->virt_chan)) { ++ if (!edmac_dma_chan->phychan && edmac_dma_chan->state != EDMAC_CHAN_WAITING) { ++ edmac_start(edmac_dma_chan); ++ } ++ } ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++} ++ ++static void edmac_free_txd_list(struct edmac_dma_chan *edmac_dma_chan) ++{ ++ LIST_HEAD(head); ++ ++ vchan_get_all_descriptors(&edmac_dma_chan->virt_chan, &head); ++ vchan_dma_desc_free_list(&edmac_dma_chan->virt_chan, &head); ++} ++ ++static int edmac_config(struct dma_chan *chan, ++ struct dma_slave_config *config) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ ++ if (!edmac_dma_chan->slave) { ++ edmac_error("slave is null!"); ++ return -EINVAL; ++ } ++ ++ edmac_dma_chan->cfg = *config; ++ ++ return 0; ++} ++ ++static void edmac_pause_phy_chan(struct edmac_dma_chan *edmac_dma_chan) ++{ ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; ++ unsigned int val; ++ int timeout; ++ ++ ++ val = edmac_readl(edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++ val &= ~CCFG_EN; ++ edmac_writel(val, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++ ++ /* Wait for channel inactive */ ++ for (timeout = 2000; timeout > 0; timeout--) { ++ if (!(0x1 << phychan->id & edmac_readl(edmac->base + EDMAC_CH_STAT))) { ++ break; ++ } ++ edmac_writel(val, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++ udelay(1); ++ } ++ ++ if (timeout == 0) { ++ edmac_error(":channel%u timeout waiting for pause, timeout:%d\n", ++ phychan->id, timeout); ++ } ++} ++ ++static int edmac_pause(struct dma_chan *chan) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); ++ ++ if (!edmac_dma_chan->phychan) { ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ return 0; ++ } ++ ++ edmac_pause_phy_chan(edmac_dma_chan); ++ edmac_dma_chan->state = EDMAC_CHAN_PAUSED; ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ ++ return 0; ++} ++ ++static void edmac_resume_phy_chan(struct edmac_dma_chan *edmac_dma_chan) ++{ ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; ++ unsigned int val; ++ ++ val = edmac_readl(edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++ val |= CCFG_EN; ++ edmac_writel(val, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); ++} ++ ++static int edmac_resume(struct dma_chan *chan) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); ++ ++ if (!edmac_dma_chan->phychan) { ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ return 0; ++ } ++ ++ edmac_resume_phy_chan(edmac_dma_chan); ++ edmac_dma_chan->state = EDMAC_CHAN_RUNNING; ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ ++ return 0; ++} ++ ++void edmac_phy_free(struct edmac_dma_chan *chan); ++static void edmac_desc_free(struct virt_dma_desc *vd); ++static int edmac_terminate_all(struct dma_chan *chan) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); ++ if (!edmac_dma_chan->phychan && !edmac_dma_chan->at) { ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ return 0; ++ } ++ ++ edmac_dma_chan->state = EDMAC_CHAN_IDLE; ++ ++ if (edmac_dma_chan->phychan) { ++ edmac_phy_free(edmac_dma_chan); ++ } ++ ++ if (edmac_dma_chan->at) { ++ edmac_desc_free(&edmac_dma_chan->at->virt_desc); ++ edmac_dma_chan->at = NULL; ++ } ++ edmac_free_txd_list(edmac_dma_chan); ++ ++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); ++ ++ return 0; ++} ++ ++static struct transfer_desc *edmac_get_tsf_desc(struct edmac_driver_data *plchan) ++{ ++ struct transfer_desc *tsf_desc = kzalloc(sizeof(struct transfer_desc), GFP_NOWAIT); ++ ++ if (tsf_desc) { ++ tsf_desc->ccfg = 0; ++ } ++ ++ return tsf_desc; ++} ++ ++static void edmac_free_tsf_desc(struct edmac_driver_data *edmac, ++ struct transfer_desc *tsf_desc) ++{ ++ if (tsf_desc->llis_vaddr) { ++ dma_pool_free(edmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); ++ } ++ ++ kfree(tsf_desc); ++} ++ ++static u32 get_width(enum dma_slave_buswidth width) ++{ ++ switch (width) { ++ case DMA_SLAVE_BUSWIDTH_1_BYTE: ++ return EDMAC_WIDTH_8BIT; ++ case DMA_SLAVE_BUSWIDTH_2_BYTES: ++ return EDMAC_WIDTH_16BIT; ++ case DMA_SLAVE_BUSWIDTH_4_BYTES: ++ return EDMAC_WIDTH_32BIT; ++ case DMA_SLAVE_BUSWIDTH_8_BYTES: ++ return EDMAC_WIDTH_64BIT; ++ default: ++ edmac_error("check here, width warning!\n"); ++ return ~0; ++ } ++} ++ ++struct transfer_desc *edmac_init_tsf_desc ( ++ struct dma_chan *chan, ++ enum dma_transfer_direction direction, ++ dma_addr_t *slave_addr) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct transfer_desc *tsf_desc; ++ unsigned int config = 0, burst = 0; ++ unsigned int addr_width = 0, maxburst = 0; ++ unsigned int width = 0; ++ ++ tsf_desc = edmac_get_tsf_desc(edmac); ++ if (!tsf_desc) { ++ edmac_error("get tsf desc fail!\n"); ++ return NULL; ++ } ++ ++ if (direction == DMA_MEM_TO_DEV) { ++ config = EDMAC_CONFIG_SRC_INC; ++ *slave_addr = edmac_dma_chan->cfg.dst_addr; ++ addr_width = edmac_dma_chan->cfg.dst_addr_width; ++ maxburst = edmac_dma_chan->cfg.dst_maxburst; ++ } else if (direction == DMA_DEV_TO_MEM) { ++ config = EDMAC_CONFIG_DST_INC; ++ *slave_addr = edmac_dma_chan->cfg.src_addr; ++ addr_width = edmac_dma_chan->cfg.src_addr_width; ++ maxburst = edmac_dma_chan->cfg.src_maxburst; ++ } else { ++ edmac_free_tsf_desc(edmac, tsf_desc); ++ edmac_error("direction unsupported!\n"); ++ return NULL; ++ } ++ ++ edmac_trace(3, "addr_width = 0x%x\n", addr_width); ++ width = get_width(addr_width); ++ edmac_trace(3, "width = 0x%x\n", width); ++ config |= width << EDMAC_CONFIG_SRC_WIDTH_SHIFT; ++ config |= width << EDMAC_CONFIG_DST_WIDTH_SHIFT; ++ edmac_trace(2, "tsf_desc->ccfg = 0x%x\n", config); ++ ++ edmac_trace(3, "maxburst = 0x%x\n", maxburst); ++ if (maxburst > (EDMAC_MAX_BURST_WIDTH)) { ++ burst |= (EDMAC_MAX_BURST_WIDTH - 1); ++ } else if (maxburst == 0) { ++ burst |= EDMAC_MIN_BURST_WIDTH; ++ } else { ++ burst |= (maxburst - 1); ++ } ++ edmac_trace(3, "burst = 0x%x\n", burst); ++ config |= burst << EDMAC_CONFIG_SRC_BURST_SHIFT; ++ config |= burst << EDMAC_CONFIG_DST_BURST_SHIFT; ++ ++ if (edmac_dma_chan->signal >= 0) { ++ edmac_trace(2, "edmac_dma_chan->signal = %d\n", edmac_dma_chan->signal); ++ config |= (unsigned int)edmac_dma_chan->signal << EDMAC_CXCONFIG_SIGNAL_SHIFT; ++ } ++ ++ config |= EDMAC_CXCONFIG_DEV_MEM_TYPE << EDMAC_CXCONFIG_TSF_TYPE_SHIFT; ++ tsf_desc->ccfg = config; ++ edmac_trace(2, "tsf_desc->ccfg = 0x%x\n", tsf_desc->ccfg); ++ ++ return tsf_desc; ++} ++ ++static void edmac_fill_desc(struct transfer_desc *tsf_desc, dma_addr_t src, ++ dma_addr_t dst, unsigned int length, unsigned int num) ++{ ++ edmac_lli *plli; ++ ++ plli = (edmac_lli *)(tsf_desc->llis_vaddr); ++ memset(&plli[num], 0x0, sizeof(edmac_lli)); ++ ++ plli[num].src_addr = src; ++ plli[num].dest_addr = dst; ++ plli[num].config = tsf_desc->ccfg; ++ plli[num].count = length; ++ tsf_desc->size += length; ++ ++ if (num > 0) { ++ plli[num - 1].next_lli = (tsf_desc->llis_busaddr + (num) * sizeof(edmac_lli)) & (~(EDMAC_LLI_ALIGN - 1)); ++ plli[num - 1].next_lli |= EDMAC_LLI_ENABLE; ++ } ++} ++ ++static struct dma_async_tx_descriptor *edmac_perp_slave_sg( ++ struct dma_chan *chan, struct scatterlist *sgl, ++ unsigned int sg_len, enum dma_transfer_direction direction, ++ unsigned long flags, void *context) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct transfer_desc *tsf_desc = NULL; ++ struct scatterlist *sg = NULL; ++ int tmp = 0; ++ dma_addr_t src = 0, dst = 0, addr = 0, slave_addr = 0; ++ unsigned int length = 0, num = 0; ++ ++ edmac_lli *last_plli = NULL; ++ ++ if (sgl == NULL) { ++ edmac_error("sgl is null!\n"); ++ return NULL; ++ } ++ ++ tsf_desc = edmac_init_tsf_desc(chan, direction, &slave_addr); ++ if (!tsf_desc) { ++ edmac_error("desc init fail\n"); ++ return NULL; ++ } ++ ++ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, &tsf_desc->llis_busaddr); ++ if (!tsf_desc->llis_vaddr) { ++ edmac_free_tsf_desc(edmac, tsf_desc); ++ edmac_error("malloc memory from pool fail !\n"); ++ return 0; ++ } ++ ++ for_each_sg(sgl, sg, sg_len, tmp) { ++ addr = sg_dma_address(sg); ++ length = sg_dma_len(sg); ++ if (direction == DMA_MEM_TO_DEV) { ++ src = addr; ++ dst = slave_addr; ++ } else if (direction == DMA_DEV_TO_MEM) { ++ src = slave_addr; ++ dst = addr; ++ } ++ edmac_fill_desc(tsf_desc, src, dst, length, num); ++ num++; ++ } ++ ++ last_plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num - 1) * sizeof(edmac_lli)); ++ last_plli->next_lli |= EDMAC_LLI_DISABLE; ++ dump_lli(tsf_desc->llis_vaddr, num); ++ ++ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); ++} ++ ++static struct dma_async_tx_descriptor *edmac_prep_dma_memcpy( ++ struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, ++ size_t len, unsigned long flags) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct transfer_desc *tsf_desc = NULL; ++ u32 config = 0; ++ size_t num = 0; ++ size_t length = 0; ++ edmac_lli *last_plli = NULL; ++ ++ if (!len) { ++ return NULL; ++ } ++ ++ tsf_desc = edmac_get_tsf_desc(edmac); ++ if (!tsf_desc) { ++ edmac_error("get tsf desc fail!\n"); ++ return NULL; ++ } ++ ++ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, &tsf_desc->llis_busaddr); ++ if (!tsf_desc->llis_vaddr) { ++ edmac_free_tsf_desc(edmac, tsf_desc); ++ edmac_error("malloc memory from pool fail !\n"); ++ return 0; ++ } ++ ++ config |= EDMAC_CONFIG_SRC_INC | EDMAC_CONFIG_DST_INC; ++ config |= EDMAC_CXCONFIG_MEM_TYPE << EDMAC_CXCONFIG_TSF_TYPE_SHIFT; ++ ++ /* max burst width is 16 ,but reg value set 0xf */ ++ config |= (EDMAC_MAX_BURST_WIDTH - 1) << EDMAC_CONFIG_SRC_BURST_SHIFT; ++ config |= (EDMAC_MAX_BURST_WIDTH - 1) << EDMAC_CONFIG_DST_BURST_SHIFT; ++ ++ tsf_desc->ccfg = config; ++ ++ do { ++ length = min_t(size_t, len, MAX_TRANSFER_BYTES); ++ edmac_fill_desc(tsf_desc, src, dest, length, num); ++ ++ src += length; ++ dest += length; ++ len -= length; ++ num++; ++ } while(len); ++ ++ last_plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num - 1) * sizeof(edmac_lli)); ++ last_plli->next_lli |= EDMAC_LLI_DISABLE; ++ dump_lli(tsf_desc->llis_vaddr, num); ++ ++ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); ++} ++ ++ ++ ++static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( ++ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, ++ size_t period_len, enum dma_transfer_direction direction, ++ unsigned long flags) ++{ ++ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); ++ struct edmac_driver_data *edmac = edmac_dma_chan->host; ++ struct transfer_desc *tsf_desc; ++ dma_addr_t src = 0, dst = 0, addr = 0, slave_addr = 0; ++ size_t length = 0, since = 0, total = 0, num = 0, len = 0; ++ edmac_lli *last_plli = NULL; ++ edmac_lli *plli = NULL; ++ ++ tsf_desc = edmac_init_tsf_desc(chan, direction, &slave_addr); ++ if (!tsf_desc) { ++ edmac_error("desc init fail\n"); ++ return NULL; ++ } ++ ++ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, &tsf_desc->llis_busaddr); ++ if (!tsf_desc->llis_vaddr) { ++ edmac_free_tsf_desc(edmac, tsf_desc); ++ edmac_error("malloc memory from pool fail !\n"); ++ return 0; ++ } ++ ++ tsf_desc->cyclic = true; ++ addr = buf_addr; ++ total = buf_len; ++ ++ if (period_len < MAX_TRANSFER_BYTES) { ++ len = period_len; ++ } ++ do { ++ length = min_t(size_t, total, len); ++ ++ if (direction == DMA_MEM_TO_DEV) { ++ src = addr; ++ dst = slave_addr; ++ } else if (direction == DMA_DEV_TO_MEM) { ++ src = slave_addr; ++ dst = addr; ++ } ++ ++ edmac_fill_desc(tsf_desc, src, dst, length, num); ++ ++ since += length; ++ if (since >= period_len) { ++ plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num) * sizeof(edmac_lli)); ++ plli->config |= EDMAC_CXCONFIG_ITC_EN << EDMAC_CXCONFIG_ITC_EN_SHIFT; ++ since -= period_len; ++ } ++ addr += length; ++ total -= length; ++ num++; ++ } while(total); ++ ++ last_plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num - 1) * sizeof(edmac_lli)); ++ ++ last_plli->next_lli = (unsigned long)(tsf_desc->llis_vaddr); ++ ++ dump_lli(tsf_desc->llis_vaddr, num); ++ ++ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); ++} ++ ++ ++static void edmac_phy_reassign(struct edmac_phy_chan *phy_chan, ++ struct edmac_dma_chan *chan) ++{ ++ phy_chan->serving = chan; ++ chan->phychan = phy_chan; ++ chan->state = EDMAC_CHAN_RUNNING; ++ ++ edmac_start_next_txd(chan); ++} ++ ++static void edmac_terminate_phy_chan(struct edmac_driver_data *edmac, ++ struct edmac_dma_chan *edmac_dma_chan) ++{ ++ unsigned int val; ++ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; ++ ++ edmac_pause_phy_chan(edmac_dma_chan); ++ ++ val = 0x1 << phychan->id; ++ ++ edmac_writel(val, edmac->base + EDMAC_INT_TC1_RAW); ++ edmac_writel(val, edmac->base + EDMAC_INT_ERR1_RAW); ++ edmac_writel(val, edmac->base + EDMAC_INT_ERR2_RAW); ++} ++ ++void edmac_phy_free(struct edmac_dma_chan *chan) ++{ ++ struct edmac_driver_data *edmac = chan->host; ++ struct edmac_dma_chan *p = NULL; ++ struct edmac_dma_chan *next = NULL; ++ ++ list_for_each_entry(p, &edmac->memcpy.channels, virt_chan.chan.device_node) { ++ if (p->state == EDMAC_CHAN_WAITING) { ++ next = p; ++ break; ++ } ++ } ++ ++ if (!next) { ++ list_for_each_entry(p, &edmac->slave.channels, virt_chan.chan.device_node) { ++ if (p->state == EDMAC_CHAN_WAITING) { ++ next = p; ++ break; ++ } ++ } ++ } ++ edmac_terminate_phy_chan(edmac, chan); ++ ++ if (next) { ++ spin_lock(&next->virt_chan.lock); ++ edmac_phy_reassign(chan->phychan, next); ++ spin_unlock(&next->virt_chan.lock); ++ } else { ++ chan->phychan->serving = NULL; ++ } ++ ++ chan->phychan = NULL; ++ chan->state = EDMAC_CHAN_IDLE; ++} ++ ++static irqreturn_t edmac_irq(int irq, void *dev) ++{ ++ struct edmac_driver_data *edmac = (struct edmac_driver_data *)dev; ++ struct edmac_dma_chan *chan = NULL; ++ struct edmac_phy_chan *phy_chan = NULL; ++ struct transfer_desc * tsf_desc = NULL; ++ ++ u32 mask = 0; ++ unsigned int channel_err_status[3]; ++ unsigned int channel_status = 0; ++ unsigned int temp = 0; ++ unsigned int channel_tc_status = -1; ++ unsigned int i = 0; ++ ++ channel_status = edmac_readl(edmac->base + EDMAC_INT_STAT); ++ ++ if (!channel_status) { ++ edmac_error("channel_status = 0x%x\n", channel_status); ++ return IRQ_NONE; ++ } ++ ++ for (i = 0; i < edmac->channels; i++) { ++ temp = (channel_status >> i) & 0x1; ++ if (temp) { ++ phy_chan = &edmac->phy_chans[i]; ++ chan = phy_chan->serving; ++ if (!chan) { ++ edmac_error("error interrupt on chan: %d!\n", i); ++ continue; ++ } ++ tsf_desc = chan->at; ++ ++ channel_tc_status = edmac_readl(edmac->base + EDMAC_INT_TC1_RAW); ++ channel_tc_status = (channel_tc_status >> i) & 0x01; ++ if (channel_tc_status) { ++ edmac_writel(channel_tc_status << i, edmac->base + EDMAC_INT_TC1_RAW); ++ } ++ ++ channel_tc_status = edmac_readl(edmac->base + EDMAC_INT_TC2); ++ channel_tc_status = (channel_tc_status >> i) & 0x01; ++ if (channel_tc_status) { ++ edmac_writel(channel_tc_status << i, edmac->base + EDMAC_INT_TC2_RAW); ++ } ++ ++ channel_err_status[0] = edmac_readl(edmac->base + EDMAC_INT_ERR1); ++ channel_err_status[0] = (channel_err_status[0] >> i) & 0x01; ++ channel_err_status[1] = edmac_readl(edmac->base + EDMAC_INT_ERR2); ++ channel_err_status[1] = (channel_err_status[1] >> i) & 0x01; ++ channel_err_status[2] = edmac_readl(edmac->base + EDMAC_INT_ERR3); ++ channel_err_status[2] = (channel_err_status[2] >> i) & 0x01; ++ if (channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) { ++ edmac_error("Error in edmac %d finish!,ERR1 = 0x%x,ERR2 = 0x%x,ERR3 = 0x%x\n", ++ i, channel_err_status[0], channel_err_status[1], channel_err_status[2]); ++ edmac_writel(1 << i, edmac->base + EDMAC_INT_ERR1_RAW); ++ edmac_writel(1 << i, edmac->base + EDMAC_INT_ERR2_RAW); ++ edmac_writel(1 << i, edmac->base + EDMAC_INT_ERR3_RAW); ++ } ++ ++ spin_lock(&chan->virt_chan.lock); ++ ++ if (tsf_desc->cyclic) { ++ vchan_cyclic_callback(&tsf_desc->virt_desc); ++ spin_unlock(&chan->virt_chan.lock); ++ continue; ++ } ++ chan->at = NULL; ++ tsf_desc->done = true; ++ vchan_cookie_complete(&tsf_desc->virt_desc); ++ ++ if (vchan_next_desc(&chan->virt_chan)) { ++ edmac_start_next_txd(chan); ++ } else { ++ edmac_phy_free(chan); ++ } ++ ++ spin_unlock(&chan->virt_chan.lock); ++ mask |= (1 << i); ++ } ++ } ++ ++ return mask ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++static void edmac_dma_slave_init(struct edmac_dma_chan *chan) ++{ ++ chan->slave = true; ++} ++ ++static void edmac_desc_free(struct virt_dma_desc *vd) ++{ ++ struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx); ++ struct edmac_dma_chan * edmac_dma_chan = to_edamc_chan(vd->tx.chan); ++ ++ dma_descriptor_unmap(&vd->tx); ++ edmac_free_tsf_desc(edmac_dma_chan->host, tsf_desc); ++} ++ ++static int edmac_init_virt_channels(struct edmac_driver_data *edmac, ++ struct dma_device *dmadev, unsigned int channels, bool slave) ++{ ++ struct edmac_dma_chan *chan = NULL; ++ int i; ++ INIT_LIST_HEAD(&dmadev->channels); ++ ++ for (i = 0; i < channels; i++) { ++ chan = kzalloc(sizeof(struct edmac_dma_chan), GFP_KERNEL); ++ if (!chan) { ++ edmac_error("fail to allocate memory for virt channels!"); ++ return -1; ++ } ++ ++ chan->host = edmac; ++ chan->state = EDMAC_CHAN_IDLE; ++ chan->signal = -1; ++ ++ if (slave) { ++ chan->id = i; ++ edmac_dma_slave_init(chan); ++ } ++ chan->virt_chan.desc_free = edmac_desc_free; ++ vchan_init(&chan->virt_chan, dmadev); ++ } ++ return 0; ++} ++ ++void edmac_free_virt_channels(struct dma_device *dmadev) ++{ ++ struct edmac_dma_chan *chan = NULL; ++ struct edmac_dma_chan *next = NULL; ++ ++ list_for_each_entry_safe(chan, ++ next, &dmadev->channels, virt_chan.chan.device_node) { ++ list_del(&chan->virt_chan.chan.device_node); ++ kfree(chan); ++ } ++} ++ ++ ++#define MAX_TSFR_LLIS 32 ++#define EDMACV300_LLI_WORDS 16 ++#define EDMACV300_POOL_ALIGN 16 ++ ++static int __init edmac_probe(struct platform_device *pdev) ++{ ++ ++ int ret = 0, i = 0; ++ struct edmac_driver_data *edmac = NULL; ++ size_t trasfer_size = 0; ++ ++ ret = dma_set_mask_and_coherent(&(pdev->dev), DMA_BIT_MASK(64)); ++ if (ret) { ++ return ret; ++ } ++ ++ edmac = kzalloc(sizeof(*edmac), GFP_KERNEL); ++ if (!edmac) { ++ edmac_error("malloc for edmac fail!"); ++ ret = -ENOMEM; ++ return ret; ++ } ++ edmac->dev = pdev; ++ ++ ret = get_of_probe(edmac); ++ if (ret) { ++ edmac_error("get dts info fail!"); ++ goto free_edmac; ++ } ++ ++ ++ clk_prepare_enable(edmac->clk); ++ clk_prepare_enable(edmac->axi_clk); ++ ++ reset_control_deassert(edmac->rstc); ++ ++ dma_cap_set(DMA_MEMCPY, edmac->memcpy.cap_mask); ++ edmac->memcpy.dev = &pdev->dev; ++ edmac->memcpy.device_free_chan_resources = edmac_free_chan_resources; ++ edmac->memcpy.device_prep_dma_memcpy = edmac_prep_dma_memcpy; ++ edmac->memcpy.device_tx_status = edmac_tx_status; ++ edmac->memcpy.device_issue_pending = edmac_issue_pending; ++ edmac->memcpy.device_config = edmac_config; ++ edmac->memcpy.device_pause = edmac_pause; ++ edmac->memcpy.device_resume = edmac_resume; ++ edmac->memcpy.device_terminate_all = edmac_terminate_all; ++ edmac->memcpy.directions = BIT(DMA_MEM_TO_MEM); ++ edmac->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; ++ ++ dma_cap_set(DMA_SLAVE, edmac->slave.cap_mask); ++ dma_cap_set(DMA_CYCLIC, edmac->slave.cap_mask); ++ edmac->slave.dev = &pdev->dev; ++ edmac->slave.device_free_chan_resources = edmac_free_chan_resources; ++ edmac->slave.device_tx_status = edmac_tx_status; ++ edmac->slave.device_issue_pending = edmac_issue_pending; ++ edmac->slave.device_prep_slave_sg = edmac_perp_slave_sg; ++ edmac->slave.device_prep_dma_cyclic = edma_prep_dma_cyclic; ++ edmac->slave.device_config = edmac_config; ++ edmac->slave.device_resume = edmac_resume; ++ edmac->slave.device_pause = edmac_pause; ++ edmac->slave.device_terminate_all = edmac_terminate_all; ++ edmac->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); ++ edmac->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; ++ ++ edmac->max_transfer_size = MAX_TRANSFER_BYTES; ++ trasfer_size = MAX_TSFR_LLIS * EDMACV300_LLI_WORDS * sizeof(u32); ++ ++ edmac->pool = dma_pool_create(DRIVER_NAME, &(pdev->dev), ++ trasfer_size, EDMACV300_POOL_ALIGN, 0); ++ if (!edmac->pool) { ++ edmac_error("create pool fail!"); ++ ret = -ENOMEM; ++ goto free_edmac; ++ } ++ ++ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC1_RAW); ++ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC2_RAW); ++ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR1_RAW); ++ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR2_RAW); ++ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR3_RAW); ++ ++ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_TC1_MASK); ++ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_TC2_MASK); ++ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_ERR1_MASK); ++ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_ERR2_MASK); ++ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_ERR3_MASK); ++ ++ ret = request_irq(edmac->irq, edmac_irq, 0, DRIVER_NAME, edmac); ++ if (ret) { ++ edmac_error("fail to request irq"); ++ goto free_pool; ++ } ++ ++ edmac->phy_chans = kzalloc((edmac->channels * sizeof(struct edmac_phy_chan)), ++ GFP_KERNEL); ++ if (!edmac->phy_chans) { ++ edmac_error("malloc for phy chans fail!"); ++ ret = -ENOMEM; ++ goto free_irq_res; ++ } ++ ++ /* initialize the phy chan */ ++ for (i = 0; i < edmac->channels; i++) { ++ struct edmac_phy_chan* phy_ch = &edmac->phy_chans[i]; ++ phy_ch->id = i; ++ phy_ch->base = edmac->base + EDMAC_Cx_BASE(i); ++ spin_lock_init(&phy_ch->lock); ++ phy_ch->serving = NULL; ++ } ++ ++ /* initialize the memory virt chan */ ++ ret = edmac_init_virt_channels(edmac, &edmac->memcpy, edmac->channels, false); ++ if (ret) { ++ edmac_error("fail to init memory virt channels!"); ++ goto free_phychans; ++ } ++ ++ /* initialize the slave virt chan */ ++ ret = edmac_init_virt_channels(edmac, &edmac->slave, edmac->slave_requests, true); ++ if (ret) { ++ edmac_error("fail to init slave virt channels!"); ++ goto free_memory_virt_channels; ++ ++ } ++ ++ ret = dma_async_device_register(&edmac->memcpy); ++ if (ret) { ++ edmac_error( ++ "%s failed to register memcpy as an async device - %d\n", ++ __func__, ret); ++ goto free_slave_virt_channels; ++ } ++ ++ ret = dma_async_device_register(&edmac->slave); ++ if (ret) { ++ edmac_error( ++ "%s failed to register slave as an async device - %d\n", ++ __func__, ret); ++ goto free_memcpy_device; ++ } ++ ++ return 0; ++ ++free_memcpy_device: ++ dma_async_device_unregister(&edmac->memcpy); ++free_slave_virt_channels: ++ edmac_free_virt_channels(&edmac->slave); ++free_memory_virt_channels: ++ edmac_free_virt_channels(&edmac->memcpy); ++free_phychans: ++ kfree(edmac->phy_chans); ++free_irq_res: ++ free_irq(edmac->irq, edmac); ++free_pool: ++ dma_pool_destroy(edmac->pool); ++free_edmac: ++ kfree(edmac); ++ ++ return ret; ++} ++ ++ ++static int edma_remove(struct platform_device *pdev) ++{ ++ int err = 0; ++ return err; ++} ++ ++ ++static const struct of_device_id edmac_match[] = { ++ { .compatible = "goke,edmac" }, ++ {}, ++}; ++ ++ ++static struct platform_driver edmac_driver = { ++ .remove = edma_remove, ++ .driver = { ++ .name = "edmac", ++ .of_match_table = edmac_match, ++ }, ++}; ++ ++static int __init edmac_init(void) ++{ ++ return platform_driver_probe(&edmac_driver, edmac_probe); ++} ++subsys_initcall(edmac_init); ++ ++static void __exit edmac_exit(void) ++{ ++ platform_driver_unregister(&edmac_driver); ++} ++module_exit(edmac_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Goke"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-edmac_goke.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-edmac_goke.h.patch new file mode 100644 index 00000000..cef48385 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-dma-edmac_goke.h.patch @@ -0,0 +1,135 @@ +--- linux-4.9.37/drivers/dma/edmac_goke.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/dma/edmac_goke.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,132 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __EDMAC_H__ ++#define __EDMAC_H__ ++ ++/* debug control */ ++extern int edmac_trace_level; ++#define EDMAC_TRACE_LEVEL 5 ++ ++#define EDMAC_TRACE_FMT KERN_INFO ++ ++//#define DEBUG_EDMAC ++#ifdef DEBUG_EDMAC ++ ++#define edmac_trace(level, msg...) do { \ ++ if ((level) >= edmac_trace_level) { \ ++ printk(EDMAC_TRACE_FMT"%s:%d: ", __func__, __LINE__); \ ++ printk(msg); \ ++ printk("\n"); \ ++ } \ ++} while (0) ++ ++ ++#define edmac_assert(cond) do { \ ++ if (!(cond)) { \ ++ printk(KERN_ERR "Assert:edmac:%s:%d\n", \ ++ __func__, \ ++ __LINE__); \ ++ BUG(); \ ++ } \ ++} while (0) ++ ++#define edmac_error(s...) do { \ ++ printk(KERN_ERR "edmac:%s:%d: ", __func__, __LINE__); \ ++ printk(s); \ ++ printk("\n"); \ ++} while (0) ++ ++#else ++ ++#define edmac_trace(level, msg...) do { } while (0) ++#define edmac_assert(level, msg...) do { } while (0) ++#define edmac_error(level, msg...) do { } while (0) ++ ++#endif ++ ++#define edmac_readl(addr) ({ unsigned int reg = readl((void *)(addr)); \ ++ reg; }) ++ ++#define edmac_writel(v, addr) do { writel(v, (void *)(addr)); \ ++} while (0) ++ ++ ++#define MAX_TRANSFER_BYTES 0xffff ++ ++/* reg offset */ ++#define EDMAC_INT_STAT (0x0) ++#define EDMAC_INT_TC1 (0x4) ++#define EDMAC_INT_TC2 (0x8) ++#define EDMAC_INT_ERR1 (0xc) ++#define EDMAC_INT_ERR2 (0x10) ++#define EDMAC_INT_ERR3 (0x14) ++ ++#define EDMAC_INT_TC1_MASK (0x18) ++#define EDMAC_INT_TC2_MASK (0x1c) ++#define EDMAC_INT_ERR1_MASK (0x20) ++#define EDMAC_INT_ERR2_MASK (0x24) ++#define EDMAC_INT_ERR3_MASK (0x28) ++ ++#define EDMAC_INT_TC1_RAW (0x600) ++#define EDMAC_INT_TC2_RAW (0x608) ++#define EDMAC_INT_ERR1_RAW (0x610) ++#define EDMAC_INT_ERR2_RAW (0x618) ++#define EDMAC_INT_ERR3_RAW (0x620) ++ ++#define EDMAC_Cx_CURR_CNT0(cn) (0x404+cn*0x20) ++#define EDMAC_Cx_CURR_SRC_ADDR_L(cn) (0x408+cn*0x20) ++#define EDMAC_Cx_CURR_SRC_ADDR_H(cn) (0x40c+cn*0x20) ++#define EDMAC_Cx_CURR_DEST_ADDR_L(cn) (0x410+cn*0x20) ++#define EDMAC_Cx_CURR_DEST_ADDR_H(cn) (0x414+cn*0x20) ++ ++#define EDMAC_CH_PRI (0x688) ++#define EDMAC_CH_STAT (0x690) ++#define EDMAC_DMA_CTRL (0x698) ++ ++#define EDMAC_Cx_BASE(cn) (0x800+cn*0x40) ++#define EDMAC_Cx_LLI_L(cn) (0x800+cn*0x40) ++#define EDMAC_Cx_LLI_H(cn) (0x804+cn*0x40) ++#define EDMAC_Cx_CNT0(cn) (0x81c+cn*0x40) ++#define EDMAC_Cx_SRC_ADDR_L(cn) (0x820+cn*0x40) ++#define EDMAC_Cx_SRC_ADDR_H(cn) (0x824+cn*0x40) ++#define EDMAC_Cx_DEST_ADDR_L(cn) (0x828+cn*0x40) ++#define EDMAC_Cx_DEST_ADDR_H(cn) (0x82c+cn*0x40) ++#define EDMAC_Cx_CONFIG(cn) (0x830+cn*0x40) ++ ++#define EDMAC_ALL_CHAN_CLR (0xff) ++#define EDMAC_INT_ENABLE_ALL_CHAN (0xff) ++ ++ ++#define EDMAC_CONFIG_SRC_INC (1<<31) ++#define EDMAC_CONFIG_DST_INC (1<<30) ++ ++#define EDMAC_CONFIG_SRC_WIDTH_SHIFT (16) ++#define EDMAC_CONFIG_DST_WIDTH_SHIFT (12) ++#define EDMAC_WIDTH_8BIT (0x0) ++#define EDMAC_WIDTH_16BIT (0x1) ++#define EDMAC_WIDTH_32BIT (0x10) ++#define EDMAC_WIDTH_64BIT (0x11) ++ ++#define EDMAC_MAX_BURST_WIDTH (16) ++#define EDMAC_MIN_BURST_WIDTH (1) ++#define EDMAC_CONFIG_SRC_BURST_SHIFT (24) ++#define EDMAC_CONFIG_DST_BURST_SHIFT (20) ++ ++#define EDMAC_LLI_ALIGN 0x40 ++#define EDMAC_LLI_DISABLE 0x0 ++#define EDMAC_LLI_ENABLE 0x2 ++ ++#define EDMAC_CXCONFIG_SIGNAL_SHIFT (0x4) ++#define EDMAC_CXCONFIG_MEM_TYPE (0x0) ++#define EDMAC_CXCONFIG_DEV_MEM_TYPE (0x1) ++#define EDMAC_CXCONFIG_TSF_TYPE_SHIFT (0x2) ++#define EDMAC_CxCONFIG_LLI_START (0x1) ++ ++#define EDMAC_CXCONFIG_ITC_EN (0x1) ++#define EDMAC_CXCONFIG_ITC_EN_SHIFT (0x1) ++ ++#define CCFG_EN 0x1 ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-Kconfig.patch new file mode 100644 index 00000000..65f34ac4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-Kconfig.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/drivers/fence/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,8 @@ ++ ++config GOKE_FENCE ++ bool "Goke fence suppport" ++ default y ++ select SW_SYNC ++ select SYNC_FILE ++ help ++ Goke fence suppport diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-Makefile.patch new file mode 100644 index 00000000..8421784e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-Makefile.patch @@ -0,0 +1,5 @@ +--- linux-4.9.37/drivers/fence/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,2 @@ ++ ++obj-y += sw_sync.o sync.o sync_debug.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-_sw_sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-_sw_sync.h.patch new file mode 100644 index 00000000..c2d8a1fb --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-_sw_sync.h.patch @@ -0,0 +1,35 @@ +--- linux-4.9.37/drivers/fence/_sw_sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/_sw_sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _UAPI_LINUX_SW_SYNC_H ++#define _UAPI_LINUX_SW_SYNC_H ++ ++#include ++ ++struct sw_sync_create_fence_data { ++ __u32 value; ++ char name[32]; ++ __s32 fence; /* fd of new fence */ ++}; ++ ++#define SW_SYNC_IOC_MAGIC 'W' ++ ++#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ ++ struct sw_sync_create_fence_data) ++#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) ++ ++#endif /* _UAPI_LINUX_SW_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-_sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-_sync.h.patch new file mode 100644 index 00000000..e71cb06f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-_sync.h.patch @@ -0,0 +1,100 @@ +--- linux-4.9.37/drivers/fence/_sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/_sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _UAPI_LINUX_SYNC_H ++#define _UAPI_LINUX_SYNC_H ++ ++#include ++#include ++ ++/** ++ * struct sync_merge_data - data passed to merge ioctl ++ * @fd2: file descriptor of second fence ++ * @name: name of new fence ++ * @fence: returns the fd of the new fence to userspace ++ */ ++struct sync_merge_data { ++ __s32 fd2; /* fd of second fence */ ++ char name[32]; /* name of new fence */ ++ __s32 fence; /* fd on newly created fence */ ++}; ++ ++/** ++ * struct sync_pt_info - detailed sync_pt information ++ * @len: length of sync_pt_info including any driver_data ++ * @obj_name: name of parent sync_timeline ++ * @driver_name: name of driver implementing the parent ++ * @status: status of the sync_pt 0:active 1:signaled <0:error ++ * @timestamp_ns: timestamp of status change in nanoseconds ++ * @driver_data: any driver dependent data ++ */ ++struct sync_pt_info { ++ __u32 len; ++ char obj_name[32]; ++ char driver_name[32]; ++ __s32 status; ++ __u64 timestamp_ns; ++ ++ __u8 driver_data[0]; ++}; ++ ++/** ++ * struct sync_fence_info_data - data returned from fence info ioctl ++ * @len: ioctl caller writes the size of the buffer its passing in. ++ * ioctl returns length of sync_fence_data returned to userspace ++ * including pt_info. ++ * @name: name of fence ++ * @status: status of fence. 1: signaled 0:active <0:error ++ * @pt_info: a sync_pt_info struct for every sync_pt in the fence ++ */ ++struct sync_fence_info_data { ++ __u32 len; ++ char name[32]; ++ __s32 status; ++ ++ __u8 pt_info[0]; ++}; ++ ++#define SYNC_IOC_MAGIC '>' ++ ++/** ++ * DOC: SYNC_IOC_WAIT - wait for a fence to signal ++ * ++ * pass timeout in milliseconds. Waits indefinitely timeout < 0. ++ */ ++#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) ++ ++/** ++ * DOC: SYNC_IOC_MERGE - merge two fences ++ * ++ * Takes a struct sync_merge_data. Creates a new fence containing copies of ++ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the ++ * new fence's fd in sync_merge_data.fence ++ */ ++#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) ++ ++/** ++ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence ++ * ++ * Takes a struct sync_fence_info_data with extra space allocated for pt_info. ++ * Caller should write the size of the buffer into len. On return, len is ++ * updated to reflect the total size of the sync_fence_info_data including ++ * pt_info. ++ * ++ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. ++ * To iterate over the sync_pt_infos, use the sync_pt_info.len field. ++ */ ++#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ ++ struct sync_fence_info_data) ++ ++#endif /* _UAPI_LINUX_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sw_sync.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sw_sync.c.patch new file mode 100644 index 00000000..e69d4d08 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sw_sync.c.patch @@ -0,0 +1,280 @@ +--- linux-4.9.37/drivers/fence/sw_sync.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/sw_sync.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,277 @@ ++/* ++ * drivers/base/sw_sync.c ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sw_sync.h" ++ ++static int sw_sync_cmp(u32 a, u32 b) ++{ ++ if (a == b) ++ return 0; ++ ++ return ((s32)a - (s32)b) < 0 ? -1 : 1; ++} ++ ++struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value) ++{ ++ struct sw_sync_pt *pt; ++ ++ pt = (struct sw_sync_pt *) ++ bsp_sync_pt_create(&obj->obj, sizeof(struct sw_sync_pt)); ++ if (pt != NULL) { ++ pt->value = value; ++ } ++ ++ return (struct sync_pt *)pt; ++} ++EXPORT_SYMBOL(bsp_sw_sync_pt_create); ++ ++static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt) ++{ ++ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; ++ struct sw_sync_timeline *obj = ++ (struct sw_sync_timeline *)sync_pt_parent(sync_pt); ++ ++ return (struct sync_pt *)bsp_sw_sync_pt_create(obj, pt->value); ++} ++ ++static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt) ++{ ++ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; ++ struct sw_sync_timeline *obj = ++ (struct sw_sync_timeline *)sync_pt_parent(sync_pt); ++ ++ return sw_sync_cmp(obj->value, pt->value) >= 0; ++} ++ ++static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b) ++{ ++ struct sw_sync_pt *pt_a = (struct sw_sync_pt *)a; ++ struct sw_sync_pt *pt_b = (struct sw_sync_pt *)b; ++ ++ return sw_sync_cmp(pt_a->value, pt_b->value); ++} ++ ++static int sw_sync_fill_driver_data(struct sync_pt *sync_pt, ++ void *data, int size) ++{ ++ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; ++ ++ if (size < sizeof(pt->value)) ++ return -ENOMEM; ++ ++ memcpy(data, &pt->value, sizeof(pt->value)); ++ ++ return sizeof(pt->value); ++} ++ ++static void sw_sync_timeline_value_str(struct sync_timeline *sync_timeline, ++ char *str, int size) ++{ ++ struct sw_sync_timeline *timeline = ++ (struct sw_sync_timeline *)sync_timeline; ++ snprintf(str, size, "%d", timeline->value); ++} ++ ++static void sw_sync_pt_value_str(struct sync_pt *sync_pt, ++ char *str, int size) ++{ ++ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; ++ ++ snprintf(str, size, "%d", pt->value); ++} ++ ++static struct sync_timeline_ops sw_sync_timeline_ops = { ++ .driver_name = "sw_sync", ++ .dup = sw_sync_pt_dup, ++ .has_signaled = sw_sync_pt_has_signaled, ++ .compare = sw_sync_pt_compare, ++ .fill_driver_data = sw_sync_fill_driver_data, ++ .timeline_value_str = sw_sync_timeline_value_str, ++ .pt_value_str = sw_sync_pt_value_str, ++}; ++ ++struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name) ++{ ++ struct sw_sync_timeline *obj = (struct sw_sync_timeline *) ++ bsp_sync_timeline_create(&sw_sync_timeline_ops, ++ sizeof(struct sw_sync_timeline), ++ name); ++ ++ return obj; ++} ++EXPORT_SYMBOL(bsp_sw_sync_timeline_create); ++ ++void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) ++{ ++ obj->value += inc; ++ ++ bsp_sync_timeline_signal(&obj->obj); ++} ++EXPORT_SYMBOL(bsp_sw_sync_timeline_inc); ++ ++#ifdef CONFIG_SW_SYNC_USER ++/* *WARNING* ++ * ++ * improper use of this can result in deadlocking kernel drivers from userspace. ++ */ ++ ++/* opening sw_sync create a new sync obj */ ++static int sw_sync_open(struct inode *inode, struct file *file) ++{ ++ struct sw_sync_timeline *obj = NULL; ++ char task_comm[TASK_COMM_LEN]; ++ ++ get_task_comm(task_comm, current); ++ ++ obj = bsp_sw_sync_timeline_create(task_comm); ++ if (!obj) ++ return -ENOMEM; ++ ++ file->private_data = obj; ++ ++ return 0; ++} ++ ++static int sw_sync_release(struct inode *inode, struct file *file) ++{ ++ struct sw_sync_timeline *obj = file->private_data; ++ ++ bsp_sync_timeline_destroy(&obj->obj); ++ return 0; ++} ++ ++static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, ++ unsigned long arg) ++{ ++ int fd = get_unused_fd_flags(O_CLOEXEC); ++ int err; ++ struct sync_pt *pt = NULL; ++ #if 0 ++ struct sync_fence *fence; ++ #else ++ struct sync_file *fence = NULL; ++ #endif ++ struct sw_sync_create_fence_data data; ++ ++ if (fd < 0) ++ return fd; ++ ++ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { ++ err = -EFAULT; ++ goto err; ++ } ++ ++ pt = bsp_sw_sync_pt_create(obj, data.value); ++ if (!pt) { ++ err = -ENOMEM; ++ goto err; ++ } ++ ++ data.name[sizeof(data.name) - 1] = '\0'; ++ #if 0 ++ fence = bsp_sync_fence_create(data.name, pt); ++ #else ++ fence = sync_file_create(&pt->base); ++ #endif ++ if (!fence) { ++ bsp_sync_pt_free(pt); ++ err = -ENOMEM; ++ goto err; ++ } ++ ++ data.fence = fd; ++ if (copy_to_user((void __user *)arg, &data, sizeof(data))) { ++ #if 0 ++ bsp_sync_fence_put(fence); ++ #else ++ fput(fence->file); ++ #endif ++ err = -EFAULT; ++ goto err; ++ } ++ ++ #if 0 ++ bsp_sync_fence_install(fence, fd); ++ #else ++ fd_install(fd, fence->file); ++ #endif ++ ++ return 0; ++ ++err: ++ put_unused_fd(fd); ++ return err; ++} ++ ++static long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) ++{ ++ u32 value; ++ ++ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) ++ return -EFAULT; ++ ++ bsp_sw_sync_timeline_inc(obj, value); ++ ++ return 0; ++} ++ ++static long sw_sync_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct sw_sync_timeline *obj = file->private_data; ++ ++ switch (cmd) { ++ case SW_SYNC_IOC_CREATE_FENCE: ++ return sw_sync_ioctl_create_fence(obj, arg); ++ ++ case SW_SYNC_IOC_INC: ++ return sw_sync_ioctl_inc(obj, arg); ++ ++ default: ++ return -ENOTTY; ++ } ++} ++ ++static const struct file_operations sw_sync_fops = { ++ .owner = THIS_MODULE, ++ .open = sw_sync_open, ++ .release = sw_sync_release, ++ .unlocked_ioctl = sw_sync_ioctl, ++ .compat_ioctl = sw_sync_ioctl, ++}; ++ ++static struct miscdevice sw_sync_dev = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = "sw_sync", ++ .fops = &sw_sync_fops, ++}; ++ ++static int __init sw_sync_device_init(void) ++{ ++ return misc_register(&sw_sync_dev); ++} ++device_initcall(sw_sync_device_init); ++ ++#endif /* CONFIG_SW_SYNC_USER */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sw_sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sw_sync.h.patch new file mode 100644 index 00000000..64256f73 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sw_sync.h.patch @@ -0,0 +1,63 @@ +--- linux-4.9.37/drivers/fence/sw_sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/sw_sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,60 @@ ++/* ++ * include/linux/sw_sync.h ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_SW_SYNC_H ++#define _LINUX_SW_SYNC_H ++ ++#include ++#include ++#include "sync.h" ++#include "_sw_sync.h" ++#include ++ ++struct sw_sync_timeline { ++ struct sync_timeline obj; ++ ++ u32 value; ++}; ++ ++struct sw_sync_pt { ++ struct sync_pt pt; ++ ++ u32 value; ++}; ++ ++#if IS_ENABLED(CONFIG_SW_SYNC) ++struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name); ++void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); ++ ++struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); ++#else ++static inline struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name) ++{ ++ return NULL; ++} ++ ++static inline void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) ++{ ++} ++ ++static inline struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, ++ u32 value) ++{ ++ return NULL; ++} ++#endif /* IS_ENABLED(CONFIG_SW_SYNC) */ ++ ++#endif /* _LINUX_SW_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync.c.patch new file mode 100644 index 00000000..0589e5b8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync.c.patch @@ -0,0 +1,743 @@ +--- linux-4.9.37/drivers/fence/sync.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/sync.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,740 @@ ++/* ++ * drivers/base/sync.c ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sync.h" ++ ++#include ++ ++static const struct fence_ops android_fence_ops; ++static const struct file_operations sync_fence_fops; ++ ++struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, ++ int size, const char *name) ++{ ++ struct sync_timeline *obj = NULL; ++ ++ if (size < sizeof(struct sync_timeline)) ++ return NULL; ++ ++ obj = kzalloc(size, GFP_KERNEL); ++ if (obj == NULL) ++ return NULL; ++ ++ kref_init(&obj->kref); ++ obj->ops = ops; ++ obj->context = fence_context_alloc(1); ++ strlcpy(obj->name, name, sizeof(obj->name)); ++ ++ INIT_LIST_HEAD(&obj->child_list_head); ++ INIT_LIST_HEAD(&obj->active_list_head); ++ spin_lock_init(&obj->child_list_lock); ++#if 0 ++ bsp_sync_timeline_debug_add(obj); ++#endif ++ ++ return obj; ++} ++EXPORT_SYMBOL(bsp_sync_timeline_create); ++ ++static void sync_timeline_free(struct kref *kref) ++{ ++ struct sync_timeline *obj = ++ container_of(kref, struct sync_timeline, kref); ++#if 0 ++ bsp_sync_timeline_debug_remove(obj); ++#endif ++ if (obj->ops->release_obj) ++ obj->ops->release_obj(obj); ++ ++ kfree(obj); ++} ++ ++static void sync_timeline_get(struct sync_timeline *obj) ++{ ++ kref_get(&obj->kref); ++} ++ ++static void sync_timeline_put(struct sync_timeline *obj) ++{ ++ kref_put(&obj->kref, sync_timeline_free); ++} ++ ++void bsp_sync_timeline_destroy(struct sync_timeline *obj) ++{ ++ obj->destroyed = true; ++ /* ++ * Ensure timeline is marked as destroyed before ++ * changing timeline's fences status. ++ */ ++ smp_wmb(); ++ ++ /* ++ * signal any children that their parent is going away. ++ */ ++ bsp_sync_timeline_signal(obj); ++ sync_timeline_put(obj); ++} ++EXPORT_SYMBOL(bsp_sync_timeline_destroy); ++ ++void bsp_sync_timeline_signal(struct sync_timeline *obj) ++{ ++ unsigned long flags; ++ LIST_HEAD(signaled_pts); ++ struct sync_pt *pt = NULL; ++ struct sync_pt *next = NULL; ++ ++ spin_lock_irqsave(&obj->child_list_lock, flags); ++ ++ list_for_each_entry_safe(pt, next, &obj->active_list_head, ++ active_list) { ++ if (fence_is_signaled_locked(&pt->base)) { ++ list_del_init(&pt->active_list); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) ++ fence_put(&pt->base); ++#endif ++ } ++ } ++ ++ spin_unlock_irqrestore(&obj->child_list_lock, flags); ++} ++EXPORT_SYMBOL(bsp_sync_timeline_signal); ++ ++struct sync_pt *bsp_sync_pt_create(struct sync_timeline *obj, int size) ++{ ++ unsigned long flags; ++ struct sync_pt *pt = NULL; ++ ++ if (size < sizeof(struct sync_pt)) ++ return NULL; ++ ++ pt = kzalloc(size, GFP_KERNEL); ++ if (pt == NULL) ++ return NULL; ++ ++ spin_lock_irqsave(&obj->child_list_lock, flags); ++ sync_timeline_get(obj); ++ fence_init(&pt->base, &android_fence_ops, &obj->child_list_lock, ++ obj->context, ++obj->value); ++ list_add_tail(&pt->child_list, &obj->child_list_head); ++ INIT_LIST_HEAD(&pt->active_list); ++ spin_unlock_irqrestore(&obj->child_list_lock, flags); ++ return pt; ++} ++EXPORT_SYMBOL(bsp_sync_pt_create); ++ ++void bsp_sync_pt_free(struct sync_pt *pt) ++{ ++ fence_put(&pt->base); ++} ++EXPORT_SYMBOL(bsp_sync_pt_free); ++ ++#if 0 ++static struct sync_fence *sync_fence_alloc(int size, const char *name) ++{ ++ struct sync_fence *fence; ++ ++ fence = kzalloc(size, GFP_KERNEL); ++ if (fence == NULL) ++ return NULL; ++ ++ fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, ++ fence, 0); ++ if (IS_ERR(fence->file)) ++ goto err; ++ ++ kref_init(&fence->kref); ++ strlcpy(fence->name, name, sizeof(fence->name)); ++ ++ init_waitqueue_head(&fence->wq); ++ ++ return fence; ++ ++err: ++ kfree(fence); ++ return NULL; ++} ++ ++static void fence_check_cb_func(struct fence *f, struct fence_cb *cb) ++{ ++ struct sync_fence_cb *check; ++ struct sync_fence *fence; ++ ++ check = container_of(cb, struct sync_fence_cb, cb); ++ fence = check->fence; ++ ++ if (atomic_dec_and_test(&fence->status)) ++ wake_up_all(&fence->wq); ++} ++ ++/* TODO: implement a create which takes more that one sync_pt */ ++struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt) ++{ ++ struct sync_fence *fence; ++ ++ fence = sync_fence_alloc(offsetof(struct sync_fence, cbs[1]), name); ++ if (fence == NULL) ++ return NULL; ++ ++ fence->num_fences = 1; ++ atomic_set(&fence->status, 1); ++ ++ fence->cbs[0].sync_pt = &pt->base; ++ fence->cbs[0].fence = fence; ++ if (fence_add_callback(&pt->base, &fence->cbs[0].cb, ++ fence_check_cb_func)) ++ atomic_dec(&fence->status); ++#if 0 ++ bsp_sync_fence_debug_add(fence); ++#endif ++ ++ return fence; ++} ++EXPORT_SYMBOL(bsp_sync_fence_create); ++ ++struct sync_fence *bsp_sync_fence_fdget(int fd) ++{ ++ struct file *file = fget(fd); ++ ++ if (file == NULL) ++ return NULL; ++ ++ if (file->f_op != &sync_fence_fops) ++ goto err; ++ ++ return file->private_data; ++ ++err: ++ fput(file); ++ return NULL; ++} ++EXPORT_SYMBOL(bsp_sync_fence_fdget); ++ ++void bsp_sync_fence_put(struct sync_fence *fence) ++{ ++ fput(fence->file); ++} ++EXPORT_SYMBOL(bsp_sync_fence_put); ++ ++void bsp_sync_fence_install(struct sync_fence *fence, int fd) ++{ ++ printk("<%s> Line %d: fd =%d, fence=%p, name=%s\n", __func__, __LINE__, fd, fence, fence->name); ++ fd_install(fd, fence->file); ++} ++EXPORT_SYMBOL(bsp_sync_fence_install); ++ ++static void sync_fence_add_pt(struct sync_fence *fence, ++ int *i, struct fence *pt) ++{ ++ fence->cbs[*i].sync_pt = pt; ++ fence->cbs[*i].fence = fence; ++ ++ if (!fence_add_callback(pt, &fence->cbs[*i].cb, fence_check_cb_func)) { ++ fence_get(pt); ++ (*i)++; ++ } ++} ++ ++struct sync_fence *bsp_sync_fence_merge(const char *name, ++ struct sync_fence *a, struct sync_fence *b) ++{ ++ int num_fences = a->num_fences + b->num_fences; ++ struct sync_fence *fence; ++ int i, i_a, i_b; ++ unsigned long size = offsetof(struct sync_fence, cbs[num_fences]); ++ ++ fence = sync_fence_alloc(size, name); ++ if (fence == NULL) ++ return NULL; ++ ++ atomic_set(&fence->status, num_fences); ++ ++ /* ++ * Assume sync_fence a and b are both ordered and have no ++ * duplicates with the same context. ++ * ++ * If a sync_fence can only be created with sync_fence_merge ++ * and sync_fence_create, this is a reasonable assumption. ++ */ ++ for (i = i_a = i_b = 0; i_a < a->num_fences && i_b < b->num_fences; ) { ++ struct fence *pt_a = a->cbs[i_a].sync_pt; ++ struct fence *pt_b = b->cbs[i_b].sync_pt; ++ ++ if (pt_a->context < pt_b->context) { ++ sync_fence_add_pt(fence, &i, pt_a); ++ ++ i_a++; ++ } else if (pt_a->context > pt_b->context) { ++ sync_fence_add_pt(fence, &i, pt_b); ++ ++ i_b++; ++ } else { ++ if (pt_a->seqno - pt_b->seqno <= INT_MAX) ++ sync_fence_add_pt(fence, &i, pt_a); ++ else ++ sync_fence_add_pt(fence, &i, pt_b); ++ ++ i_a++; ++ i_b++; ++ } ++ } ++ ++ for (; i_a < a->num_fences; i_a++) ++ sync_fence_add_pt(fence, &i, a->cbs[i_a].sync_pt); ++ ++ for (; i_b < b->num_fences; i_b++) ++ sync_fence_add_pt(fence, &i, b->cbs[i_b].sync_pt); ++ ++ if (num_fences > i) ++ atomic_sub(num_fences - i, &fence->status); ++ fence->num_fences = i; ++#if 0 ++ bsp_sync_fence_debug_add(fence); ++#endif ++ return fence; ++} ++EXPORT_SYMBOL(bsp_sync_fence_merge); ++ ++int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, ++ int wake_flags, void *key) ++{ ++ struct sync_fence_waiter *wait; ++ ++ wait = container_of(curr, struct sync_fence_waiter, work); ++ list_del_init(&wait->work.task_list); ++ ++ wait->callback(wait->work.private, wait); ++ return 1; ++} ++ ++int bsp_sync_fence_wait_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter) ++{ ++ int err = atomic_read(&fence->status); ++ unsigned long flags; ++ ++ if (err < 0) ++ return err; ++ ++ if (!err) ++ return 1; ++ ++ init_waitqueue_func_entry(&waiter->work, bsp_sync_fence_wake_up_wq); ++ waiter->work.private = fence; ++ ++ spin_lock_irqsave(&fence->wq.lock, flags); ++ err = atomic_read(&fence->status); ++ if (err > 0) ++ __add_wait_queue_tail(&fence->wq, &waiter->work); ++ spin_unlock_irqrestore(&fence->wq.lock, flags); ++ ++ if (err < 0) ++ return err; ++ ++ return !err; ++} ++EXPORT_SYMBOL(bsp_sync_fence_wait_async); ++ ++int bsp_sync_fence_cancel_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter) ++{ ++ unsigned long flags; ++ int ret = 0; ++ ++ spin_lock_irqsave(&fence->wq.lock, flags); ++ if (!list_empty(&waiter->work.task_list)) ++ list_del_init(&waiter->work.task_list); ++ else ++ ret = -ENOENT; ++ spin_unlock_irqrestore(&fence->wq.lock, flags); ++ return ret; ++} ++EXPORT_SYMBOL(bsp_sync_fence_cancel_async); ++ ++int bsp_sync_fence_wait(struct sync_fence *fence, long timeout) ++{ ++ long ret; ++ ++ if (timeout < 0) ++ timeout = MAX_SCHEDULE_TIMEOUT; ++ else ++ timeout = msecs_to_jiffies(timeout); ++ ++ ret = wait_event_interruptible_timeout(fence->wq, ++ atomic_read(&fence->status) <= 0, ++ timeout); ++ ++ if (ret < 0) { ++ return ret; ++ } else if (ret == 0) { ++ if (timeout) { ++ pr_info("fence timeout on [%p] after %dms\n", fence, ++ jiffies_to_msecs(timeout)); ++ bsp_sync_dump(); ++ } ++ return -ETIME; ++ } ++ ++ ret = atomic_read(&fence->status); ++ if (ret) { ++ pr_info("fence error %ld on [%p]\n", ret, fence); ++ bsp_sync_dump(); ++ } ++ return ret; ++} ++EXPORT_SYMBOL(bsp_sync_fence_wait); ++#endif ++ ++static const char *android_fence_get_driver_name(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ return parent->ops->driver_name; ++} ++ ++static const char *android_fence_get_timeline_name(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ return parent->name; ++} ++ ++static void android_fence_release(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ unsigned long flags; ++ ++ spin_lock_irqsave(fence->lock, flags); ++ list_del(&pt->child_list); ++ if (WARN_ON_ONCE(!list_empty(&pt->active_list))) ++ list_del(&pt->active_list); ++ spin_unlock_irqrestore(fence->lock, flags); ++ ++ if (parent->ops->free_pt) ++ parent->ops->free_pt(pt); ++ ++ sync_timeline_put(parent); ++ fence_free(&pt->base); ++} ++ ++static bool android_fence_signaled(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ int ret; ++ ++ ret = parent->ops->has_signaled(pt); ++ if (ret < 0) ++ fence->status = ret; ++ return ret; ++} ++ ++static bool android_fence_enable_signaling(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (android_fence_signaled(fence)) ++ return false; ++ ++ list_add_tail(&pt->active_list, &parent->active_list_head); ++ return true; ++} ++ ++static void android_fence_disable_signaling(struct fence *fence) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ ++ list_del_init(&pt->active_list); ++} ++ ++static int android_fence_fill_driver_data(struct fence *fence, ++ void *data, int size) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (!parent->ops->fill_driver_data) ++ return 0; ++ return parent->ops->fill_driver_data(pt, data, size); ++} ++ ++static void android_fence_value_str(struct fence *fence, ++ char *str, int size) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (!parent->ops->pt_value_str) { ++ if (size) ++ *str = 0; ++ return; ++ } ++ parent->ops->pt_value_str(pt, str, size); ++} ++ ++static void android_fence_timeline_value_str(struct fence *fence, ++ char *str, int size) ++{ ++ struct sync_pt *pt = container_of(fence, struct sync_pt, base); ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (!parent->ops->timeline_value_str) { ++ if (size) ++ *str = 0; ++ return; ++ } ++ parent->ops->timeline_value_str(parent, str, size); ++} ++ ++static const struct fence_ops android_fence_ops = { ++ .get_driver_name = android_fence_get_driver_name, ++ .get_timeline_name = android_fence_get_timeline_name, ++ .enable_signaling = android_fence_enable_signaling, ++ .disable_signaling = android_fence_disable_signaling, ++ .signaled = android_fence_signaled, ++ .wait = fence_default_wait, ++ .release = android_fence_release, ++ .fill_driver_data = android_fence_fill_driver_data, ++ .fence_value_str = android_fence_value_str, ++ .timeline_value_str = android_fence_timeline_value_str, ++}; ++ ++#if 0 ++static void sync_fence_free(struct kref *kref) ++{ ++ struct sync_fence *fence = container_of(kref, struct sync_fence, kref); ++ int i; ++ ++ for (i = 0; i < fence->num_fences; ++i) { ++ fence_remove_callback(fence->cbs[i].sync_pt, &fence->cbs[i].cb); ++ fence_put(fence->cbs[i].sync_pt); ++ } ++ ++ kfree(fence); ++} ++ ++static int sync_fence_release(struct inode *inode, struct file *file) ++{ ++ struct sync_fence *fence = file->private_data; ++ ++ bsp_sync_fence_debug_remove(fence); ++ ++ kref_put(&fence->kref, sync_fence_free); ++ return 0; ++} ++ ++static unsigned int sync_fence_poll(struct file *file, poll_table *wait) ++{ ++ struct sync_fence *fence = file->private_data; ++ int status; ++ ++ poll_wait(file, &fence->wq, wait); ++ ++ status = atomic_read(&fence->status); ++ ++ if (!status) ++ return POLLIN; ++ else if (status < 0) ++ return POLLERR; ++ return 0; ++} ++ ++static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) ++{ ++ __s32 value; ++ ++ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) ++ return -EFAULT; ++ ++ return bsp_sync_fence_wait(fence, value); ++} ++ ++static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) ++{ ++ int fd = get_unused_fd_flags(O_CLOEXEC); ++ int err; ++ struct sync_fence *fence2, *fence3; ++ struct sync_merge_data data; ++ ++ if (fd < 0) ++ return fd; ++ ++ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { ++ err = -EFAULT; ++ goto err_put_fd; ++ } ++ ++ fence2 = bsp_sync_fence_fdget(data.fd2); ++ if (fence2 == NULL) { ++ err = -ENOENT; ++ goto err_put_fd; ++ } ++ ++ data.name[sizeof(data.name) - 1] = '\0'; ++ fence3 = bsp_sync_fence_merge(data.name, fence, fence2); ++ if (fence3 == NULL) { ++ err = -ENOMEM; ++ goto err_put_fence2; ++ } ++ ++ data.fence = fd; ++ if (copy_to_user((void __user *)arg, &data, sizeof(data))) { ++ err = -EFAULT; ++ goto err_put_fence3; ++ } ++ ++ bsp_sync_fence_install(fence3, fd); ++ bsp_sync_fence_put(fence2); ++ return 0; ++ ++err_put_fence3: ++ bsp_sync_fence_put(fence3); ++ ++err_put_fence2: ++ bsp_sync_fence_put(fence2); ++ ++err_put_fd: ++ put_unused_fd(fd); ++ return err; ++} ++ ++static int sync_fill_pt_info(struct fence *fence, void *data, int size) ++{ ++ struct sync_pt_info *info = data; ++ int ret; ++ ++ if (size < sizeof(struct sync_pt_info)) ++ return -ENOMEM; ++ ++ info->len = sizeof(struct sync_pt_info); ++ ++ if (fence->ops->fill_driver_data) { ++ ret = fence->ops->fill_driver_data(fence, info->driver_data, ++ size - sizeof(*info)); ++ if (ret < 0) ++ return ret; ++ ++ info->len += ret; ++ } ++ ++ strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), ++ sizeof(info->obj_name)); ++ strlcpy(info->driver_name, fence->ops->get_driver_name(fence), ++ sizeof(info->driver_name)); ++ if (fence_is_signaled(fence)) ++ info->status = fence->status >= 0 ? 1 : fence->status; ++ else ++ info->status = 0; ++ info->timestamp_ns = ktime_to_ns(fence->timestamp); ++ ++ return info->len; ++} ++ ++static long sync_fence_ioctl_fence_info(struct sync_fence *fence, ++ unsigned long arg) ++{ ++ struct sync_fence_info_data *data; ++ __u32 size; ++ __u32 len = 0; ++ int ret, i; ++ ++ if (copy_from_user(&size, (void __user *)arg, sizeof(size))) ++ return -EFAULT; ++ ++ if (size < sizeof(struct sync_fence_info_data)) ++ return -EINVAL; ++ ++ if (size > 4096) ++ size = 4096; ++ ++ data = kzalloc(size, GFP_KERNEL); ++ if (data == NULL) ++ return -ENOMEM; ++ ++ strlcpy(data->name, fence->name, sizeof(data->name)); ++ data->status = atomic_read(&fence->status); ++ if (data->status >= 0) ++ data->status = !data->status; ++ ++ len = sizeof(struct sync_fence_info_data); ++ ++ for (i = 0; i < fence->num_fences; ++i) { ++ struct fence *pt = fence->cbs[i].sync_pt; ++ ++ ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len); ++ ++ if (ret < 0) ++ goto out; ++ ++ len += ret; ++ } ++ ++ data->len = len; ++ ++ if (copy_to_user((void __user *)arg, data, len)) ++ ret = -EFAULT; ++ else ++ ret = 0; ++ ++out: ++ kfree(data); ++ ++ return ret; ++} ++ ++static long sync_fence_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct sync_fence *fence = file->private_data; ++ ++ switch (cmd) { ++ case SYNC_IOC_WAIT: ++ return sync_fence_ioctl_wait(fence, arg); ++ ++ case SYNC_IOC_MERGE: ++ return sync_fence_ioctl_merge(fence, arg); ++ ++ case SYNC_IOC_FENCE_INFO: ++ return sync_fence_ioctl_fence_info(fence, arg); ++ ++ default: ++ return -ENOTTY; ++ } ++} ++ ++static const struct file_operations sync_fence_fops = { ++ .release = sync_fence_release, ++ .poll = sync_fence_poll, ++ .unlocked_ioctl = sync_fence_ioctl, ++ .compat_ioctl = sync_fence_ioctl, ++}; ++#endif ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync.h.patch new file mode 100644 index 00000000..630dba81 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync.h.patch @@ -0,0 +1,366 @@ +--- linux-4.9.37/drivers/fence/sync.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/sync.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,363 @@ ++/* ++ * include/linux/sync.h ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_SYNC_H ++#define _LINUX_SYNC_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "_sync.h" ++ ++struct sync_timeline; ++struct sync_pt; ++#if 0 ++struct sync_fence; ++#endif ++ ++/** ++ * struct sync_timeline_ops - sync object implementation ops ++ * @driver_name: name of the implementation ++ * @dup: duplicate a sync_pt ++ * @has_signaled: returns: ++ * 1 if pt has signaled ++ * 0 if pt has not signaled ++ * <0 on error ++ * @compare: returns: ++ * 1 if b will signal before a ++ * 0 if a and b will signal at the same time ++ * -1 if a will signal before b ++ * @free_pt: called before sync_pt is freed ++ * @release_obj: called before sync_timeline is freed ++ * @fill_driver_data: write implementation specific driver data to data. ++ * should return an error if there is not enough room ++ * as specified by size. This information is returned ++ * to userspace by SYNC_IOC_FENCE_INFO. ++ * @timeline_value_str: fill str with the value of the sync_timeline's counter ++ * @pt_value_str: fill str with the value of the sync_pt ++ */ ++struct sync_timeline_ops { ++ const char *driver_name; ++ ++ /* required */ ++ struct sync_pt * (*dup)(struct sync_pt *pt); ++ ++ /* required */ ++ int (*has_signaled)(struct sync_pt *pt); ++ ++ /* required */ ++ int (*compare)(struct sync_pt *a, struct sync_pt *b); ++ ++ /* optional */ ++ void (*free_pt)(struct sync_pt *sync_pt); ++ ++ /* optional */ ++ void (*release_obj)(struct sync_timeline *sync_timeline); ++ ++ /* optional */ ++ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size); ++ ++ /* optional */ ++ void (*timeline_value_str)(struct sync_timeline *timeline, char *str, ++ int size); ++ ++ /* optional */ ++ void (*pt_value_str)(struct sync_pt *pt, char *str, int size); ++}; ++ ++/** ++ * struct sync_timeline - sync object ++ * @kref: reference count on fence. ++ * @ops: ops that define the implementation of the sync_timeline ++ * @name: name of the sync_timeline. Useful for debugging ++ * @destroyed: set when sync_timeline is destroyed ++ * @child_list_head: list of children sync_pts for this sync_timeline ++ * @child_list_lock: lock protecting @child_list_head, destroyed, and ++ * sync_pt.status ++ * @active_list_head: list of active (unsignaled/errored) sync_pts ++ * @sync_timeline_list: membership in global sync_timeline_list ++ */ ++struct sync_timeline { ++ struct kref kref; ++ const struct sync_timeline_ops *ops; ++ char name[32]; ++ ++ /* protected by child_list_lock */ ++ bool destroyed; ++ int context, value; ++ ++ struct list_head child_list_head; ++ spinlock_t child_list_lock; ++ ++ struct list_head active_list_head; ++ ++#ifdef CONFIG_DEBUG_FS ++ struct list_head sync_timeline_list; ++#endif ++}; ++ ++/** ++ * struct sync_pt - sync point ++ * @fence: base fence class ++ * @child_list: membership in sync_timeline.child_list_head ++ * @active_list: membership in sync_timeline.active_list_head ++ * @signaled_list: membership in temporary signaled_list on stack ++ * @fence: sync_fence to which the sync_pt belongs ++ * @pt_list: membership in sync_fence.pt_list_head ++ * @status: 1: signaled, 0:active, <0: error ++ * @timestamp: time which sync_pt status transitioned from active to ++ * signaled or error. ++ */ ++struct sync_pt { ++ struct fence base; ++ ++ struct list_head child_list; ++ struct list_head active_list; ++}; ++ ++static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt) ++{ ++ return container_of(pt->base.lock, struct sync_timeline, ++ child_list_lock); ++} ++ ++#if 0 ++struct sync_fence_cb { ++ struct fence_cb cb; ++ struct fence *sync_pt; ++ struct sync_fence *fence; ++}; ++ ++/** ++ * struct sync_fence - sync fence ++ * @file: file representing this fence ++ * @kref: reference count on fence. ++ * @name: name of sync_fence. Useful for debugging ++ * @pt_list_head: list of sync_pts in the fence. immutable once fence ++ * is created ++ * @status: 0: signaled, >0:active, <0: error ++ * ++ * @wq: wait queue for fence signaling ++ * @sync_fence_list: membership in global fence list ++ */ ++struct sync_fence { ++ struct file *file; ++ struct kref kref; ++ char name[32]; ++#ifdef CONFIG_DEBUG_FS ++ struct list_head sync_fence_list; ++#endif ++ int num_fences; ++ ++ wait_queue_head_t wq; ++ atomic_t status; ++ ++ struct sync_fence_cb cbs[]; ++}; ++ ++struct sync_fence_waiter; ++typedef void (*sync_callback_t)(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter); ++ ++/** ++ * struct sync_fence_waiter - metadata for asynchronous waiter on a fence ++ * @waiter_list: membership in sync_fence.waiter_list_head ++ * @callback: function pointer to call when fence signals ++ * @callback_data: pointer to pass to @callback ++ */ ++struct sync_fence_waiter { ++ wait_queue_t work; ++ sync_callback_t callback; ++}; ++ ++static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter, ++ sync_callback_t callback) ++{ ++ INIT_LIST_HEAD(&waiter->work.task_list); ++ waiter->callback = callback; ++} ++#endif ++ ++/* ++ * API for sync_timeline implementers ++ */ ++ ++/** ++ * sync_timeline_create() - creates a sync object ++ * @ops: specifies the implementation ops for the object ++ * @size: size to allocate for this obj ++ * @name: sync_timeline name ++ * ++ * Creates a new sync_timeline which will use the implementation specified by ++ * @ops. @size bytes will be allocated allowing for implementation specific ++ * data to be kept after the generic sync_timeline struct. ++ */ ++struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, ++ int size, const char *name); ++ ++/** ++ * sync_timeline_destroy() - destroys a sync object ++ * @obj: sync_timeline to destroy ++ * ++ * A sync implementation should call this when the @obj is going away ++ * (i.e. module unload.) @obj won't actually be freed until all its children ++ * sync_pts are freed. ++ */ ++void bsp_sync_timeline_destroy(struct sync_timeline *obj); ++ ++/** ++ * sync_timeline_signal() - signal a status change on a sync_timeline ++ * @obj: sync_timeline to signal ++ * ++ * A sync implementation should call this any time one of it's sync_pts ++ * has signaled or has an error condition. ++ */ ++void bsp_sync_timeline_signal(struct sync_timeline *obj); ++ ++/** ++ * sync_pt_create() - creates a sync pt ++ * @parent: sync_pt's parent sync_timeline ++ * @size: size to allocate for this pt ++ * ++ * Creates a new sync_pt as a child of @parent. @size bytes will be ++ * allocated allowing for implementation specific data to be kept after ++ * the generic sync_timeline struct. ++ */ ++struct sync_pt *bsp_sync_pt_create(struct sync_timeline *parent, int size); ++ ++/** ++ * sync_pt_free() - frees a sync pt ++ * @pt: sync_pt to free ++ * ++ * This should only be called on sync_pts which have been created but ++ * not added to a fence. ++ */ ++void bsp_sync_pt_free(struct sync_pt *pt); ++ ++#if 0 ++/** ++ * sync_fence_create() - creates a sync fence ++ * @name: name of fence to create ++ * @pt: sync_pt to add to the fence ++ * ++ * Creates a fence containg @pt. Once this is called, the fence takes ++ * ownership of @pt. ++ */ ++struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt); ++ ++/* ++ * API for sync_fence consumers ++ */ ++ ++/** ++ * sync_fence_merge() - merge two fences ++ * @name: name of new fence ++ * @a: fence a ++ * @b: fence b ++ * ++ * Creates a new fence which contains copies of all the sync_pts in both ++ * @a and @b. @a and @b remain valid, independent fences. ++ */ ++struct sync_fence *bsp_sync_fence_merge(const char *name, ++ struct sync_fence *a, struct sync_fence *b); ++ ++/** ++ * sync_fence_fdget() - get a fence from an fd ++ * @fd: fd referencing a fence ++ * ++ * Ensures @fd references a valid fence, increments the refcount of the backing ++ * file, and returns the fence. ++ */ ++struct sync_fence *bsp_sync_fence_fdget(int fd); ++ ++/** ++ * sync_fence_put() - puts a reference of a sync fence ++ * @fence: fence to put ++ * ++ * Puts a reference on @fence. If this is the last reference, the fence and ++ * all it's sync_pts will be freed ++ */ ++void bsp_sync_fence_put(struct sync_fence *fence); ++ ++/** ++ * sync_fence_install() - installs a fence into a file descriptor ++ * @fence: fence to install ++ * @fd: file descriptor in which to install the fence ++ * ++ * Installs @fence into @fd. @fd's should be acquired through ++ * get_unused_fd_flags(O_CLOEXEC). ++ */ ++void bsp_sync_fence_install(struct sync_fence *fence, int fd); ++ ++/** ++ * sync_fence_wait_async() - registers and async wait on the fence ++ * @fence: fence to wait on ++ * @waiter: waiter callback struck ++ * ++ * Returns 1 if @fence has already signaled. ++ * ++ * Registers a callback to be called when @fence signals or has an error. ++ * @waiter should be initialized with sync_fence_waiter_init(). ++ */ ++int bsp_sync_fence_wait_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter); ++ ++/** ++ * sync_fence_cancel_async() - cancels an async wait ++ * @fence: fence to wait on ++ * @waiter: waiter callback struck ++ * ++ * returns 0 if waiter was removed from fence's async waiter list. ++ * returns -ENOENT if waiter was not found on fence's async waiter list. ++ * ++ * Cancels a previously registered async wait. Will fail gracefully if ++ * @waiter was never registered or if @fence has already signaled @waiter. ++ */ ++int bsp_sync_fence_cancel_async(struct sync_fence *fence, ++ struct sync_fence_waiter *waiter); ++ ++/** ++ * sync_fence_wait() - wait on fence ++ * @fence: fence to wait on ++ * @tiemout: timeout in ms ++ * ++ * Wait for @fence to be signaled or have an error. Waits indefinitely ++ * if @timeout < 0 ++ */ ++int bsp_sync_fence_wait(struct sync_fence *fence, long timeout); ++ ++#ifdef CONFIG_DEBUG_FS ++ ++void bsp_sync_timeline_debug_add(struct sync_timeline *obj); ++void bsp_sync_timeline_debug_remove(struct sync_timeline *obj); ++void bsp_sync_fence_debug_add(struct sync_fence *fence); ++void bsp_sync_fence_debug_remove(struct sync_fence *fence); ++void bsp_sync_dump(void); ++ ++#else ++# define bsp_sync_timeline_debug_add(obj) ++# define bsp_sync_timeline_debug_remove(obj) ++# define bsp_sync_fence_debug_add(fence) ++# define bsp_sync_fence_debug_remove(fence) ++# define bsp_sync_dump() ++#endif ++int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, ++ int wake_flags, void *key); ++ ++#endif ++ ++#endif /* _LINUX_SYNC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync_debug.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync_debug.c.patch new file mode 100644 index 00000000..976ad796 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-fence-sync_debug.c.patch @@ -0,0 +1,262 @@ +--- linux-4.9.37/drivers/fence/sync_debug.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/fence/sync_debug.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,259 @@ ++/* ++ * drivers/base/sync.c ++ * ++ * Copyright (C) 2012 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sync.h" ++ ++#ifdef CONFIG_DEBUG_FS ++ ++static LIST_HEAD(sync_timeline_list_head); ++static DEFINE_SPINLOCK(sync_timeline_list_lock); ++#if 0 ++static LIST_HEAD(sync_fence_list_head); ++static DEFINE_SPINLOCK(sync_fence_list_lock); ++#endif ++ ++void bsp_sync_timeline_debug_add(struct sync_timeline *obj) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sync_timeline_list_lock, flags); ++ list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head); ++ spin_unlock_irqrestore(&sync_timeline_list_lock, flags); ++} ++ ++void bsp_sync_timeline_debug_remove(struct sync_timeline *obj) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sync_timeline_list_lock, flags); ++ list_del(&obj->sync_timeline_list); ++ spin_unlock_irqrestore(&sync_timeline_list_lock, flags); ++} ++ ++#if 0 ++void bsp_sync_fence_debug_add(struct sync_fence *fence) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sync_fence_list_lock, flags); ++ list_add_tail(&fence->sync_fence_list, &sync_fence_list_head); ++ spin_unlock_irqrestore(&sync_fence_list_lock, flags); ++} ++ ++void bsp_sync_fence_debug_remove(struct sync_fence *fence) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sync_fence_list_lock, flags); ++ list_del(&fence->sync_fence_list); ++ spin_unlock_irqrestore(&sync_fence_list_lock, flags); ++} ++#endif ++ ++static const char *sync_status_str(int status) ++{ ++ if (status == 0) ++ return "signaled"; ++ ++ if (status > 0) ++ return "active"; ++ ++ return "error"; ++} ++ ++static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) ++{ ++ int status = 1; ++ struct sync_timeline *parent = sync_pt_parent(pt); ++ ++ if (fence_is_signaled_locked(&pt->base)) ++ status = pt->base.status; ++ ++ seq_printf(s, " %s%spt %s", ++ fence ? parent->name : "", ++ fence ? "_" : "", ++ sync_status_str(status)); ++ ++ if (status <= 0) { ++ struct timespec64 ts64 = ++ ktime_to_timespec64(pt->base.timestamp); ++ ++ seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec); ++ } ++ ++ if (parent->ops->timeline_value_str && ++ parent->ops->pt_value_str) { ++ char value[64]; ++ ++ parent->ops->pt_value_str(pt, value, sizeof(value)); ++ seq_printf(s, ": %s", value); ++ if (fence) { ++ parent->ops->timeline_value_str(parent, value, ++ sizeof(value)); ++ seq_printf(s, " / %s", value); ++ } ++ } ++ ++ seq_puts(s, "\n"); ++} ++ ++static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) ++{ ++ struct list_head *pos = NULL; ++ unsigned long flags; ++ ++ seq_printf(s, "%s %s", obj->name, obj->ops->driver_name); ++ ++ if (obj->ops->timeline_value_str) { ++ char value[64]; ++ ++ obj->ops->timeline_value_str(obj, value, sizeof(value)); ++ seq_printf(s, ": %s", value); ++ } ++ ++ seq_puts(s, "\n"); ++ ++ spin_lock_irqsave(&obj->child_list_lock, flags); ++ list_for_each(pos, &obj->child_list_head) { ++ struct sync_pt *pt = ++ container_of(pos, struct sync_pt, child_list); ++ sync_print_pt(s, pt, false); ++ } ++ spin_unlock_irqrestore(&obj->child_list_lock, flags); ++} ++#if 0 ++static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) ++{ ++ wait_queue_t *pos; ++ unsigned long flags; ++ int i; ++ ++ seq_printf(s, "[%p] %s: %s\n", fence, fence->name, ++ sync_status_str(atomic_read(&fence->status))); ++ ++ for (i = 0; i < fence->num_fences; ++i) { ++ struct sync_pt *pt = ++ container_of(fence->cbs[i].sync_pt, ++ struct sync_pt, base); ++ ++ sync_print_pt(s, pt, true); ++ } ++ ++ spin_lock_irqsave(&fence->wq.lock, flags); ++ list_for_each_entry(pos, &fence->wq.task_list, task_list) { ++ struct sync_fence_waiter *waiter; ++ ++ if (pos->func != &bsp_sync_fence_wake_up_wq) ++ continue; ++ ++ waiter = container_of(pos, struct sync_fence_waiter, work); ++ ++ seq_printf(s, "waiter %pF\n", waiter->callback); ++ } ++ spin_unlock_irqrestore(&fence->wq.lock, flags); ++} ++#endif ++static int sync_debugfs_show(struct seq_file *s, void *unused) ++{ ++ unsigned long flags; ++ struct list_head *pos = NULL; ++ ++ seq_puts(s, "objs:\n--------------\n"); ++ ++ spin_lock_irqsave(&sync_timeline_list_lock, flags); ++ list_for_each(pos, &sync_timeline_list_head) { ++ struct sync_timeline *obj = ++ container_of(pos, struct sync_timeline, ++ sync_timeline_list); ++ ++ sync_print_obj(s, obj); ++ seq_puts(s, "\n"); ++ } ++ spin_unlock_irqrestore(&sync_timeline_list_lock, flags); ++ ++ seq_puts(s, "fences:\n--------------\n"); ++#if 0 ++ spin_lock_irqsave(&sync_fence_list_lock, flags); ++ list_for_each(pos, &sync_fence_list_head) { ++ struct sync_fence *fence = ++ container_of(pos, struct sync_fence, sync_fence_list); ++ ++ sync_print_fence(s, fence); ++ seq_puts(s, "\n"); ++ } ++ spin_unlock_irqrestore(&sync_fence_list_lock, flags); ++#endif ++ return 0; ++} ++ ++static int sync_debugfs_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, sync_debugfs_show, inode->i_private); ++} ++ ++static const struct file_operations sync_debugfs_fops = { ++ .open = sync_debugfs_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static int __init _sync_debugfs_init(void) ++{ ++ debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops); ++ return 0; ++} ++module_init(_sync_debugfs_init); ++ ++#define DUMP_CHUNK 256 ++static char sync_dump_buf[64 * 1024]; ++void bsp_sync_dump(void) ++{ ++ struct seq_file s = { ++ .buf = sync_dump_buf, ++ .size = sizeof(sync_dump_buf) - 1, ++ }; ++ int i; ++ ++ sync_debugfs_show(&s, NULL); ++ ++ for (i = 0; i < s.count; i += DUMP_CHUNK) { ++ if (((s.count - i) > DUMP_CHUNK) && (i + DUMP_CHUNK < sizeof(sync_dump_buf))) { ++ char c = s.buf[i + DUMP_CHUNK]; ++ ++ s.buf[i + DUMP_CHUNK] = 0; ++ pr_cont("%s", s.buf + i); ++ s.buf[i + DUMP_CHUNK] = c; ++ } else { ++ s.buf[s.count] = 0; ++ pr_cont("%s", s.buf + i); ++ } ++ } ++} ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-firmware-psci.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-firmware-psci.c.patch new file mode 100644 index 00000000..9688e9e3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-firmware-psci.c.patch @@ -0,0 +1,69 @@ +--- linux-4.9.37/drivers/firmware/psci.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/firmware/psci.c 2021-06-07 13:01:33.000000000 +0300 +@@ -59,7 +59,9 @@ + return cpu == resident_cpu; + } + +-struct psci_operations psci_ops; ++struct psci_operations psci_ops = { ++ .conduit = PSCI_CONDUIT_NONE, ++}; + + typedef unsigned long (psci_fn)(unsigned long, unsigned long, + unsigned long, unsigned long); +@@ -210,6 +212,22 @@ + 0, 0, 0); + } + ++static void set_conduit(enum psci_conduit conduit) ++{ ++ switch (conduit) { ++ case PSCI_CONDUIT_HVC: ++ invoke_psci_fn = __invoke_psci_fn_hvc; ++ break; ++ case PSCI_CONDUIT_SMC: ++ invoke_psci_fn = __invoke_psci_fn_smc; ++ break; ++ default: ++ WARN(1, "Unexpected PSCI conduit %d\n", conduit); ++ } ++ ++ psci_ops.conduit = conduit; ++} ++ + static int get_set_conduit_method(struct device_node *np) + { + const char *method; +@@ -222,9 +240,9 @@ + } + + if (!strcmp("hvc", method)) { +- invoke_psci_fn = __invoke_psci_fn_hvc; ++ set_conduit(PSCI_CONDUIT_HVC); + } else if (!strcmp("smc", method)) { +- invoke_psci_fn = __invoke_psci_fn_smc; ++ set_conduit(PSCI_CONDUIT_SMC); + } else { + pr_warn("invalid \"method\" property: %s\n", method); + return -EINVAL; +@@ -496,6 +514,8 @@ + static void __init psci_0_2_set_functions(void) + { + pr_info("Using standard PSCI v0.2 function IDs\n"); ++ psci_ops.get_version = psci_get_version; ++ + psci_function_id[PSCI_FN_CPU_SUSPEND] = + PSCI_FN_NATIVE(0_2, CPU_SUSPEND); + psci_ops.cpu_suspend = psci_cpu_suspend; +@@ -652,9 +672,9 @@ + pr_info("probing for conduit method from ACPI.\n"); + + if (acpi_psci_use_hvc()) +- invoke_psci_fn = __invoke_psci_fn_hvc; ++ set_conduit(PSCI_CONDUIT_HVC); + else +- invoke_psci_fn = __invoke_psci_fn_smc; ++ set_conduit(PSCI_CONDUIT_SMC); + + return psci_probe(); + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-Kconfig.patch new file mode 100644 index 00000000..4bbae481 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-Kconfig.patch @@ -0,0 +1,7 @@ +--- linux-4.9.37/drivers/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/goke/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,4 @@ ++menu "goke driver support" ++ ++source "drivers/goke/cma/Kconfig" ++endmenu diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-Makefile.patch new file mode 100644 index 00000000..7d51a63d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-Makefile.patch @@ -0,0 +1,4 @@ +--- linux-4.9.37/drivers/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/goke/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1 @@ ++obj-$(CONFIG_CMA) += cma/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-Kconfig.patch new file mode 100644 index 00000000..86e70c64 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-Kconfig.patch @@ -0,0 +1,19 @@ +--- linux-4.9.37/drivers/goke/cma/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/goke/cma/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,16 @@ ++ ++config CMA_MEM_SHARED ++ bool "Support sharing CMA memory with the heap" ++ depends on CMA && DMA_CMA ++ default no ++ help ++ Support sharing CMA memory with the heap. ++ ++config CMA_ADVANCE_SHARE ++ bool "Support cma advance share" ++ depends on CMA && DMA_CMA ++ select CMA_MEM_SHARED ++ default no ++ help ++ Support advance sharing CMA memory with the heap. ++ CMA Multiplex Ratio will be improved when this macro defined. diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-Makefile.patch new file mode 100644 index 00000000..d0d62ccc --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-Makefile.patch @@ -0,0 +1,5 @@ +--- linux-4.9.37/drivers/goke/cma/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/goke/cma/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,2 @@ ++ ++obj-$(CONFIG_CMA) += cma.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-cma.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-cma.c.patch new file mode 100644 index 00000000..223e1aa2 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-goke-cma-cma.c.patch @@ -0,0 +1,181 @@ +--- linux-4.9.37/drivers/goke/cma/cma.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/goke/cma/cma.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,178 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include ++ ++static u32 num_zones; ++static struct cma_zone zone[ZONE_MAX]; ++static int use_bootargs; ++ ++unsigned int get_cma_size(void) ++{ ++ int i; ++ u64 total = 0; ++ ++ for (i = 0; i < num_zones; i++) { ++ total += zone[i].nbytes; ++ } ++ ++ /* unit is M */ ++ return (unsigned int)(total >> 20); ++} ++ ++int is_cma_address(phys_addr_t phys, unsigned long size) ++{ ++ phys_addr_t start, end; ++ int i; ++ ++ for (i = 0; i < num_zones; i++) { ++ start = zone[i].phys_start; ++ end = zone[i].phys_start + zone[i].nbytes; ++ ++ if ((phys >= start) && ((phys + size) <= end)) { ++ /* ++ * Yes, found! ++ */ ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(is_cma_address); ++ ++static int __init mmz_parse_cmdline(char *s) ++{ ++ char *line = NULL; ++ char *tmp = NULL; ++ char tmpline[256]; ++ ++ if (s == NULL) { ++ pr_info("There is no cma zone!\n"); ++ return 0; ++ } ++ strncpy(tmpline, s, sizeof(tmpline)); ++ tmpline[sizeof(tmpline) - 1] = '\0'; ++ tmp = tmpline; ++ ++ while ((line = strsep(&tmp, ":")) != NULL) { ++ int i; ++ char *argv[6]; ++ ++ for (i = 0; (argv[i] = strsep(&line, ",")) != NULL;) ++ if (++i == ARRAY_SIZE(argv)) { ++ break; ++ } ++ ++ zone[num_zones].pdev.coherent_dma_mask = DMA_BIT_MASK(64); ++ if (i == 4) { ++ strlcpy(zone[num_zones].name, argv[0], NAME_LEN_MAX); ++ zone[num_zones].gfp = memparse(argv[1], NULL); ++ zone[num_zones].phys_start = memparse(argv[2], NULL); ++ zone[num_zones].nbytes = memparse(argv[3], NULL); ++ } ++ ++ else if (i == 6) { ++ strlcpy(zone[num_zones].name, argv[0], NAME_LEN_MAX); ++ zone[num_zones].gfp = memparse(argv[1], NULL); ++ zone[num_zones].phys_start = memparse(argv[2], NULL); ++ zone[num_zones].nbytes = memparse(argv[3], NULL); ++ zone[num_zones].alloc_type = memparse(argv[4], NULL); ++ zone[num_zones].block_align = memparse(argv[5], NULL); ++ } else { ++ pr_err("ion parameter is not correct\n"); ++ continue; ++ } ++ ++ num_zones++; ++ } ++ if (num_zones != 0) { ++ use_bootargs = 1; ++ } ++ ++ return 0; ++} ++early_param("mmz", mmz_parse_cmdline); ++ ++phys_addr_t goke_get_zones_start(void) ++{ ++ int i; ++ phys_addr_t lowest_zone_base = memblock_end_of_DRAM(); ++ ++ for (i = 0; i < num_zones; i++) { ++ if (lowest_zone_base > zone[i].phys_start) { ++ lowest_zone_base = zone[i].phys_start; ++ } ++ } ++ ++ return lowest_zone_base; ++} ++EXPORT_SYMBOL(goke_get_zones_start); ++ ++struct cma_zone *goke_get_cma_zone(const char *name) ++{ ++ int i = 0; ++ ++ for (i = 0; i < num_zones; i++) ++ if (strcmp(zone[i].name, name) == 0) { ++ break; ++ } ++ ++ if (i == num_zones) { ++ return NULL; ++ } ++ ++ return &zone[i]; ++} ++EXPORT_SYMBOL(goke_get_cma_zone); ++ ++struct device *goke_get_cma_device(const char *name) ++{ ++ int i = 0; ++ ++ for (i = 0; i < num_zones; i++) ++ if (strcmp(zone[i].name, name) == 0) { ++ break; ++ } ++ ++ if (i == num_zones) { ++ return NULL; ++ } ++ ++ return &zone[i].pdev; ++} ++EXPORT_SYMBOL(goke_get_cma_device); ++ ++int __init goke_declare_heap_memory(void) ++{ ++ int i; ++ int ret = 0; ++ ++ if (use_bootargs == 0) { ++ pr_info("cma zone is not set!\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < num_zones; i++) { ++ ret = dma_declare_contiguous(&zone[i].pdev, ++ zone[i].nbytes, zone[i].phys_start, 0); ++ if (ret) { ++ panic("declare cma zone %s base: %lux size:%lux MB failed. ret:%d", ++ zone[i].name, (unsigned long)zone[i].phys_start, ++ (unsigned long)zone[i].nbytes >> 20, ret); ++ } ++ zone[i].phys_start = cma_get_base(zone[i].pdev.cma_area); ++ zone[i].nbytes = cma_get_size(zone[i].pdev.cma_area); ++ ++ /* FIXME need to fix dma_declare_contiguous return value &&value type */ ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL(goke_declare_heap_memory); ++ ++static int mmz_setup(struct reserved_mem *rmem) ++{ ++ return 0; ++} ++RESERVEDMEM_OF_DECLARE(cma, "mmz", mmz_setup); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-gpio-gpio-pl061.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-gpio-gpio-pl061.c.patch new file mode 100644 index 00000000..4a90f34e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-gpio-gpio-pl061.c.patch @@ -0,0 +1,76 @@ +--- linux-4.9.37/drivers/gpio/gpio-pl061.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/gpio/gpio-pl061.c 2021-06-07 13:01:33.000000000 +0300 +@@ -208,6 +208,25 @@ + return 0; + } + ++#ifdef CONFIG_ARCH_GOKE ++static irqreturn_t pl061_irq_handler(int irq, void *data) ++{ ++ unsigned long pending; ++ int offset; ++ struct gpio_chip *gc = data; ++ struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); ++ ++ pending = readb(chip->base + GPIOMIS); ++ writeb(pending, chip->base + GPIOIC); ++ if (pending) { ++ for_each_set_bit(offset, &pending, PL061_GPIO_NR) ++ generic_handle_irq(irq_find_mapping(gc->irqdomain, ++ offset)); ++ } ++ ++ return IRQ_HANDLED; ++} ++#else + static void pl061_irq_handler(struct irq_desc *desc) + { + unsigned long pending; +@@ -227,6 +246,7 @@ + + chained_irq_exit(irqchip, desc); + } ++#endif + + static void pl061_irq_mask(struct irq_data *d) + { +@@ -308,7 +328,17 @@ + return -ENODEV; + } + } else { ++#ifdef CONFIG_ARCH_GOKE ++ if (dev->of_node) { ++ i = of_alias_get_id(dev->of_node, "gpio"); ++ chip->gc.base = i * PL061_GPIO_NR; ++ } ++ ++ if (chip->gc.base < 0) ++ chip->gc.base = -1; ++#else + chip->gc.base = -1; ++#endif + irq_base = 0; + } + +@@ -353,8 +383,21 @@ + dev_info(&adev->dev, "could not add irqchip\n"); + return ret; + } ++#ifdef CONFIG_ARCH_GOKE ++ ret = devm_request_irq(dev, irq, pl061_irq_handler, IRQF_SHARED, ++ dev_name(dev), &chip->gc); ++ if (ret) { ++ dev_info(dev, "request irq failed: %d\n", ret); ++ return ret; ++ } ++ ++ /* Set the parent IRQ for all affected IRQs */ ++ for (i = 0; i < chip->gc.ngpio; i++) ++ irq_set_parent(irq_find_mapping(chip->gc.irqdomain, i), irq); ++#else + gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip, + irq, pl061_irq_handler); ++#endif + + for (i = 0; i < PL061_GPIO_NR; i++) { + if (pdata) { diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-Kconfig.patch new file mode 100644 index 00000000..85584171 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-Kconfig.patch @@ -0,0 +1,40 @@ +--- linux-4.9.37/drivers/i2c/busses/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/i2c/busses/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -555,6 +555,16 @@ + This is a very simple bitbanging I2C driver utilizing the + arch-neutral GPIO API to control the SCL and SDA lines. + ++config I2C_GOKE ++ tristate "Goke I2C Controller" ++ depends on ARCH_GOKE ++ help ++ Say Y here to include support for Goke I2C controller in the ++ Goke SoCs. ++ ++ This driver can also be built as a module. If so, the module ++ will be called i2c. ++ + config I2C_HIGHLANDER + tristate "Highlander FPGA SMBus interface" + depends on SH_HIGHLANDER +@@ -1214,4 +1224,20 @@ + This driver can also be built as a module. If so, the module will be + called as i2c-opal. + ++config DMA_MSG_MIN_LEN ++ int "Goke I2C support DMA minimum LEN" ++ depends on I2C_GOKE ++ range 1 4090 ++ default 5 ++ help ++ The i2c_msg minimum LEN of i2c support DMA,range from 1 to 4091 ++ ++config DMA_MSG_MAX_LEN ++ int "Goke I2C support DMA maximum LEN" ++ depends on I2C_GOKE ++ range DMA_MSG_MIN_LEN 4090 ++ default 4090 ++ help ++ The i2c_msg maximum LEN of i2c support DMA,range from i2c_msg minimum LEN to 4090, ++ because DMA for 0xFFC one-time largest data transfers; + endmenu diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-Makefile.patch new file mode 100644 index 00000000..18637e52 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/i2c/busses/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/i2c/busses/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -51,6 +51,7 @@ + obj-$(CONFIG_I2C_EMEV2) += i2c-emev2.o + obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o + obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o ++obj-$(CONFIG_I2C_GOKE) += i2c-goke.o + obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o + obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o + obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-i2c-goke.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-i2c-goke.c.patch new file mode 100644 index 00000000..ce0a3d90 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-busses-i2c-goke.c.patch @@ -0,0 +1,970 @@ +--- linux-4.9.37/drivers/i2c/busses/i2c-goke.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/i2c/busses/i2c-goke.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,967 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * I2C Registers offsets ++ */ ++#define GOKE_I2C_GLB 0x0 ++#define GOKE_I2C_SCL_H 0x4 ++#define GOKE_I2C_SCL_L 0x8 ++#define GOKE_I2C_DATA1 0x10 ++#define GOKE_I2C_TXF 0x20 ++#define GOKE_I2C_RXF 0x24 ++#define GOKE_I2C_CMD_BASE 0x30 ++#define GOKE_I2C_LOOP1 0xb0 ++#define GOKE_I2C_DST1 0xb4 ++#define GOKE_I2C_TX_WATER 0xc8 ++#define GOKE_I2C_RX_WATER 0xcc ++#define GOKE_I2C_CTRL1 0xd0 ++#define GOKE_I2C_CTRL2 0xd4 ++#define GOKE_I2C_STAT 0xd8 ++#define GOKE_I2C_INTR_RAW 0xe0 ++#define GOKE_I2C_INTR_EN 0xe4 ++#define GOKE_I2C_INTR_STAT 0xe8 ++ ++/* ++ * I2C Global Config Register -- GOKE_I2C_GLB ++ */ ++#define GLB_EN_MASK BIT(0) ++#define GLB_SDA_HOLD_MASK GENMASK(23, 8) ++#define GLB_SDA_HOLD_SHIFT (8) ++ ++/* ++ * I2C Timing CMD Register -- GOKE_I2C_CMD_BASE + n * 4 (n = 0, 1, 2, ... 31) ++ */ ++#define CMD_EXIT 0x0 ++#define CMD_TX_S 0x1 ++#define CMD_TX_D1_2 0x4 ++#define CMD_TX_D1_1 0x5 ++#define CMD_TX_FIFO 0x9 ++#define CMD_RX_FIFO 0x12 ++#define CMD_RX_ACK 0x13 ++#define CMD_IGN_ACK 0x15 ++#define CMD_TX_ACK 0x16 ++#define CMD_TX_NACK 0x17 ++#define CMD_JMP1 0x18 ++#define CMD_UP_TXF 0x1d ++#define CMD_TX_RS 0x1e ++#define CMD_TX_P 0x1f ++ ++/* ++ * I2C Control Register 1 -- GOKE_I2C_CTRL1 ++ */ ++#define CTRL1_CMD_START_MASK BIT(0) ++#define CTRL1_DMA_OP_MASK (0x3 << 8) ++#define CTRL1_DMA_R (0x3 << 8) ++#define CTRL1_DMA_W (0x2 << 8) ++ ++/* ++ * I2C Status Register -- GOKE_I2C_STAT ++ */ ++#define STAT_RXF_NOE_MASK BIT(16) /* RX FIFO not empty flag */ ++#define STAT_TXF_NOF_MASK BIT(19) /* TX FIFO not full flag */ ++ ++ ++/* ++ * I2C Interrupt status and mask Register -- ++ * GOKE_I2C_INTR_RAW, GOKE_I2C_STAT, GOKE_I2C_INTR_STAT ++ */ ++#define INTR_ABORT_MASK (BIT(0) | BIT(11)) ++#define INTR_RX_MASK BIT(2) ++#define INTR_TX_MASK BIT(4) ++#define INTR_CMD_DONE_MASK BIT(12) ++#define INTR_USE_MASK (INTR_ABORT_MASK \ ++ |INTR_RX_MASK \ ++ | INTR_TX_MASK \ ++ | INTR_CMD_DONE_MASK) ++#define INTR_ALL_MASK GENMASK(31, 0) ++ ++#define I2C_DEFAULT_FREQUENCY 100000 ++#define I2C_TXF_DEPTH 64 ++#define I2C_RXF_DEPTH 64 ++#define I2C_TXF_WATER 32 ++#define I2C_RXF_WATER 32 ++#define I2C_WAIT_TIMEOUT 0x400 ++#define I2C_IRQ_TIMEOUT (msecs_to_jiffies(1000)) ++ ++ ++struct goke_i2c_dev { ++ struct device *dev; ++ struct i2c_adapter adap; ++ resource_size_t phybase; ++ void __iomem *base; ++ struct clk *clk; ++ int irq; ++ ++ unsigned int freq; ++ struct i2c_msg *msg; ++ unsigned int msg_num; ++ unsigned int msg_idx; ++ unsigned int msg_buf_ptr; ++ struct completion msg_complete; ++ ++ spinlock_t lock; ++ int status; ++}; ++static inline void goke_i2c_disable(struct goke_i2c_dev *i2c); ++static inline void goke_i2c_cfg_irq(struct goke_i2c_dev *i2c, ++ unsigned int flag); ++static inline unsigned int goke_i2c_clr_irq(struct goke_i2c_dev *i2c); ++static inline void goke_i2c_enable(struct goke_i2c_dev *i2c); ++ ++#define CHECK_SDA_IN_SHIFT (16) ++#define GPIO_MODE_SHIFT (8) ++#define FORCE_SCL_OEN_SHIFT (4) ++#define FORCE_SDA_OEN_SHIFT (0) ++ ++static void goke_i2c_rescue(struct goke_i2c_dev *i2c) ++{ ++ unsigned int val; ++ unsigned int time_cnt; ++ int index; ++ ++ goke_i2c_disable(i2c); ++ goke_i2c_cfg_irq(i2c, 0); ++ goke_i2c_clr_irq(i2c); ++ ++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); ++ writel(val, i2c->base + GOKE_I2C_CTRL2); ++ ++ time_cnt = 0; ++ do { ++ for (index = 0; index < 9; index++) { ++ val = (0x1 << GPIO_MODE_SHIFT) | 0x1; ++ writel(val, i2c->base + GOKE_I2C_CTRL2); ++ ++ udelay(5); ++ ++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); ++ writel(val, i2c->base + GOKE_I2C_CTRL2); ++ ++ udelay(5); ++ } ++ ++ time_cnt++; ++ if (time_cnt > I2C_WAIT_TIMEOUT) { ++ dev_err(i2c->dev, "wait Timeout!\n"); ++ goto disable_rescue; ++ } ++ ++ val = readl(i2c->base + GOKE_I2C_CTRL2); ++ } while(!(val & (0x1 << CHECK_SDA_IN_SHIFT))); ++ ++ ++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); ++ writel(val, i2c->base + GOKE_I2C_CTRL2); ++ ++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT); ++ writel(val, i2c->base + GOKE_I2C_CTRL2); ++ ++ udelay(10); ++ ++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); ++ writel(val, i2c->base + GOKE_I2C_CTRL2); ++ ++disable_rescue: ++ val = (0x1 << FORCE_SCL_OEN_SHIFT) | 0x1; ++ writel(val, i2c->base + GOKE_I2C_CTRL2); ++} ++ ++static inline void goke_i2c_disable(struct goke_i2c_dev *i2c) ++{ ++ unsigned int val; ++ ++ val = readl(i2c->base + GOKE_I2C_GLB); ++ val &= ~GLB_EN_MASK; ++ writel(val, i2c->base + GOKE_I2C_GLB); ++} ++ ++static inline void goke_i2c_enable(struct goke_i2c_dev *i2c) ++{ ++ unsigned int val; ++ ++ val = readl(i2c->base + GOKE_I2C_GLB); ++ val |= GLB_EN_MASK; ++ writel(val, i2c->base + GOKE_I2C_GLB); ++} ++ ++static inline void goke_i2c_cfg_irq(struct goke_i2c_dev *i2c, ++ unsigned int flag) ++{ ++ writel(flag, i2c->base + GOKE_I2C_INTR_EN); ++} ++ ++static inline void goke_i2c_disable_irq(struct goke_i2c_dev *i2c, ++ unsigned int flag) ++{ ++ unsigned int val; ++ ++ val = readl(i2c->base + GOKE_I2C_INTR_EN); ++ val &= ~flag; ++ writel(val, i2c->base + GOKE_I2C_INTR_EN); ++} ++ ++static inline unsigned int goke_i2c_clr_irq(struct goke_i2c_dev *i2c) ++{ ++ unsigned int val; ++ ++ val = readl(i2c->base + GOKE_I2C_INTR_STAT); ++ writel(INTR_ALL_MASK, i2c->base + GOKE_I2C_INTR_RAW); ++ ++ return val; ++} ++ ++static inline void goke_i2c_cmdreg_set(struct goke_i2c_dev *i2c, ++ unsigned int cmd, unsigned int *offset) ++{ ++ dev_dbg(i2c->dev, "i2c reg: offset=0x%x, cmd=0x%x...\n", ++ *offset * 4, cmd); ++ writel(cmd, i2c->base + GOKE_I2C_CMD_BASE + *offset * 4); ++ (*offset)++; ++} ++ ++/* ++ * config i2c slave addr ++ */ ++static inline void goke_i2c_set_addr(struct goke_i2c_dev *i2c) ++{ ++ struct i2c_msg *msg = i2c->msg; ++ u16 addr; ++ ++ if (msg->flags & I2C_M_TEN) { ++ /* First byte is 11110XX0 where XX is upper 2 bits */ ++ addr = ((msg->addr & 0x300) << 1) | 0xf000; ++ if (msg->flags & I2C_M_RD) { ++ addr |= 1 << 8; ++ } ++ ++ /* Second byte is the remaining 8 bits */ ++ addr |= msg->addr & 0xff; ++ } else { ++ addr = (msg->addr & 0x7f) << 1; ++ if (msg->flags & I2C_M_RD) { ++ addr |= 1; ++ } ++ } ++ ++ writel(addr, i2c->base + GOKE_I2C_DATA1); ++} ++ ++/* ++ * Start command sequence ++ */ ++static inline void goke_i2c_start_cmd(struct goke_i2c_dev *i2c) ++{ ++ unsigned int val; ++ ++ val = readl(i2c->base + GOKE_I2C_CTRL1); ++ val |= CTRL1_CMD_START_MASK; ++ writel(val, i2c->base + GOKE_I2C_CTRL1); ++} ++ ++static int goke_i2c_wait_rx_noempty(struct goke_i2c_dev *i2c) ++{ ++ unsigned int time_cnt = 0; ++ unsigned int val; ++ ++ do { ++ val = readl(i2c->base + GOKE_I2C_STAT); ++ if (val & STAT_RXF_NOE_MASK) { ++ return 0; ++ } ++ ++ udelay(50); ++ } while (time_cnt++ < I2C_WAIT_TIMEOUT); ++ ++ goke_i2c_rescue(i2c); ++ ++ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", ++ readl(i2c->base + GOKE_I2C_INTR_RAW), val); ++ return -EIO; ++} ++ ++static int goke_i2c_wait_tx_nofull(struct goke_i2c_dev *i2c) ++{ ++ unsigned int time_cnt = 0; ++ unsigned int val; ++ ++ do { ++ val = readl(i2c->base + GOKE_I2C_STAT); ++ if (val & STAT_TXF_NOF_MASK) { ++ return 0; ++ } ++ ++ udelay(50); ++ } while (time_cnt++ < I2C_WAIT_TIMEOUT); ++ ++ goke_i2c_rescue(i2c); ++ ++ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", ++ readl(i2c->base + GOKE_I2C_INTR_RAW), val); ++ return -EIO; ++} ++ ++static int goke_i2c_wait_idle(struct goke_i2c_dev *i2c) ++{ ++ unsigned int time_cnt = 0; ++ unsigned int val; ++ ++ do { ++ val = readl(i2c->base + GOKE_I2C_INTR_RAW); ++ if (val & (INTR_ABORT_MASK)) { ++ dev_err(i2c->dev, "wait idle abort!, RIS: 0x%x\n", ++ val); ++ return -EIO; ++ } ++ ++ if (val & INTR_CMD_DONE_MASK) { ++ return 0; ++ } ++ ++ udelay(50); ++ } while (time_cnt++ < I2C_WAIT_TIMEOUT); ++ ++ goke_i2c_rescue(i2c); ++ ++ dev_err(i2c->dev, "wait idle timeout, RIS: 0x%x, SR: 0x%x\n", ++ val, readl(i2c->base + GOKE_I2C_STAT)); ++ ++ return -EIO; ++} ++ ++static void goke_i2c_set_freq(struct goke_i2c_dev *i2c) ++{ ++ unsigned int max_freq, freq; ++ unsigned int clk_rate; ++ unsigned int val; ++ ++ freq = i2c->freq; ++ clk_rate = clk_get_rate(i2c->clk); ++ max_freq = clk_rate >> 1; ++ ++ if (freq > max_freq) { ++ i2c->freq = max_freq; ++ freq = i2c->freq; ++ } ++ ++ if (!freq) { ++ pr_err("goke_i2c_set_freq:freq can't be zero!"); ++ return; ++ } ++ ++ if (freq <= 100000) { ++ /* in normal mode F_scl: freq ++ i2c_scl_hcnt = (F_i2c / F_scl) * 0.5 ++ i2c_scl_hcnt = (F_i2c / F_scl) * 0.5 ++ */ ++ val = clk_rate / (freq * 2); ++ writel(val, i2c->base + GOKE_I2C_SCL_H); ++ writel(val, i2c->base + GOKE_I2C_SCL_L); ++ } else { ++ /* in fast mode F_scl: freq ++ i2c_scl_hcnt = (F_i2c / F_scl) * 0.36 ++ i2c_scl_hcnt = (F_i2c / F_scl) * 0.64 ++ */ ++ val = ((clk_rate / 100) * 36) / freq; ++ writel(val, i2c->base + GOKE_I2C_SCL_H); ++ val = ((clk_rate / 100) * 64) / freq; ++ writel(val, i2c->base + GOKE_I2C_SCL_L); ++ } ++ ++ val = readl(i2c->base + GOKE_I2C_GLB); ++ val &= ~GLB_SDA_HOLD_MASK; ++ val |= ((0xa << GLB_SDA_HOLD_SHIFT) & GLB_SDA_HOLD_MASK); ++ writel(val, i2c->base + GOKE_I2C_GLB); ++} ++ ++/* ++ * set i2c controller TX and RX FIFO water ++ */ ++static inline void goke_i2c_set_water(struct goke_i2c_dev *i2c) ++{ ++ writel(I2C_TXF_WATER, i2c->base + GOKE_I2C_TX_WATER); ++ writel(I2C_RXF_WATER, i2c->base + GOKE_I2C_RX_WATER); ++} ++ ++/* ++ * initialise the controller, set i2c bus interface freq ++ */ ++static void goke_i2c_hw_init(struct goke_i2c_dev *i2c) ++{ ++ goke_i2c_disable(i2c); ++ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); ++ goke_i2c_set_freq(i2c); ++ goke_i2c_set_water(i2c); ++} ++ ++/* ++ * goke_i2c_cfg_cmd - config i2c controller command sequence ++ * ++ * After all the timing command is configured, ++ * and then start the command, you can i2c communication, ++ * and then only need to read and write i2c fifo. ++ */ ++static void goke_i2c_cfg_cmd(struct goke_i2c_dev *i2c) ++{ ++ struct i2c_msg *msg = i2c->msg; ++ int offset = 0; ++ ++ if (i2c->msg_idx == 0) { ++ goke_i2c_cmdreg_set(i2c, CMD_TX_S, &offset); ++ } else { ++ goke_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset); ++ } ++ ++ if (msg->flags & I2C_M_TEN) { ++ if (i2c->msg_idx == 0) { ++ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); ++ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); ++ } else { ++ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); ++ } ++ } else { ++ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); ++ } ++ ++ if (msg->flags & I2C_M_IGNORE_NAK) { ++ goke_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); ++ } else { ++ goke_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); ++ } ++ ++ if (msg->flags & I2C_M_RD) { ++ if (msg->len >= 2) { ++ writel(offset, i2c->base + GOKE_I2C_DST1); ++ writel(msg->len - 2, i2c->base + GOKE_I2C_LOOP1); ++ goke_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); ++ goke_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset); ++ goke_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); ++ } ++ goke_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); ++ goke_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset); ++ } else { ++ writel(offset, i2c->base + GOKE_I2C_DST1); ++ writel(msg->len - 1, i2c->base + GOKE_I2C_LOOP1); ++ goke_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); ++ goke_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); ++ ++ if (msg->flags & I2C_M_IGNORE_NAK) { ++ goke_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); ++ } else { ++ goke_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); ++ } ++ ++ goke_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); ++ } ++ ++ if ((i2c->msg_idx == (i2c->msg_num - 1)) || (msg->flags & I2C_M_STOP)) { ++ dev_dbg(i2c->dev, "run to %s %d...TX STOP\n", ++ __func__, __LINE__); ++ goke_i2c_cmdreg_set(i2c, CMD_TX_P, &offset); ++ } ++ ++ goke_i2c_cmdreg_set(i2c, CMD_EXIT, &offset); ++} ++ ++static int goke_i2c_polling_xfer_one_msg(struct goke_i2c_dev *i2c) ++{ ++ int status; ++ unsigned int val; ++ struct i2c_msg *msg = i2c->msg; ++ ++ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", ++ __func__, __LINE__, msg->flags, msg->len); ++ ++ goke_i2c_enable(i2c); ++ goke_i2c_clr_irq(i2c); ++ goke_i2c_set_addr(i2c); ++ goke_i2c_cfg_cmd(i2c); ++ goke_i2c_start_cmd(i2c); ++ ++ i2c->msg_buf_ptr = 0; ++ ++ if (msg->flags & I2C_M_RD) { ++ while (i2c->msg_buf_ptr < msg->len) { ++ status = goke_i2c_wait_rx_noempty(i2c); ++ if (status) { ++ goto end; ++ } ++ ++ val = readl(i2c->base + GOKE_I2C_RXF); ++ msg->buf[i2c->msg_buf_ptr] = val; ++ i2c->msg_buf_ptr++; ++ ++ } ++ } else { ++ while (i2c->msg_buf_ptr < msg->len) { ++ status = goke_i2c_wait_tx_nofull(i2c); ++ if (status) { ++ goto end; ++ } ++ ++ val = msg->buf[i2c->msg_buf_ptr]; ++ writel(val, i2c->base + GOKE_I2C_TXF); ++ i2c->msg_buf_ptr++; ++ } ++ } ++ ++ status = goke_i2c_wait_idle(i2c); ++end: ++ goke_i2c_disable(i2c); ++ ++ return status; ++} ++ ++static irqreturn_t goke_i2c_isr(int irq, void *dev_id) ++{ ++ struct goke_i2c_dev *i2c = dev_id; ++ unsigned int irq_status; ++ struct i2c_msg *msg = i2c->msg; ++ ++ spin_lock(&i2c->lock); ++ ++ irq_status = goke_i2c_clr_irq(i2c); ++ dev_dbg(i2c->dev, "%s RIS: 0x%x\n", __func__, irq_status); ++ ++ if (!irq_status) { ++ dev_dbg(i2c->dev, "no irq\n"); ++ goto end; ++ } ++ ++ if (irq_status & INTR_ABORT_MASK) { ++ dev_err(i2c->dev, "irq handle abort, RIS: 0x%x\n", ++ irq_status); ++ i2c->status = -EIO; ++ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); ++ ++ complete(&i2c->msg_complete); ++ goto end; ++ } ++ ++ if (msg->flags & I2C_M_RD) { ++ while ((readl(i2c->base + GOKE_I2C_STAT) & STAT_RXF_NOE_MASK) ++ && (i2c->msg_buf_ptr < msg->len)) { ++ msg->buf[i2c->msg_buf_ptr] = ++ readl(i2c->base + GOKE_I2C_RXF); ++ i2c->msg_buf_ptr++; ++ } ++ } else { ++ while ((readl(i2c->base + GOKE_I2C_STAT) & STAT_TXF_NOF_MASK) ++ && (i2c->msg_buf_ptr < msg->len)) { ++ writel(msg->buf[i2c->msg_buf_ptr], ++ i2c->base + GOKE_I2C_TXF); ++ i2c->msg_buf_ptr++; ++ } ++ } ++ ++ if (i2c->msg_buf_ptr >= msg->len) { ++ goke_i2c_disable_irq(i2c, INTR_TX_MASK | INTR_RX_MASK); ++ } ++ ++ if (irq_status & INTR_CMD_DONE_MASK) { ++ dev_dbg(i2c->dev, "cmd done\n"); ++ i2c->status = 0; ++ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); ++ ++ complete(&i2c->msg_complete); ++ } ++ ++end: ++ spin_unlock(&i2c->lock); ++ ++ return IRQ_HANDLED; ++} ++ ++static int goke_i2c_interrupt_xfer_one_msg(struct goke_i2c_dev *i2c) ++{ ++ int status; ++ struct i2c_msg *msg = i2c->msg; ++ unsigned long timeout; ++ unsigned long flags; ++ ++ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", ++ __func__, __LINE__, msg->flags, msg->len); ++ ++ reinit_completion(&i2c->msg_complete); ++ i2c->msg_buf_ptr = 0; ++ i2c->status = -EIO; ++ ++ spin_lock_irqsave(&i2c->lock, flags); ++ goke_i2c_enable(i2c); ++ goke_i2c_clr_irq(i2c); ++ if (msg->flags & I2C_M_RD) { ++ goke_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_TX_MASK); ++ } else { ++ goke_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_RX_MASK); ++ } ++ ++ goke_i2c_set_addr(i2c); ++ goke_i2c_cfg_cmd(i2c); ++ goke_i2c_start_cmd(i2c); ++ spin_unlock_irqrestore(&i2c->lock, flags); ++ ++ timeout = wait_for_completion_timeout(&i2c->msg_complete, ++ I2C_IRQ_TIMEOUT); ++ ++ spin_lock_irqsave(&i2c->lock, flags); ++ if (timeout == 0) { ++ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); ++ status = -EIO; ++ dev_err(i2c->dev, "%s timeout\n", ++ msg->flags & I2C_M_RD ? "rx" : "tx"); ++ } else { ++ status = i2c->status; ++ } ++ ++ goke_i2c_disable(i2c); ++ ++ spin_unlock_irqrestore(&i2c->lock, flags); ++ return status; ++} ++ ++/* ++ * Master transfer function ++ */ ++static int goke_i2c_xfer(struct i2c_adapter *adap, ++ struct i2c_msg *msgs, int num) ++{ ++ struct goke_i2c_dev *i2c = i2c_get_adapdata(adap); ++ int status = -EINVAL; ++ unsigned long flags; ++ ++ if (!msgs || (num <= 0)) { ++ dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n"); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&i2c->lock, flags); ++ ++ i2c->msg = msgs; ++ i2c->msg_num = num; ++ i2c->msg_idx = 0; ++ ++ /* FIXME: The wait_for_completion_timeout in goke_i2c_interrupt_xfer_one_msg ++ * function can not be locked by spin_lock_irqsave. And actually I2C interrupt ++ * tranfer is rarely used, so we ignore the irq setting to limit the interrupt ++ * way. But we keep these codes below, reserve for future modifications */ ++ ++ while (i2c->msg_idx < i2c->msg_num) { ++ if (i2c->irq >= 0) { ++ spin_unlock_irqrestore(&i2c->lock, flags); ++ status = goke_i2c_interrupt_xfer_one_msg(i2c); ++ spin_lock_irqsave(&i2c->lock, flags); ++ if (status) { ++ break; ++ } ++ } else { ++ status = goke_i2c_polling_xfer_one_msg(i2c); ++ if (status) { ++ break; ++ } ++ } ++ i2c->msg++; ++ i2c->msg_idx++; ++ } ++ ++ if (!status || i2c->msg_idx > 0) { ++ status = i2c->msg_idx; ++ } ++ ++ spin_unlock_irqrestore(&i2c->lock, flags); ++ return status; ++} ++ ++/* goke_i2c_break_polling_xfer ++ * ++ * I2c polling independent branch, Shielding interrupt interface ++ */ ++static int goke_i2c_break_polling_xfer(struct i2c_adapter *adap, ++ struct i2c_msg *msgs, int num) ++{ ++ struct goke_i2c_dev *i2c = i2c_get_adapdata(adap); ++ int status = -EINVAL; ++ unsigned long flags; ++ if (!msgs || (num <= 0)) { ++ dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n"); ++ return -EINVAL; ++ } ++ spin_lock_irqsave(&i2c->lock, flags); ++ i2c->msg = msgs; ++ i2c->msg_num = num; ++ i2c->msg_idx = 0; ++ while (i2c->msg_idx < i2c->msg_num) { ++ status = goke_i2c_polling_xfer_one_msg(i2c); ++ if (status) { ++ break; ++ } ++ i2c->msg++; ++ i2c->msg_idx++; ++ } ++ if (!status || i2c->msg_idx > 0) { ++ status = i2c->msg_idx; ++ } ++ spin_unlock_irqrestore(&i2c->lock, flags); ++ return status; ++} ++/* ++ * bsp_i2c_master_recv - issue a single I2C message in master receive mode ++ * @client: Handle to slave device ++ * @buf: Where to store data read from slave ++ * @count: How many bytes to read, must be less than 64k since msg.len is u16 ++ * ++ * Returns negative errno, or else the number of bytes read. ++ */ ++int gk_i2c_master_recv(const struct i2c_client *client, char *buf, ++ int count) ++{ ++ printk("Wrong interface call." ++ "bsp_i2c_transfer is the only interface to i2c read!!!\n"); ++ ++ return -EIO; ++} ++EXPORT_SYMBOL(gk_i2c_master_recv); ++ ++/*I2C WRITE* ++ * bsp_i2c_master_send - issue a single I2C message in master transmit mode ++ * @client: Handle to slave device ++ * @buf: Data that will be written to the slave ++ * @count: How many bytes to write, must be less than 64k since msg.len is u16 ++ * ++ * Returns negative errno, or else the number of bytes written. ++ */ ++int gk_i2c_master_send(const struct i2c_client *client, ++ const char *buf, int count) ++{ ++ struct i2c_adapter *adap = client->adapter; ++ struct i2c_msg msg; ++ int msgs_count; ++ ++ if ((client->addr > 0x3ff) ++ || (((client->flags & I2C_M_TEN) == 0) && (client->addr > 0x7f))) { ++ printk(KERN_ERR "dev address out of range\n"); ++ return -EINVAL; ++ } ++ ++ msg.addr = client->addr; ++ msg.flags = client->flags; ++ msg.len = count; ++ ++ if ((!buf)||(count < 0)) { ++ printk(KERN_ERR "buf == NULL || count < 0, Invalid argument!\n"); ++ return -EINVAL; ++ } ++ msg.buf = (__u8 *)buf; ++ ++ msgs_count = goke_i2c_break_polling_xfer(adap, &msg, 1); ++ ++ return (msgs_count == 1) ? count : -EIO; ++} ++EXPORT_SYMBOL(gk_i2c_master_send); ++ ++/** ++ * bsp_i2c_transfer - execute a single or combined I2C message ++ * @adap: Handle to I2C bus ++ * @msgs: One or more messages to execute before STOP is issued to ++ * terminate the operation; each message begins with a START. ++ * @num: Number of messages to be executed. ++ * ++ * Returns negative errno, else the number of messages executed. ++ * ++ * Note that there is no requirement that each message be sent to ++ * the same slave address, although that is the most common model. ++ */ ++int gk_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ++ int num) ++{ ++ int msgs_count; ++ ++ if((!adap)||(!msgs)) { ++ printk(KERN_ERR "adap == NULL || msgs == NULL, Invalid argument!\n"); ++ return -EINVAL; ++ } ++ ++ if ((msgs[0].addr > 0x3ff) ++ || (((msgs[0].flags & I2C_M_TEN) == 0) && (msgs[0].addr > 0x7f))) { ++ printk(KERN_ERR "msgs[0] dev address out of range\n"); ++ return -EINVAL; ++ } ++ ++ if ((msgs[1].addr > 0x3ff) ++ || (((msgs[1].flags & I2C_M_TEN) == 0) && (msgs[1].addr > 0x7f))) { ++ printk(KERN_ERR "msgs[1] dev address out of range\n"); ++ return -EINVAL; ++ } ++ ++ msgs_count = goke_i2c_xfer(adap, msgs, num); ++ ++ return msgs_count; ++} ++EXPORT_SYMBOL(gk_i2c_transfer); ++ ++static u32 goke_i2c_func(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR ++ | I2C_FUNC_PROTOCOL_MANGLING ++ | I2C_FUNC_SMBUS_WORD_DATA ++ | I2C_FUNC_SMBUS_BYTE_DATA ++ | I2C_FUNC_SMBUS_BYTE ++ | I2C_FUNC_SMBUS_I2C_BLOCK; ++} ++ ++static const struct i2c_algorithm goke_i2c_algo = { ++ .master_xfer = goke_i2c_xfer, ++ .functionality = goke_i2c_func, ++}; ++ ++static int goke_i2c_probe(struct platform_device *pdev) ++{ ++ int status; ++ struct goke_i2c_dev *i2c = NULL; ++ struct i2c_adapter *adap = NULL; ++ struct resource *res = NULL; ++ ++ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); ++ if (!i2c) { ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, i2c); ++ i2c->dev = &pdev->dev; ++ spin_lock_init(&i2c->lock); ++ init_completion(&i2c->msg_complete); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(i2c->dev, "Invalid mem resource./n"); ++ return -ENODEV; ++ } ++ ++ i2c->phybase = res->start; ++ i2c->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(i2c->base)) { ++ dev_err(i2c->dev, "cannot ioremap resource\n"); ++ return -ENOMEM; ++ } ++ ++ i2c->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(i2c->clk)) { ++ dev_err(i2c->dev, "cannot get clock\n"); ++ return -ENOENT; ++ } ++ clk_prepare_enable(i2c->clk); ++ ++ if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", ++ &i2c->freq)) { ++ dev_warn(i2c->dev, "setting default clock-frequency@%dHz\n", ++ I2C_DEFAULT_FREQUENCY); ++ i2c->freq = I2C_DEFAULT_FREQUENCY; ++ } ++ ++ /* i2c controller initialization, disable interrupt */ ++ goke_i2c_hw_init(i2c); ++ ++ i2c->irq = platform_get_irq(pdev, 0); ++ status = devm_request_irq(&pdev->dev, i2c->irq, goke_i2c_isr, ++ IRQF_SHARED, dev_name(&pdev->dev), i2c); ++ if (status) { ++ dev_dbg(i2c->dev, "falling back to polling mode"); ++ i2c->irq = -1; ++ } ++ ++ adap = &i2c->adap; ++ i2c_set_adapdata(adap, i2c); ++ adap->owner = THIS_MODULE; ++ strlcpy(adap->name, "goke-i2c", sizeof(adap->name)); ++ adap->dev.parent = &pdev->dev; ++ adap->dev.of_node = pdev->dev.of_node; ++ adap->algo = &goke_i2c_algo; ++ ++ /* Add the i2c adapter */ ++ status = i2c_add_adapter(adap); ++ if (status) { ++ dev_err(i2c->dev, "failed to add bus to i2c core\n"); ++ goto err_add_adapter; ++ } ++ ++ dev_info(i2c->dev, "%s%d@%dhz registered\n", ++ adap->name, adap->nr, i2c->freq); ++ ++ return 0; ++ ++err_add_adapter: ++ clk_disable_unprepare(i2c->clk); ++ return status; ++} ++ ++static int goke_i2c_remove(struct platform_device *pdev) ++{ ++ struct goke_i2c_dev *i2c = platform_get_drvdata(pdev); ++ if (i2c == NULL){ ++ printk("i2c remove err!!!\n"); ++ return 0; ++ } ++ clk_disable_unprepare(i2c->clk); ++ i2c_del_adapter(&i2c->adap); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static int goke_i2c_suspend(struct device *dev) ++{ ++ struct goke_i2c_dev *i2c = dev_get_drvdata(dev); ++ ++ i2c_lock_adapter(&i2c->adap); ++ clk_disable_unprepare(i2c->clk); ++ i2c_unlock_adapter(&i2c->adap); ++ ++ return 0; ++} ++ ++static int goke_i2c_resume(struct device *dev) ++{ ++ struct goke_i2c_dev *i2c = dev_get_drvdata(dev); ++ ++ i2c_lock_adapter(&i2c->adap); ++ clk_prepare_enable(i2c->clk); ++ goke_i2c_hw_init(i2c); ++ i2c_unlock_adapter(&i2c->adap); ++ ++ return 0; ++} ++#endif ++ ++static SIMPLE_DEV_PM_OPS(goke_i2c_dev_pm, goke_i2c_suspend, ++ goke_i2c_resume); ++ ++static const struct of_device_id goke_i2c_match[] = { ++ { .compatible = "goke,goke-i2c"}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, goke_i2c_match); ++ ++static struct platform_driver goke_i2c_driver = { ++ .driver = { ++ .name = "goke-i2c", ++ .of_match_table = goke_i2c_match, ++ .pm = &goke_i2c_dev_pm, ++ }, ++ .probe = goke_i2c_probe, ++ .remove = goke_i2c_remove, ++}; ++ ++module_platform_driver(goke_i2c_driver); ++ ++MODULE_AUTHOR("Goke"); ++MODULE_DESCRIPTION("GOKE I2C Bus driver"); ++MODULE_LICENSE("GPL v2"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-i2c-dev.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-i2c-dev.c.patch new file mode 100644 index 00000000..28443c2b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-i2c-i2c-dev.c.patch @@ -0,0 +1,24 @@ +--- linux-4.9.37/drivers/i2c/i2c-dev.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/i2c/i2c-dev.c 2021-06-07 13:01:33.000000000 +0300 +@@ -170,6 +170,9 @@ + if (count > 8192) + count = 8192; + ++ if (count == 0) ++ return -EINVAL; ++ + tmp = memdup_user(buf, count); + if (IS_ERR(tmp)) + return PTR_ERR(tmp); +@@ -273,6 +276,11 @@ + res = -EINVAL; + break; + } ++ ++ if (rdwr_pa[i].len == 0) { ++ res = -EINVAL; ++ break; ++ } + + data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf; + rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-irqchip-irq-gic-v3.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-irqchip-irq-gic-v3.c.patch new file mode 100644 index 00000000..d95919c6 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-irqchip-irq-gic-v3.c.patch @@ -0,0 +1,39 @@ +--- linux-4.9.37/drivers/irqchip/irq-gic-v3.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/irqchip/irq-gic-v3.c 2021-06-07 13:01:33.000000000 +0300 +@@ -120,11 +120,10 @@ + } + + #ifdef CONFIG_ARM64 +-static DEFINE_STATIC_KEY_FALSE(is_cavium_thunderx); + + static u64 __maybe_unused gic_read_iar(void) + { +- if (static_branch_unlikely(&is_cavium_thunderx)) ++ if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_23154)) + return gic_read_iar_cavium_thunderx(); + else + return gic_read_iar_common(); +@@ -905,14 +904,6 @@ + .select = gic_irq_domain_select, + }; + +-static void gicv3_enable_quirks(void) +-{ +-#ifdef CONFIG_ARM64 +- if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_23154)) +- static_branch_enable(&is_cavium_thunderx); +-#endif +-} +- + static int __init gic_init_bases(void __iomem *dist_base, + struct redist_region *rdist_regs, + u32 nr_redist_regions, +@@ -935,8 +926,6 @@ + gic_data.nr_redist_regions = nr_redist_regions; + gic_data.redist_stride = redist_stride; + +- gicv3_enable_quirks(); +- + /* + * Find out how many interrupts are supported. + * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-irqchip-irq-gic.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-irqchip-irq-gic.c.patch new file mode 100644 index 00000000..d244cb28 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-irqchip-irq-gic.c.patch @@ -0,0 +1,36 @@ +--- linux-4.9.37/drivers/irqchip/irq-gic.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/irqchip/irq-gic.c 2021-06-07 13:01:33.000000000 +0300 +@@ -1069,7 +1069,9 @@ + { + irq_hw_number_t hwirq_base; + int gic_irqs, irq_base, ret; +- ++ struct device_node *np; ++ void * sysctrl_reg_base; ++ int gic_dist_init_flag; + if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) { + /* Frankein-GIC without banked registers... */ + unsigned int cpu; +@@ -1149,7 +1151,21 @@ + goto error; + } + +- gic_dist_init(gic); ++#define GIC_DIST_INIT_FLAG 0x47444946 ++#define GIC_DIST_INIT_FLAG_OFFSET 0x0130 ++ /* 0x47444946('G''D''I''F') is abbreviation of GIC_DIST_INIT_FLAG. */ ++ ++ np = of_find_compatible_node(NULL, NULL, "goke,sysctrl"); ++ sysctrl_reg_base = of_iomap(np, 0); ++ gic_dist_init_flag = readl(sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET); ++ ++ if(gic_dist_init_flag != GIC_DIST_INIT_FLAG) { ++ printk("Gic dist init...\n"); ++ gic_dist_init(gic); ++ writel_relaxed(GIC_DIST_INIT_FLAG, sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET); ++ } else ++ printk("Gic dist not init...\n"); ++ + ret = gic_cpu_init(gic); + if (ret) + goto error; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-media-usb-uvc-uvc_video.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-media-usb-uvc-uvc_video.c.patch new file mode 100644 index 00000000..e60f4017 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-media-usb-uvc-uvc_video.c.patch @@ -0,0 +1,20 @@ +--- linux-4.9.37/drivers/media/usb/uvc/uvc_video.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/media/usb/uvc/uvc_video.c 2021-06-07 13:01:33.000000000 +0300 +@@ -1467,6 +1467,7 @@ + struct usb_host_endpoint *ep) + { + u16 psize; ++ u16 mult; + + switch (dev->speed) { + case USB_SPEED_SUPER: +@@ -1474,7 +1475,8 @@ + return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); + case USB_SPEED_HIGH: + psize = usb_endpoint_maxp(&ep->desc); +- return (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); ++ mult = usb_endpoint_maxp_mult(&ep->desc); ++ return (psize & 0x07ff) * mult; + case USB_SPEED_WIRELESS: + psize = usb_endpoint_maxp(&ep->desc); + return psize; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-media-v4l2-core-videobuf2-v4l2.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-media-v4l2-core-videobuf2-v4l2.c.patch new file mode 100644 index 00000000..04c4495f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-media-v4l2-core-videobuf2-v4l2.c.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/media/v4l2-core/videobuf2-v4l2.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/media/v4l2-core/videobuf2-v4l2.c 2021-06-07 13:01:33.000000000 +0300 +@@ -146,7 +146,6 @@ + return; + + check_once = true; +- WARN_ON(1); + + pr_warn("use of bytesused == 0 is deprecated and will be removed in the future,\n"); + if (vb->vb2_queue->allow_zero_bytesused) diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-Kconfig.patch new file mode 100644 index 00000000..b64df0f0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-Kconfig.patch @@ -0,0 +1,19 @@ +--- linux-4.9.37/drivers/mfd/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mfd/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -358,6 +358,16 @@ + help + Select this option to enable Hisilicon hi655x series pmic driver. + ++config MFD_GOKE_FMC ++ tristate "Goke Flash Memory Controller" ++ depends on OF ++ depends on ARCH_GOKE ++ select MFD_CORE ++ select REGMAP_MMIO ++ help ++ Select this option to enable the Goke Flash Memory ++ Controller(FMC) driver. ++ + config HTC_PASIC3 + tristate "HTC PASIC3 LED/DS1WM chip support" + select MFD_CORE diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-Makefile.patch new file mode 100644 index 00000000..05477958 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/mfd/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mfd/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -180,6 +180,7 @@ + obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o + obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o + obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o ++obj-$(CONFIG_MFD_GOKE_FMC) += goke_fmc.o + obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o + obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o + obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-goke_fmc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-goke_fmc.c.patch new file mode 100644 index 00000000..3b9822c8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mfd-goke_fmc.c.patch @@ -0,0 +1,124 @@ +--- linux-4.9.37/drivers/mfd/goke_fmc.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mfd/goke_fmc.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,121 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++unsigned char fmc_cs_user[FMC_MAX_CHIP_NUM]; ++ ++DEFINE_MUTEX(fmc_switch_mutex); ++EXPORT_SYMBOL_GPL(fmc_switch_mutex); ++ ++/* ------------------------------------------------------------------------ */ ++static const struct mfd_cell bsp_fmc_devs[] = { ++ { ++ .name = "bsp_spi_nor", ++ .of_compatible = "goke,fmc-spi-nor", ++ }, ++ { ++ .name = "bsp_spi_nand", ++ .of_compatible = "goke,fmc-spi-nand", ++ }, ++}; ++ ++static int bsp_fmc_probe(struct platform_device *pdev) ++{ ++ struct bsp_fmc *fmc; ++ struct resource *res; ++ struct device *dev = &pdev->dev; ++ int ret; ++ ++ fmc = devm_kzalloc(dev, sizeof(*fmc), GFP_KERNEL); ++ if (!fmc) { ++ return -ENOMEM; ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control"); ++ fmc->regbase = devm_ioremap_resource(dev, res); ++ if (IS_ERR(fmc->regbase)) { ++ return PTR_ERR(fmc->regbase); ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); ++ fmc->iobase = devm_ioremap_resource(dev, res); ++ if (IS_ERR(fmc->iobase)) { ++ return PTR_ERR(fmc->iobase); ++ } ++ ++ fmc->clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(fmc->clk)) { ++ return PTR_ERR(fmc->clk); ++ } ++ ++ if (of_property_read_u32(dev->of_node, "max-dma-size", &fmc->dma_len)) { ++ dev_err(dev, "Please set the suitable max-dma-size value !!!\n"); ++ return -ENOMEM; ++ } ++ ++ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); ++ if (ret) { ++ dev_warn(dev, "Unable to set dma mask\n"); ++ return ret; ++ } ++ ++ fmc->buffer = dmam_alloc_coherent(dev, fmc->dma_len, ++ &fmc->dma_buffer, GFP_KERNEL); ++ if (IS_ERR(fmc->buffer)) { ++ return PTR_ERR(fmc->buffer); ++ } ++ ++ mutex_init(&fmc->lock); ++ ++ platform_set_drvdata(pdev, fmc); ++ ++ ret = mfd_add_devices(dev, 0, bsp_fmc_devs, ++ ARRAY_SIZE(bsp_fmc_devs), NULL, 0, NULL); ++ if (ret) { ++ dev_err(dev, "add mfd devices failed: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int bsp_fmc_remove(struct platform_device *pdev) ++{ ++ struct bsp_fmc *fmc = platform_get_drvdata(pdev); ++ ++ dmam_free_coherent(&pdev->dev, fmc->dma_len, ++ fmc->buffer, fmc->dma_buffer); ++ mfd_remove_devices(&pdev->dev); ++ mutex_destroy(&fmc->lock); ++ ++ return 0; ++} ++ ++static const struct of_device_id bsp_fmc_of_match_tbl[] = { ++ { .compatible = "goke,fmc"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bsp_fmc_of_match_tbl); ++ ++static struct platform_driver bsp_fmc_driver = { ++ .driver = { ++ .name = "fmc", ++ .of_match_table = bsp_fmc_of_match_tbl, ++ }, ++ .probe = bsp_fmc_probe, ++ .remove = bsp_fmc_remove, ++}; ++module_platform_driver(bsp_fmc_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Goke Flash Memory Controller Driver"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-block.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-block.c.patch new file mode 100644 index 00000000..1b2e01f9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-block.c.patch @@ -0,0 +1,1092 @@ +--- linux-4.9.37/drivers/mmc/card/block.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/card/block.c 2021-06-07 13:01:33.000000000 +0300 +@@ -63,6 +63,8 @@ + #define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ + #define MMC_SANITIZE_REQ_TIMEOUT 240000 + #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) ++#define MMC_CMDQ_STOP_TIMEOUT_MS 100 ++#define MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD 6 /* microseconds */ + + #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ + (rq_data_dir(req) == WRITE)) +@@ -103,6 +105,7 @@ + #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ + #define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ + #define MMC_BLK_PACKED_CMD (1 << 2) /* MMC packed command support */ ++#define MMC_BLK_CMD_QUEUE (1 << 3) /* MMC command queue support */ + + unsigned int usage; + unsigned int read_only; +@@ -519,21 +522,40 @@ + + mrq.cmd = &cmd; + ++ if (mmc_card_cmdq(card)) { ++ err = mmc_cmdq_halt_on_empty_queue(card->host); ++ if (err) { ++ pr_err("%s: halt failed while doing %s err (%d)\n", ++ mmc_hostname(card->host), ++ __func__, err); ++ return err; ++ } ++ } ++ ++ if (mmc_card_doing_bkops(card)) { ++ err = mmc_stop_bkops(card); ++ if (err) { ++ dev_err(mmc_dev(card->host), ++ "%s: stop_bkops failed %d\n", __func__, err); ++ goto cmd_rel_host; ++ } ++ } ++ + err = mmc_blk_part_switch(card, md); + if (err) +- return err; ++ goto cmd_rel_host; + + if (idata->ic.is_acmd) { + err = mmc_app_cmd(card->host, card); + if (err) +- return err; ++ goto cmd_rel_host; + } + + if (is_rpmb) { + err = mmc_set_blockcount(card, data.blocks, + idata->ic.write_flag & (1 << 31)); + if (err) +- return err; ++ goto cmd_rel_host; + } + + if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) && +@@ -544,7 +566,7 @@ + pr_err("%s: ioctl_do_sanitize() failed. err = %d", + __func__, err); + +- return err; ++ goto cmd_rel_host; + } + + mmc_wait_for_req(card->host, &mrq); +@@ -552,12 +574,14 @@ + if (cmd.error) { + dev_err(mmc_dev(card->host), "%s: cmd error %d\n", + __func__, cmd.error); +- return cmd.error; ++ err = cmd.error; ++ goto cmd_rel_host; + } + if (data.error) { + dev_err(mmc_dev(card->host), "%s: data error %d\n", + __func__, data.error); +- return data.error; ++ err = data.error; ++ goto cmd_rel_host; + } + + /* +@@ -581,6 +605,13 @@ + __func__, status, err); + } + ++cmd_rel_host: ++ if (mmc_card_cmdq(card)) { ++ if (mmc_cmdq_halt(card->host, false)) ++ pr_err("%s: %s: cmdq unhalt failed\n", ++ mmc_hostname(card->host), __func__); ++ } ++ + return err; + } + +@@ -746,13 +777,64 @@ + #endif + }; + ++static int mmc_blk_cmdq_switch(struct mmc_card *card, ++ struct mmc_blk_data *md, bool enable) ++{ ++ int ret = 0; ++ bool cmdq_mode = !!mmc_card_cmdq(card); ++ struct mmc_host *host = card->host; ++ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; ++ ++ if (!(card->host->caps2 & MMC_CAP2_CMD_QUEUE) || ++ !card->ext_csd.cmdq_support || ++ (enable && !(md->flags & MMC_BLK_CMD_QUEUE)) || ++ (cmdq_mode == enable)) ++ return 0; ++ ++ if (enable) { ++ ret = mmc_set_blocklen(card, MMC_CARD_CMDQ_BLK_SIZE); ++ if (ret) { ++ pr_err("%s: failed (%d) to set block-size to %d\n", ++ __func__, ret, MMC_CARD_CMDQ_BLK_SIZE); ++ goto out; ++ } ++ ++ } else { ++ if (!test_bit(CMDQ_STATE_HALT, &ctx->curr_state)) { ++ ret = mmc_cmdq_halt(host, true); ++ if (ret) { ++ pr_err("%s: halt: failed: %d\n", ++ mmc_hostname(host), ret); ++ goto out; ++ } ++ } ++ } ++ ++ ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, ++ EXT_CSD_CMDQ, enable, ++ card->ext_csd.generic_cmd6_time); ++ if (ret) { ++ pr_err("%s: cmdq mode %sable failed %d\n", ++ md->disk->disk_name, enable ? "en" : "dis", ret); ++ goto out; ++ } ++ ++ if (enable) ++ mmc_card_set_cmdq(card); ++ else ++ mmc_card_clr_cmdq(card); ++out: ++ return ret; ++} ++ + static inline int mmc_blk_part_switch(struct mmc_card *card, + struct mmc_blk_data *md) + { + int ret; + struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); + +- if (main_md->part_curr == md->part_type) ++ if ((main_md->part_curr == md->part_type) && ++ (card->part_curr == md->part_type)) + return 0; + + if (mmc_card_mmc(card)) { +@@ -761,6 +843,13 @@ + if (md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) + mmc_retune_pause(card->host); + ++ if (md->part_type) { ++ /* disable CQ mode for non-user data partitions */ ++ ret = mmc_blk_cmdq_switch(card, md, false); ++ if (ret) ++ return ret; ++ } ++ + part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; + part_config |= md->part_type; + +@@ -774,6 +863,7 @@ + } + + card->ext_csd.part_config = part_config; ++ card->part_curr = md->part_type; + + if (main_md->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB) + mmc_retune_unpause(card->host); +@@ -2210,6 +2300,813 @@ + !(card->csd.cmdclass & CCC_BLOCK_WRITE); + } + ++/* prepare for non-data commands */ ++static struct mmc_cmdq_req *mmc_cmdq_prep_dcmd( ++ struct mmc_queue_req *mqrq, struct mmc_queue *mq) ++{ ++ struct request *req = mqrq->req; ++ struct mmc_cmdq_req *cmdq_req = &mqrq->cmdq_req; ++ ++ memset(&mqrq->cmdq_req, 0, sizeof(struct mmc_cmdq_req)); ++ ++ cmdq_req->mrq.data = NULL; ++ cmdq_req->cmd_flags = req->cmd_flags; ++ cmdq_req->mrq.req = mqrq->req; ++ req->special = mqrq; ++ cmdq_req->cmdq_req_flags |= DCMD; ++ cmdq_req->mrq.cmdq_req = cmdq_req; ++ ++ return &mqrq->cmdq_req; ++} ++ ++#define IS_RT_CLASS_REQ(x) \ ++ (IOPRIO_PRIO_CLASS(req_get_ioprio(x)) == IOPRIO_CLASS_RT) ++ ++static struct mmc_cmdq_req *mmc_blk_cmdq_rw_prep( ++ struct mmc_queue_req *mqrq, struct mmc_queue *mq) ++{ ++ struct mmc_card *card = mq->card; ++ struct request *req = mqrq->req; ++ struct mmc_blk_data *md = mq->data; ++ bool do_rel_wr = mmc_req_rel_wr(req) && (md->flags & MMC_BLK_REL_WR); ++ bool do_data_tag; ++ bool read_dir = (rq_data_dir(req) == READ); ++ bool prio = IS_RT_CLASS_REQ(req); ++ struct mmc_cmdq_req *cmdq_rq = &mqrq->cmdq_req; ++ ++ memset(&mqrq->cmdq_req, 0, sizeof(struct mmc_cmdq_req)); ++ ++ cmdq_rq->tag = req->tag; ++ if (read_dir) { ++ cmdq_rq->cmdq_req_flags |= DIR; ++ cmdq_rq->data.flags = MMC_DATA_READ; ++ } else { ++ cmdq_rq->data.flags = MMC_DATA_WRITE; ++ } ++ if (prio) ++ cmdq_rq->cmdq_req_flags |= PRIO; ++ ++ if (do_rel_wr) ++ cmdq_rq->cmdq_req_flags |= REL_WR; ++ ++ cmdq_rq->data.blocks = blk_rq_sectors(req); ++ cmdq_rq->blk_addr = blk_rq_pos(req); ++ cmdq_rq->data.blksz = MMC_CARD_CMDQ_BLK_SIZE; ++ ++ mmc_set_data_timeout(&cmdq_rq->data, card); ++ ++ do_data_tag = (card->ext_csd.data_tag_unit_size) && ++ (req->cmd_flags & REQ_META) && ++ (rq_data_dir(req) == WRITE) && ++ ((cmdq_rq->data.blocks * cmdq_rq->data.blksz) >= ++ card->ext_csd.data_tag_unit_size); ++ if (do_data_tag) ++ cmdq_rq->cmdq_req_flags |= DAT_TAG; ++ cmdq_rq->data.sg = mqrq->sg; ++ cmdq_rq->data.sg_len = mmc_queue_map_sg(mq, mqrq); ++ ++ /* ++ * Adjust the sg list so it is the same size as the ++ * request. ++ */ ++ if (cmdq_rq->data.blocks > card->host->max_blk_count) ++ cmdq_rq->data.blocks = card->host->max_blk_count; ++ ++ if (cmdq_rq->data.blocks != blk_rq_sectors(req)) { ++ int i, data_size = cmdq_rq->data.blocks << 9; ++ struct scatterlist *sg; ++ ++ for_each_sg(cmdq_rq->data.sg, sg, cmdq_rq->data.sg_len, i) { ++ data_size -= sg->length; ++ if (data_size <= 0) { ++ sg->length += data_size; ++ i++; ++ break; ++ } ++ } ++ cmdq_rq->data.sg_len = i; ++ } ++ ++ mqrq->cmdq_req.cmd_flags = req->cmd_flags; ++ mqrq->cmdq_req.mrq.req = mqrq->req; ++ mqrq->cmdq_req.mrq.cmdq_req = &mqrq->cmdq_req; ++ mqrq->cmdq_req.mrq.data = &mqrq->cmdq_req.data; ++ mqrq->req->special = mqrq; ++ ++ pr_debug("%s: %s: mrq: 0x%p req: 0x%p mqrq: 0x%p bytes to xf: %d mmc_cmdq_req: 0x%p card-addr: 0x%08x dir(r-1/w-0): %d\n", ++ mmc_hostname(card->host), __func__, &mqrq->cmdq_req.mrq, ++ mqrq->req, mqrq, (cmdq_rq->data.blocks * cmdq_rq->data.blksz), ++ cmdq_rq, cmdq_rq->blk_addr, ++ (cmdq_rq->cmdq_req_flags & DIR) ? 1 : 0); ++ ++ return &mqrq->cmdq_req; ++} ++ ++/* ++ * Complete reqs from block layer softirq context ++ * Invoked in irq context ++ */ ++void mmc_blk_cmdq_req_done(struct mmc_request *mrq) ++{ ++ struct request *req = mrq->req; ++ ++ blk_complete_request(req); ++} ++EXPORT_SYMBOL(mmc_blk_cmdq_req_done); ++ ++static int mmc_blk_cmdq_start_req(struct mmc_host *host, ++ struct mmc_cmdq_req *cmdq_req) ++{ ++ struct mmc_request *mrq = &cmdq_req->mrq; ++ ++ mrq->done = mmc_blk_cmdq_req_done; ++ return mmc_cmdq_start_req(host, cmdq_req); ++} ++ ++static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req) ++{ ++ struct mmc_queue_req *active_mqrq; ++ struct mmc_card *card = mq->card; ++ struct mmc_host *host = card->host; ++ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; ++ struct mmc_cmdq_req *mc_rq; ++ u8 active_small_sector_read = 0; ++ int ret = 0; ++ ++ BUG_ON((req->tag < 0) || (req->tag > card->ext_csd.cmdq_depth)); ++ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.data_active_reqs)); ++ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs)); ++ ++ active_mqrq = &mq->mqrq_cmdq[req->tag]; ++ active_mqrq->req = req; ++ ++ mc_rq = mmc_blk_cmdq_rw_prep(active_mqrq, mq); ++ ++ if (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD) { ++ unsigned int sectors = blk_rq_sectors(req); ++ ++ if (((sectors > 0) && (sectors < 8)) ++ && (rq_data_dir(req) == READ)) ++ active_small_sector_read = 1; ++ } ++ ret = mmc_blk_cmdq_start_req(card->host, mc_rq); ++ if (!ret && active_small_sector_read) ++ host->cmdq_ctx.active_small_sector_read_reqs++; ++ /* ++ * When in SVS2 on low load scenario and there are lots of requests ++ * queued for CMDQ we need to wait till the queue is empty to scale ++ * back up to Nominal even if there is a sudden increase in load. ++ * This impacts performance where lots of IO get executed in SVS2 ++ * frequency since the queue is full. As SVS2 is a low load use case ++ * we can serialize the requests and not queue them in parallel ++ * without impacting other use cases. This makes sure the queue gets ++ * empty faster and we will be able to scale up to Nominal frequency ++ * when needed. ++ */ ++ if (!ret) ++ wait_event_interruptible(ctx->queue_empty_wq, ++ (!ctx->active_reqs)); ++ ++ return ret; ++} ++ ++/* ++ * Issues a flush (dcmd) request ++ */ ++int mmc_blk_cmdq_issue_flush_rq(struct mmc_queue *mq, struct request *req) ++{ ++ int err; ++ struct mmc_queue_req *active_mqrq; ++ struct mmc_card *card = mq->card; ++ struct mmc_host *host; ++ struct mmc_cmdq_req *cmdq_req; ++ struct mmc_cmdq_context_info *ctx_info; ++ ++ BUG_ON(!card); ++ host = card->host; ++ BUG_ON(!host); ++ BUG_ON(req->tag > card->ext_csd.cmdq_depth); ++ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs)); ++ ++ ctx_info = &host->cmdq_ctx; ++ ++ set_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state); ++ ++ active_mqrq = &mq->mqrq_cmdq[req->tag]; ++ active_mqrq->req = req; ++ ++ cmdq_req = mmc_cmdq_prep_dcmd(active_mqrq, mq); ++ cmdq_req->cmdq_req_flags |= QBR; ++ cmdq_req->mrq.cmd = &cmdq_req->cmd; ++ cmdq_req->tag = req->tag; ++ ++ err = mmc_cmdq_prepare_flush(cmdq_req->mrq.cmd); ++ if (err) { ++ pr_err("%s: failed (%d) preparing flush req\n", ++ mmc_hostname(host), err); ++ return err; ++ } ++ err = mmc_blk_cmdq_start_req(card->host, cmdq_req); ++ return err; ++} ++EXPORT_SYMBOL(mmc_blk_cmdq_issue_flush_rq); ++ ++static inline int mmc_blk_cmdq_part_switch(struct mmc_card *card, ++ struct mmc_blk_data *md) ++{ ++ struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); ++ struct mmc_host *host = card->host; ++ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; ++ u8 part_config = card->ext_csd.part_config; ++ ++ if ((main_md->part_curr == md->part_type) && ++ (card->part_curr == md->part_type)) ++ return 0; ++ ++ WARN_ON(!((card->host->caps2 & MMC_CAP2_CMD_QUEUE) && ++ card->ext_csd.cmdq_support && ++ (md->flags & MMC_BLK_CMD_QUEUE))); ++ ++ if (!test_bit(CMDQ_STATE_HALT, &ctx->curr_state)) ++ WARN_ON(mmc_cmdq_halt(host, true)); ++ ++ /* disable CQ mode in card */ ++ if (mmc_card_cmdq(card)) { ++ WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, ++ EXT_CSD_CMDQ, 0, ++ card->ext_csd.generic_cmd6_time)); ++ mmc_card_clr_cmdq(card); ++ } ++ ++ part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; ++ part_config |= md->part_type; ++ ++ WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, ++ EXT_CSD_PART_CONFIG, part_config, ++ card->ext_csd.part_time)); ++ ++ card->ext_csd.part_config = part_config; ++ card->part_curr = md->part_type; ++ ++ main_md->part_curr = md->part_type; ++ ++ WARN_ON(mmc_blk_cmdq_switch(card, md, true)); ++ WARN_ON(mmc_cmdq_halt(host, false)); ++ ++ return 0; ++} ++ ++static struct mmc_cmdq_req *mmc_blk_cmdq_prep_discard_req(struct mmc_queue *mq, ++ struct request *req) ++{ ++ struct mmc_blk_data *md = mq->data; ++ struct mmc_card *card = md->queue.card; ++ struct mmc_host *host = card->host; ++ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; ++ struct mmc_cmdq_req *cmdq_req; ++ struct mmc_queue_req *active_mqrq; ++ ++ BUG_ON(req->tag > card->ext_csd.cmdq_depth); ++ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs)); ++ ++ set_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state); ++ ++ active_mqrq = &mq->mqrq_cmdq[req->tag]; ++ active_mqrq->req = req; ++ ++ cmdq_req = mmc_cmdq_prep_dcmd(active_mqrq, mq); ++ cmdq_req->cmdq_req_flags |= QBR; ++ cmdq_req->mrq.cmd = &cmdq_req->cmd; ++ cmdq_req->tag = req->tag; ++ return cmdq_req; ++} ++ ++static int mmc_blk_cmdq_issue_discard_rq(struct mmc_queue *mq, ++ struct request *req) ++{ ++ struct mmc_blk_data *md = mq->data; ++ struct mmc_card *card = md->queue.card; ++ struct mmc_cmdq_req *cmdq_req = NULL; ++ unsigned int from, nr, arg; ++ int err = 0; ++ ++ if (!mmc_can_erase(card)) { ++ err = -EOPNOTSUPP; ++ blk_end_request(req, err, blk_rq_bytes(req)); ++ goto out; ++ } ++ ++ from = blk_rq_pos(req); ++ nr = blk_rq_sectors(req); ++ ++ if (mmc_can_discard(card)) ++ arg = MMC_DISCARD_ARG; ++ else if (mmc_can_trim(card)) ++ arg = MMC_TRIM_ARG; ++ else ++ arg = MMC_ERASE_ARG; ++ ++ cmdq_req = mmc_blk_cmdq_prep_discard_req(mq, req); ++ if (card->quirks & MMC_QUIRK_INAND_CMD38) { ++ __mmc_switch_cmdq_mode(cmdq_req->mrq.cmd, ++ EXT_CSD_CMD_SET_NORMAL, ++ INAND_CMD38_ARG_EXT_CSD, ++ arg == MMC_TRIM_ARG ? ++ INAND_CMD38_ARG_TRIM : ++ INAND_CMD38_ARG_ERASE, ++ 0, true, false); ++ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); ++ if (err) ++ goto clear_dcmd; ++ } ++ err = mmc_cmdq_erase(cmdq_req, card, from, nr, arg); ++clear_dcmd: ++ blk_complete_request(req); ++out: ++ return err ? 1 : 0; ++} ++ ++static int mmc_blk_cmdq_issue_secdiscard_rq(struct mmc_queue *mq, ++ struct request *req) ++{ ++ struct mmc_blk_data *md = mq->data; ++ struct mmc_card *card = md->queue.card; ++ struct mmc_cmdq_req *cmdq_req = NULL; ++ unsigned int from, nr, arg; ++ int err = 0; ++ ++ if (!(mmc_can_secure_erase_trim(card))) { ++ err = -EOPNOTSUPP; ++ blk_end_request(req, err, blk_rq_bytes(req)); ++ goto out; ++ } ++ ++ from = blk_rq_pos(req); ++ nr = blk_rq_sectors(req); ++ ++ if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) ++ arg = MMC_SECURE_TRIM1_ARG; ++ else ++ arg = MMC_SECURE_ERASE_ARG; ++ ++ cmdq_req = mmc_blk_cmdq_prep_discard_req(mq, req); ++ if (card->quirks & MMC_QUIRK_INAND_CMD38) { ++ __mmc_switch_cmdq_mode(cmdq_req->mrq.cmd, ++ EXT_CSD_CMD_SET_NORMAL, ++ INAND_CMD38_ARG_EXT_CSD, ++ arg == MMC_SECURE_TRIM1_ARG ? ++ INAND_CMD38_ARG_SECTRIM1 : ++ INAND_CMD38_ARG_SECERASE, ++ 0, true, false); ++ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); ++ if (err) ++ goto clear_dcmd; ++ } ++ ++ err = mmc_cmdq_erase(cmdq_req, card, from, nr, arg); ++ if (err) ++ goto clear_dcmd; ++ ++ if (arg == MMC_SECURE_TRIM1_ARG) { ++ if (card->quirks & MMC_QUIRK_INAND_CMD38) { ++ __mmc_switch_cmdq_mode(cmdq_req->mrq.cmd, ++ EXT_CSD_CMD_SET_NORMAL, ++ INAND_CMD38_ARG_EXT_CSD, ++ INAND_CMD38_ARG_SECTRIM2, ++ 0, true, false); ++ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); ++ if (err) ++ goto clear_dcmd; ++ } ++ ++ err = mmc_cmdq_erase(cmdq_req, card, from, nr, ++ MMC_SECURE_TRIM2_ARG); ++ } ++clear_dcmd: ++ blk_complete_request(req); ++out: ++ return err ? 1 : 0; ++} ++ ++static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req) ++{ ++ int ret; ++ struct mmc_blk_data *md = mq->data; ++ struct mmc_card *card = md->queue.card; ++ ++ mmc_get_card(card); ++ ++#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME ++ if (mmc_bus_needs_resume(card->host)) ++ mmc_resume_bus(card->host); ++#endif ++ if (!card->host->cmdq_ctx.active_reqs && mmc_card_doing_bkops(card)) { ++ ret = mmc_cmdq_halt(card->host, true); ++ if (ret) ++ goto out; ++ ret = mmc_stop_bkops(card); ++ if (ret) { ++ pr_err("%s: %s: mmc_stop_bkops failed %d\n", ++ md->disk->disk_name, __func__, ret); ++ goto out; ++ } ++ ret = mmc_cmdq_halt(card->host, false); ++ if (ret) ++ goto out; ++ } ++ ++ ret = mmc_blk_cmdq_part_switch(card, md); ++ if (ret) { ++ pr_err("%s: %s: partition switch failed %d\n", ++ md->disk->disk_name, __func__, ret); ++ goto out; ++ } ++ ++ if (req) { ++ struct mmc_host *host = card->host; ++ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; ++ ++ if ((req_op(req) == REQ_OP_FLUSH || req_op(req) == REQ_OP_DISCARD) && ++ (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD) && ++ ctx->active_small_sector_read_reqs) { ++ ret = wait_event_interruptible(ctx->queue_empty_wq, ++ !ctx->active_reqs); ++ if (ret) { ++ pr_err("%s: failed while waiting for the CMDQ to be empty %s err (%d)\n", ++ mmc_hostname(host), ++ __func__, ret); ++ BUG_ON(1); ++ } ++ /* clear the counter now */ ++ ctx->active_small_sector_read_reqs = 0; ++ /* ++ * If there were small sector (less than 8 sectors) read ++ * operations in progress then we have to wait for the ++ * outstanding requests to finish and should also have ++ * atleast 6 microseconds delay before queuing the DCMD ++ * request. ++ */ ++ udelay(MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD); ++ } ++ ++ if (req_op(req) == REQ_OP_DISCARD) { ++ if (req_op(req) == REQ_OP_SECURE_ERASE && ++ !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN)) ++ ret = mmc_blk_cmdq_issue_secdiscard_rq(mq, req); ++ else ++ ret = mmc_blk_cmdq_issue_discard_rq(mq, req); ++ } else if (req_op(req) == REQ_OP_FLUSH) { ++ ret = mmc_blk_cmdq_issue_flush_rq(mq, req); ++ } else { ++ ret = mmc_blk_cmdq_issue_rw_rq(mq, req); ++ } ++ } ++ ++ return ret; ++ ++out: ++ if (req) ++ blk_end_request_all(req, ret); ++ mmc_put_card(card); ++ ++ return ret; ++} ++ ++static void mmc_blk_cmdq_reset(struct mmc_host *host, bool clear_all) ++{ ++ int err = 0; ++ ++ if (mmc_cmdq_halt(host, true)) { ++ pr_err("%s: halt failed\n", mmc_hostname(host)); ++ goto reset; ++ } ++ ++ if (clear_all) ++ mmc_cmdq_discard_queue(host, 0); ++reset: ++ host->cmdq_ops->disable(host, true); ++ err = mmc_cmdq_hw_reset(host); ++ if (err && err != -EOPNOTSUPP) { ++ pr_err("%s: failed to cmdq_hw_reset err = %d\n", ++ mmc_hostname(host), err); ++ host->cmdq_ops->enable(host); ++ mmc_cmdq_halt(host, false); ++ goto out; ++ } ++ /* ++ * CMDQ HW reset would have already made CQE ++ * in unhalted state, but reflect the same ++ * in software state of cmdq_ctx. ++ */ ++ mmc_host_clr_halt(host); ++out: ++ return; ++} ++ ++/** ++ * is_cmdq_dcmd_req - Checks if tag belongs to DCMD request. ++ * @q: request_queue pointer. ++ * @tag: tag number of request to check. ++ * ++ * This function checks if the request with tag number "tag" ++ * is a DCMD request or not based on cmdq_req_flags set. ++ * ++ * returns true if DCMD req, otherwise false. ++ */ ++static bool is_cmdq_dcmd_req(struct request_queue *q, int tag) ++{ ++ struct request *req; ++ struct mmc_queue_req *mq_rq; ++ struct mmc_cmdq_req *cmdq_req; ++ ++ req = blk_queue_find_tag(q, tag); ++ if (WARN_ON(!req)) ++ goto out; ++ mq_rq = req->special; ++ if (WARN_ON(!mq_rq)) ++ goto out; ++ cmdq_req = &(mq_rq->cmdq_req); ++ return (cmdq_req->cmdq_req_flags & DCMD); ++out: ++ return -ENOENT; ++} ++ ++/** ++ * mmc_blk_cmdq_reset_all - Reset everything for CMDQ block request. ++ * @host: mmc_host pointer. ++ * @err: error for which reset is performed. ++ * ++ * This function implements reset_all functionality for ++ * cmdq. It resets the controller, power cycle the card, ++ * and invalidate all busy tags(requeue all request back to ++ * elevator). ++ */ ++static void mmc_blk_cmdq_reset_all(struct mmc_host *host, int err) ++{ ++ struct mmc_request *mrq = host->err_mrq; ++ struct mmc_card *card = host->card; ++ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; ++ struct request_queue *q; ++ int itag = 0; ++ int ret = 0; ++ ++ if (WARN_ON(!mrq)) ++ return; ++ ++ q = mrq->req->q; ++ WARN_ON(!test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)); ++ ++ pr_debug("%s: %s: active_reqs = %lu\n", ++ mmc_hostname(host), __func__, ++ ctx_info->active_reqs); ++ ++ mmc_blk_cmdq_reset(host, false); ++ ++ for_each_set_bit(itag, &ctx_info->active_reqs, ++ host->num_cq_slots) { ++ ret = is_cmdq_dcmd_req(q, itag); ++ if (WARN_ON(ret == -ENOENT)) ++ continue; ++ if (!ret) { ++ WARN_ON(!test_and_clear_bit(itag, ++ &ctx_info->data_active_reqs)); ++ mmc_cmdq_post_req(host, itag, err); ++ } else { ++ clear_bit(CMDQ_STATE_DCMD_ACTIVE, ++ &ctx_info->curr_state); ++ } ++ WARN_ON(!test_and_clear_bit(itag, ++ &ctx_info->active_reqs)); ++ mmc_put_card(card); ++ } ++ ++ spin_lock_irq(q->queue_lock); ++ blk_queue_invalidate_tags(q); ++ spin_unlock_irq(q->queue_lock); ++} ++ ++static void mmc_blk_cmdq_shutdown(struct mmc_queue *mq) ++{ ++ int err; ++ struct mmc_card *card = mq->card; ++ struct mmc_host *host = card->host; ++ ++ mmc_get_card(card); ++ err = mmc_cmdq_halt(host, true); ++ if (err) { ++ pr_err("%s: halt: failed: %d\n", __func__, err); ++ goto out; ++ } ++ ++ /* disable CQ mode in card */ ++ if (mmc_card_cmdq(card)) { ++ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, ++ EXT_CSD_CMDQ, 0, ++ card->ext_csd.generic_cmd6_time); ++ if (err) { ++ pr_err("%s: failed to switch card to legacy mode: %d\n", ++ __func__, err); ++ goto out; ++ } ++ mmc_card_clr_cmdq(card); ++ } ++ host->cmdq_ops->disable(host, false); ++ host->card->cmdq_init = false; ++out: ++ mmc_put_card(card); ++} ++ ++static enum blk_eh_timer_return mmc_blk_cmdq_req_timed_out(struct request *req) ++{ ++ struct mmc_queue *mq = req->q->queuedata; ++ struct mmc_host *host = mq->card->host; ++ struct mmc_queue_req *mq_rq = req->special; ++ struct mmc_request *mrq; ++ struct mmc_cmdq_req *cmdq_req; ++ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; ++ ++ BUG_ON(!host); ++ ++ /* ++ * The mmc_queue_req will be present only if the request ++ * is issued to the LLD. The request could be fetched from ++ * block layer queue but could be waiting to be issued ++ * (for e.g. clock scaling is waiting for an empty cmdq queue) ++ * Reset the timer in such cases to give LLD more time ++ */ ++ if (!mq_rq) { ++ pr_warn("%s: restart timer for tag: %d\n", __func__, req->tag); ++ return BLK_EH_RESET_TIMER; ++ } ++ ++ mrq = &mq_rq->cmdq_req.mrq; ++ cmdq_req = &mq_rq->cmdq_req; ++ ++ BUG_ON(!mrq || !cmdq_req); ++ ++ if (cmdq_req->cmdq_req_flags & DCMD) ++ mrq->cmd->error = -ETIMEDOUT; ++ else ++ mrq->data->error = -ETIMEDOUT; ++ ++ if (mrq->cmd && mrq->cmd->error) { ++ if (!(req_op(req) == REQ_OP_FLUSH)) { ++ /* ++ * Notify completion for non flush commands like ++ * discard that wait for DCMD finish. ++ */ ++ set_bit(CMDQ_STATE_REQ_TIMED_OUT, ++ &ctx_info->curr_state); ++ complete(&mrq->completion); ++ return BLK_EH_NOT_HANDLED; ++ } ++ } ++ ++ if (test_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state) || ++ test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)) ++ return BLK_EH_NOT_HANDLED; ++ ++ set_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state); ++ return BLK_EH_HANDLED; ++} ++ ++/* ++ * mmc_blk_cmdq_err: error handling of cmdq error requests. ++ * Function should be called in context of error out request ++ * which has claim_host and rpm acquired. ++ * This may be called with CQ engine halted. Make sure to ++ * unhalt it after error recovery. ++ * ++ * TODO: Currently cmdq error handler does reset_all in case ++ * of any erorr. Need to optimize error handling. ++ */ ++static void mmc_blk_cmdq_err(struct mmc_queue *mq) ++{ ++ struct mmc_host *host = mq->card->host; ++ struct mmc_request *mrq = host->err_mrq; ++ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; ++ struct request_queue *q; ++ int err; ++ ++ host->cmdq_ops->dumpstate(host); ++ ++ if (WARN_ON(!mrq)) ++ return; ++ ++ q = mrq->req->q; ++ err = mmc_cmdq_halt(host, true); ++ if (err) { ++ pr_err("halt: failed: %d\n", err); ++ goto reset; ++ } ++ ++ /* RED error - Fatal: requires reset */ ++ if (mrq->cmdq_req->resp_err) { ++ err = mrq->cmdq_req->resp_err; ++ pr_crit("%s: Response error detected: Device in bad state\n", ++ mmc_hostname(host)); ++ goto reset; ++ } ++ ++ /* ++ * In case of software request time-out, we schedule err work only for ++ * the first error out request and handles all other request in flight ++ * here. ++ */ ++ if (test_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state)) { ++ err = -ETIMEDOUT; ++ } else if (mrq->data && mrq->data->error) { ++ err = mrq->data->error; ++ } else if (mrq->cmd && mrq->cmd->error) { ++ /* DCMD commands */ ++ err = mrq->cmd->error; ++ } ++ ++reset: ++ mmc_blk_cmdq_reset_all(host, err); ++ if (mrq->cmdq_req->resp_err) ++ mrq->cmdq_req->resp_err = false; ++ mmc_cmdq_halt(host, false); ++ ++ host->err_mrq = NULL; ++ clear_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state); ++ WARN_ON(!test_and_clear_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)); ++ wake_up(&ctx_info->wait); ++} ++ ++/* invoked by block layer in softirq context */ ++void mmc_blk_cmdq_complete_rq(struct request *rq) ++{ ++ struct mmc_queue_req *mq_rq = rq->special; ++ struct mmc_request *mrq = &mq_rq->cmdq_req.mrq; ++ struct mmc_host *host = mrq->host; ++ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; ++ struct mmc_cmdq_req *cmdq_req = &mq_rq->cmdq_req; ++ struct mmc_queue *mq = (struct mmc_queue *)rq->q->queuedata; ++ int err = 0; ++ bool is_dcmd = false; ++ ++ if (mrq->cmd && mrq->cmd->error) ++ err = mrq->cmd->error; ++ else if (mrq->data && mrq->data->error) ++ err = mrq->data->error; ++ ++ if (err || cmdq_req->resp_err) { ++ pr_err("%s: %s: txfr error(%d)/resp_err(%d)\n", ++ mmc_hostname(mrq->host), __func__, err, ++ cmdq_req->resp_err); ++ if (test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)) { ++ pr_err("%s: CQ in error state, ending current req: %d\n", ++ __func__, err); ++ } else { ++ set_bit(CMDQ_STATE_ERR, &ctx_info->curr_state); ++ BUG_ON(host->err_mrq != NULL); ++ host->err_mrq = mrq; ++ schedule_work(&mq->cmdq_err_work); ++ } ++ goto out; ++ } ++ /* ++ * In case of error CMDQ is expected to be either in halted ++ * or disable state so cannot receive any completion of ++ * other requests. ++ */ ++ BUG_ON(test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)); ++ ++ /* clear pending request */ ++ BUG_ON(!test_and_clear_bit(cmdq_req->tag, ++ &ctx_info->active_reqs)); ++ if (cmdq_req->cmdq_req_flags & DCMD) ++ is_dcmd = true; ++ else ++ BUG_ON(!test_and_clear_bit(cmdq_req->tag, ++ &ctx_info->data_active_reqs)); ++ if (!is_dcmd) ++ mmc_cmdq_post_req(host, cmdq_req->tag, err); ++ if (cmdq_req->cmdq_req_flags & DCMD) { ++ clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state); ++ blk_end_request_all(rq, err); ++ goto out; ++ } ++ ++ blk_end_request(rq, err, cmdq_req->data.bytes_xfered); ++ ++out: ++ ++ if (!test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)) { ++ wake_up(&ctx_info->wait); ++ mmc_put_card(host->card); ++ } ++ ++ if (!ctx_info->active_reqs) ++ wake_up_interruptible(&host->cmdq_ctx.queue_empty_wq); ++ ++ if (blk_queue_stopped(mq->queue) && !ctx_info->active_reqs) ++ complete(&mq->cmdq_shutdown_complete); ++ ++ return; ++} ++ + static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, + struct device *parent, + sector_t size, +@@ -2262,7 +3159,7 @@ + INIT_LIST_HEAD(&md->part); + md->usage = 1; + +- ret = mmc_init_queue(&md->queue, card, &md->lock, subname); ++ ret = mmc_init_queue(&md->queue, card, &md->lock, subname, area_type); + if (ret) + goto err_putdisk; + +@@ -2318,7 +3215,16 @@ + blk_queue_write_cache(md->queue.queue, true, true); + } + +- if (mmc_card_mmc(card) && ++ if (card->cmdq_init) { ++ md->flags |= MMC_BLK_CMD_QUEUE; ++ md->queue.cmdq_complete_fn = mmc_blk_cmdq_complete_rq; ++ md->queue.cmdq_issue_fn = mmc_blk_cmdq_issue_rq; ++ md->queue.cmdq_error_fn = mmc_blk_cmdq_err; ++ md->queue.cmdq_req_timed_out = mmc_blk_cmdq_req_timed_out; ++ md->queue.cmdq_shutdown = mmc_blk_cmdq_shutdown; ++ } ++ ++ if (mmc_card_mmc(card) && !card->cmdq_init && + (area_type == MMC_BLK_DATA_AREA_MAIN) && + (md->flags & MMC_BLK_CMD23) && + card->ext_csd.packed_event_en) { +@@ -2431,6 +3337,8 @@ + mmc_cleanup_queue(&md->queue); + if (md->flags & MMC_BLK_PACKED_CMD) + mmc_packed_clean(&md->queue); ++ if (md->flags & MMC_BLK_CMD_QUEUE) ++ mmc_cmdq_clean(&md->queue, card); + if (md->disk->flags & GENHD_FL_UP) { + device_remove_file(disk_to_dev(md->disk), &md->force_ro); + if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && +@@ -2648,23 +3556,36 @@ + dev_set_drvdata(&card->dev, NULL); + } + +-static int _mmc_blk_suspend(struct mmc_card *card) ++static int _mmc_blk_suspend(struct mmc_card *card, bool wait) + { + struct mmc_blk_data *part_md; + struct mmc_blk_data *md = dev_get_drvdata(&card->dev); ++ int rc = 0; + + if (md) { +- mmc_queue_suspend(&md->queue); ++ rc = mmc_queue_suspend(&md->queue, wait); ++ if (rc) ++ goto out; + list_for_each_entry(part_md, &md->part, part) { +- mmc_queue_suspend(&part_md->queue); ++ rc = mmc_queue_suspend(&part_md->queue, wait); ++ if (rc) ++ goto out_resume; + } + } +- return 0; ++ goto out; ++ ++ out_resume: ++ mmc_queue_resume(&md->queue); ++ list_for_each_entry(part_md, &md->part, part) { ++ mmc_queue_resume(&part_md->queue); ++ } ++ out: ++ return rc; + } + + static void mmc_blk_shutdown(struct mmc_card *card) + { +- _mmc_blk_suspend(card); ++ _mmc_blk_suspend(card, 1); + } + + #ifdef CONFIG_PM_SLEEP +@@ -2672,7 +3593,7 @@ + { + struct mmc_card *card = mmc_dev_to_card(dev); + +- return _mmc_blk_suspend(card); ++ return _mmc_blk_suspend(card, 0); + } + + static int mmc_blk_resume(struct device *dev) diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-queue.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-queue.c.patch new file mode 100644 index 00000000..ada98099 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-queue.c.patch @@ -0,0 +1,360 @@ +--- linux-4.9.37/drivers/mmc/card/queue.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/card/queue.c 2021-06-07 13:01:33.000000000 +0300 +@@ -179,6 +179,122 @@ + queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); + } + ++static struct request *mmc_peek_request(struct mmc_queue *mq) ++{ ++ struct request_queue *q = mq->queue; ++ mq->cmdq_req_peeked = NULL; ++ ++ spin_lock_irq(q->queue_lock); ++ if (!blk_queue_stopped(q)) ++ mq->cmdq_req_peeked = blk_peek_request(q); ++ spin_unlock_irq(q->queue_lock); ++ ++ return mq->cmdq_req_peeked; ++} ++ ++static bool mmc_check_blk_queue_start_tag(struct request_queue *q, ++ struct request *req) ++{ ++ int ret; ++ ++ spin_lock_irq(q->queue_lock); ++ ret = blk_queue_start_tag(q, req); ++ spin_unlock_irq(q->queue_lock); ++ ++ return !!ret; ++} ++ ++static inline void mmc_cmdq_ready_wait(struct mmc_host *host, ++ struct mmc_queue *mq) ++{ ++ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; ++ struct request_queue *q = mq->queue; ++ ++ /* ++ * Wait until all of the following conditions are true: ++ * 1. There is a request pending in the block layer queue ++ * to be processed. ++ * 2. If the peeked request is flush/discard then there shouldn't ++ * be any other direct command active. ++ * 3. cmdq state should be unhalted. ++ * 4. cmdq state shouldn't be in error state. ++ * 5. free tag available to process the new request. ++ */ ++ wait_event(ctx->wait, kthread_should_stop() ++ || (mmc_peek_request(mq) && ++ !((mq->cmdq_req_peeked->cmd_flags & (REQ_OP_FLUSH | REQ_OP_DISCARD)) ++ && test_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx->curr_state)) ++ && !(!host->card->part_curr && !mmc_card_suspended(host->card) ++ && mmc_host_halt(host)) ++ && !(!host->card->part_curr && mmc_host_cq_disable(host) && ++ !mmc_card_suspended(host->card)) ++ && !test_bit(CMDQ_STATE_ERR, &ctx->curr_state) ++ && !mmc_check_blk_queue_start_tag(q, mq->cmdq_req_peeked))); ++} ++ ++static int mmc_cmdq_thread(void *d) ++{ ++ struct mmc_queue *mq = d; ++ struct mmc_card *card = mq->card; ++ struct mmc_host *host = card->host; ++ ++ current->flags |= PF_MEMALLOC; ++ ++ while (1) { ++ int ret = 0; ++ ++ mmc_cmdq_ready_wait(host, mq); ++ if (kthread_should_stop()) ++ break; ++ ++ ret = mq->cmdq_issue_fn(mq, mq->cmdq_req_peeked); ++ /* ++ * Don't requeue if issue_fn fails, just bug on. ++ * We don't expect failure here and there is no recovery other ++ * than fixing the actual issue if there is any. ++ * Also we end the request if there is a partition switch error, ++ * so we should not requeue the request here. ++ */ ++ if (ret) ++ BUG_ON(1); ++ } /* loop */ ++ ++ return 0; ++} ++ ++static void mmc_cmdq_dispatch_req(struct request_queue *q) ++{ ++ struct mmc_queue *mq = q->queuedata; ++ ++ wake_up(&mq->card->host->cmdq_ctx.wait); ++} ++ ++/** ++ * mmc_blk_cmdq_setup_queue ++ * @mq: mmc queue ++ * @card: card to attach to this queue ++ * ++ * Setup queue for CMDQ supporting MMC card ++ */ ++void mmc_cmdq_setup_queue(struct mmc_queue *mq, struct mmc_card *card) ++{ ++ u64 limit = BLK_BOUNCE_HIGH; ++ struct mmc_host *host = card->host; ++ ++ if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) ++ limit = *mmc_dev(host)->dma_mask; ++ ++ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); ++ if (mmc_can_erase(card)) ++ mmc_queue_setup_discard(mq->queue, card); ++ ++ blk_queue_bounce_limit(mq->queue, limit); ++ blk_queue_max_hw_sectors(mq->queue, min(host->max_blk_count, ++ host->max_req_size / 512)); ++ blk_queue_max_segment_size(mq->queue, host->max_seg_size); ++ blk_queue_max_segments(mq->queue, host->max_segs); ++} ++ + /** + * mmc_init_queue - initialise a queue structure. + * @mq: mmc queue +@@ -189,7 +305,7 @@ + * Initialise a MMC card request queue. + */ + int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, +- spinlock_t *lock, const char *subname) ++ spinlock_t *lock, const char *subname, int area_type) + { + struct mmc_host *host = card->host; + u64 limit = BLK_BOUNCE_HIGH; +@@ -201,6 +317,37 @@ + limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; + + mq->card = card; ++ if (card->ext_csd.cmdq_support && ++ (area_type == MMC_BLK_DATA_AREA_MAIN)) { ++ mq->queue = blk_init_queue(mmc_cmdq_dispatch_req, lock); ++ if (!mq->queue) ++ return -ENOMEM; ++ mmc_cmdq_setup_queue(mq, card); ++ ret = mmc_cmdq_init(mq, card); ++ if (ret) { ++ pr_err("%s: %d: cmdq: unable to set-up\n", ++ mmc_hostname(card->host), ret); ++ blk_cleanup_queue(mq->queue); ++ } else { ++ sema_init(&mq->thread_sem, 1); ++ /* hook for pm qos cmdq init */ ++ if (card->host->cmdq_ops->init) ++ card->host->cmdq_ops->init(card->host); ++ mq->queue->queuedata = mq; ++ mq->thread = kthread_run(mmc_cmdq_thread, mq, ++ "mmc-cmdqd/%d%s", ++ host->index, ++ subname ? subname : ""); ++ if (IS_ERR(mq->thread)) { ++ pr_err("%s: %d: cmdq: failed to start mmc-cmdqd thread\n", ++ mmc_hostname(card->host), ret); ++ ret = PTR_ERR(mq->thread); ++ } ++ ++ return ret; ++ } ++ } ++ + mq->queue = blk_init_queue(mmc_request_fn, lock); + if (!mq->queue) + return -ENOMEM; +@@ -413,20 +560,76 @@ + * complete any outstanding requests. This ensures that we + * won't suspend while a request is being processed. + */ +-void mmc_queue_suspend(struct mmc_queue *mq) ++int mmc_queue_suspend(struct mmc_queue *mq, int wait) + { + struct request_queue *q = mq->queue; + unsigned long flags; ++ int rc = 0; ++ struct mmc_card *card = mq->card; ++ struct request *req; + + if (!(mq->flags & MMC_QUEUE_SUSPENDED)) { + mq->flags |= MMC_QUEUE_SUSPENDED; + +- spin_lock_irqsave(q->queue_lock, flags); +- blk_stop_queue(q); +- spin_unlock_irqrestore(q->queue_lock, flags); ++ if (card->cmdq_init && blk_queue_tagged(q)) { ++ struct mmc_host *host = card->host; + +- down(&mq->thread_sem); ++ if (wait) { ++ /* ++ * After blk_stop_queue is called, wait for all ++ * active_reqs to complete. ++ * Then wait for cmdq thread to exit before calling ++ * cmdq shutdown to avoid race between issuing ++ * requests and shutdown of cmdq. ++ */ ++ spin_lock_irqsave(q->queue_lock, flags); ++ blk_stop_queue(q); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ if (host->cmdq_ctx.active_reqs) ++ wait_for_completion( ++ &mq->cmdq_shutdown_complete); ++ kthread_stop(mq->thread); ++ mq->cmdq_shutdown(mq); ++ } else { ++ spin_lock_irqsave(q->queue_lock, flags); ++ blk_stop_queue(q); ++ wake_up(&host->cmdq_ctx.wait); ++ req = blk_peek_request(q); ++ if (req || mq->cmdq_req_peeked || ++ host->cmdq_ctx.active_reqs) { ++ mq->flags &= ~MMC_QUEUE_SUSPENDED; ++ blk_start_queue(q); ++ rc = -EBUSY; ++ } ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ } ++ ++ goto out; ++ } else { ++ spin_lock_irqsave(q->queue_lock, flags); ++ blk_stop_queue(q); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ rc = down_trylock(&mq->thread_sem); ++ if (rc && !wait) { ++ /* ++ * Failed to take the lock so better to abort the ++ * suspend because mmcqd thread is processing requests. ++ */ ++ mq->flags &= ~MMC_QUEUE_SUSPENDED; ++ spin_lock_irqsave(q->queue_lock, flags); ++ blk_start_queue(q); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ rc = -EBUSY; ++ } else if (rc && wait) { ++ down(&mq->thread_sem); ++ rc = 0; ++ } ++ } + } ++out: ++ return rc; + } + + /** +@@ -555,3 +758,105 @@ + sg_copy_from_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, + mqrq->bounce_buf, mqrq->sg[0].length); + } ++ ++static void mmc_cmdq_softirq_done(struct request *rq) ++{ ++ struct mmc_queue *mq = rq->q->queuedata; ++ mq->cmdq_complete_fn(rq); ++} ++ ++static void mmc_cmdq_error_work(struct work_struct *work) ++{ ++ struct mmc_queue *mq = container_of(work, struct mmc_queue, ++ cmdq_err_work); ++ ++ mq->cmdq_error_fn(mq); ++} ++ ++enum blk_eh_timer_return mmc_cmdq_rq_timed_out(struct request *req) ++{ ++ struct mmc_queue *mq = req->q->queuedata; ++ ++ pr_err("%s: request with tag: %d flags: 0x%llx timed out\n", ++ mmc_hostname(mq->card->host), req->tag, req->cmd_flags); ++ ++ return mq->cmdq_req_timed_out(req); ++} ++ ++int mmc_cmdq_init(struct mmc_queue *mq, struct mmc_card *card) ++{ ++ int i, ret = 0; ++ /* one slot is reserved for dcmd requests */ ++ int q_depth = card->ext_csd.cmdq_depth - 1; ++ ++ card->cmdq_init = false; ++ if (!(card->host->caps2 & MMC_CAP2_CMD_QUEUE)) { ++ ret = -ENOTSUPP; ++ goto out; ++ } ++ ++ init_waitqueue_head(&card->host->cmdq_ctx.queue_empty_wq); ++ init_waitqueue_head(&card->host->cmdq_ctx.wait); ++ ++ mq->mqrq_cmdq = kzalloc( ++ sizeof(struct mmc_queue_req) * q_depth, GFP_KERNEL); ++ if (!mq->mqrq_cmdq) { ++ pr_warn("%s: unable to allocate mqrq's for q_depth %d\n", ++ mmc_card_name(card), q_depth); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ /* sg is allocated for data request slots only */ ++ for (i = 0; i < q_depth; i++) { ++ mq->mqrq_cmdq[i].sg = mmc_alloc_sg(card->host->max_segs, &ret); ++ if (ret) { ++ pr_warn("%s: unable to allocate cmdq sg of size %d\n", ++ mmc_card_name(card), ++ card->host->max_segs); ++ goto free_mqrq_sg; ++ } ++ } ++ ++ ret = blk_queue_init_tags(mq->queue, q_depth, NULL, BLK_TAG_ALLOC_FIFO); ++ if (ret) { ++ pr_warn("%s: unable to allocate cmdq tags %d\n", ++ mmc_card_name(card), q_depth); ++ goto free_mqrq_sg; ++ } ++ ++ blk_queue_softirq_done(mq->queue, mmc_cmdq_softirq_done); ++ INIT_WORK(&mq->cmdq_err_work, mmc_cmdq_error_work); ++ init_completion(&mq->cmdq_shutdown_complete); ++ init_completion(&mq->cmdq_pending_req_done); ++ ++ blk_queue_rq_timed_out(mq->queue, mmc_cmdq_rq_timed_out); ++ blk_queue_rq_timeout(mq->queue, 120 * HZ); ++ card->cmdq_init = true; ++ ++ goto out; ++ ++free_mqrq_sg: ++ for (i = 0; i < q_depth; i++) ++ kfree(mq->mqrq_cmdq[i].sg); ++ kfree(mq->mqrq_cmdq); ++ mq->mqrq_cmdq = NULL; ++out: ++ return ret; ++} ++ ++void mmc_cmdq_clean(struct mmc_queue *mq, struct mmc_card *card) ++{ ++ int i; ++ int q_depth = card->ext_csd.cmdq_depth - 1; ++ ++ blk_free_tags(mq->queue->queue_tags); ++ mq->queue->queue_tags = NULL; ++ blk_queue_free_tags(mq->queue); ++ ++ for (i = 0; i < q_depth; i++) ++ kfree(mq->mqrq_cmdq[i].sg); ++ kfree(mq->mqrq_cmdq); ++ mq->mqrq_cmdq = NULL; ++} ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-queue.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-queue.h.patch new file mode 100644 index 00000000..e1408285 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-card-queue.h.patch @@ -0,0 +1,46 @@ +--- linux-4.9.37/drivers/mmc/card/queue.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/card/queue.h 2021-06-07 13:01:33.000000000 +0300 +@@ -48,6 +48,7 @@ + struct mmc_async_req mmc_active; + enum mmc_packed_type cmd_type; + struct mmc_packed *packed; ++ struct mmc_cmdq_req cmdq_req; + }; + + struct mmc_queue { +@@ -62,12 +63,25 @@ + struct mmc_queue_req mqrq[2]; + struct mmc_queue_req *mqrq_cur; + struct mmc_queue_req *mqrq_prev; ++ struct mmc_queue_req *mqrq_cmdq; ++ struct work_struct cmdq_err_work; ++ ++ struct completion cmdq_pending_req_done; ++ struct completion cmdq_shutdown_complete; ++ struct request *cmdq_req_peeked; ++ ++ int (*cmdq_issue_fn)(struct mmc_queue *, ++ struct request *); ++ void (*cmdq_complete_fn)(struct request *); ++ void (*cmdq_error_fn)(struct mmc_queue *); ++ enum blk_eh_timer_return (*cmdq_req_timed_out)(struct request *); ++ void (*cmdq_shutdown)(struct mmc_queue *); + }; + + extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, +- const char *); ++ const char *, int); + extern void mmc_cleanup_queue(struct mmc_queue *); +-extern void mmc_queue_suspend(struct mmc_queue *); ++extern int mmc_queue_suspend(struct mmc_queue *, int); + extern void mmc_queue_resume(struct mmc_queue *); + + extern unsigned int mmc_queue_map_sg(struct mmc_queue *, +@@ -79,5 +93,6 @@ + extern void mmc_packed_clean(struct mmc_queue *); + + extern int mmc_access_rpmb(struct mmc_queue *); +- ++extern int mmc_cmdq_init(struct mmc_queue *mq, struct mmc_card *card); ++extern void mmc_cmdq_clean(struct mmc_queue *mq, struct mmc_card *card); + #endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-core.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-core.c.patch new file mode 100644 index 00000000..4bc79683 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-core.c.patch @@ -0,0 +1,479 @@ +--- linux-4.9.37/drivers/mmc/core/core.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/core/core.c 2021-06-07 13:01:33.000000000 +0300 +@@ -569,7 +569,12 @@ + mmc_hostname(host), __func__); + } + } +- if (!cmd->error || !cmd->retries || ++ ++ /* ++ * If the return code is EACCES, exit the loop. This solves the problem ++ * that the system suspends for a long time when the protected card is accessed. ++ */ ++ if ((cmd->error == -EACCES) || !cmd->error || !cmd->retries || + mmc_card_removed(host->card)) + break; + +@@ -641,6 +646,179 @@ + host->ops->post_req(host, mrq, err); + } + ++int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host) ++{ ++ int err = 0; ++ ++ err = wait_event_interruptible(host->cmdq_ctx.queue_empty_wq, ++ (!host->cmdq_ctx.active_reqs)); ++ if (host->cmdq_ctx.active_reqs) { ++ pr_err("%s: %s: unexpected active requests (%lu)\n", ++ mmc_hostname(host), __func__, ++ host->cmdq_ctx.active_reqs); ++ return -EPERM; ++ } ++ ++ err = mmc_cmdq_halt(host, true); ++ if (err) { ++ pr_err("%s: %s: mmc_cmdq_halt failed (%d)\n", ++ mmc_hostname(host), __func__, err); ++ goto out; ++ } ++ ++out: ++ return err; ++} ++EXPORT_SYMBOL(mmc_cmdq_halt_on_empty_queue); ++ ++/** ++ * mmc_cmdq_discard_card_queue - discard the task[s] in the device ++ * @host: host instance ++ * @tasks: mask of tasks to be knocked off ++ * 0: remove all queued tasks ++ */ ++int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks) ++{ ++ return mmc_discard_queue(host, tasks); ++} ++EXPORT_SYMBOL(mmc_cmdq_discard_queue); ++ ++ ++/** ++ * mmc_cmdq_post_req - post process of a completed request ++ * @host: host instance ++ * @tag: the request tag. ++ * @err: non-zero is error, success otherwise ++ */ ++void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err) ++{ ++ if (likely(host->cmdq_ops->post_req)) ++ host->cmdq_ops->post_req(host, tag, err); ++} ++EXPORT_SYMBOL(mmc_cmdq_post_req); ++ ++/** ++ * mmc_cmdq_halt - halt/un-halt the command queue engine ++ * @host: host instance ++ * @halt: true - halt, un-halt otherwise ++ * ++ * Host halts the command queue engine. It should complete ++ * the ongoing transfer and release the bus. ++ * All legacy commands can be sent upon successful ++ * completion of this function. ++ * Returns 0 on success, negative otherwise ++ */ ++int mmc_cmdq_halt(struct mmc_host *host, bool halt) ++{ ++ int err = 0; ++ ++ if ((halt && mmc_host_halt(host)) || ++ (!halt && !mmc_host_halt(host))) { ++ pr_debug("%s: %s: CQE is already %s\n", mmc_hostname(host), ++ __func__, halt ? "halted" : "un-halted"); ++ return 0; ++ } ++ ++ if (host->cmdq_ops->halt) { ++ err = host->cmdq_ops->halt(host, halt); ++ if (!err && host->ops->notify_halt) ++ host->ops->notify_halt(host, halt); ++ if (!err && halt) ++ mmc_host_set_halt(host); ++ else if (!err && !halt) { ++ mmc_host_clr_halt(host); ++ wake_up(&host->cmdq_ctx.wait); ++ } ++ } else { ++ err = -ENOSYS; ++ } ++ return err; ++} ++EXPORT_SYMBOL(mmc_cmdq_halt); ++ ++static void mmc_start_cmdq_request(struct mmc_host *host, ++ struct mmc_request *mrq) ++{ ++ if (mrq->data) { ++ pr_debug("%s: blksz %d blocks %d flags %08x tsac %lu ms nsac %d\n", ++ mmc_hostname(host), mrq->data->blksz, ++ mrq->data->blocks, mrq->data->flags, ++ mrq->data->timeout_ns / NSEC_PER_MSEC, ++ mrq->data->timeout_clks); ++ ++ BUG_ON(mrq->data->blksz > host->max_blk_size); ++ BUG_ON(mrq->data->blocks > host->max_blk_count); ++ BUG_ON(mrq->data->blocks * mrq->data->blksz > ++ host->max_req_size); ++ mrq->data->error = 0; ++ mrq->data->mrq = mrq; ++ } ++ ++ if (mrq->cmd) { ++ mrq->cmd->error = 0; ++ mrq->cmd->mrq = mrq; ++ } ++ ++ if (likely(host->cmdq_ops->request)) ++ host->cmdq_ops->request(host, mrq); ++ else ++ pr_err("%s: %s: issue request failed\n", mmc_hostname(host), ++ __func__); ++} ++ ++int mmc_cmdq_start_req(struct mmc_host *host, struct mmc_cmdq_req *cmdq_req) ++{ ++ struct mmc_request *mrq = &cmdq_req->mrq; ++ ++ mrq->host = host; ++ if (mmc_card_removed(host->card)) { ++ mrq->cmd->error = -ENOMEDIUM; ++ return -ENOMEDIUM; ++ } ++ mmc_start_cmdq_request(host, mrq); ++ return 0; ++} ++EXPORT_SYMBOL(mmc_cmdq_start_req); ++ ++static void mmc_cmdq_dcmd_req_done(struct mmc_request *mrq) ++{ ++ complete(&mrq->completion); ++} ++ ++int mmc_cmdq_wait_for_dcmd(struct mmc_host *host, ++ struct mmc_cmdq_req *cmdq_req) ++{ ++ struct mmc_request *mrq = &cmdq_req->mrq; ++ struct mmc_command *cmd = mrq->cmd; ++ int err = 0; ++ ++ init_completion(&mrq->completion); ++ mrq->done = mmc_cmdq_dcmd_req_done; ++ err = mmc_cmdq_start_req(host, cmdq_req); ++ if (err) ++ return err; ++ ++ wait_for_completion_io(&mrq->completion); ++ if (cmd->error) { ++ pr_err("%s: DCMD %d failed with err %d\n", ++ mmc_hostname(host), cmd->opcode, ++ cmd->error); ++ err = cmd->error; ++ if (host->cmdq_ops->dumpstate) ++ host->cmdq_ops->dumpstate(host); ++ } ++ return err; ++} ++EXPORT_SYMBOL(mmc_cmdq_wait_for_dcmd); ++ ++int mmc_cmdq_prepare_flush(struct mmc_command *cmd) ++{ ++ return __mmc_switch_cmdq_mode(cmd, EXT_CSD_CMD_SET_NORMAL, ++ EXT_CSD_FLUSH_CACHE, 1, ++ 0, true, true); ++} ++EXPORT_SYMBOL(mmc_cmdq_prepare_flush); ++ + /** + * mmc_start_req - start a non-blocking request + * @host: MMC host to start command +@@ -1873,6 +2051,9 @@ + + void mmc_power_cycle(struct mmc_host *host, u32 ocr) + { ++ if(host->type == MMC_HOST_TYPE_MMC) ++ return; ++ + mmc_power_off(host); + /* Wait at least 1 ms according to SD spec */ + mmc_delay(1); +@@ -2149,6 +2330,125 @@ + return mmc_mmc_erase_timeout(card, arg, qty); + } + ++static u32 mmc_get_erase_qty(struct mmc_card *card, u32 from, u32 to) ++{ ++ u32 qty = 0; ++ /* ++ * qty is used to calculate the erase timeout which depends on how many ++ * erase groups (or allocation units in SD terminology) are affected. ++ * We count erasing part of an erase group as one erase group. ++ * For SD, the allocation units are always a power of 2. For MMC, the ++ * erase group size is almost certainly also power of 2, but it does not ++ * seem to insist on that in the JEDEC standard, so we fall back to ++ * division in that case. SD may not specify an allocation unit size, ++ * in which case the timeout is based on the number of write blocks. ++ * ++ * Note that the timeout for secure trim 2 will only be correct if the ++ * number of erase groups specified is the same as the total of all ++ * preceding secure trim 1 commands. Since the power may have been ++ * lost since the secure trim 1 commands occurred, it is generally ++ * impossible to calculate the secure trim 2 timeout correctly. ++ */ ++ if (card->erase_shift) ++ qty += ((to >> card->erase_shift) - ++ (from >> card->erase_shift)) + 1; ++ else if (mmc_card_sd(card)) ++ qty += to - from + 1; ++ else ++ qty += ((to / card->erase_size) - ++ (from / card->erase_size)) + 1; ++ return qty; ++} ++ ++static int mmc_cmdq_send_erase_cmd(struct mmc_cmdq_req *cmdq_req, ++ struct mmc_card *card, u32 opcode, u32 arg, u32 qty) ++{ ++ struct mmc_command *cmd = cmdq_req->mrq.cmd; ++ int err; ++ ++ memset(cmd, 0, sizeof(struct mmc_command)); ++ ++ cmd->opcode = opcode; ++ cmd->arg = arg; ++ if (cmd->opcode == MMC_ERASE) { ++ cmd->flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; ++ cmd->busy_timeout = mmc_erase_timeout(card, arg, qty); ++ } else { ++ cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; ++ } ++ ++ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); ++ if (err) { ++ pr_err("mmc_erase: group start error %d, status %#x\n", ++ err, cmd->resp[0]); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int mmc_cmdq_do_erase(struct mmc_cmdq_req *cmdq_req, ++ struct mmc_card *card, unsigned int from, ++ unsigned int to, unsigned int arg) ++{ ++ struct mmc_command *cmd = cmdq_req->mrq.cmd; ++ unsigned int qty = 0; ++ unsigned long timeout; ++ int err; ++ ++ mmc_retune_hold(card->host); ++ ++ qty = mmc_get_erase_qty(card, from, to); ++ ++ if (!mmc_card_blockaddr(card)) { ++ from <<= 9; ++ to <<= 9; ++ } ++ ++ err = mmc_cmdq_send_erase_cmd(cmdq_req, card, MMC_ERASE_GROUP_START, ++ from, qty); ++ if (err) ++ goto out; ++ ++ err = mmc_cmdq_send_erase_cmd(cmdq_req, card, MMC_ERASE_GROUP_END, ++ to, qty); ++ if (err) ++ goto out; ++ ++ err = mmc_cmdq_send_erase_cmd(cmdq_req, card, MMC_ERASE, ++ arg, qty); ++ if (err) ++ goto out; ++ ++ timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS); ++ do { ++ memset(cmd, 0, sizeof(struct mmc_command)); ++ cmd->opcode = MMC_SEND_STATUS; ++ cmd->arg = card->rca << 16; ++ cmd->flags = MMC_RSP_R1 | MMC_CMD_AC; ++ /* Do not retry else we can't see errors */ ++ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); ++ if (err || (cmd->resp[0] & 0xFDF92000)) { ++ pr_err("error %d requesting status %#x\n", ++ err, cmd->resp[0]); ++ err = -EIO; ++ goto out; ++ } ++ /* Timeout if the device never becomes ready for data and ++ * never leaves the program state. ++ */ ++ if (time_after(jiffies, timeout)) { ++ pr_err("%s: Card stuck in programming state! %s\n", ++ mmc_hostname(card->host), __func__); ++ err = -EIO; ++ goto out; ++ } ++ } while (!(cmd->resp[0] & R1_READY_FOR_DATA) || ++ (R1_CURRENT_STATE(cmd->resp[0]) == R1_STATE_PRG)); ++out: ++ mmc_retune_release(card->host); ++ return err; ++} ++ + static int mmc_do_erase(struct mmc_card *card, unsigned int from, + unsigned int to, unsigned int arg) + { +@@ -2336,21 +2636,9 @@ + return nr_new; + } + +-/** +- * mmc_erase - erase sectors. +- * @card: card to erase +- * @from: first sector to erase +- * @nr: number of sectors to erase +- * @arg: erase command argument (SD supports only %MMC_ERASE_ARG) +- * +- * Caller must claim host before calling this function. +- */ +-int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, +- unsigned int arg) ++static int mmc_erase_sanity_check(struct mmc_card *card, unsigned int from, ++ unsigned int nr, unsigned int arg) + { +- unsigned int rem, to = from + nr; +- int err; +- + if (!(card->host->caps & MMC_CAP_ERASE) || + !(card->csd.cmdclass & CCC_ERASE)) + return -EOPNOTSUPP; +@@ -2373,6 +2661,70 @@ + if (from % card->erase_size || nr % card->erase_size) + return -EINVAL; + } ++ return 0; ++} ++ ++int mmc_cmdq_erase(struct mmc_cmdq_req *cmdq_req, ++ struct mmc_card *card, unsigned int from, unsigned int nr, ++ unsigned int arg) ++{ ++ unsigned int rem, to = from + nr; ++ int err; ++ ++ err = mmc_erase_sanity_check(card, from, nr, arg); ++ if (err) ++ return err; ++ ++ if (arg == MMC_ERASE_ARG) ++ nr = mmc_align_erase_size(card, &from, &to, nr); ++ ++ if (nr == 0) ++ return 0; ++ ++ if (to <= from) ++ return -EINVAL; ++ ++ /* 'from' and 'to' are inclusive */ ++ to -= 1; ++ ++ /* ++ * Special case where only one erase-group fits in the timeout budget: ++ * If the region crosses an erase-group boundary on this particular ++ * case, we will be trimming more than one erase-group which, does not ++ * fit in the timeout budget of the controller, so we need to split it ++ * and call mmc_do_erase() twice if necessary. This special case is ++ * identified by the card->eg_boundary flag. ++ */ ++ rem = card->erase_size - (from % card->erase_size); ++ if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) { ++ err = mmc_cmdq_do_erase(cmdq_req, card, from, from + rem - 1, arg); ++ from += rem; ++ if ((err) || (to <= from)) ++ return err; ++ } ++ ++ return mmc_cmdq_do_erase(cmdq_req, card, from, to, arg); ++} ++EXPORT_SYMBOL(mmc_cmdq_erase); ++ ++/** ++ * mmc_erase - erase sectors. ++ * @card: card to erase ++ * @from: first sector to erase ++ * @nr: number of sectors to erase ++ * @arg: erase command argument (SD supports only %MMC_ERASE_ARG) ++ * ++ * Caller must claim host before calling this function. ++ */ ++int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, ++ unsigned int arg) ++{ ++ unsigned int rem, to = from + nr; ++ int err; ++ ++ err = mmc_erase_sanity_check(card, from, nr, arg); ++ if (err) ++ return err; + + if (arg == MMC_ERASE_ARG) + nr = mmc_align_erase_size(card, &from, &to, nr); +@@ -2631,6 +2983,22 @@ + return ret; + } + EXPORT_SYMBOL(mmc_hw_reset); ++/* ++ * mmc_cmdq_hw_reset: Helper API for doing ++ * reset_all of host and reinitializing card. ++ * This must be called with mmc_claim_host ++ * acquired by the caller. ++ */ ++int mmc_cmdq_hw_reset(struct mmc_host *host) ++{ ++ if (!host->bus_ops->power_restore) ++ return -EOPNOTSUPP; ++ ++ mmc_power_cycle(host, host->ocr_avail); ++ mmc_select_voltage(host, host->card->ocr); ++ return host->bus_ops->power_restore(host); ++} ++EXPORT_SYMBOL(mmc_cmdq_hw_reset); + + static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) + { +@@ -2798,16 +3166,27 @@ + mmc_bus_put(host); + + mmc_claim_host(host); ++ host->card_status = MMC_CARD_UNINIT; + if (mmc_card_is_removable(host) && host->ops->get_cd && + host->ops->get_cd(host) == 0) { + mmc_power_off(host); ++ if (host->ops->card_info_save) ++ host->ops->card_info_save(host); + mmc_release_host(host); + goto out; + } + + for (i = 0; i < ARRAY_SIZE(freqs); i++) { +- if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) ++ if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) { ++ host->card_status = MMC_CARD_INIT; ++ if (host->ops->card_info_save) ++ host->ops->card_info_save(host); + break; ++ } else if ((i == (ARRAY_SIZE(freqs) - 1)) || ++ (freqs[i] <= host->f_min)) { ++ host->card_status = MMC_CARD_INIT_FAIL; ++ } ++ + if (freqs[i] <= host->f_min) + break; + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc.c.patch new file mode 100644 index 00000000..747ae2e3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc.c.patch @@ -0,0 +1,151 @@ +--- linux-4.9.37/drivers/mmc/core/mmc.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/core/mmc.c 2021-06-07 13:01:33.000000000 +0300 +@@ -528,6 +528,9 @@ + card->ext_csd.man_bkops_en = + (ext_csd[EXT_CSD_BKOPS_EN] & + EXT_CSD_MANUAL_BKOPS_MASK); ++ card->ext_csd.auto_bkops_en = ++ (ext_csd[EXT_CSD_BKOPS_EN] & ++ EXT_CSD_AUTO_BKOPS_MASK) ? 1 : 0; + card->ext_csd.raw_bkops_status = + ext_csd[EXT_CSD_BKOPS_STATUS]; + if (!card->ext_csd.man_bkops_en) +@@ -617,6 +620,21 @@ + card->ext_csd.ffu_capable = + (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) && + !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1); ++ card->ext_csd.cmdq_support = ext_csd[EXT_CSD_CMDQ_SUPPORT]; ++ if (card->ext_csd.cmdq_support) { ++ /* ++ * Queue Depth = N + 1, ++ * see JEDEC JESD84-B51 section 7.4.19 ++ */ ++ card->ext_csd.cmdq_depth = ++ ext_csd[EXT_CSD_CMDQ_DEPTH] + 1; ++ pr_info("%s: CMDQ supported: depth: %d\n", ++ mmc_hostname(card->host), ++ card->ext_csd.cmdq_depth); ++ } ++ } else { ++ card->ext_csd.cmdq_support = 0; ++ card->ext_csd.cmdq_depth = 0; + } + out: + return err; +@@ -1318,6 +1336,9 @@ + + /* Set host controller to HS400 timing and frequency */ + mmc_set_timing(host, MMC_TIMING_MMC_HS400); ++#if defined(CONFIG_MMC_SDHCI_GOKE) || (defined(MODULE) && defined(CONFIG_MMC_SDHCI_GOKE_MODULE)) ++ mmc_set_bus_speed(card); ++#endif + + /* Controller enable enhanced strobe function */ + host->ios.enhanced_strobe = true; +@@ -1466,6 +1487,41 @@ + return mmc_execute_tuning(card); + } + ++static int mmc_select_cmdq(struct mmc_card *card) ++{ ++ struct mmc_host *host = card->host; ++ int ret = 0; ++ ++ if (!host->cmdq_ops) { ++ pr_err("%s: host controller doesn't support CMDQ\n", ++ mmc_hostname(host)); ++ return 0; ++ } ++ ++ ret = mmc_set_blocklen(card, MMC_CARD_CMDQ_BLK_SIZE); ++ if (ret) ++ goto out; ++ ++ ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CMDQ, 1, ++ card->ext_csd.generic_cmd6_time); ++ if (ret) ++ goto out; ++ ++ mmc_card_set_cmdq(card); ++ ret = host->cmdq_ops->enable(card->host); ++ if (ret) { ++ pr_err("%s: failed (%d) enabling CMDQ on host\n", ++ mmc_hostname(host), ret); ++ mmc_card_clr_cmdq(card); ++ ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CMDQ, 0, ++ card->ext_csd.generic_cmd6_time); ++ goto out; ++ } ++ ++ pr_info_once("%s: CMDQ enabled on card\n", mmc_hostname(host)); ++out: ++ return ret; ++} + /* + * Handle the detection and initialisation of a card. + * +@@ -1690,7 +1746,7 @@ + err = mmc_select_hs400(card); + if (err) + goto free_card; +- } else { ++ } else if (!mmc_card_hs400es(card)) { + /* Select the desired bus width optionally */ + err = mmc_select_bus_width(card); + if (err > 0 && mmc_card_hs(card)) { +@@ -1773,6 +1829,18 @@ + if (!oldcard) + host->card = card; + ++ if (card->ext_csd.cmdq_support && (card->host->caps2 & ++ MMC_CAP2_CMD_QUEUE)) { ++ err = mmc_select_cmdq(card); ++ if (err) { ++ pr_err("%s: selecting CMDQ mode: failed: %d\n", ++ mmc_hostname(card->host), err); ++ card->ext_csd.cmdq_support = 0; ++ oldcard = card; ++ goto err; ++ } ++ } ++ + return 0; + + free_card: +@@ -1928,6 +1996,17 @@ + if (mmc_card_suspended(host->card)) + goto out; + ++ if (host->card->cmdq_init) { ++ BUG_ON(host->cmdq_ctx.active_reqs); ++ ++ err = mmc_cmdq_halt(host, true); ++ if (err) { ++ pr_err("%s: halt: failed: %d\n", __func__, err); ++ goto out; ++ } ++ host->cmdq_ops->disable(host, true); ++ } ++ + if (mmc_card_doing_bkops(host->card)) { + err = mmc_stop_bkops(host->card); + if (err) +@@ -1951,6 +2030,10 @@ + mmc_card_set_suspended(host->card); + } + out: ++ /* Kick CMDQ thread to process any requests came in while suspending */ ++ if (host->card->cmdq_init) ++ wake_up(&host->cmdq_ctx.wait); ++ + mmc_release_host(host); + return err; + } +@@ -2125,6 +2208,7 @@ + if (err) + return err; + ++ host->type = MMC_HOST_TYPE_MMC; + mmc_attach_bus(host, &mmc_ops); + if (host->ocr_avail_mmc) + host->ocr_avail = host->ocr_avail_mmc; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc_ops.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc_ops.c.patch new file mode 100644 index 00000000..cdbf0ef9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc_ops.c.patch @@ -0,0 +1,70 @@ +--- linux-4.9.37/drivers/mmc/core/mmc_ops.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/core/mmc_ops.c 2021-06-07 13:01:33.000000000 +0300 +@@ -456,6 +456,45 @@ + } + + /** ++ * mmc_prepare_switch - helper; prepare to modify EXT_CSD register ++ * @card: the MMC card associated with the data transfer ++ * @set: cmd set values ++ * @index: EXT_CSD register index ++ * @value: value to program into EXT_CSD register ++ * @tout_ms: timeout (ms) for operation performed by register write, ++ * timeout of zero implies maximum possible timeout ++ * @use_busy_signal: use the busy signal as response type ++ * ++ * Helper to prepare to modify EXT_CSD register for selected card. ++ */ ++ ++static inline void mmc_prepare_switch(struct mmc_command *cmd, u8 index, ++ u8 value, u8 set, unsigned int tout_ms, ++ bool use_busy_signal) ++{ ++ cmd->opcode = MMC_SWITCH; ++ cmd->arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | ++ (index << 16) | ++ (value << 8) | ++ set; ++ cmd->flags = MMC_CMD_AC; ++ cmd->busy_timeout = tout_ms; ++ if (use_busy_signal) ++ cmd->flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; ++ else ++ cmd->flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; ++} ++ ++int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, u8 value, ++ unsigned int timeout_ms, bool use_busy_signal, ++ bool ignore_timeout) ++{ ++ mmc_prepare_switch(cmd, index, value, set, timeout_ms, use_busy_signal); ++ return 0; ++} ++EXPORT_SYMBOL(__mmc_switch_cmdq_mode); ++ ++/** + * __mmc_switch - modify EXT_CSD register + * @card: the MMC card associated with the data transfer + * @set: cmd set values +@@ -797,3 +836,21 @@ + { + return (card && card->csd.mmca_vsn > CSD_SPEC_VER_3); + } ++ ++int mmc_discard_queue(struct mmc_host *host, u32 tasks) ++{ ++ struct mmc_command cmd = {0}; ++ ++ cmd.opcode = MMC_CMDQ_TASK_MGMT; ++ if (tasks) { ++ cmd.arg = DISCARD_TASK; ++ cmd.arg |= (tasks << 16); ++ } else { ++ cmd.arg = DISCARD_QUEUE; ++ } ++ ++ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; ++ ++ return mmc_wait_for_cmd(host, &cmd, 0); ++} ++EXPORT_SYMBOL(mmc_discard_queue); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc_ops.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc_ops.h.patch new file mode 100644 index 00000000..693712ee --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-mmc_ops.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/mmc/core/mmc_ops.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/core/mmc_ops.h 2021-06-07 13:01:33.000000000 +0300 +@@ -27,6 +27,7 @@ + int mmc_bus_test(struct mmc_card *card, u8 bus_width); + int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); + int mmc_can_ext_csd(struct mmc_card *card); ++int mmc_discard_queue(struct mmc_host *host, u32 tasks); + int mmc_switch_status_error(struct mmc_host *host, u32 status); + int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, + unsigned int timeout_ms, bool use_busy_signal, bool send_status, diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-sd.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-sd.c.patch new file mode 100644 index 00000000..a9556559 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-sd.c.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/mmc/core/sd.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/core/sd.c 2021-06-07 13:01:33.000000000 +0300 +@@ -1236,6 +1236,7 @@ + if (err) + return err; + ++ host->type = MMC_HOST_TYPE_SD; + mmc_attach_bus(host, &mmc_sd_ops); + if (host->ocr_avail_sd) + host->ocr_avail = host->ocr_avail_sd; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-sdio.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-sdio.c.patch new file mode 100644 index 00000000..35288e15 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-core-sdio.c.patch @@ -0,0 +1,85 @@ +--- linux-4.9.37/drivers/mmc/core/sdio.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/core/sdio.c 2021-06-07 13:01:33.000000000 +0300 +@@ -28,6 +28,10 @@ + #include "sdio_ops.h" + #include "sdio_cis.h" + ++#ifdef CONFIG_ARCH_GOKE ++#include "host.h" ++#endif ++ + static int sdio_read_fbr(struct sdio_func *func) + { + int ret; +@@ -158,15 +162,19 @@ + if (mmc_host_uhs(card->host)) { + if (data & SDIO_UHS_DDR50) + card->sw_caps.sd3_bus_mode +- |= SD_MODE_UHS_DDR50; ++ |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50 | ++ SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12; + + if (data & SDIO_UHS_SDR50) + card->sw_caps.sd3_bus_mode +- |= SD_MODE_UHS_SDR50; ++ |= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25 | ++ SD_MODE_UHS_SDR12; + + if (data & SDIO_UHS_SDR104) + card->sw_caps.sd3_bus_mode +- |= SD_MODE_UHS_SDR104; ++ |= SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50 | ++ SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25 | ++ SD_MODE_UHS_SDR12; + } + + ret = mmc_io_rw_direct(card, 0, 0, +@@ -1070,6 +1078,7 @@ + if (err) + return err; + ++ host->type = MMC_HOST_TYPE_SDIO; + mmc_attach_bus(host, &mmc_sdio_ops); + if (host->ocr_avail_sdio) + host->ocr_avail = host->ocr_avail_sdio; +@@ -1173,3 +1182,40 @@ + return err; + } + ++#ifdef CONFIG_ARCH_GOKE ++/* sdio_reset_comm has been fixed in latest kernel/msm.git for Linux ++ * 2.6.27. The implementation prior to that buggy, and needs broadcom's ++ * patch for it*/ ++int sdio_reset_comm(struct mmc_card *card) ++{ ++ struct mmc_host *host = card->host; ++ u32 ocr; ++ u32 rocr; ++ int err; ++ ++ mmc_claim_host(host); ++ mmc_retune_disable(host); ++ mmc_go_idle(host); ++ mmc_set_clock(host, host->f_min); ++ err = mmc_send_io_op_cond(host, 0, &ocr); ++ if (err) ++ goto err; ++ rocr = mmc_select_voltage(host, ocr); ++ if (!rocr) { ++ err = -EINVAL; ++ goto err; ++ } ++ err = mmc_sdio_init_card(host, rocr, card, 0); ++ if (err) ++ goto err; ++ mmc_release_host(host); ++ return 0; ++err: ++ printk("%s: Error resetting SDIO communications (%d)\n", ++ mmc_hostname(host), err); ++ mmc_release_host(host); ++ return err; ++} ++EXPORT_SYMBOL(sdio_reset_comm); ++#endif ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-Kconfig.patch new file mode 100644 index 00000000..4f2f6363 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-Kconfig.patch @@ -0,0 +1,36 @@ +--- linux-4.9.37/drivers/mmc/host/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -176,6 +176,15 @@ + + If unsure, say N. + ++config MMC_SDHCI_GOKE ++ tristate "SDHCI support on the Goke SoC" ++ depends on ARCH_GK7205V200 || ARCH_GK7205V300 || ARCH_GK7202V300 || ARCH_GK7605V100 ++ depends on MMC_SDHCI_PLTFM ++ help ++ This selects the SDHCI support for Goke System-on-Chip devices. ++ If you have a controller with this interface, say Y or M here. ++ If unsure, say N. ++ + config MMC_SDHCI_ESDHC_IMX + tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller" + depends on ARCH_MXC +@@ -798,3 +807,17 @@ + Broadcom STB SoCs. + + If unsure, say Y. ++ ++config MMC_CQ_HCI ++ tristate "Command Queue Support" ++ depends on HAS_DMA ++ help ++ This selects the Command Queue Host Controller Interface (CQHCI) ++ support present in host controllers of Qualcomm Technologies, Inc ++ amongst others. ++ This controller supports eMMC devices with command queue support. ++ ++ If you have a controller with this interface, say Y or M here. ++ ++ If unsure, say N. ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-Makefile.patch new file mode 100644 index 00000000..7631007c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-Makefile.patch @@ -0,0 +1,15 @@ +--- linux-4.9.37/drivers/mmc/host/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -70,6 +70,12 @@ + obj-$(CONFIG_MMC_SDHCI_OF_AT91) += sdhci-of-at91.o + obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o + obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o ++obj-$(CONFIG_MMC_SDHCI_GOKE) += sdhci-proc.o ++obj-$(CONFIG_MMC_CQ_HCI) += sdhci-cmdq.o ++obj-$(CONFIG_ARCH_GK7205V200) += sdhci-gk7205v200.o ++obj-$(CONFIG_ARCH_GK7205V300) += sdhci-gk7205v300.o ++obj-$(CONFIG_ARCH_GK7202V300) += sdhci-gk7202v300.o ++obj-$(CONFIG_ARCH_GK7605V100) += sdhci-gk7605v100.o + obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o + obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o + obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-cmdq.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-cmdq.c.patch new file mode 100644 index 00000000..2bee12d7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-cmdq.c.patch @@ -0,0 +1,1111 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-cmdq.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-cmdq.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,1108 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++//#include ++#include ++ ++#include "sdhci-cmdq.h" ++#include "sdhci.h" ++ ++#define DCMD_SLOT 31 ++#define NUM_SLOTS 32 ++ ++/* 1 sec */ ++#define HALT_TIMEOUT_MS 1000 ++ ++static int cmdq_halt_poll(struct mmc_host *mmc, bool halt); ++static int cmdq_halt(struct mmc_host *mmc, bool halt); ++ ++#ifdef CONFIG_PM_RUNTIME ++static int cmdq_runtime_pm_get(struct cmdq_host *host) ++{ ++ return pm_runtime_get_sync(host->mmc->parent); ++} ++static int cmdq_runtime_pm_put(struct cmdq_host *host) ++{ ++ pm_runtime_mark_last_busy(host->mmc->parent); ++ return pm_runtime_put_autosuspend(host->mmc->parent); ++} ++#else ++static inline int cmdq_runtime_pm_get(struct cmdq_host *host) ++{ ++ return 0; ++} ++static inline int cmdq_runtime_pm_put(struct cmdq_host *host) ++{ ++ return 0; ++} ++#endif ++static inline struct mmc_request *get_req_by_tag(struct cmdq_host *cq_host, ++ unsigned int tag) ++{ ++ return cq_host->mrq_slot[tag]; ++} ++ ++static inline u8 *get_desc(struct cmdq_host *cq_host, u8 tag) ++{ ++ return cq_host->desc_base + (tag * cq_host->slot_sz); ++} ++ ++static inline u8 *get_link_desc(struct cmdq_host *cq_host, u8 tag) ++{ ++ u8 *desc = get_desc(cq_host, tag); ++ ++ return desc + cq_host->task_desc_len; ++} ++ ++static inline dma_addr_t get_trans_desc_dma(struct cmdq_host *cq_host, u8 tag) ++{ ++ return cq_host->trans_desc_dma_base + ++ (cq_host->slot_desc_sz * tag); ++} ++ ++static inline u8 *get_trans_desc(struct cmdq_host *cq_host, u8 tag) ++{ ++ return cq_host->trans_desc_base + ++ (cq_host->slot_desc_sz * tag); ++} ++ ++static void setup_trans_desc(struct cmdq_host *cq_host, u8 tag) ++{ ++ u8 *link_temp; ++ dma_addr_t trans_temp; ++ ++ link_temp = get_link_desc(cq_host, tag); ++ trans_temp = get_trans_desc_dma(cq_host, tag); ++ ++ memset(link_temp, 0, cq_host->link_desc_len); ++ if (cq_host->link_desc_len > 8) ++ *(link_temp + 8) = 0; ++ ++ if (tag == DCMD_SLOT) { ++ *link_temp = VALID(0) | ACT(0) | END(1); ++ return; ++ } ++ ++ *link_temp = VALID(1) | ACT(0x6) | END(0); ++ ++ if (cq_host->dma64) { ++ __le64 *data_addr = (__le64 __force *)(link_temp + 4); ++ data_addr[0] = cpu_to_le64(trans_temp); ++ } else { ++ __le32 *data_addr = (__le32 __force *)(link_temp + 4); ++ data_addr[0] = cpu_to_le32(trans_temp); ++ } ++} ++ ++static void cmdq_set_halt_irq(struct cmdq_host *cq_host, bool enable) ++{ ++ u32 ier; ++ ++ ier = cmdq_readl(cq_host, CQISTE); ++ if (enable) { ++ cmdq_writel(cq_host, ier | HALT, CQISTE); ++ cmdq_writel(cq_host, ier | HALT, CQISGE); ++ } else { ++ cmdq_writel(cq_host, ier & ~HALT, CQISTE); ++ cmdq_writel(cq_host, ier & ~HALT, CQISGE); ++ } ++} ++ ++static void cmdq_clear_set_irqs(struct cmdq_host *cq_host, u32 clear, u32 set) ++{ ++ u32 ier; ++ ++ ier = cmdq_readl(cq_host, CQISTE); ++ ier &= ~clear; ++ ier |= set; ++ cmdq_writel(cq_host, ier, CQISTE); ++ cmdq_writel(cq_host, ier, CQISGE); ++ /* ensure the writes are done */ ++ mb(); ++} ++ ++ ++#define DRV_NAME "cmdq-host" ++ ++static void cmdq_dump_task_history(struct cmdq_host *cq_host) ++{ ++ int i; ++ ++ if (likely(!cq_host->mmc->cmdq_thist_enabled)) ++ return; ++ ++ if (!cq_host->thist) { ++ pr_err("%s: %s: CMDQ task history buffer not allocated\n", ++ mmc_hostname(cq_host->mmc), __func__); ++ return; ++ } ++ ++ pr_err("---- Circular Task History ----\n"); ++ pr_err(DRV_NAME ": Last entry index: %d", cq_host->thist_idx - 1); ++ ++ for (i = 0; i < cq_host->num_slots; i++) { ++ pr_err(DRV_NAME ": [%02d]%s Task: 0x%08x | Args: 0x%08x\n", i, ++ (cq_host->thist[i].is_dcmd) ? "DCMD" : "DATA", ++ lower_32_bits(cq_host->thist[i].task), ++ upper_32_bits(cq_host->thist[i].task)); ++ } ++ pr_err("-------------------------\n"); ++} ++ ++static void cmdq_dump_adma_mem(struct cmdq_host *cq_host) ++{ ++ struct mmc_host *mmc = cq_host->mmc; ++ dma_addr_t desc_dma; ++ int tag = 0; ++ unsigned long data_active_reqs = ++ mmc->cmdq_ctx.data_active_reqs; ++ unsigned long desc_size = cq_host->slot_desc_sz; ++ ++ for_each_set_bit(tag, &data_active_reqs, cq_host->num_slots) { ++ desc_dma = get_trans_desc_dma(cq_host, tag); ++ pr_err("%s: %s: tag = %d, trans_dma(phys) = %pad, trans_desc(virt) = 0x%p\n", ++ mmc_hostname(mmc), __func__, tag, ++ &desc_dma, get_trans_desc(cq_host, tag)); ++ print_hex_dump(KERN_ERR, "cmdq-adma:", DUMP_PREFIX_ADDRESS, ++ 32, 8, get_trans_desc(cq_host, tag), ++ (desc_size), false); ++ } ++} ++ ++static void cmdq_dumpregs(struct cmdq_host *cq_host) ++{ ++ struct mmc_host *mmc = cq_host->mmc; ++ ++ pr_err(DRV_NAME ": ========== REGISTER DUMP (%s)==========\n", ++ mmc_hostname(mmc)); ++ ++ pr_err(DRV_NAME ": Caps: 0x%08x | Version: 0x%08x\n", ++ cmdq_readl(cq_host, CQCAP), ++ cmdq_readl(cq_host, CQVER)); ++ pr_err(DRV_NAME ": Queing config: 0x%08x | Queue Ctrl: 0x%08x\n", ++ cmdq_readl(cq_host, CQCFG), ++ cmdq_readl(cq_host, CQCTL)); ++ pr_err(DRV_NAME ": Int stat: 0x%08x | Int enab: 0x%08x\n", ++ cmdq_readl(cq_host, CQIS), ++ cmdq_readl(cq_host, CQISTE)); ++ pr_err(DRV_NAME ": Int sig: 0x%08x | Int Coal: 0x%08x\n", ++ cmdq_readl(cq_host, CQISGE), ++ cmdq_readl(cq_host, CQIC)); ++ pr_err(DRV_NAME ": TDL base: 0x%08x | TDL up32: 0x%08x\n", ++ cmdq_readl(cq_host, CQTDLBA), ++ cmdq_readl(cq_host, CQTDLBAU)); ++ pr_err(DRV_NAME ": Doorbell: 0x%08x | Comp Notif: 0x%08x\n", ++ cmdq_readl(cq_host, CQTDBR), ++ cmdq_readl(cq_host, CQTCN)); ++ pr_err(DRV_NAME ": Dev queue: 0x%08x | Dev Pend: 0x%08x\n", ++ cmdq_readl(cq_host, CQDQS), ++ cmdq_readl(cq_host, CQDPT)); ++ pr_err(DRV_NAME ": Task clr: 0x%08x | Send stat 1: 0x%08x\n", ++ cmdq_readl(cq_host, CQTCLR), ++ cmdq_readl(cq_host, CQSSC1)); ++ pr_err(DRV_NAME ": Send stat 2: 0x%08x | DCMD resp: 0x%08x\n", ++ cmdq_readl(cq_host, CQSSC2), ++ cmdq_readl(cq_host, CQCRDCT)); ++ pr_err(DRV_NAME ": Resp err mask: 0x%08x | Task err: 0x%08x\n", ++ cmdq_readl(cq_host, CQRMEM), ++ cmdq_readl(cq_host, CQTERRI)); ++ pr_err(DRV_NAME ": Resp idx 0x%08x | Resp arg: 0x%08x\n", ++ cmdq_readl(cq_host, CQCRI), ++ cmdq_readl(cq_host, CQCRA)); ++ pr_err(DRV_NAME": Goke cfg 0x%08x\n", ++ cmdq_readl(cq_host, CQ_GOKE_CFG)); ++ pr_err(DRV_NAME ": ===========================================\n"); ++ ++ cmdq_dump_task_history(cq_host); ++ if (cq_host->ops->dump_goke_regs) ++ cq_host->ops->dump_goke_regs(mmc); ++} ++ ++/** ++ * The allocated descriptor table for task, link & transfer descritors ++ * looks like: ++ * |----------| ++ * |task desc | |->|----------| ++ * |----------| | |trans desc| ++ * |link desc-|->| |----------| ++ * |----------| . ++ * . . ++ * no. of slots max-segs ++ * . |----------| ++ * |----------| ++ * The idea here is to create the [task+trans] table and mark & point the ++ * link desc to the transfer desc table on a per slot basis. ++ */ ++static int cmdq_host_alloc_tdl(struct cmdq_host *cq_host) ++{ ++ ++ size_t desc_size; ++ size_t data_size; ++ int i = 0; ++ ++ /* task descriptor can be 64/128 bit irrespective of arch */ ++ if (cq_host->caps & CMDQ_TASK_DESC_SZ_128) { ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCFG) | ++ CQ_TASK_DESC_SZ, CQCFG); ++ cq_host->task_desc_len = 16; ++ } else { ++ cq_host->task_desc_len = 8; ++ } ++ ++ /* ++ * 96 bits length of transfer desc instead of 128 bits which means ++ * ADMA would expect next valid descriptor at the 96th bit ++ * or 128th bit ++ */ ++ if (cq_host->dma64) { ++ if (cq_host->quirks & CMDQ_QUIRK_SHORT_TXFR_DESC_SZ) ++ cq_host->trans_desc_len = 12; ++ else ++ cq_host->trans_desc_len = 16; ++ cq_host->link_desc_len = 16; ++ } else { ++ cq_host->trans_desc_len = 8; ++ cq_host->link_desc_len = 8; ++ } ++ ++ /* total size of a slot: 1 task & 1 transfer (link) */ ++ cq_host->slot_sz = cq_host->task_desc_len + cq_host->link_desc_len; ++ ++ desc_size = cq_host->slot_sz * cq_host->num_slots; ++ ++ cq_host->slot_desc_sz = cq_host->trans_desc_len * ++ cq_host->mmc->max_segs * 2; ++ data_size = cq_host->slot_desc_sz * (cq_host->num_slots - 1); ++ ++ pr_debug("%s: desc_size: %d data_sz: %d slot-sz: %d\n", __func__, ++ (int)desc_size, (int)data_size, cq_host->slot_sz); ++ ++ /* ++ * allocate a dma-mapped chunk of memory for the descriptors ++ * allocate a dma-mapped chunk of memory for link descriptors ++ * setup each link-desc memory offset per slot-number to ++ * the descriptor table. ++ */ ++ cq_host->desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc), ++ desc_size, ++ &cq_host->desc_dma_base, ++ GFP_KERNEL); ++ cq_host->trans_desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc), ++ data_size, ++ &cq_host->trans_desc_dma_base, ++ GFP_KERNEL); ++ cq_host->thist = devm_kzalloc(mmc_dev(cq_host->mmc), ++ (sizeof(*cq_host->thist) * ++ cq_host->num_slots), ++ GFP_KERNEL); ++ if (!cq_host->desc_base || !cq_host->trans_desc_base) ++ return -ENOMEM; ++ ++ pr_debug("desc-base: 0x%p trans-base: 0x%p\ndesc_dma 0x%llx trans_dma: 0x%llx\n", ++ cq_host->desc_base, cq_host->trans_desc_base, ++ (unsigned long long)cq_host->desc_dma_base, ++ (unsigned long long) cq_host->trans_desc_dma_base); ++ ++ for (; i < (cq_host->num_slots); i++) ++ setup_trans_desc(cq_host, i); ++ ++ return 0; ++} ++ ++static int cmdq_enable(struct mmc_host *mmc) ++{ ++ int err = 0; ++ u32 cqcfg; ++ bool dcmd_enable = false; ++ struct cmdq_host *cq_host = mmc_cmdq_private(mmc); ++ ++ if (!cq_host || !mmc->card || !mmc_card_cmdq(mmc->card)) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ if (cq_host->enabled) ++ goto out; ++ ++ cmdq_runtime_pm_get(cq_host); ++ cqcfg = cmdq_readl(cq_host, CQCFG); ++ if (cqcfg & 0x1) { ++ pr_info("%s: %s: cq_host is already enabled\n", ++ mmc_hostname(mmc), __func__); ++ WARN_ON(1); ++ goto pm_ref_count; ++ } ++ ++ if (cq_host->quirks & CMDQ_QUIRK_NO_DCMD) ++ dcmd_enable = false; ++ else ++ dcmd_enable = true; ++ ++ cqcfg = ((cq_host->caps & CMDQ_TASK_DESC_SZ_128 ? CQ_TASK_DESC_SZ : 0) | ++ (dcmd_enable ? CQ_DCMD : 0)); ++ ++ cmdq_writel(cq_host, cqcfg, CQCFG); ++ /* enable CQ_HOST */ ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCFG) | CQ_ENABLE, ++ CQCFG); ++ ++ if (!cq_host->desc_base || ++ !cq_host->trans_desc_base) { ++ err = cmdq_host_alloc_tdl(cq_host); ++ if (err) ++ goto pm_ref_count; ++ } ++ ++ cmdq_writel(cq_host, lower_32_bits(cq_host->desc_dma_base), CQTDLBA); ++ cmdq_writel(cq_host, upper_32_bits(cq_host->desc_dma_base), CQTDLBAU); ++ ++ /* ++ * disable all goke interrupts ++ * enable CMDQ interrupts ++ * enable the goke error interrupts ++ */ ++ if (cq_host->ops->clear_set_irqs) ++ cq_host->ops->clear_set_irqs(mmc, true); ++ ++ cmdq_clear_set_irqs(cq_host, 0x0, CQ_INT_ALL); ++ ++ /* cq_host would use this rca to address the card */ ++ cmdq_writel(cq_host, mmc->card->rca, CQSSC2); ++ ++ /* send QSR at lesser intervals than the default */ ++ cmdq_writel(cq_host, SEND_QSR_INTERVAL, CQSSC1); ++ ++ /* enable bkops exception indication */ ++ if (mmc_card_configured_manual_bkops(mmc->card) && ++ !mmc_card_configured_auto_bkops(mmc->card)) ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQRMEM) | CQ_EXCEPTION, ++ CQRMEM); ++ ++ /* ensure the writes are done before enabling CQE */ ++ mb(); ++ ++ cq_host->enabled = true; ++ mmc_host_clr_cq_disable(mmc); ++ ++ if (cq_host->ops->set_transfer_params) ++ cq_host->ops->set_transfer_params(mmc); ++ ++ if (cq_host->ops->set_block_size) ++ cq_host->ops->set_block_size(cq_host->mmc); ++ ++ if (cq_host->ops->set_data_timeout) ++ cq_host->ops->set_data_timeout(mmc, 0xf); ++ ++ if (cq_host->ops->clear_set_dumpregs) ++ cq_host->ops->clear_set_dumpregs(mmc, 1); ++ ++ if (cq_host->ops->enhanced_strobe_mask) ++ cq_host->ops->enhanced_strobe_mask(mmc, true); ++ ++pm_ref_count: ++ cmdq_runtime_pm_put(cq_host); ++out: ++ return err; ++} ++ ++static void cmdq_disable_nosync(struct mmc_host *mmc, bool soft) ++{ ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ ++ if (soft) { ++ cmdq_writel(cq_host, cmdq_readl( ++ cq_host, CQCFG) & ~(CQ_ENABLE), ++ CQCFG); ++ } ++ if (cq_host->ops->enhanced_strobe_mask) ++ cq_host->ops->enhanced_strobe_mask(mmc, false); ++ ++ cq_host->enabled = false; ++ mmc_host_set_cq_disable(mmc); ++} ++ ++static void cmdq_disable(struct mmc_host *mmc, bool soft) ++{ ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ ++ cmdq_runtime_pm_get(cq_host); ++ cmdq_disable_nosync(mmc, soft); ++ cmdq_runtime_pm_put(cq_host); ++} ++ ++static void cmdq_reset(struct mmc_host *mmc, bool soft) ++{ ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ unsigned int cqcfg; ++ unsigned int tdlba; ++ unsigned int tdlbau; ++ unsigned int rca; ++ int ret; ++ ++ cmdq_runtime_pm_get(cq_host); ++ cqcfg = cmdq_readl(cq_host, CQCFG); ++ tdlba = cmdq_readl(cq_host, CQTDLBA); ++ tdlbau = cmdq_readl(cq_host, CQTDLBAU); ++ rca = cmdq_readl(cq_host, CQSSC2); ++ ++ cmdq_disable(mmc, true); ++ ++ if (cq_host->ops->reset) { ++ ret = cq_host->ops->reset(mmc); ++ if (ret) { ++ pr_crit("%s: reset CMDQ controller: failed\n", ++ mmc_hostname(mmc)); ++ BUG(); ++ } ++ } ++ ++ cmdq_writel(cq_host, tdlba, CQTDLBA); ++ cmdq_writel(cq_host, tdlbau, CQTDLBAU); ++ ++ if (cq_host->ops->clear_set_irqs) ++ cq_host->ops->clear_set_irqs(mmc, true); ++ ++ cmdq_clear_set_irqs(cq_host, 0x0, CQ_INT_ALL); ++ ++ /* cq_host would use this rca to address the card */ ++ cmdq_writel(cq_host, rca, CQSSC2); ++ ++ /* ensure the writes are done before enabling CQE */ ++ mb(); ++ ++ cmdq_writel(cq_host, cqcfg, CQCFG); ++ cmdq_runtime_pm_put(cq_host); ++ cq_host->enabled = true; ++ mmc_host_clr_cq_disable(mmc); ++} ++ ++static void cmdq_prep_task_desc(struct mmc_request *mrq, ++ u64 *data, bool intr, bool qbr) ++{ ++ struct mmc_cmdq_req *cmdq_req = mrq->cmdq_req; ++ u32 req_flags = cmdq_req->cmdq_req_flags; ++ ++ pr_debug("%s: %s: data-tag: 0x%08x - dir: %d - prio: %d - cnt: 0x%08x - addr: 0x%llx\n", ++ mmc_hostname(mrq->host), __func__, ++ !!(req_flags & DAT_TAG), !!(req_flags & DIR), ++ !!(req_flags & PRIO), cmdq_req->data.blocks, ++ (u64)mrq->cmdq_req->blk_addr); ++ ++ *data = VALID(1) | ++ END(1) | ++ INT(intr) | ++ ACT(0x5) | ++ FORCED_PROG(!!(req_flags & FORCED_PRG)) | ++ CONTEXT(mrq->cmdq_req->ctx_id) | ++ DATA_TAG(!!(req_flags & DAT_TAG)) | ++ DATA_DIR(!!(req_flags & DIR)) | ++ PRIORITY(!!(req_flags & PRIO)) | ++ QBAR(qbr) | ++ REL_WRITE(!!(req_flags & REL_WR)) | ++ BLK_COUNT(mrq->cmdq_req->data.blocks) | ++ BLK_ADDR((u64)mrq->cmdq_req->blk_addr); ++} ++ ++static int cmdq_dma_map(struct mmc_host *host, struct mmc_request *mrq) ++{ ++ int sg_count; ++ struct mmc_data *data = mrq->data; ++ ++ if (!data) ++ return -EINVAL; ++ ++ sg_count = dma_map_sg(mmc_dev(host), data->sg, ++ data->sg_len, ++ (data->flags & MMC_DATA_WRITE) ? ++ DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ if (!sg_count) { ++ pr_err("%s: sg-len: %d\n", __func__, data->sg_len); ++ return -ENOMEM; ++ } ++ ++ return sg_count; ++} ++ ++static void cmdq_set_tran_desc(u8 *desc, dma_addr_t addr, int len, ++ bool end, bool is_dma64) ++{ ++ __le32 *attr = (__le32 __force *)desc; ++ ++ *attr = (VALID(1) | ++ END(end ? 1 : 0) | ++ INT(0) | ++ ACT(0x4) | ++ DAT_LENGTH(len)); ++ ++ if (is_dma64) { ++ __le64 *dataddr = (__le64 __force *)(desc + 4); ++ ++ dataddr[0] = cpu_to_le64(addr); ++ } else { ++ __le32 *dataddr = (__le32 __force *)(desc + 4); ++ ++ dataddr[0] = cpu_to_le32(addr); ++ } ++} ++ ++static int cmdq_prep_tran_desc(struct mmc_request *mrq, ++ struct cmdq_host *cq_host, int tag) ++{ ++ struct mmc_data *data = mrq->data; ++ int i, sg_count, len; ++ bool end = false; ++ dma_addr_t addr; ++ u8 *desc = NULL; ++ struct scatterlist *sg = NULL; ++ ++ sg_count = cmdq_dma_map(mrq->host, mrq); ++ if (sg_count < 0) { ++ pr_err("%s: %s: unable to map sg lists, %d\n", ++ mmc_hostname(mrq->host), __func__, sg_count); ++ return sg_count; ++ } ++ ++ desc = get_trans_desc(cq_host, tag); ++ memset(desc, 0, cq_host->slot_desc_sz); ++ ++ for_each_sg(data->sg, sg, sg_count, i) { ++ addr = sg_dma_address(sg); ++ len = sg_dma_len(sg); ++ ++ if ((i+1) == sg_count) ++ end = true; ++ /* work around for buffer across 128M boundary, split the buffer */ ++ if (((addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)) + len) > ++ SDHCI_DMA_BOUNDARY_SIZE) { ++ int offset; ++ ++ offset = SDHCI_DMA_BOUNDARY_SIZE - ++ (addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)); ++ cmdq_set_tran_desc(desc, addr, offset, false, cq_host->dma64); ++ desc += cq_host->trans_desc_len; ++ addr += offset; ++ len -= offset; ++ } ++ cmdq_set_tran_desc(desc, addr, len, end, cq_host->dma64); ++ desc += cq_host->trans_desc_len; ++ } ++ ++ pr_debug("%s: req: 0x%p tag: %d calc_trans_des: 0x%p sg-cnt: %d\n", ++ __func__, mrq->req, tag, desc, sg_count); ++ ++ return 0; ++} ++ ++static void cmdq_log_task_desc_history(struct cmdq_host *cq_host, u64 task, ++ bool is_dcmd) ++{ ++ if (likely(!cq_host->mmc->cmdq_thist_enabled)) ++ return; ++ ++ if (!cq_host->thist) { ++ pr_err("%s: %s: CMDQ task history buffer not allocated\n", ++ mmc_hostname(cq_host->mmc), __func__); ++ return; ++ } ++ ++ if (cq_host->thist_idx >= cq_host->num_slots) ++ cq_host->thist_idx = 0; ++ ++ cq_host->thist[cq_host->thist_idx].is_dcmd = is_dcmd; ++ memcpy(&cq_host->thist[cq_host->thist_idx++].task, ++ &task, cq_host->task_desc_len); ++} ++ ++static void cmdq_prep_dcmd_desc(struct mmc_host *mmc, ++ struct mmc_request *mrq) ++{ ++ u64 *task_desc = NULL; ++ u64 data = 0; ++ u8 resp_type; ++ u8 *desc; ++ __le64 *dataddr == NULL; ++ struct cmdq_host *cq_host = mmc_cmdq_private(mmc); ++ u8 timing; ++ ++ if (!(mrq->cmd->flags & MMC_RSP_PRESENT)) { ++ resp_type = 0x0; ++ timing = 0x1; ++ } else { ++ if (mrq->cmd->flags & MMC_RSP_BUSY) { ++ resp_type = 0x3; ++ timing = 0x0; ++ } else { ++ resp_type = 0x2; ++ timing = 0x1; ++ } ++ } ++ ++ task_desc = (__le64 __force *)get_desc(cq_host, cq_host->dcmd_slot); ++ memset(task_desc, 0, cq_host->task_desc_len); ++ data |= (VALID(1) | ++ END(1) | ++ INT(1) | ++ QBAR(1) | ++ ACT(0x5) | ++ CMD_INDEX(mrq->cmd->opcode) | ++ CMD_TIMING(timing) | RESP_TYPE(resp_type)); ++ *task_desc |= data; ++ desc = (u8 *)task_desc; ++ pr_debug("cmdq: dcmd: cmd: %d timing: %d resp: %d\n", ++ mrq->cmd->opcode, timing, resp_type); ++ dataddr = (__le64 __force *)(desc + 4); ++ dataddr[0] = cpu_to_le64((u64)mrq->cmd->arg); ++ cmdq_log_task_desc_history(cq_host, *task_desc, true); ++} ++ ++static int cmdq_request(struct mmc_host *mmc, struct mmc_request *mrq) ++{ ++ int err = 0; ++ u64 data = 0; ++ u64 *task_desc = NULL; ++ u32 tag = mrq->cmdq_req->tag; ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ ++ if (!cq_host->enabled) { ++ pr_err("%s: CMDQ host not enabled yet !!!\n", ++ mmc_hostname(mmc)); ++ err = -EINVAL; ++ goto out; ++ } ++ ++ cmdq_runtime_pm_get(cq_host); ++ ++ if (mrq->cmdq_req->cmdq_req_flags & DCMD) { ++ cmdq_prep_dcmd_desc(mmc, mrq); ++ cq_host->mrq_slot[DCMD_SLOT] = mrq; ++ /* DCMD's are always issued on a fixed slot */ ++ tag = DCMD_SLOT; ++ goto ring_doorbell; ++ } ++ ++ if (cq_host->ops->crypto_cfg) { ++ err = cq_host->ops->crypto_cfg(mmc, mrq, tag); ++ if (err) { ++ pr_err("%s: failed to configure crypto: err %d tag %d\n", ++ mmc_hostname(mmc), err, tag); ++ goto out; ++ } ++ } ++ ++ task_desc = (__le64 __force *)get_desc(cq_host, tag); ++ ++ cmdq_prep_task_desc(mrq, &data, 1, ++ (mrq->cmdq_req->cmdq_req_flags & QBR)); ++ *task_desc = cpu_to_le64(data); ++ cmdq_log_task_desc_history(cq_host, *task_desc, false); ++ ++ err = cmdq_prep_tran_desc(mrq, cq_host, tag); ++ if (err) { ++ pr_err("%s: %s: failed to setup tx desc: %d\n", ++ mmc_hostname(mmc), __func__, err); ++ goto out; ++ } ++ ++ cq_host->mrq_slot[tag] = mrq; ++ ++ring_doorbell: ++ /* Ensure the task descriptor list is flushed before ringing doorbell */ ++ wmb(); ++ if (cmdq_readl(cq_host, CQTDBR) & (1 << tag)) { ++ cmdq_dumpregs(cq_host); ++ BUG_ON(1); ++ } ++ cmdq_writel(cq_host, 1 << tag, CQTDBR); ++ /* Commit the doorbell write immediately */ ++ wmb(); ++ ++out: ++ return err; ++} ++ ++static void cmdq_finish_data(struct mmc_host *mmc, unsigned int tag) ++{ ++ struct mmc_request *mrq; ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ ++ mrq = get_req_by_tag(cq_host, tag); ++ if (tag == cq_host->dcmd_slot) ++ mrq->cmd->resp[0] = cmdq_readl(cq_host, CQCRDCT); ++ ++ if (mrq->cmdq_req->cmdq_req_flags & DCMD) ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQ_GOKE_CFG) | ++ CMDQ_SEND_STATUS_TRIGGER, CQ_GOKE_CFG); ++ ++ cmdq_runtime_pm_put(cq_host); ++ if (cq_host->ops->crypto_cfg_reset) ++ cq_host->ops->crypto_cfg_reset(mmc, tag); ++ mrq->done(mrq); ++} ++ ++irqreturn_t cmdq_irq(struct mmc_host *mmc, int err) ++{ ++ u32 status; ++ unsigned long tag = 0, comp_status; ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ unsigned long err_info = 0; ++ struct mmc_request *mrq = NULL; ++ int ret; ++ u32 dbr_set = 0; ++ ++ status = cmdq_readl(cq_host, CQIS); ++ cmdq_writel(cq_host, status, CQIS); ++ ++ if (!status && !err) ++ return IRQ_NONE; ++ ++ if (err || (status & CQIS_RED)) { ++ err_info = cmdq_readl(cq_host, CQTERRI); ++ pr_err("%s: err: %d status: 0x%08x task-err-info (0x%08lx)\n", ++ mmc_hostname(mmc), err, status, err_info); ++ ++ /* ++ * Need to halt CQE in case of error in interrupt context itself ++ * otherwise CQE may proceed with sending CMD to device even if ++ * CQE/card is in error state. ++ * CMDQ error handling will make sure that it is unhalted after ++ * handling all the errors. ++ */ ++ ret = cmdq_halt_poll(mmc, true); ++ if (ret) ++ pr_err("%s: %s: halt failed ret=%d\n", ++ mmc_hostname(mmc), __func__, ret); ++ cmdq_dumpregs(cq_host); ++ ++ if (!err_info) { ++ /* ++ * It may so happen sometimes for few errors(like ADMA) ++ * that HW cannot give CQTERRI info. ++ * Thus below is a HW WA for recovering from such ++ * scenario. ++ * - To halt/disable CQE and do reset_all. ++ * Since there is no way to know which tag would ++ * have caused such error, so check for any first ++ * bit set in doorbell and proceed with an error. ++ */ ++ dbr_set = cmdq_readl(cq_host, CQTDBR); ++ if (!dbr_set) { ++ pr_err("%s: spurious/force error interrupt\n", ++ mmc_hostname(mmc)); ++ cmdq_halt_poll(mmc, false); ++ mmc_host_clr_halt(mmc); ++ return IRQ_HANDLED; ++ } ++ ++ tag = ffs(dbr_set) - 1; ++ pr_err("%s: error tag selected: tag = %lu\n", ++ mmc_hostname(mmc), tag); ++ mrq = get_req_by_tag(cq_host, tag); ++ if (mrq->data) ++ mrq->data->error = err; ++ else ++ mrq->cmd->error = err; ++ /* ++ * Get ADMA descriptor memory in case of ADMA ++ * error for debug. ++ */ ++ if (err == -EIO) ++ cmdq_dump_adma_mem(cq_host); ++ goto skip_cqterri; ++ } ++ ++ if (err_info & CQ_RMEFV) { ++ tag = GET_CMD_ERR_TAG(err_info); ++ pr_err("%s: CMD err tag: %lu\n", __func__, tag); ++ ++ mrq = get_req_by_tag(cq_host, tag); ++ /* CMD44/45/46/47 will not have a valid cmd */ ++ if (mrq->cmd) ++ mrq->cmd->error = err; ++ else ++ mrq->data->error = err; ++ } else if (err_info & CQ_DTEFV) { ++ tag = GET_DAT_ERR_TAG(err_info); ++ pr_err("%s: Dat err tag: %lu\n", __func__, tag); ++ mrq = get_req_by_tag(cq_host, tag); ++ mrq->data->error = err; ++ } ++ ++skip_cqterri: ++ /* ++ * If CQE halt fails then, disable CQE ++ * from processing any further requests ++ */ ++ if (ret) { ++ cmdq_disable_nosync(mmc, true); ++ /* ++ * Enable legacy interrupts as CQE halt has failed. ++ * This is needed to send legacy commands like status ++ * cmd as part of error handling work. ++ */ ++ if (cq_host->ops->clear_set_irqs) ++ cq_host->ops->clear_set_irqs(mmc, false); ++ } ++ ++ /* ++ * CQE detected a reponse error from device ++ * In most cases, this would require a reset. ++ */ ++ if (status & CQIS_RED) { ++ /* ++ * will check if the RED error is due to a bkops ++ * exception once the queue is empty ++ */ ++ BUG_ON(!mmc->card); ++ /*if (mmc_card_configured_manual_bkops(mmc->card) || ++ mmc_card_configured_auto_bkops(mmc->card)) ++ mmc->card->bkops.needs_check = true;*/ ++ ++ mrq->cmdq_req->resp_err = true; ++ pr_err("%s: Response error (0x%08x) from card !!!", ++ mmc_hostname(mmc), status); ++ } else { ++ mrq->cmdq_req->resp_idx = cmdq_readl(cq_host, CQCRI); ++ mrq->cmdq_req->resp_arg = cmdq_readl(cq_host, CQCRA); ++ } ++ ++ cmdq_finish_data(mmc, tag); ++ } ++ ++ if (status & CQIS_TCC) { ++ /* read CQTCN and complete the request */ ++ comp_status = cmdq_readl(cq_host, CQTCN); ++ if (!comp_status) ++ goto out; ++ /* ++ * The CQTCN must be cleared before notifying req completion ++ * to upper layers to avoid missing completion notification ++ * of new requests with the same tag. ++ */ ++ cmdq_writel(cq_host, comp_status, CQTCN); ++ /* ++ * A write memory barrier is necessary to guarantee that CQTCN ++ * gets cleared first before next doorbell for the same tag is ++ * set but that is already achieved by the barrier present ++ * before setting doorbell, hence one is not needed here. ++ */ ++ for_each_set_bit(tag, &comp_status, cq_host->num_slots) { ++ /* complete the corresponding mrq */ ++ pr_debug("%s: completing tag -> %lu\n", ++ mmc_hostname(mmc), tag); ++ cmdq_finish_data(mmc, tag); ++ } ++ } ++ ++ if (status & CQIS_HAC) { ++ if (cq_host->ops->post_cqe_halt) ++ cq_host->ops->post_cqe_halt(mmc); ++ /* halt is completed, wakeup waiting thread */ ++ complete(&cq_host->halt_comp); ++ } ++ ++out: ++ return IRQ_HANDLED; ++} ++EXPORT_SYMBOL(cmdq_irq); ++ ++/* cmdq_halt_poll - Halting CQE using polling method. ++ * @mmc: struct mmc_host ++ * @halt: bool halt ++ * This is used mainly from interrupt context to halt/unhalt ++ * CQE engine. ++ */ ++static int cmdq_halt_poll(struct mmc_host *mmc, bool halt) ++{ ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ int retries = 100; ++ ++ if (!halt) { ++ if (cq_host->ops->set_data_timeout) ++ cq_host->ops->set_data_timeout(mmc, 0xf); ++ if (cq_host->ops->clear_set_irqs) ++ cq_host->ops->clear_set_irqs(mmc, true); ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) & ~HALT, ++ CQCTL); ++ return 0; ++ } ++ ++ cmdq_set_halt_irq(cq_host, false); ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) | HALT, CQCTL); ++ while (retries) { ++ if (!(cmdq_readl(cq_host, CQCTL) & HALT)) { ++ udelay(5); ++ retries--; ++ continue; ++ } else { ++ if (cq_host->ops->post_cqe_halt) ++ cq_host->ops->post_cqe_halt(mmc); ++ /* halt done: re-enable legacy interrupts */ ++ if (cq_host->ops->clear_set_irqs) ++ cq_host->ops->clear_set_irqs(mmc, ++ false); ++ mmc_host_set_halt(mmc); ++ break; ++ } ++ } ++ cmdq_set_halt_irq(cq_host, true); ++ return retries ? 0 : -ETIMEDOUT; ++} ++ ++/* May sleep */ ++static int cmdq_halt(struct mmc_host *mmc, bool halt) ++{ ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ u32 ret = 0; ++ int retries = 3; ++ ++ cmdq_runtime_pm_get(cq_host); ++ if (halt) { ++ while (retries) { ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) | HALT, ++ CQCTL); ++ ret = wait_for_completion_timeout(&cq_host->halt_comp, ++ msecs_to_jiffies(HALT_TIMEOUT_MS)); ++ if (!ret && !(cmdq_readl(cq_host, CQCTL) & HALT)) { ++ retries--; ++ continue; ++ } else { ++ /* halt done: re-enable legacy interrupts */ ++ if (cq_host->ops->clear_set_irqs) ++ cq_host->ops->clear_set_irqs(mmc, ++ false); ++ break; ++ } ++ } ++ ret = retries ? 0 : -ETIMEDOUT; ++ } else { ++ if (cq_host->ops->set_transfer_params) ++ cq_host->ops->set_transfer_params(mmc); ++ if (cq_host->ops->set_block_size) ++ cq_host->ops->set_block_size(mmc); ++ if (cq_host->ops->set_data_timeout) ++ cq_host->ops->set_data_timeout(mmc, 0xf); ++ if (cq_host->ops->clear_set_irqs) ++ cq_host->ops->clear_set_irqs(mmc, true); ++ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) & ~HALT, ++ CQCTL); ++ } ++ cmdq_runtime_pm_put(cq_host); ++ return ret; ++} ++ ++static void cmdq_post_req(struct mmc_host *mmc, int tag, int err) ++{ ++ struct cmdq_host *cq_host = NULL; ++ struct mmc_request *mrq = NULL; ++ struct mmc_data *data = NULL; ++ ++ if (WARN_ON(!mmc)) ++ return; ++ ++ cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ mrq = get_req_by_tag(cq_host, tag); ++ data = mrq->data; ++ ++ if (data) { ++ data->error = err; ++ dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, ++ (data->flags & MMC_DATA_READ) ? ++ DMA_FROM_DEVICE : DMA_TO_DEVICE); ++ if (err) ++ data->bytes_xfered = 0; ++ else ++ data->bytes_xfered = blk_rq_bytes(mrq->req); ++ ++ } ++} ++ ++static void cmdq_dumpstate(struct mmc_host *mmc) ++{ ++ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); ++ cmdq_runtime_pm_get(cq_host); ++ cmdq_dumpregs(cq_host); ++ cmdq_runtime_pm_put(cq_host); ++} ++ ++static const struct mmc_cmdq_host_ops cmdq_host_ops = { ++ .enable = cmdq_enable, ++ .disable = cmdq_disable, ++ .request = cmdq_request, ++ .post_req = cmdq_post_req, ++ .halt = cmdq_halt, ++ .reset = cmdq_reset, ++ .dumpstate = cmdq_dumpstate, ++}; ++ ++struct cmdq_host *cmdq_pltfm_init(struct platform_device *pdev) ++{ ++ struct cmdq_host *cq_host = NULL; ++ struct resource *cmdq_memres = NULL; ++ ++ /* check and setup CMDQ interface */ ++ cmdq_memres = platform_get_resource_byname(pdev, IORESOURCE_MEM, ++ "cmdq_mem"); ++ if (!cmdq_memres) { ++ dev_dbg(&pdev->dev, "CMDQ not supported\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ cq_host = kzalloc(sizeof(*cq_host), GFP_KERNEL); ++ if (!cq_host) { ++ dev_err(&pdev->dev, "failed to allocate memory for CMDQ\n"); ++ return ERR_PTR(-ENOMEM); ++ } ++ cq_host->mmio = devm_ioremap(&pdev->dev, ++ cmdq_memres->start, ++ resource_size(cmdq_memres)); ++ if (!cq_host->mmio) { ++ dev_err(&pdev->dev, "failed to remap cmdq regs\n"); ++ kfree(cq_host); ++ return ERR_PTR(-EBUSY); ++ } ++ dev_dbg(&pdev->dev, "CMDQ ioremap: done\n"); ++ ++ return cq_host; ++} ++EXPORT_SYMBOL(cmdq_pltfm_init); ++ ++int cmdq_init(struct cmdq_host *cq_host, struct mmc_host *mmc, ++ bool dma64) ++{ ++ int err = 0; ++ ++ cq_host->dma64 = dma64; ++ cq_host->mmc = mmc; ++ cq_host->mmc->cmdq_private = cq_host; ++ ++ cq_host->num_slots = NUM_SLOTS; ++ cq_host->dcmd_slot = DCMD_SLOT; ++ ++ mmc->cmdq_ops = &cmdq_host_ops; ++ mmc->num_cq_slots = NUM_SLOTS; ++ mmc->dcmd_cq_slot = DCMD_SLOT; ++ ++ cq_host->mrq_slot = kzalloc(sizeof(cq_host->mrq_slot) * ++ cq_host->num_slots, GFP_KERNEL); ++ if (!cq_host->mrq_slot) ++ return -ENOMEM; ++ ++ init_completion(&cq_host->halt_comp); ++ return err; ++} ++EXPORT_SYMBOL(cmdq_init); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-cmdq.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-cmdq.h.patch new file mode 100644 index 00000000..acf6fa31 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-cmdq.h.patch @@ -0,0 +1,233 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-cmdq.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-cmdq.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,230 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#ifndef LINUX_MMC_CQ_HCI_H ++#define LINUX_MMC_CQ_HCI_H ++#include ++ ++/* registers */ ++/* version */ ++#define CQVER 0x00 ++/* capabilities */ ++#define CQCAP 0x04 ++/* configuration */ ++#define CQCFG 0x08 ++#define CQ_DCMD 0x00001000 ++#define CQ_TASK_DESC_SZ 0x00000100 ++#define CQ_ENABLE 0x00000001 ++ ++/* control */ ++#define CQCTL 0x0C ++#define CLEAR_ALL_TASKS 0x00000100 ++#define HALT 0x00000001 ++ ++/* interrupt status */ ++#define CQIS 0x10 ++#define CQIS_HAC (1 << 0) ++#define CQIS_TCC (1 << 1) ++#define CQIS_RED (1 << 2) ++#define CQIS_TCL (1 << 3) ++ ++/* interrupt status enable */ ++#define CQISTE 0x14 ++ ++/* interrupt signal enable */ ++#define CQISGE 0x18 ++ ++/* interrupt coalescing */ ++#define CQIC 0x1C ++#define CQIC_ENABLE (1 << 31) ++#define CQIC_RESET (1 << 16) ++#define CQIC_ICCTHWEN (1 << 15) ++#define CQIC_ICCTH(x) ((x & 0x1F) << 8) ++#define CQIC_ICTOVALWEN (1 << 7) ++#define CQIC_ICTOVAL(x) (x & 0x7F) ++ ++/* task list base address */ ++#define CQTDLBA 0x20 ++ ++/* task list base address upper */ ++#define CQTDLBAU 0x24 ++ ++/* door-bell */ ++#define CQTDBR 0x28 ++ ++/* task completion notification */ ++#define CQTCN 0x2C ++ ++/* device queue status */ ++#define CQDQS 0x30 ++ ++/* device pending tasks */ ++#define CQDPT 0x34 ++ ++/* task clear */ ++#define CQTCLR 0x38 ++ ++/* send status config 1 */ ++#define CQSSC1 0x40 ++/* ++ * Value n means CQE would send CMD13 during the transfer of data block ++ * BLOCK_CNT-n ++ */ ++#define SEND_QSR_INTERVAL 0x70001 ++ ++/* send status config 2 */ ++#define CQSSC2 0x44 ++ ++/* response for dcmd */ ++#define CQCRDCT 0x48 ++ ++/* response mode error mask */ ++#define CQRMEM 0x50 ++#define CQ_EXCEPTION (1 << 6) ++ ++/* task error info */ ++#define CQTERRI 0x54 ++ ++/* CQTERRI bit fields */ ++#define CQ_RMECI 0x1F ++#define CQ_RMETI (0x1F << 8) ++#define CQ_RMEFV (1 << 15) ++#define CQ_DTECI (0x3F << 16) ++#define CQ_DTETI (0x1F << 24) ++#define CQ_DTEFV (1 << 31) ++ ++#define GET_CMD_ERR_TAG(__r__) ((__r__ & CQ_RMETI) >> 8) ++#define GET_DAT_ERR_TAG(__r__) ((__r__ & CQ_DTETI) >> 24) ++ ++/* command response index */ ++#define CQCRI 0x58 ++ ++/* command response argument */ ++#define CQCRA 0x5C ++ ++#define CQ_INT_ALL 0xF ++#define CQIC_DEFAULT_ICCTH 31 ++#define CQIC_DEFAULT_ICTOVAL 1 ++ ++/* attribute fields */ ++#define VALID(x) ((x & 1) << 0) ++#define END(x) ((x & 1) << 1) ++#define INT(x) ((x & 1) << 2) ++#define ACT(x) ((x & 0x7) << 3) ++ ++/* data command task descriptor fields */ ++#define FORCED_PROG(x) ((x & 1) << 6) ++#define CONTEXT(x) ((x & 0xF) << 7) ++#define DATA_TAG(x) ((x & 1) << 11) ++#define DATA_DIR(x) ((x & 1) << 12) ++#define PRIORITY(x) ((x & 1) << 13) ++#define QBAR(x) ((x & 1) << 14) ++#define REL_WRITE(x) ((x & 1) << 15) ++#define BLK_COUNT(x) ((x & 0xFFFF) << 16) ++#define BLK_ADDR(x) ((x & 0xFFFFFFFF) << 32) ++ ++/* direct command task descriptor fields */ ++#define CMD_INDEX(x) ((x & 0x3F) << 16) ++#define CMD_TIMING(x) ((x & 1) << 22) ++#define RESP_TYPE(x) ((x & 0x3) << 23) ++ ++/* transfer descriptor fields */ ++#define DAT_LENGTH(x) ((x & 0xFFFF) << 16) ++#define DAT_ADDR_LO(x) ((x & 0xFFFFFFFF) << 32) ++#define DAT_ADDR_HI(x) ((x & 0xFFFFFFFF) << 0) ++ ++#define CQ_GOKE_CFG 0x100 ++#define CMDQ_SEND_STATUS_TRIGGER (1 << 31) ++ ++struct task_history { ++ u64 task; ++ bool is_dcmd; ++}; ++ ++struct cmdq_host { ++ const struct cmdq_host_ops *ops; ++ void __iomem *mmio; ++ struct mmc_host *mmc; ++ ++ /* 64 bit DMA */ ++ bool dma64; ++ int num_slots; ++ ++ u32 dcmd_slot; ++ u32 caps; ++#define CMDQ_TASK_DESC_SZ_128 0x1 ++ ++ u32 quirks; ++#define CMDQ_QUIRK_SHORT_TXFR_DESC_SZ 0x1 ++#define CMDQ_QUIRK_NO_DCMD 0x2 ++ ++ bool enabled; ++ bool halted; ++ bool init_done; ++ ++ u8 *desc_base; ++ ++ /* total descriptor size */ ++ u8 slot_sz; ++ ++ /* 64/128 bit depends on CQCFG */ ++ u8 task_desc_len; ++ ++ /* 64 bit on 32-bit arch, 128 bit on 64-bit */ ++ u8 link_desc_len; ++ ++ u8 *trans_desc_base; ++ /* same length as transfer descriptor */ ++ u8 trans_desc_len; ++ /* descriptor size per slot */ ++ u32 slot_desc_sz; ++ ++ dma_addr_t desc_dma_base; ++ dma_addr_t trans_desc_dma_base; ++ ++ struct task_history *thist; ++ u8 thist_idx; ++ ++ struct completion halt_comp; ++ struct mmc_request **mrq_slot; ++ void *private; ++}; ++ ++struct cmdq_host_ops { ++ void (*set_transfer_params)(struct mmc_host *mmc); ++ void (*set_data_timeout)(struct mmc_host *mmc, u32 val); ++ void (*clear_set_irqs)(struct mmc_host *mmc, bool clear); ++ void (*set_block_size)(struct mmc_host *mmc); ++ void (*dump_goke_regs)(struct mmc_host *mmc); ++ void (*write_l)(struct cmdq_host *host, u32 val, int reg); ++ u32 (*read_l)(struct cmdq_host *host, int reg); ++ void (*clear_set_dumpregs)(struct mmc_host *mmc, bool set); ++ void (*enhanced_strobe_mask)(struct mmc_host *mmc, bool set); ++ int (*reset)(struct mmc_host *mmc); ++ int (*crypto_cfg)(struct mmc_host *mmc, struct mmc_request *mrq, ++ u32 slot); ++ void (*crypto_cfg_reset)(struct mmc_host *mmc, unsigned int slot); ++ void (*post_cqe_halt)(struct mmc_host *mmc); ++}; ++ ++static inline void cmdq_writel(struct cmdq_host *host, u32 val, int reg) ++{ ++ if (unlikely(host->ops && host->ops->write_l)) ++ host->ops->write_l(host, val, reg); ++ else ++ writel_relaxed(val, host->mmio + reg); ++} ++ ++static inline u32 cmdq_readl(struct cmdq_host *host, int reg) ++{ ++ if (unlikely(host->ops && host->ops->read_l)) ++ return host->ops->read_l(host, reg); ++ else ++ return readl_relaxed(host->mmio + reg); ++} ++ ++extern irqreturn_t cmdq_irq(struct mmc_host *mmc, int err); ++extern int cmdq_init(struct cmdq_host *cq_host, struct mmc_host *mmc, ++ bool dma64); ++extern struct cmdq_host *cmdq_pltfm_init(struct platform_device *pdev); ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7202v300.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7202v300.c.patch new file mode 100644 index 00000000..aa3a3915 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7202v300.c.patch @@ -0,0 +1,499 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-gk7202v300.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-gk7202v300.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,495 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sdhci-pltfm.h" ++#include "sdhci-proc.h" ++ ++#ifdef CONFIG_MMC_SDHCI_GOKE ++#define PHASE_SCALE 32 ++#define EDGE_TUNING_PHASE_STEP 4 ++#define NOT_FOUND (-1) ++#define MAX_TUNING_NUM 1 ++#define MAX_FREQ 200000000 ++ ++#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 ++ ++#define REG_EMMC_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO0_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO1_DRV_DLL_CTRL 0x220 ++#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ ++#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) ++#define sdio_drv_sel(phase) ((phase) << 24) ++ ++#define REG_EMMC_DRV_DLL_STATUS 0x210 ++#define REG_SDIO0_DRV_DLL_STATUS 0x210 ++#define REG_SDIO1_DRV_DLL_STATUS 0x228 ++#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ ++#define SDIO_DRV_DLL_LOCK BIT(15) ++#define SDIO_DRV_DLL_READY BIT(14) ++ ++#define REG_EMMC_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 ++#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) ++ ++#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c ++#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) ++ ++#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c ++#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) ++#define sdio_samplb_sel(phase) ((phase) << 0) ++ ++#define REG_EMMC_DS_DLL_CTRL 0x200 ++#define EMMC_DS_DLL_MODE_SSEL BIT(13) ++#define EMMC_DS_DLL_SSEL_MASK 0x7f ++ ++#define REG_EMMC_DS180_DLL_CTRL 0x204 ++#define EMMC_DS180_DLL_BYPASS BIT(15) ++#define REG_EMMC_DS180_DLL_STATUS 0x218 ++#define EMMC_DS180_DLL_READY BIT(0) ++ ++#define REG_EMMC_DS_DLL_STATUS 0x214 ++#define EMMC_DS_DLL_READY BIT(0) ++ ++#define REG_EMMC_CLK_CTRL 0x1f4 ++#define REG_SDIO0_CLK_CTRL 0x1f4 ++#define REG_SDIO1_CLK_CTRL 0x22c ++#define REG_SDIO2_CLK_CTRL /* no sdio2 */ ++#define SDIO_CLK_DRV_DLL_RST BIT(29) ++#define SDIO_CLK_CRG_RST BIT(27) ++ ++#define IO_CFG_SR BIT(10) ++#define IO_CFG_PULL_DOWN BIT(9) ++#define IO_CFG_PULL_UP BIT(8) ++#define IO_CFG_DRV_STR_MASK (0xf << 4) ++#define io_cfg_drv_str_sel(str) ((str) << 4) ++#define IO_CFG_PIN_MUX_MASK (0xf << 0) ++#define io_cfg_pin_mux_sel(type) ((type) << 0) ++#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 ++#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 ++ ++#define IO_CFG_EMMC_DATA_LINE_COUNT 4 ++#define REG_CTRL_EMMC_CLK 0x0014 ++#define REG_CTRL_EMMC_CMD 0x0018 ++#define REG_CTRL_EMMC_DATA0 0x001c ++#define REG_CTRL_EMMC_DATA1 0x0028 ++#define REG_CTRL_EMMC_DATA2 0x0024 ++#define REG_CTRL_EMMC_DATA3 0x0020 ++ ++#define REG_CTRL_EMMC_DS 0x0058 ++#define REG_CTRL_EMMC_RST 0x005c ++static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { ++ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, ++ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3 ++}; ++ ++#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO0_CLK 0x0040 ++#define REG_CTRL_SDIO0_CMD 0x0044 ++#define REG_CTRL_SDIO0_DATA0 0x0048 ++#define REG_CTRL_SDIO0_DATA1 0x004C ++#define REG_CTRL_SDIO0_DATA2 0x0050 ++#define REG_CTRL_SDIO0_DATA3 0x0054 ++static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, ++ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 ++}; ++ ++#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO1_CLK 0x0048 ++#define REG_CTRL_SDIO1_CMD 0x004C ++#define REG_CTRL_SDIO1_DATA0 0x0064 ++#define REG_CTRL_SDIO1_DATA1 0x0060 ++#define REG_CTRL_SDIO1_DATA2 0x005C ++#define REG_CTRL_SDIO1_DATA3 0x0058 ++static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, ++ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 ++}; ++ ++struct sdhci_bsp_priv { ++ struct reset_control *crg_rst; ++ struct reset_control *dll_rst; ++ struct reset_control *sampl_rst; /* Not used */ ++ struct regmap *crg_regmap; ++ struct regmap *iocfg_regmap; ++ unsigned int f_max; ++ unsigned int devid; ++ unsigned int drv_phase; ++ unsigned int sampl_phase; ++ unsigned int tuning_phase; ++}; ++ ++static void bsp_mmc_crg_init(struct sdhci_host *host); ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); ++static int sdhci_bsp_parse_dt(struct sdhci_host *host); ++ ++static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) ++{ ++ return sdhci_pltfm_priv(sdhci_priv(host)); ++} ++ ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ u32 ctrl; ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ if (ios->enhanced_strobe) ++ ctrl |= SDHCI_ENH_STROBE_EN; ++ else ++ ctrl &= ~SDHCI_ENH_STROBE_EN; ++ ++ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); ++} ++ ++static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); ++ struct device_node *np = pdev->dev.of_node; ++ struct clk *clk = NULL; ++ int ret; ++ ++ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { ++ dev_err(&pdev->dev, "get crg_rst failed.\n"); ++ return PTR_ERR(bsp_priv->crg_rst); ++ } ++ ++ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { ++ dev_err(&pdev->dev, "get dll_rst failed.\n"); ++ return PTR_ERR(bsp_priv->dll_rst); ++ } ++ ++ bsp_priv->sampl_rst = NULL; ++ ++ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); ++ if (IS_ERR(bsp_priv->crg_regmap)) { ++ dev_err(&pdev->dev, "get crg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->crg_regmap); ++ } ++ ++ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); ++ if (IS_ERR(bsp_priv->iocfg_regmap)) { ++ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->iocfg_regmap); ++ } ++ ++ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) ++ return -EINVAL; ++ ++ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); ++ if (IS_ERR_OR_NULL(clk)) { ++ dev_err(mmc_dev(host->mmc), "get clk err\n"); ++ return -EINVAL; ++ } ++ ++ pltfm_host->clk = clk; ++ ++ bsp_mmc_crg_init(host); ++ ret = sdhci_bsp_parse_dt(host); ++ if (ret) ++ return ret; ++ ++ /* ++ * Only eMMC has a hw reset, and now eMMC signaling ++ * is fixed to 180 ++ */ ++ if (host->mmc->caps & MMC_CAP_HW_RESET) { ++ host->flags &= ~SDHCI_SIGNALING_330; ++ host->flags |= SDHCI_SIGNALING_180; ++ } ++ ++ /* ++ * We parse the support timings from dts, so we read the ++ * host capabilities early and clear the timing capabilities, ++ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would ++ * not read it again ++ */ ++ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); ++ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); ++ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | ++ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); ++ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | ++ SDHCI_QUIRK_SINGLE_POWER_WRITE; ++ ++ host->mmc_host_ops.hs400_enhanced_strobe = ++ sdhci_bsp_hs400_enhanced_strobe; ++ ++ mci_host[slot_index++] = host->mmc; ++ ++ return 0; ++} ++ ++static void bsp_wait_ds_dll_lock(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int reg; ++ unsigned int timeout = 20; ++ ++ do { ++ reg = 0; ++ regmap_read(bsp_priv->crg_regmap, ++ REG_EMMC_DS180_DLL_STATUS, ®); ++ if (reg & EMMC_DS180_DLL_READY) ++ return; ++ ++ mdelay(1); ++ timeout--; ++ } while (timeout > 0); ++ ++ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); ++} ++ ++static void bsp_set_ds_dll_delay(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_host_extra_init(struct sdhci_host *host) ++{ ++ unsigned short ctrl; ++ unsigned int mbiiu_ctrl, val; ++ ++ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); ++ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; ++ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); ++ ++ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); ++ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | ++ SDHCI_UNDEFL_INCR_EN); ++ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ ++ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ ++ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); ++ ++ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ val &= ~SDHCI_CMD_DLY_EN; ++ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; ++ val &= ~SDHCI_DOUT_EN_F_EDGE; ++ ++ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); ++ host->error_count = 0; ++} ++ ++static void bsp_set_drv_str(struct regmap *iocfg_regmap, ++ unsigned int offset, unsigned int pull_up, ++ unsigned int pull_down, unsigned int sr, ++ unsigned int drv_str) ++{ ++ unsigned int reg = 0; ++ ++ regmap_read(iocfg_regmap, offset, ®); ++ ++ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | ++ IO_CFG_DRV_STR_MASK | IO_CFG_SR); ++ reg |= (pull_up ? IO_CFG_PULL_UP : 0); ++ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); ++ reg |= (sr ? IO_CFG_SR : 0); ++ reg |= io_cfg_drv_str_sel(drv_str); ++ ++ regmap_write(iocfg_regmap, offset, reg); ++} ++ ++static void bsp_set_emmc_ctrl(struct sdhci_host *host) ++{ ++ unsigned int reg; ++ ++ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ reg |= SDHCI_CARD_IS_EMMC; ++ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); ++} ++ ++ ++static void bsp_set_mmc_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_MMC_HS400: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS200: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ case MMC_TIMING_MMC_DDR52: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ } ++} ++ ++static void bsp_set_sd_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_SD_HS: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ } ++} ++ ++static void bsp_set_sdio_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio1_data_reg[i], 1, 0, 0, 0x6); /* set drv level 6 */ ++} ++ ++static void bsp_set_io_config(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ unsigned int reg = 0; ++ ++ if (devid == 0) { ++ /* For mmc0: eMMC and SD card */ ++ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) ++ bsp_set_mmc_drv(host); ++ ++ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) ++ bsp_set_sd_drv(host); ++ } else { ++ /* For mmc1: sdio wifi */ ++ bsp_set_sdio_drv(host); ++ } ++} ++ ++static void bsp_get_phase(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ if (devid == 0) { ++ /* For eMMC and SD card */ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { ++ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { ++ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { ++ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } else { ++ /* For SDIO device */ ++ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || ++ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else { ++ /* UHS_SDR12 */ ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } ++} ++ ++static int bsp_support_runtime_pm(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ /* Only enable for mmc0 eMMC and SD card */ ++ if (devid == 0) ++ return 1; ++ else ++ return 0; ++} ++ ++#include "sdhci-goke.c" ++#endif +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7205v200.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7205v200.c.patch new file mode 100644 index 00000000..93a0cae2 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7205v200.c.patch @@ -0,0 +1,499 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-gk7205v200.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-gk7205v200.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,495 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sdhci-pltfm.h" ++#include "sdhci-proc.h" ++ ++#ifdef CONFIG_MMC_SDHCI_GOKE ++#define PHASE_SCALE 32 ++#define EDGE_TUNING_PHASE_STEP 4 ++#define NOT_FOUND (-1) ++#define MAX_TUNING_NUM 1 ++#define MAX_FREQ 200000000 ++ ++#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 ++ ++#define REG_EMMC_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO0_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO1_DRV_DLL_CTRL 0x220 ++#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ ++#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) ++#define sdio_drv_sel(phase) ((phase) << 24) ++ ++#define REG_EMMC_DRV_DLL_STATUS 0x210 ++#define REG_SDIO0_DRV_DLL_STATUS 0x210 ++#define REG_SDIO1_DRV_DLL_STATUS 0x228 ++#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ ++#define SDIO_DRV_DLL_LOCK BIT(15) ++#define SDIO_DRV_DLL_READY BIT(14) ++ ++#define REG_EMMC_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 ++#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) ++ ++#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c ++#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) ++ ++#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c ++#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) ++#define sdio_samplb_sel(phase) ((phase) << 0) ++ ++#define REG_EMMC_DS_DLL_CTRL 0x200 ++#define EMMC_DS_DLL_MODE_SSEL BIT(13) ++#define EMMC_DS_DLL_SSEL_MASK 0x7f ++ ++#define REG_EMMC_DS180_DLL_CTRL 0x204 ++#define EMMC_DS180_DLL_BYPASS BIT(15) ++#define REG_EMMC_DS180_DLL_STATUS 0x218 ++#define EMMC_DS180_DLL_READY BIT(0) ++ ++#define REG_EMMC_DS_DLL_STATUS 0x214 ++#define EMMC_DS_DLL_READY BIT(0) ++ ++#define REG_EMMC_CLK_CTRL 0x1f4 ++#define REG_SDIO0_CLK_CTRL 0x1f4 ++#define REG_SDIO1_CLK_CTRL 0x22c ++#define REG_SDIO2_CLK_CTRL /* no sdio2 */ ++#define SDIO_CLK_DRV_DLL_RST BIT(29) ++#define SDIO_CLK_CRG_RST BIT(27) ++ ++#define IO_CFG_SR BIT(10) ++#define IO_CFG_PULL_DOWN BIT(9) ++#define IO_CFG_PULL_UP BIT(8) ++#define IO_CFG_DRV_STR_MASK (0xf << 4) ++#define io_cfg_drv_str_sel(str) ((str) << 4) ++#define IO_CFG_PIN_MUX_MASK (0xf << 0) ++#define io_cfg_pin_mux_sel(type) ((type) << 0) ++#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 ++#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 ++ ++#define IO_CFG_EMMC_DATA_LINE_COUNT 4 ++#define REG_CTRL_EMMC_CLK 0x0014 ++#define REG_CTRL_EMMC_CMD 0x0018 ++#define REG_CTRL_EMMC_DATA0 0x001c ++#define REG_CTRL_EMMC_DATA1 0x0028 ++#define REG_CTRL_EMMC_DATA2 0x0024 ++#define REG_CTRL_EMMC_DATA3 0x0020 ++ ++#define REG_CTRL_EMMC_DS 0x0058 ++#define REG_CTRL_EMMC_RST 0x005c ++static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { ++ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, ++ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3 ++}; ++ ++#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO0_CLK 0x0040 ++#define REG_CTRL_SDIO0_CMD 0x0044 ++#define REG_CTRL_SDIO0_DATA0 0x0048 ++#define REG_CTRL_SDIO0_DATA1 0x004C ++#define REG_CTRL_SDIO0_DATA2 0x0050 ++#define REG_CTRL_SDIO0_DATA3 0x0054 ++static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, ++ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 ++}; ++ ++#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO1_CLK 0x0048 ++#define REG_CTRL_SDIO1_CMD 0x004C ++#define REG_CTRL_SDIO1_DATA0 0x0064 ++#define REG_CTRL_SDIO1_DATA1 0x0060 ++#define REG_CTRL_SDIO1_DATA2 0x005C ++#define REG_CTRL_SDIO1_DATA3 0x0058 ++static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, ++ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 ++}; ++ ++struct sdhci_bsp_priv { ++ struct reset_control *crg_rst; ++ struct reset_control *dll_rst; ++ struct reset_control *sampl_rst; /* Not used */ ++ struct regmap *crg_regmap; ++ struct regmap *iocfg_regmap; ++ unsigned int f_max; ++ unsigned int devid; ++ unsigned int drv_phase; ++ unsigned int sampl_phase; ++ unsigned int tuning_phase; ++}; ++ ++static void bsp_mmc_crg_init(struct sdhci_host *host); ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); ++static int sdhci_bsp_parse_dt(struct sdhci_host *host); ++ ++static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) ++{ ++ return sdhci_pltfm_priv(sdhci_priv(host)); ++} ++ ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ u32 ctrl; ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ if (ios->enhanced_strobe) ++ ctrl |= SDHCI_ENH_STROBE_EN; ++ else ++ ctrl &= ~SDHCI_ENH_STROBE_EN; ++ ++ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); ++} ++ ++static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); ++ struct device_node *np = pdev->dev.of_node; ++ struct clk *clk = NULL; ++ int ret; ++ ++ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { ++ dev_err(&pdev->dev, "get crg_rst failed.\n"); ++ return PTR_ERR(bsp_priv->crg_rst); ++ } ++ ++ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { ++ dev_err(&pdev->dev, "get dll_rst failed.\n"); ++ return PTR_ERR(bsp_priv->dll_rst); ++ } ++ ++ bsp_priv->sampl_rst = NULL; ++ ++ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); ++ if (IS_ERR(bsp_priv->crg_regmap)) { ++ dev_err(&pdev->dev, "get crg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->crg_regmap); ++ } ++ ++ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); ++ if (IS_ERR(bsp_priv->iocfg_regmap)) { ++ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->iocfg_regmap); ++ } ++ ++ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) ++ return -EINVAL; ++ ++ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); ++ if (IS_ERR_OR_NULL(clk)) { ++ dev_err(mmc_dev(host->mmc), "get clk err\n"); ++ return -EINVAL; ++ } ++ ++ pltfm_host->clk = clk; ++ ++ bsp_mmc_crg_init(host); ++ ret = sdhci_bsp_parse_dt(host); ++ if (ret) ++ return ret; ++ ++ /* ++ * Only eMMC has a hw reset, and now eMMC signaling ++ * is fixed to 180 ++ */ ++ if (host->mmc->caps & MMC_CAP_HW_RESET) { ++ host->flags &= ~SDHCI_SIGNALING_330; ++ host->flags |= SDHCI_SIGNALING_180; ++ } ++ ++ /* ++ * We parse the support timings from dts, so we read the ++ * host capabilities early and clear the timing capabilities, ++ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would ++ * not read it again ++ */ ++ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); ++ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); ++ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | ++ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); ++ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | ++ SDHCI_QUIRK_SINGLE_POWER_WRITE; ++ ++ host->mmc_host_ops.hs400_enhanced_strobe = ++ sdhci_bsp_hs400_enhanced_strobe; ++ ++ mci_host[slot_index++] = host->mmc; ++ ++ return 0; ++} ++ ++static void bsp_wait_ds_dll_lock(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int reg; ++ unsigned int timeout = 20; ++ ++ do { ++ reg = 0; ++ regmap_read(bsp_priv->crg_regmap, ++ REG_EMMC_DS180_DLL_STATUS, ®); ++ if (reg & EMMC_DS180_DLL_READY) ++ return; ++ ++ mdelay(1); ++ timeout--; ++ } while (timeout > 0); ++ ++ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); ++} ++ ++static void bsp_set_ds_dll_delay(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_host_extra_init(struct sdhci_host *host) ++{ ++ unsigned short ctrl; ++ unsigned int mbiiu_ctrl, val; ++ ++ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); ++ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; ++ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); ++ ++ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); ++ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | ++ SDHCI_UNDEFL_INCR_EN); ++ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ ++ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ ++ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); ++ ++ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ val &= ~SDHCI_CMD_DLY_EN; ++ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; ++ val &= ~SDHCI_DOUT_EN_F_EDGE; ++ ++ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); ++ host->error_count = 0; ++} ++ ++static void bsp_set_drv_str(struct regmap *iocfg_regmap, ++ unsigned int offset, unsigned int pull_up, ++ unsigned int pull_down, unsigned int sr, ++ unsigned int drv_str) ++{ ++ unsigned int reg = 0; ++ ++ regmap_read(iocfg_regmap, offset, ®); ++ ++ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | ++ IO_CFG_DRV_STR_MASK | IO_CFG_SR); ++ reg |= (pull_up ? IO_CFG_PULL_UP : 0); ++ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); ++ reg |= (sr ? IO_CFG_SR : 0); ++ reg |= io_cfg_drv_str_sel(drv_str); ++ ++ regmap_write(iocfg_regmap, offset, reg); ++} ++ ++static void bsp_set_emmc_ctrl(struct sdhci_host *host) ++{ ++ unsigned int reg; ++ ++ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ reg |= SDHCI_CARD_IS_EMMC; ++ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); ++} ++ ++ ++static void bsp_set_mmc_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_MMC_HS400: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS200: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ case MMC_TIMING_MMC_DDR52: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ } ++} ++ ++static void bsp_set_sd_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_SD_HS: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ } ++} ++ ++static void bsp_set_sdio_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio1_data_reg[i], 1, 0, 0, 0x7); /* set drv level 7 */ ++} ++ ++static void bsp_set_io_config(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ unsigned int reg = 0; ++ ++ if (devid == 0) { ++ /* For mmc0: eMMC and SD card */ ++ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) ++ bsp_set_mmc_drv(host); ++ ++ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) ++ bsp_set_sd_drv(host); ++ } else { ++ /* For mmc1: sdio wifi */ ++ bsp_set_sdio_drv(host); ++ } ++} ++ ++static void bsp_get_phase(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ if (devid == 0) { ++ /* For eMMC and SD card */ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { ++ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { ++ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { ++ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } else { ++ /* For SDIO device */ ++ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || ++ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else { ++ /* UHS_SDR12 */ ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } ++} ++ ++static int bsp_support_runtime_pm(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ /* Only enable for mmc0 eMMC and SD card */ ++ if (devid == 0) ++ return 1; ++ else ++ return 0; ++} ++ ++#include "sdhci-goke.c" ++#endif +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7205v300.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7205v300.c.patch new file mode 100644 index 00000000..e78fa22c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7205v300.c.patch @@ -0,0 +1,512 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-gk7205v300.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-gk7205v300.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,508 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sdhci-pltfm.h" ++#include "sdhci-proc.h" ++ ++#ifdef CONFIG_MMC_SDHCI_GOKE ++#define PHASE_SCALE 32 ++#define EDGE_TUNING_PHASE_STEP 4 ++#define NOT_FOUND (-1) ++#define MAX_TUNING_NUM 1 ++#define MAX_FREQ 200000000 ++ ++#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 ++ ++#define REG_EMMC_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO0_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO1_DRV_DLL_CTRL 0x220 ++#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ ++#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) ++#define sdio_drv_sel(phase) ((phase) << 24) ++ ++#define REG_EMMC_DRV_DLL_STATUS 0x210 ++#define REG_SDIO0_DRV_DLL_STATUS 0x210 ++#define REG_SDIO1_DRV_DLL_STATUS 0x228 ++#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ ++#define SDIO_DRV_DLL_LOCK BIT(15) ++#define SDIO_DRV_DLL_READY BIT(14) ++ ++#define REG_EMMC_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 ++#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) ++ ++#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c ++#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) ++ ++#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c ++#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) ++#define sdio_samplb_sel(phase) ((phase) << 0) ++ ++#define REG_EMMC_DS_DLL_CTRL 0x200 ++#define EMMC_DS_DLL_MODE_SSEL BIT(13) ++#define EMMC_DS_DLL_SSEL_MASK 0x7f ++ ++#define REG_EMMC_DS180_DLL_CTRL 0x204 ++#define EMMC_DS180_DLL_BYPASS BIT(15) ++#define REG_EMMC_DS180_DLL_STATUS 0x218 ++#define EMMC_DS180_DLL_READY BIT(0) ++ ++#define REG_EMMC_DS_DLL_STATUS 0x214 ++#define EMMC_DS_DLL_READY BIT(0) ++ ++#define REG_EMMC_CLK_CTRL 0x1f4 ++#define REG_SDIO0_CLK_CTRL 0x1f4 ++#define REG_SDIO1_CLK_CTRL 0x22c ++#define REG_SDIO2_CLK_CTRL /* no sdio2 */ ++#define SDIO_CLK_DRV_DLL_RST BIT(29) ++#define SDIO_CLK_CRG_RST BIT(27) ++ ++#define IO_CFG_SR BIT(10) ++#define IO_CFG_PULL_DOWN BIT(9) ++#define IO_CFG_PULL_UP BIT(8) ++#define IO_CFG_DRV_STR_MASK (0xf << 4) ++#define io_cfg_drv_str_sel(str) ((str) << 4) ++#define IO_CFG_PIN_MUX_MASK (0xf << 0) ++#define io_cfg_pin_mux_sel(type) ((type) << 0) ++#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 ++#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 ++ ++#define IO_CFG_EMMC_DATA_LINE_COUNT 8 ++#define REG_CTRL_EMMC_CLK 0x0014 ++#define REG_CTRL_EMMC_CMD 0x0018 ++#define REG_CTRL_EMMC_DATA0 0x001c ++#define REG_CTRL_EMMC_DATA1 0x0028 ++#define REG_CTRL_EMMC_DATA2 0x0024 ++#define REG_CTRL_EMMC_DATA3 0x0020 ++#define REG_CTRL_EMMC_DATA4 0x0030 ++#define REG_CTRL_EMMC_DATA5 0x0034 ++#define REG_CTRL_EMMC_DATA6 0x0038 ++#define REG_CTRL_EMMC_DATA7 0x003c ++#define REG_CTRL_EMMC_DS 0x0058 ++#define REG_CTRL_EMMC_RST 0x005c ++static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { ++ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, ++ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3, ++ REG_CTRL_EMMC_DATA4, REG_CTRL_EMMC_DATA5, ++ REG_CTRL_EMMC_DATA6, REG_CTRL_EMMC_DATA7 ++}; ++ ++#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO0_CLK 0x0040 ++#define REG_CTRL_SDIO0_CMD 0x0044 ++#define REG_CTRL_SDIO0_DATA0 0x0048 ++#define REG_CTRL_SDIO0_DATA1 0x004C ++#define REG_CTRL_SDIO0_DATA2 0x0050 ++#define REG_CTRL_SDIO0_DATA3 0x0054 ++static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, ++ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 ++}; ++ ++#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO1_CLK 0x0060 ++#define REG_CTRL_SDIO1_CMD 0x0064 ++#define REG_CTRL_SDIO1_DATA0 0x0068 ++#define REG_CTRL_SDIO1_DATA1 0x006C ++#define REG_CTRL_SDIO1_DATA2 0x0070 ++#define REG_CTRL_SDIO1_DATA3 0x0074 ++static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, ++ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 ++}; ++ ++struct sdhci_bsp_priv { ++ struct reset_control *crg_rst; ++ struct reset_control *dll_rst; ++ struct reset_control *sampl_rst; /* Not used */ ++ struct regmap *crg_regmap; ++ struct regmap *iocfg_regmap; ++ unsigned int f_max; ++ unsigned int devid; ++ unsigned int drv_phase; ++ unsigned int sampl_phase; ++ unsigned int tuning_phase; ++}; ++ ++static void bsp_mmc_crg_init(struct sdhci_host *host); ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); ++static int sdhci_bsp_parse_dt(struct sdhci_host *host); ++ ++static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) ++{ ++ return sdhci_pltfm_priv(sdhci_priv(host)); ++} ++ ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ u32 ctrl; ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ if (ios->enhanced_strobe) ++ ctrl |= SDHCI_ENH_STROBE_EN; ++ else ++ ctrl &= ~SDHCI_ENH_STROBE_EN; ++ ++ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); ++ ++ ctrl = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ if (ios->enhanced_strobe) ++ ctrl |= SDHCI_CMD_DLY_EN; ++ else ++ ctrl &= ~SDHCI_CMD_DLY_EN; ++ ++ sdhci_writel(host, ctrl, SDHCI_MULTI_CYCLE); ++} ++ ++static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); ++ struct device_node *np = pdev->dev.of_node; ++ struct clk *clk = NULL; ++ int ret; ++ ++ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { ++ dev_err(&pdev->dev, "get crg_rst failed.\n"); ++ return PTR_ERR(bsp_priv->crg_rst); ++ } ++ ++ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { ++ dev_err(&pdev->dev, "get dll_rst failed.\n"); ++ return PTR_ERR(bsp_priv->dll_rst); ++ } ++ ++ bsp_priv->sampl_rst = NULL; ++ ++ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); ++ if (IS_ERR(bsp_priv->crg_regmap)) { ++ dev_err(&pdev->dev, "get crg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->crg_regmap); ++ } ++ ++ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); ++ if (IS_ERR(bsp_priv->iocfg_regmap)) { ++ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->iocfg_regmap); ++ } ++ ++ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) ++ return -EINVAL; ++ ++ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); ++ if (IS_ERR_OR_NULL(clk)) { ++ dev_err(mmc_dev(host->mmc), "get clk err\n"); ++ return -EINVAL; ++ } ++ ++ pltfm_host->clk = clk; ++ ++ bsp_mmc_crg_init(host); ++ ret = sdhci_bsp_parse_dt(host); ++ if (ret) ++ return ret; ++ ++ /* ++ * Only eMMC has a hw reset, and now eMMC signaling ++ * is fixed to 180 ++ */ ++ if (host->mmc->caps & MMC_CAP_HW_RESET) { ++ host->flags &= ~SDHCI_SIGNALING_330; ++ host->flags |= SDHCI_SIGNALING_180; ++ } ++ ++ /* ++ * We parse the support timings from dts, so we read the ++ * host capabilities early and clear the timing capabilities, ++ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would ++ * not read it again ++ */ ++ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); ++ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); ++ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | ++ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); ++ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | ++ SDHCI_QUIRK_SINGLE_POWER_WRITE; ++ ++ host->mmc_host_ops.hs400_enhanced_strobe = ++ sdhci_bsp_hs400_enhanced_strobe; ++ ++ mci_host[slot_index++] = host->mmc; ++ ++ return 0; ++} ++ ++static void bsp_wait_ds_dll_lock(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int reg; ++ unsigned int timeout = 20; ++ ++ do { ++ reg = 0; ++ regmap_read(bsp_priv->crg_regmap, ++ REG_EMMC_DS180_DLL_STATUS, ®); ++ if (reg & EMMC_DS180_DLL_READY) ++ return; ++ ++ mdelay(1); ++ timeout--; ++ } while (timeout > 0); ++ ++ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); ++} ++ ++static void bsp_set_ds_dll_delay(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_host_extra_init(struct sdhci_host *host) ++{ ++ unsigned short ctrl; ++ unsigned int mbiiu_ctrl, val; ++ ++ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); ++ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; ++ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); ++ ++ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); ++ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | ++ SDHCI_UNDEFL_INCR_EN); ++ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ ++ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ ++ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); ++ ++ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ val &= ~SDHCI_CMD_DLY_EN; ++ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; ++ val &= ~SDHCI_DOUT_EN_F_EDGE; ++ ++ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); ++ host->error_count = 0; ++} ++ ++static void bsp_set_drv_str(struct regmap *iocfg_regmap, ++ unsigned int offset, unsigned int pull_up, ++ unsigned int pull_down, unsigned int sr, ++ unsigned int drv_str) ++{ ++ unsigned int reg = 0; ++ ++ regmap_read(iocfg_regmap, offset, ®); ++ ++ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | ++ IO_CFG_DRV_STR_MASK | IO_CFG_SR); ++ reg |= (pull_up ? IO_CFG_PULL_UP : 0); ++ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); ++ reg |= (sr ? IO_CFG_SR : 0); ++ reg |= io_cfg_drv_str_sel(drv_str); ++ ++ regmap_write(iocfg_regmap, offset, reg); ++} ++ ++static void bsp_set_emmc_ctrl(struct sdhci_host *host) ++{ ++ unsigned int reg; ++ ++ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ reg |= SDHCI_CARD_IS_EMMC; ++ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); ++} ++ ++ ++static void bsp_set_mmc_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_MMC_HS400: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS200: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ case MMC_TIMING_MMC_DDR52: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ } ++} ++ ++static void bsp_set_sd_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_SD_HS: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ } ++} ++ ++static void bsp_set_sdio_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio1_data_reg[i], 1, 0, 0, 0x7); /* set drv level 7 */ ++} ++ ++static void bsp_set_io_config(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ unsigned int reg = 0; ++ ++ if (devid == 0) { ++ /* For mmc0: eMMC and SD card */ ++ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) ++ bsp_set_mmc_drv(host); ++ ++ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) ++ bsp_set_sd_drv(host); ++ } else { ++ /* For mmc1: sdio wifi */ ++ bsp_set_sdio_drv(host); ++ } ++} ++ ++static void bsp_get_phase(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ if (devid == 0) { ++ /* For eMMC and SD card */ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { ++ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { ++ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { ++ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } else { ++ /* For SDIO device */ ++ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || ++ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else { ++ /* UHS_SDR12 */ ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } ++} ++ ++static int bsp_support_runtime_pm(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ /* Only enable for mmc0 eMMC and SD card */ ++ if (devid == 0) ++ return 1; ++ else ++ return 0; ++} ++ ++#include "sdhci-goke.c" ++#endif +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7605v100.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7605v100.c.patch new file mode 100644 index 00000000..92e855c3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-gk7605v100.c.patch @@ -0,0 +1,512 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-gk7605v100.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-gk7605v100.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,508 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sdhci-pltfm.h" ++#include "sdhci-proc.h" ++ ++#ifdef CONFIG_MMC_SDHCI_GOKE ++#define PHASE_SCALE 32 ++#define EDGE_TUNING_PHASE_STEP 4 ++#define NOT_FOUND (-1) ++#define MAX_TUNING_NUM 1 ++#define MAX_FREQ 200000000 ++ ++#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 ++ ++#define REG_EMMC_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO0_DRV_DLL_CTRL 0x1fc ++#define REG_SDIO1_DRV_DLL_CTRL 0x220 ++#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ ++#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) ++#define sdio_drv_sel(phase) ((phase) << 24) ++ ++#define REG_EMMC_DRV_DLL_STATUS 0x210 ++#define REG_SDIO0_DRV_DLL_STATUS 0x210 ++#define REG_SDIO1_DRV_DLL_STATUS 0x228 ++#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ ++#define SDIO_DRV_DLL_LOCK BIT(15) ++#define SDIO_DRV_DLL_READY BIT(14) ++ ++#define REG_EMMC_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 ++#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 ++#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) ++ ++#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 ++#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c ++#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) ++ ++#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 ++#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c ++#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ ++#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) ++#define sdio_samplb_sel(phase) ((phase) << 0) ++ ++#define REG_EMMC_DS_DLL_CTRL 0x200 ++#define EMMC_DS_DLL_MODE_SSEL BIT(13) ++#define EMMC_DS_DLL_SSEL_MASK 0x7f ++ ++#define REG_EMMC_DS180_DLL_CTRL 0x204 ++#define EMMC_DS180_DLL_BYPASS BIT(15) ++#define REG_EMMC_DS180_DLL_STATUS 0x218 ++#define EMMC_DS180_DLL_READY BIT(0) ++ ++#define REG_EMMC_DS_DLL_STATUS 0x214 ++#define EMMC_DS_DLL_READY BIT(0) ++ ++#define REG_EMMC_CLK_CTRL 0x1f4 ++#define REG_SDIO0_CLK_CTRL 0x1f4 ++#define REG_SDIO1_CLK_CTRL 0x22c ++#define REG_SDIO2_CLK_CTRL /* no sdio2 */ ++#define SDIO_CLK_DRV_DLL_RST BIT(29) ++#define SDIO_CLK_CRG_RST BIT(27) ++ ++#define IO_CFG_SR BIT(10) ++#define IO_CFG_PULL_DOWN BIT(9) ++#define IO_CFG_PULL_UP BIT(8) ++#define IO_CFG_DRV_STR_MASK (0xf << 4) ++#define io_cfg_drv_str_sel(str) ((str) << 4) ++#define IO_CFG_PIN_MUX_MASK (0xf << 0) ++#define io_cfg_pin_mux_sel(type) ((type) << 0) ++#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 ++#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 ++ ++#define IO_CFG_EMMC_DATA_LINE_COUNT 8 ++#define REG_CTRL_EMMC_CLK 0x0014 ++#define REG_CTRL_EMMC_CMD 0x0018 ++#define REG_CTRL_EMMC_DATA0 0x001c ++#define REG_CTRL_EMMC_DATA1 0x0028 ++#define REG_CTRL_EMMC_DATA2 0x0024 ++#define REG_CTRL_EMMC_DATA3 0x0020 ++#define REG_CTRL_EMMC_DATA4 0x0030 ++#define REG_CTRL_EMMC_DATA5 0x0034 ++#define REG_CTRL_EMMC_DATA6 0x0038 ++#define REG_CTRL_EMMC_DATA7 0x003c ++#define REG_CTRL_EMMC_DS 0x0058 ++#define REG_CTRL_EMMC_RST 0x005c ++static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { ++ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, ++ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3, ++ REG_CTRL_EMMC_DATA4, REG_CTRL_EMMC_DATA5, ++ REG_CTRL_EMMC_DATA6, REG_CTRL_EMMC_DATA7 ++}; ++ ++#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO0_CLK 0x0040 ++#define REG_CTRL_SDIO0_CMD 0x0044 ++#define REG_CTRL_SDIO0_DATA0 0x0048 ++#define REG_CTRL_SDIO0_DATA1 0x004C ++#define REG_CTRL_SDIO0_DATA2 0x0050 ++#define REG_CTRL_SDIO0_DATA3 0x0054 ++static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, ++ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 ++}; ++ ++#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 ++#define REG_CTRL_SDIO1_CLK 0x0060 ++#define REG_CTRL_SDIO1_CMD 0x0064 ++#define REG_CTRL_SDIO1_DATA0 0x0068 ++#define REG_CTRL_SDIO1_DATA1 0x006C ++#define REG_CTRL_SDIO1_DATA2 0x0070 ++#define REG_CTRL_SDIO1_DATA3 0x0074 ++static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { ++ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, ++ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 ++}; ++ ++struct sdhci_bsp_priv { ++ struct reset_control *crg_rst; ++ struct reset_control *dll_rst; ++ struct reset_control *sampl_rst; /* Not used */ ++ struct regmap *crg_regmap; ++ struct regmap *iocfg_regmap; ++ unsigned int f_max; ++ unsigned int devid; ++ unsigned int drv_phase; ++ unsigned int sampl_phase; ++ unsigned int tuning_phase; ++}; ++ ++static void bsp_mmc_crg_init(struct sdhci_host *host); ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); ++static int sdhci_bsp_parse_dt(struct sdhci_host *host); ++ ++static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) ++{ ++ return sdhci_pltfm_priv(sdhci_priv(host)); ++} ++ ++static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ u32 ctrl; ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ if (ios->enhanced_strobe) ++ ctrl |= SDHCI_ENH_STROBE_EN; ++ else ++ ctrl &= ~SDHCI_ENH_STROBE_EN; ++ ++ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); ++ ++ ctrl = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ if (ios->enhanced_strobe) ++ ctrl |= SDHCI_CMD_DLY_EN; ++ else ++ ctrl &= ~SDHCI_CMD_DLY_EN; ++ ++ sdhci_writel(host, ctrl, SDHCI_MULTI_CYCLE); ++} ++ ++static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); ++ struct device_node *np = pdev->dev.of_node; ++ struct clk *clk = NULL; ++ int ret; ++ ++ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { ++ dev_err(&pdev->dev, "get crg_rst failed.\n"); ++ return PTR_ERR(bsp_priv->crg_rst); ++ } ++ ++ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); ++ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { ++ dev_err(&pdev->dev, "get dll_rst failed.\n"); ++ return PTR_ERR(bsp_priv->dll_rst); ++ } ++ ++ bsp_priv->sampl_rst = NULL; ++ ++ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); ++ if (IS_ERR(bsp_priv->crg_regmap)) { ++ dev_err(&pdev->dev, "get crg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->crg_regmap); ++ } ++ ++ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); ++ if (IS_ERR(bsp_priv->iocfg_regmap)) { ++ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); ++ return PTR_ERR(bsp_priv->iocfg_regmap); ++ } ++ ++ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) ++ return -EINVAL; ++ ++ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); ++ if (IS_ERR_OR_NULL(clk)) { ++ dev_err(mmc_dev(host->mmc), "get clk err\n"); ++ return -EINVAL; ++ } ++ ++ pltfm_host->clk = clk; ++ ++ bsp_mmc_crg_init(host); ++ ret = sdhci_bsp_parse_dt(host); ++ if (ret) ++ return ret; ++ ++ /* ++ * Only eMMC has a hw reset, and now eMMC signaling ++ * is fixed to 180 ++ */ ++ if (host->mmc->caps & MMC_CAP_HW_RESET) { ++ host->flags &= ~SDHCI_SIGNALING_330; ++ host->flags |= SDHCI_SIGNALING_180; ++ } ++ ++ /* ++ * We parse the support timings from dts, so we read the ++ * host capabilities early and clear the timing capabilities, ++ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would ++ * not read it again ++ */ ++ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); ++ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); ++ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | ++ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); ++ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | ++ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | ++ SDHCI_QUIRK_SINGLE_POWER_WRITE; ++ ++ host->mmc_host_ops.hs400_enhanced_strobe = ++ sdhci_bsp_hs400_enhanced_strobe; ++ ++ mci_host[slot_index++] = host->mmc; ++ ++ return 0; ++} ++ ++static void bsp_wait_ds_dll_lock(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int reg; ++ unsigned int timeout = 20; ++ ++ do { ++ reg = 0; ++ regmap_read(bsp_priv->crg_regmap, ++ REG_EMMC_DS180_DLL_STATUS, ®); ++ if (reg & EMMC_DS180_DLL_READY) ++ return; ++ ++ mdelay(1); ++ timeout--; ++ } while (timeout > 0); ++ ++ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); ++} ++ ++static void bsp_set_ds_dll_delay(struct sdhci_host *host) ++{ ++ /* Do nothing */ ++} ++ ++static void bsp_host_extra_init(struct sdhci_host *host) ++{ ++ unsigned short ctrl; ++ unsigned int mbiiu_ctrl, val; ++ ++ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); ++ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; ++ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); ++ ++ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); ++ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | ++ SDHCI_UNDEFL_INCR_EN); ++ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ ++ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ ++ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); ++ ++ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ val &= ~SDHCI_CMD_DLY_EN; ++ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; ++ val &= ~SDHCI_DOUT_EN_F_EDGE; ++ ++ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); ++ host->error_count = 0; ++} ++ ++static void bsp_set_drv_str(struct regmap *iocfg_regmap, ++ unsigned int offset, unsigned int pull_up, ++ unsigned int pull_down, unsigned int sr, ++ unsigned int drv_str) ++{ ++ unsigned int reg = 0; ++ ++ regmap_read(iocfg_regmap, offset, ®); ++ ++ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | ++ IO_CFG_DRV_STR_MASK | IO_CFG_SR); ++ reg |= (pull_up ? IO_CFG_PULL_UP : 0); ++ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); ++ reg |= (sr ? IO_CFG_SR : 0); ++ reg |= io_cfg_drv_str_sel(drv_str); ++ ++ regmap_write(iocfg_regmap, offset, reg); ++} ++ ++static void bsp_set_emmc_ctrl(struct sdhci_host *host) ++{ ++ unsigned int reg; ++ ++ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); ++ reg |= SDHCI_CARD_IS_EMMC; ++ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); ++} ++ ++ ++static void bsp_set_mmc_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_MMC_HS400: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS200: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_MMC_HS: ++ bsp_set_emmc_ctrl(host); ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ case MMC_TIMING_MMC_DDR52: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ ++ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ ++ break; ++ } ++} ++ ++static void bsp_set_sd_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ switch (host->timing) { ++ case MMC_TIMING_SD_HS: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ case MMC_TIMING_LEGACY: ++ default: ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ ++ break; ++ } ++} ++ ++static void bsp_set_sdio_drv(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ int i; ++ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ ++ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x7); /* set drv level 7 */ ++ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) ++ bsp_set_drv_str(iocfg_regmap, ++ io_sdio1_data_reg[i], 1, 0, 0, 0x7); /* set drv level 7 */ ++} ++ ++static void bsp_set_io_config(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ void *iocfg_regmap = bsp_priv->iocfg_regmap; ++ unsigned int reg = 0; ++ ++ if (devid == 0) { ++ /* For mmc0: eMMC and SD card */ ++ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) ++ bsp_set_mmc_drv(host); ++ ++ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); ++ if ((reg & IO_CFG_PIN_MUX_MASK) == ++ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) ++ bsp_set_sd_drv(host); ++ } else { ++ /* For mmc1: sdio wifi */ ++ bsp_set_sdio_drv(host); ++ } ++} ++ ++static void bsp_get_phase(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ if (devid == 0) { ++ /* For eMMC and SD card */ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { ++ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { ++ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { ++ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ ++ bsp_priv->sampl_phase = bsp_priv->tuning_phase; ++ } else { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } else { ++ /* For SDIO device */ ++ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || ++ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ ++ } else { ++ /* UHS_SDR12 */ ++ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ ++ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ ++ } ++ } ++} ++ ++static int bsp_support_runtime_pm(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ ++ /* Only enable for mmc0 eMMC and SD card */ ++ if (devid == 0) ++ return 1; ++ else ++ return 0; ++} ++ ++#include "sdhci-goke.c" ++#endif +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-goke.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-goke.c.patch new file mode 100644 index 00000000..7122a27c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-goke.c.patch @@ -0,0 +1,717 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-goke.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-goke.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,714 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++static unsigned int sdhci_bsp_get_max_clk(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ ++ return bsp_priv->f_max; ++} ++ ++static int sdhci_bsp_parse_dt(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ struct device_node *np = host->mmc->parent->of_node; ++ int ret, len; ++ ++ ret = mmc_of_parse(host->mmc); ++ if (ret) ++ return ret; ++ ++ if (of_property_read_u32(np, "max-frequency", &bsp_priv->f_max)) ++ bsp_priv->f_max = MAX_FREQ; ++ ++ if (of_find_property(np, "mmc-cmd-queue", &len)) ++ host->mmc->caps2 |= MMC_CAP2_CMD_QUEUE; ++ ++ if (of_find_property(np, "mmc-broken-cmd23", &len) || ++ (host->mmc->caps2 & MMC_CAP2_CMD_QUEUE)) ++ host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; ++ ++ return 0; ++} ++ ++static void bsp_mmc_crg_init(struct sdhci_host *host) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); ++ ++ clk_prepare_enable(pltfm_host->clk); ++ reset_control_assert(bsp_priv->crg_rst); ++ reset_control_assert(bsp_priv->dll_rst); ++ if (bsp_priv->sampl_rst) ++ reset_control_assert(bsp_priv->sampl_rst); ++ ++ udelay(25); /* delay 25us */ ++ reset_control_deassert(bsp_priv->crg_rst); ++ udelay(10); /* delay 10us */ ++} ++ ++static void bsp_set_drv_phase(struct sdhci_host *host, unsigned int phase) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ unsigned int offset[] = { ++ REG_EMMC_DRV_DLL_CTRL, ++ REG_SDIO0_DRV_DLL_CTRL, ++ REG_SDIO1_DRV_DLL_CTRL, ++ REG_SDIO2_DRV_DLL_CTRL ++ }; ++ ++ regmap_write_bits(bsp_priv->crg_regmap, offset[devid], ++ SDIO_DRV_PHASE_SEL_MASK, sdio_drv_sel(phase)); ++} ++ ++static void bsp_set_sampl_phase(struct sdhci_host *host, unsigned int phase) ++{ ++ unsigned int reg; ++ ++ reg = sdhci_readl(host, SDHCI_AT_STAT); ++ reg &= ~SDHCI_PHASE_SEL_MASK; ++ reg |= phase; ++ sdhci_writel(host, reg, SDHCI_AT_STAT); ++} ++ ++static void bsp_disable_card_clk(struct sdhci_host *host) ++{ ++ u16 clk; ++ ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ clk &= ~SDHCI_CLOCK_CARD_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++} ++ ++static void bsp_enable_card_clk(struct sdhci_host *host) ++{ ++ u16 clk; ++ ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ clk |= SDHCI_CLOCK_CARD_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++} ++ ++static void bsp_disable_inter_clk(struct sdhci_host *host) ++{ ++ u16 clk; ++ ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ clk &= ~SDHCI_CLOCK_INT_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++} ++ ++static void bsp_enable_sampl_dll_slave(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ unsigned int offset[] = { ++ REG_EMMC_SAMPL_DLL_CTRL, ++ REG_SDIO0_SAMPL_DLL_CTRL, ++ REG_SDIO1_SAMPL_DLL_CTRL, ++ REG_SDIO2_SAMPL_DLL_CTRL ++ }; ++ ++ regmap_write_bits(bsp_priv->crg_regmap, offset[devid], ++ SDIO_SAMPL_DLL_SLAVE_EN, SDIO_SAMPL_DLL_SLAVE_EN); ++} ++ ++static void bsp_wait_drv_dll_lock(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ unsigned int reg; ++ unsigned int timeout = 20; ++ unsigned int offset[] = { ++ REG_EMMC_DRV_DLL_STATUS, ++ REG_SDIO0_DRV_DLL_STATUS, ++ REG_SDIO1_DRV_DLL_STATUS, ++ REG_SDIO2_DRV_DLL_STATUS ++ }; ++ ++ do { ++ reg = 0; ++ regmap_read(bsp_priv->crg_regmap, offset[devid], ®); ++ if (reg & SDIO_DRV_DLL_LOCK) ++ return; ++ ++ mdelay(1); ++ timeout--; ++ } while (timeout > 0); ++ ++ pr_err("%s: DRV DLL master not locked.\n", mmc_hostname(host->mmc)); ++} ++ ++static void bsp_wait_sampl_dll_slave_ready(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ unsigned int reg; ++ unsigned int timeout = 20; ++ unsigned int offset[] = { ++ REG_EMMC_SAMPL_DLL_STATUS, ++ REG_SDIO0_SAMPL_DLL_STATUS, ++ REG_SDIO1_SAMPL_DLL_STATUS, ++ REG_SDIO2_SAMPL_DLL_STATUS ++ }; ++ ++ do { ++ reg = 0; ++ regmap_read(bsp_priv->crg_regmap, offset[devid], ®); ++ if (reg & SDIO_SAMPL_DLL_SLAVE_READY) ++ return; ++ ++ mdelay(1); ++ timeout--; ++ } while (timeout > 0); ++ ++ pr_err("%s: SAMPL DLL slave not ready.\n", mmc_hostname(host->mmc)); ++} ++ ++static void bsp_enable_sample(struct sdhci_host *host) ++{ ++ unsigned int reg; ++ ++ reg = sdhci_readl(host, SDHCI_AT_CTRL); ++ reg |= SDHCI_SAMPLE_EN; ++ sdhci_writel(host, reg, SDHCI_AT_CTRL); ++} ++ ++static void sdhci_bsp_set_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); ++ unsigned long timeout; ++ u16 clk; ++ ++ host->mmc->actual_clock = 0; ++ bsp_disable_card_clk(host); ++ udelay(25); /* delay 25us */ ++ bsp_disable_inter_clk(host); ++ if (clock == 0) ++ return; ++ ++ reset_control_assert(bsp_priv->dll_rst); ++ if (bsp_priv->sampl_rst) ++ reset_control_assert(bsp_priv->sampl_rst); ++ udelay(25); /* delay 25us */ ++ ++ clk_set_rate(pltfm_host->clk, clock); ++ host->mmc->actual_clock = clk_get_rate(pltfm_host->clk); ++ ++ bsp_get_phase(host); ++ bsp_set_drv_phase(host, bsp_priv->drv_phase); ++ bsp_enable_sample(host); ++ bsp_set_sampl_phase(host, bsp_priv->sampl_phase); ++ udelay(25); /* delay 25us */ ++ ++ if (host->mmc->actual_clock > MMC_HIGH_52_MAX_DTR) { ++ bsp_enable_sampl_dll_slave(host); ++ reset_control_deassert(bsp_priv->dll_rst); ++ if (bsp_priv->sampl_rst) ++ reset_control_deassert(bsp_priv->sampl_rst); ++ } ++ ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_PLL_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++ timeout = 20; /* default timeout 20ms */ ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ while (!(clk & SDHCI_CLOCK_INT_STABLE)) { ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ if (timeout == 0) { ++ pr_err("%s: Internal clock never stabilised.\n", ++ mmc_hostname(host->mmc)); ++ return; ++ } ++ timeout--; ++ mdelay(1); ++ } ++ ++ if (host->mmc->actual_clock > MMC_HIGH_52_MAX_DTR) { ++ bsp_wait_drv_dll_lock(host); ++ bsp_wait_sampl_dll_slave_ready(host); ++ } ++ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) ++ bsp_wait_ds_180_dll_ready(host); ++ ++ clk |= SDHCI_CLOCK_CARD_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); ++ udelay(100); /* delay 100us */ ++ ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ bsp_wait_ds_dll_lock(host); ++ bsp_set_ds_dll_delay(host); ++ } ++} ++ ++static void bsp_select_sampl_phase(struct sdhci_host *host, unsigned int phase) ++{ ++ bsp_disable_card_clk(host); ++ bsp_set_sampl_phase(host, phase); ++ bsp_wait_sampl_dll_slave_ready(host); ++ bsp_enable_card_clk(host); ++ udelay(1); ++} ++ ++static int bsp_send_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ int count, err; ++ ++ count = 0; ++ do { ++ err = mmc_send_tuning(host->mmc, opcode, NULL); ++ if (err) ++ break; ++ ++ count++; ++ } while (count < MAX_TUNING_NUM); ++ ++ return err; ++} ++ ++static void bsp_pre_tuning(struct sdhci_host *host) ++{ ++ sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE); ++ sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, ++ SDHCI_SIGNAL_ENABLE); ++ ++ bsp_wait_drv_dll_lock(host); ++ bsp_enable_sampl_dll_slave(host); ++ bsp_enable_sample(host); ++ host->is_tuning = 1; ++} ++ ++static void bsp_post_tuning(struct sdhci_host *host) ++{ ++ unsigned short ctrl; ++ ++ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); ++ ctrl |= SDHCI_CTRL_TUNED_CLK; ++ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); ++ ++ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); ++ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ host->is_tuning = 0; ++} ++ ++#ifndef SDHCI_GOKE_EDGE_TUNING ++static int bsp_get_best_sampl(u32 candidates) ++{ ++ int rise = NOT_FOUND; ++ int fall = NOT_FOUND; ++ int win_max_r = NOT_FOUND; ++ int win_max_f = NOT_FOUND; ++ int end_fall = NOT_FOUND; ++ int found = NOT_FOUND; ++ int win_max = 0; ++ int i, win; ++ ++ for (i = 0; i < PHASE_SCALE; i++) { ++ if ((candidates & 0x3) == 0x2) ++ rise = (i + 1) % PHASE_SCALE; ++ ++ if ((candidates & 0x3) == 0x1) { ++ fall = i; ++ if (rise != NOT_FOUND) { ++ win = fall - rise + 1; ++ if (win > win_max) { ++ win_max = win; ++ found = (fall + rise) / 2; /* Get window center by devide 2 */ ++ win_max_r = rise; ++ win_max_f = fall; ++ rise = NOT_FOUND; ++ fall = NOT_FOUND; ++ } ++ } else { ++ end_fall = fall; ++ } ++ } ++ candidates = ror32(candidates, 1); ++ } ++ ++ if (end_fall != NOT_FOUND && rise != NOT_FOUND) { ++ fall = end_fall; ++ if (end_fall < rise) ++ end_fall += PHASE_SCALE; ++ ++ win = end_fall - rise + 1; ++ if (win > win_max) { ++ found = (rise + (win / 2)) % PHASE_SCALE; /* Get window center by devide 2 */ ++ win_max_r = rise; ++ win_max_f = fall; ++ } ++ } ++ ++ if (found != NOT_FOUND) ++ pr_info("valid phase shift [%d, %d] Final Phase:%d\n", ++ win_max_r, win_max_f, found); ++ ++ return found; ++} ++ ++static int sdhci_bsp_exec_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int sampl; ++ unsigned int candidates = 0; ++ int phase, err; ++ ++ bsp_pre_tuning(host); ++ ++ for (sampl = 0; sampl < PHASE_SCALE; sampl++) { ++ bsp_select_sampl_phase(host, sampl); ++ ++ err = bsp_send_tuning(host, opcode); ++ if (err) ++ pr_debug("send tuning CMD%u fail! phase:%d err:%d\n", ++ opcode, sampl, err); ++ else ++ candidates |= (0x1 << sampl); ++ } ++ ++ pr_info("%s: tuning done! candidates 0x%X: ", ++ mmc_hostname(host->mmc), candidates); ++ ++ phase = bsp_get_best_sampl(candidates); ++ if (phase == NOT_FOUND) { ++ phase = bsp_priv->sampl_phase; ++ pr_err("no valid phase shift! use default %d\n", phase); ++ } ++ ++ bsp_priv->tuning_phase = phase; ++ bsp_select_sampl_phase(host, phase); ++ bsp_post_tuning(host); ++ ++ return 0; ++} ++ ++#else ++static void bsp_enable_edge_tuning(struct sdhci_host *host) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int devid = bsp_priv->devid; ++ unsigned int samplb_offset[] = { ++ REG_EMMC_SAMPLB_DLL_CTRL, ++ REG_SDIO0_SAMPLB_DLL_CTRL, ++ REG_SDIO1_SAMPLB_DLL_CTRL, ++ REG_SDIO2_SAMPLB_DLL_CTRL ++ }; ++ unsigned int reg; ++ ++ regmap_write_bits(bsp_priv->crg_regmap, samplb_offset[devid], ++ SDIO_SAMPLB_DLL_CLK_MASK, sdio_samplb_sel(8)); /* 8 for 180 degree */ ++ ++ reg = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ reg |= SDHCI_EDGE_DETECT_EN; ++ sdhci_writel(host, reg, SDHCI_MULTI_CYCLE); ++} ++ ++static void bsp_disable_edge_tuning(struct sdhci_host *host) ++{ ++ unsigned int reg; ++ ++ reg = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ reg &= ~SDHCI_EDGE_DETECT_EN; ++ sdhci_writel(host, reg, SDHCI_MULTI_CYCLE); ++} ++ ++static int sdhci_bsp_exec_edge_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); ++ unsigned int index, val; ++ unsigned int edge_p2f, edge_f2p, start, end, phase; ++ unsigned int fall, rise, fall_updat_flag; ++ unsigned int found = 0; ++ unsigned int prev_found = 0; ++ int prev_err = 0; ++ int err; ++ ++ bsp_pre_tuning(host); ++ bsp_enable_edge_tuning(host); ++ ++ start = 0; ++ end = PHASE_SCALE / EDGE_TUNING_PHASE_STEP; ++ ++ edge_p2f = start; ++ edge_f2p = end; ++ for (index = 0; index <= end; index++) { ++ bsp_select_sampl_phase(host, index * EDGE_TUNING_PHASE_STEP); ++ ++ err = mmc_send_tuning(host->mmc, opcode, NULL); ++ if (!err) { ++ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); ++ found = val & SDHCI_FOUND_EDGE; ++ } else { ++ found = 1; ++ } ++ ++ if (prev_found && !found) ++ edge_f2p = index; ++ else if (!prev_found && found) ++ edge_p2f = index; ++ ++ if ((edge_p2f != start) && (edge_f2p != end)) ++ break; ++ ++ prev_found = found; ++ found = 0; ++ } ++ ++ if ((edge_p2f == start) && (edge_f2p == end)) { ++ pr_err("%s: tuning failed! can not found edge!\n", ++ mmc_hostname(host->mmc)); ++ return -1; ++ } ++ ++ bsp_disable_edge_tuning(host); ++ ++ start = edge_p2f * EDGE_TUNING_PHASE_STEP; ++ end = edge_f2p * EDGE_TUNING_PHASE_STEP; ++ if (end <= start) ++ end += PHASE_SCALE; ++ ++ fall = start; ++ rise = end; ++ fall_updat_flag = 0; ++ for (index = start; index <= end; index++) { ++ bsp_select_sampl_phase(host, index % PHASE_SCALE); ++ ++ err = bsp_send_tuning(host, opcode); ++ if (err) ++ pr_debug("send tuning CMD%u fail! phase:%d err:%d\n", ++ opcode, index, err); ++ ++ if (err && index == start) { ++ if (!fall_updat_flag) { ++ fall_updat_flag = 1; ++ fall = start; ++ } ++ } else { ++ if (!prev_err && err) { ++ if (!fall_updat_flag) { ++ fall_updat_flag = 1; ++ fall = index; ++ } ++ } ++ } ++ ++ ++ if (prev_err && !err) ++ rise = index; ++ ++ if (err && index == end) ++ rise = end; ++ ++ ++ prev_err = err; ++ } ++ ++ phase = ((fall + rise) / 2 + PHASE_SCALE / 2) % PHASE_SCALE; /* Get window center by divide 2 */ ++ ++ pr_info("%s: tuning done! valid phase shift [%d, %d] Final Phase:%d\n", ++ mmc_hostname(host->mmc), rise % PHASE_SCALE, ++ fall % PHASE_SCALE, phase); ++ ++ bsp_priv->tuning_phase = phase; ++ bsp_select_sampl_phase(host, phase); ++ bsp_post_tuning(host); ++ ++ return 0; ++} ++#endif ++ ++static void sdhci_bsp_set_uhs_signaling(struct sdhci_host *host, unsigned timing) ++{ ++ sdhci_set_uhs_signaling(host, timing); ++ host->timing = timing; ++ ++ /* Goke add set io config here to set pin drv strength */ ++ bsp_set_io_config(host); ++} ++ ++static void sdhci_bsp_hw_reset(struct sdhci_host *host) ++{ ++ sdhci_writel(host, 0x0, SDHCI_EMMC_HW_RESET); ++ udelay(10); /* delay 10us */ ++ sdhci_writel(host, 0x1, SDHCI_EMMC_HW_RESET); ++ udelay(200); /* delay 200us */ ++} ++ ++/* ++ * This api is for wifi driver rescan the sdio device, ++ * ugly but it is needed ++ */ ++int bsp_sdio_rescan(int slot) ++{ ++ struct mmc_host *mmc = mci_host[slot]; ++ ++ if (mmc == NULL) { ++ pr_err("invalid mmc, please check the argument\n"); ++ return -EINVAL; ++ } ++ ++ mmc_detect_change(mmc, 0); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(bsp_sdio_rescan); ++ ++static const struct sdhci_ops sdhci_bsp_ops = { ++ .get_max_clock = sdhci_bsp_get_max_clk, ++ .set_clock = sdhci_bsp_set_clock, ++ .set_bus_width = sdhci_set_bus_width, ++ .reset = sdhci_reset, ++ .set_uhs_signaling = sdhci_bsp_set_uhs_signaling, ++ .hw_reset = sdhci_bsp_hw_reset, ++ ++#ifdef SDHCI_GOKE_EDGE_TUNING ++ .platform_execute_tuning = sdhci_bsp_exec_edge_tuning, ++#else ++ .platform_execute_tuning = sdhci_bsp_exec_tuning, ++#endif ++ .pre_init = bsp_mmc_crg_init, ++ .extra_init = bsp_host_extra_init, ++}; ++ ++static const struct sdhci_pltfm_data sdhci_bsp_pdata = { ++ .ops = &sdhci_bsp_ops, ++ .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_INVERTED_WRITE_PROTECT | ++ SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | ++ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, ++}; ++static int sdhci_bsp_probe(struct platform_device *pdev) ++{ ++ struct sdhci_host *host; ++ struct sdhci_pltfm_host *pltfm_host = NULL; ++ int ret; ++ ++ host = sdhci_pltfm_init(pdev, &sdhci_bsp_pdata, ++ sizeof(struct sdhci_bsp_priv)); ++ if (IS_ERR(host)) ++ return PTR_ERR(host); ++ ++ ret = sdhci_bsp_pltfm_init(pdev, host); ++ if (ret) ++ goto err_sdhci_add; ++ ++ if (bsp_support_runtime_pm(host)) { ++ pm_runtime_get_noresume(&pdev->dev); ++ pm_runtime_set_autosuspend_delay(&pdev->dev, ++ GOKE_MMC_AUTOSUSPEND_DELAY_MS); ++ pm_runtime_use_autosuspend(&pdev->dev); ++ pm_runtime_set_active(&pdev->dev); ++ pm_runtime_enable(&pdev->dev); ++ } ++ ++ ret = sdhci_add_host(host); ++ if (ret) ++ goto pm_runtime_disable; ++ ++ if (bsp_support_runtime_pm(host)) { ++ pm_runtime_mark_last_busy(&pdev->dev); ++ pm_runtime_put_autosuspend(&pdev->dev); ++ } ++ ++ return 0; ++ ++pm_runtime_disable: ++ if (bsp_support_runtime_pm(host)) { ++ pm_runtime_disable(&pdev->dev); ++ pm_runtime_set_suspended(&pdev->dev); ++ pm_runtime_put_noidle(&pdev->dev); ++ } ++ ++err_sdhci_add: ++ pltfm_host = sdhci_priv(host); ++ clk_disable_unprepare(pltfm_host->clk); ++ sdhci_pltfm_free(pdev); ++ return ret; ++} ++ ++static int sdhci_bsp_remove(struct platform_device *pdev) ++{ ++ struct sdhci_host *host = platform_get_drvdata(pdev); ++ ++ if (bsp_support_runtime_pm(host)) { ++ pm_runtime_get_sync(&pdev->dev); ++ pm_runtime_disable(&pdev->dev); ++ pm_runtime_put_noidle(&pdev->dev); ++ } ++ return sdhci_pltfm_unregister(pdev); ++} ++ ++#ifdef CONFIG_PM ++static int sdhci_bsp_runtime_suspend(struct device *dev) ++{ ++ struct sdhci_host *host = dev_get_drvdata(dev); ++ ++ bsp_disable_card_clk(host); ++ return 0; ++} ++ ++static int sdhci_bsp_runtime_resume(struct device *dev) ++{ ++ struct sdhci_host *host = dev_get_drvdata(dev); ++ ++ bsp_enable_card_clk(host); ++ return 0; ++} ++#endif ++ ++static const struct of_device_id sdhci_bsp_match[] = { ++ { .compatible = "goke,sdhci" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, sdhci_bsp_match); ++ ++static const struct dev_pm_ops sdhci_bsp_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, ++ sdhci_pltfm_resume) ++ ++ SET_RUNTIME_PM_OPS(sdhci_bsp_runtime_suspend, ++ sdhci_bsp_runtime_resume, ++ NULL) ++}; ++ ++static struct platform_driver sdhci_bsp_driver = { ++ .driver = { ++ .name = "sdhci-goke", ++ .of_match_table = sdhci_bsp_match, ++ .pm = &sdhci_bsp_pm_ops, ++ }, ++ .probe = sdhci_bsp_probe, ++ .remove = sdhci_bsp_remove, ++}; ++ ++static int __init sdhci_bsp_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&sdhci_bsp_driver); ++ if (ret) ++ return ret; ++ ++ ret = mci_proc_init(); ++ if (ret) ++ platform_driver_unregister(&sdhci_bsp_driver); ++ ++ return ret; ++} ++ ++static void __exit sdhci_bsp_exit(void) ++{ ++ mci_proc_shutdown(); ++ ++ platform_driver_unregister(&sdhci_bsp_driver); ++} ++ ++module_init(sdhci_bsp_init); ++module_exit(sdhci_bsp_exit); ++ ++MODULE_DESCRIPTION("SDHCI driver for goke"); ++MODULE_LICENSE("GPL v2"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-pltfm.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-pltfm.c.patch new file mode 100644 index 00000000..95e6d2dd --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-pltfm.c.patch @@ -0,0 +1,26 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-pltfm.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-pltfm.c 2021-06-07 13:01:33.000000000 +0300 +@@ -209,19 +209,21 @@ + EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); + + #ifdef CONFIG_PM_SLEEP +-static int sdhci_pltfm_suspend(struct device *dev) ++int sdhci_pltfm_suspend(struct device *dev) + { + struct sdhci_host *host = dev_get_drvdata(dev); + + return sdhci_suspend_host(host); + } ++EXPORT_SYMBOL_GPL(sdhci_pltfm_suspend); + +-static int sdhci_pltfm_resume(struct device *dev) ++int sdhci_pltfm_resume(struct device *dev) + { + struct sdhci_host *host = dev_get_drvdata(dev); + + return sdhci_resume_host(host); + } ++EXPORT_SYMBOL_GPL(sdhci_pltfm_resume); + #endif + + const struct dev_pm_ops sdhci_pltfm_pmops = { diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-pltfm.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-pltfm.h.patch new file mode 100644 index 00000000..94966440 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-pltfm.h.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-pltfm.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-pltfm.h 2021-06-07 13:01:33.000000000 +0300 +@@ -109,6 +109,8 @@ + return (void *)host->private; + } + ++int sdhci_pltfm_suspend(struct device *dev); ++int sdhci_pltfm_resume(struct device *dev); + extern const struct dev_pm_ops sdhci_pltfm_pmops; + + #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-proc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-proc.c.patch new file mode 100644 index 00000000..ff340d27 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-proc.c.patch @@ -0,0 +1,275 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-proc.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-proc.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,272 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "sdhci.h" ++#include "sdhci-proc.h" ++ ++#define MCI_PARENT "mci" ++#define MCI_STATS_PROC "mci_info" ++#define MAX_CLOCK_SCALE 4 ++ ++unsigned int slot_index; ++struct mmc_host *mci_host[MCI_SLOT_NUM] = {NULL}; ++static struct proc_dir_entry *proc_mci_dir; ++ ++static char *card_type[MAX_CARD_TYPE + 1] = { ++ "MMC card", ++ "SD card", ++ "SDIO card", ++ "SD combo (IO+mem) card", ++ "unknown" ++}; ++static char *clock_unit[MAX_CLOCK_SCALE] = { ++ "Hz", ++ "KHz", ++ "MHz", ++ "GHz" ++}; ++ ++static char *mci_get_card_type(unsigned int sd_type) ++{ ++ if (sd_type >= MAX_CARD_TYPE) ++ return card_type[MAX_CARD_TYPE]; ++ else ++ return card_type[sd_type]; ++} ++ ++static unsigned int analyze_clock_scale(unsigned int clock, unsigned int *clock_val) ++{ ++ unsigned int scale = 0; ++ unsigned int tmp = clock; ++ ++ while (1) { ++ tmp = tmp / 1000; /* 1000 for clk calculate */ ++ if (tmp > 0) { ++ *clock_val = tmp; ++ scale++; ++ } else { ++ break; ++ } ++ } ++ return scale; ++} ++ ++static inline int is_card_uhs(unsigned char timing) ++{ ++ return timing >= MMC_TIMING_UHS_SDR12 && ++ timing <= MMC_TIMING_UHS_DDR50; ++}; ++ ++static inline int is_card_hs(unsigned char timing) ++{ ++ return timing == MMC_TIMING_SD_HS || timing == MMC_TIMING_MMC_HS; ++}; ++ ++static void mci_stats_seq_printout(struct seq_file *s) ++{ ++ unsigned int index_mci; ++ unsigned int clock; ++ unsigned int clock_scale; ++ unsigned int clock_value = 0; ++ const char *type = NULL; ++ static struct mmc_host *mmc = NULL; ++ const char *uhs_bus_speed_mode = ""; ++ static const char *uhs_speeds[] = { ++ [UHS_SDR12_BUS_SPEED] = "SDR12 ", ++ [UHS_SDR25_BUS_SPEED] = "SDR25 ", ++ [UHS_SDR50_BUS_SPEED] = "SDR50 ", ++ [UHS_SDR104_BUS_SPEED] = "SDR104 ", ++ [UHS_DDR50_BUS_SPEED] = "DDR50 ", ++ }; ++ unsigned int speed_class, grade_speed_uhs; ++ struct card_info *info = NULL; ++ unsigned int present; ++ struct sdhci_host *host = NULL; ++ ++ for (index_mci = 0; index_mci < MCI_SLOT_NUM; index_mci++) { ++ mmc = mci_host[index_mci]; ++ if (mmc == NULL) { ++ seq_printf(s, "MCI%d: invalid\n", index_mci); ++ continue; ++ } else { ++ seq_printf(s, "MCI%d", index_mci); ++ } ++ host = mmc_priv(mmc); ++ info = &host->c_info; ++ ++ present = host->mmc->ops->get_cd(host->mmc); ++ if (present) ++ seq_puts(s, ": pluged"); ++ else ++ seq_puts(s, ": unplugged"); ++ ++ if (info->card_connect != CARD_CONNECT) { ++ if (mmc->card_status == MMC_CARD_INIT_FAIL) ++ seq_puts(s, "_init_failed\n"); ++ else ++ seq_puts(s, "_disconnected\n"); ++ } else { ++ seq_puts(s, "_connected\n"); ++ ++ seq_printf(s, "\tType: %s", ++ mci_get_card_type(info->card_type)); ++ ++ if (info->card_state & MMC_STATE_BLOCKADDR) { ++ if (info->card_state & MMC_CARD_SDXC) ++ type = "SDXC"; ++ else ++ type = "SDHC"; ++ seq_printf(s, "(%s)\n", type); ++ } ++ ++ if (is_card_uhs(info->timing) && ++ info->sd_bus_speed < ARRAY_SIZE(uhs_speeds)) ++ uhs_bus_speed_mode = ++ uhs_speeds[info->sd_bus_speed]; ++ ++ seq_printf(s, "\tMode: %s%s%s%s\n", ++ is_card_uhs(info->timing) ? "UHS " : ++ (is_card_hs(info->timing) ? "HS " : ""), ++ info->timing == MMC_TIMING_MMC_HS400 ? "HS400 " : ++ (info->timing == MMC_TIMING_MMC_HS200 ? "HS200 " : ""), ++ info->timing == MMC_TIMING_MMC_DDR52 ? "DDR " : "", ++ uhs_bus_speed_mode); ++ ++ speed_class = UNSTUFF_BITS(info->ssr, 56, 8); /* 56 equal 440 -384 */ ++ grade_speed_uhs = UNSTUFF_BITS(info->ssr, 12, 4); /* 12 equal 396 - 384 */ ++ seq_printf(s, "\tSpeed Class: Class %s\n", ++ (speed_class == 0x00) ? "0" : ++ (speed_class == 0x01) ? "2" : ++ (speed_class == 0x02) ? "4" : ++ (speed_class == 0x03) ? "6" : ++ (speed_class == 0x04) ? "10" : ++ "Reserved"); ++ seq_printf(s, "\tUhs Speed Grade: %s\n", ++ (grade_speed_uhs == 0x00) ? ++ "Less than 10MB/sec(0h)" : ++ (grade_speed_uhs == 0x01) ? ++ "10MB/sec and above(1h)" : ++ "Reserved"); ++ ++ clock = info->card_support_clock; ++ clock_scale = analyze_clock_scale(clock, &clock_value); ++ seq_printf(s, "\tHost work clock: %d%s\n", ++ clock_value, clock_unit[clock_scale]); ++ ++ clock = info->card_support_clock; ++ clock_scale = analyze_clock_scale(clock, &clock_value); ++ seq_printf(s, "\tCard support clock: %d%s\n", ++ clock_value, clock_unit[clock_scale]); ++ ++ clock = mmc->actual_clock; ++ clock_scale = analyze_clock_scale(clock, &clock_value); ++ seq_printf(s, "\tCard work clock: %d%s\n", ++ clock_value, clock_unit[clock_scale]); ++ ++ /* add card read/write error count */ ++ seq_printf(s, "\tCard error count: %d\n", ++ host->error_count); ++ } ++ } ++} ++ ++/* proc interface setup */ ++static void *mci_seq_start(struct seq_file *s, loff_t *pos) ++{ ++ /* counter is used to tracking multi proc interfaces ++ * We have only one interface so return zero ++ * pointer to start the sequence. ++ */ ++ static unsigned long counter; ++ ++ if (*pos == 0) ++ return &counter; ++ ++ *pos = 0; ++ return NULL; ++} ++ ++/* proc interface next */ ++static void *mci_seq_next(struct seq_file *s, void *v, loff_t *pos) ++{ ++ (*pos)++; ++ if (*pos >= MCI_SLOT_NUM) ++ return NULL; ++ ++ return NULL; ++} ++ ++/* define parameters where showed in proc file */ ++static int mci_stats_seq_show(struct seq_file *s, void *v) ++{ ++ mci_stats_seq_printout(s); ++ return 0; ++} ++ ++/* proc interface stop */ ++static void mci_seq_stop(struct seq_file *s, void *v) ++{ ++} ++ ++/* proc interface operation */ ++static const struct seq_operations mci_stats_seq_ops = { ++ .start = mci_seq_start, ++ .next = mci_seq_next, ++ .stop = mci_seq_stop, ++ .show = mci_stats_seq_show ++}; ++ ++/* proc file open */ ++static int mci_stats_proc_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &mci_stats_seq_ops); ++}; ++ ++/* proc file operation */ ++static const struct file_operations mci_stats_proc_ops = { ++ .owner = THIS_MODULE, ++ .open = mci_stats_proc_open, ++ .read = seq_read, ++ .release = seq_release ++}; ++ ++int mci_proc_init(void) ++{ ++ struct proc_dir_entry *proc_stats_entry = NULL; ++ ++ proc_mci_dir = proc_mkdir(MCI_PARENT, NULL); ++ if (!proc_mci_dir) { ++ pr_err("%s: failed to create proc file %s\n", ++ __func__, MCI_PARENT); ++ return 1; ++ } ++ ++ proc_stats_entry = proc_create(MCI_STATS_PROC, ++ 0, proc_mci_dir, &mci_stats_proc_ops); ++ if (!proc_stats_entry) { ++ pr_err("%s: failed to create proc file %s\n", ++ __func__, MCI_STATS_PROC); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int mci_proc_shutdown(void) ++{ ++ if (proc_mci_dir) { ++ remove_proc_entry(MCI_STATS_PROC, proc_mci_dir); ++ remove_proc_entry(MCI_PARENT, NULL); ++ proc_mci_dir = NULL; ++ } ++ ++ return 0; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-proc.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-proc.h.patch new file mode 100644 index 00000000..04e49da6 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci-proc.h.patch @@ -0,0 +1,32 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci-proc.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci-proc.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++/* ++ * MCI connection table manager ++ */ ++#ifndef __MCI_PROC_H__ ++#define __MCI_PROC_H__ ++ ++#include ++ ++#define MAX_CARD_TYPE 4 ++#define MAX_SPEED_MODE 5 ++ ++ ++ ++#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) ||\ ++ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) ++ #define MCI_SLOT_NUM 3 ++#endif ++ ++extern unsigned int slot_index; ++extern struct mmc_host *mci_host[MCI_SLOT_NUM]; ++ ++int mci_proc_init(void); ++int mci_proc_shutdown(void); ++ ++#endif /* __MCI_PROC_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci.c.patch new file mode 100644 index 00000000..e7aff39b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci.c.patch @@ -0,0 +1,779 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci.c 2021-06-07 13:01:33.000000000 +0300 +@@ -32,6 +32,7 @@ + #include + + #include "sdhci.h" ++#include "sdhci-cmdq.h" + + #define DRIVER_NAME "sdhci" + +@@ -76,8 +77,8 @@ + pr_err(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", + sdhci_readl(host, SDHCI_INT_ENABLE), + sdhci_readl(host, SDHCI_SIGNAL_ENABLE)); +- pr_err(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", +- sdhci_readw(host, SDHCI_ACMD12_ERR), ++ pr_err(DRIVER_NAME ": ACMD err: 0x%08x | Slot int: 0x%08x\n", ++ sdhci_readw(host, SDHCI_AUTO_CMD_ERR), + sdhci_readw(host, SDHCI_SLOT_INT_STATUS)); + pr_err(DRIVER_NAME ": Caps: 0x%08x | Caps_1: 0x%08x\n", + sdhci_readl(host, SDHCI_CAPABILITIES), +@@ -227,7 +228,7 @@ + SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | + SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC | + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | +- SDHCI_INT_RESPONSE; ++ SDHCI_INT_RESPONSE | SDHCI_INT_ACMD_ERR; + + if (host->tuning_mode == SDHCI_TUNING_MODE_2 || + host->tuning_mode == SDHCI_TUNING_MODE_3) +@@ -240,11 +241,17 @@ + /* force clock reconfiguration */ + host->clock = 0; + mmc->ops->set_ios(mmc, &mmc->ios); ++ } else { ++ if (host->ops->extra_init) ++ host->ops->extra_init(host); + } + } + + static void sdhci_reinit(struct sdhci_host *host) + { ++ if (host->ops->pre_init) ++ host->ops->pre_init(host); ++ + sdhci_init(host, 0); + sdhci_enable_card_detection(host); + } +@@ -522,6 +529,60 @@ + dma_desc->addr_hi = cpu_to_le32((u64)addr >> 32); + } + ++static void sdhci_write_cmd_table(u8 *desc, u32 reg, u32 attr) ++{ ++ __le32 *reg_addr = (__le32 __force *)(desc + 4); ++ __le32 *attr_addr = (__le32 __force *)desc; ++ ++ attr_addr[0] = cpu_to_le32(attr); ++ reg_addr[0] = cpu_to_le32(reg); ++} ++ ++static void sdhci_write_adma3_desc(struct sdhci_host *host, u8 *desc, ++ dma_addr_t addr, unsigned int attr) ++{ ++ __le32 *attr_addr = (__le32 __force *)desc; ++ ++ attr_addr[0] = cpu_to_le32(attr); ++ ++ if (host->flags & SDHCI_USE_64_BIT_DMA) { ++ __le64 *cmd_ddr = (__le64 __force *)(desc + 4); ++ cmd_ddr[0] = cpu_to_le64(addr); ++ } else { ++ __le32 *cmd_ddr = (__le32 __force *)(desc + 4); ++ cmd_ddr[0] = cpu_to_le32(addr); ++ } ++} ++ ++static void sdhci_prep_adma3_desc(struct sdhci_host *host, ++ struct mmc_command *cmd, int flags) ++{ ++ struct mmc_data *data = cmd->data; ++ unsigned int ctrl_2, cmd_xfer, blksz; ++ u16 mode; ++ ++ blksz = SDHCI_MAKE_BLKSZ(0, data->blksz); ++ mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); ++ cmd_xfer = (SDHCI_MAKE_CMD(cmd->opcode, flags) << 16) | mode; ++ ++ sdhci_write_cmd_table(host->cmd_table, data->blocks, ADMA3_CMD_VALID); ++ sdhci_write_cmd_table(host->cmd_table + 0x8, blksz, ADMA3_CMD_VALID); ++ sdhci_write_cmd_table(host->cmd_table + 0x10, ++ cmd->arg, ADMA3_CMD_VALID); ++ sdhci_write_cmd_table(host->cmd_table + 0x18, ++ cmd_xfer, ADMA3_CMD_VALID); ++ sdhci_adma_write_desc(host, host->cmd_table + 0x20, ++ host->adma_addr, 0x0, ADMA2_LINK_VALID); ++ sdhci_write_adma3_desc(host, host->adma3_table, ++ host->cmd_addr, ADMA3_END); ++ ++ ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); ++ ctrl_2 |= SDHCI_CTRL_HOST_VER4_ENABLE; ++ if (host->flags & SDHCI_USE_64_BIT_DMA) ++ ctrl_2 |= SDHCI_CTRL_ADDRESSING_64BIT; ++ sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); ++} ++ + static void sdhci_adma_mark_end(void *desc) + { + struct sdhci_adma2_64_desc *dma_desc = desc; +@@ -589,6 +650,17 @@ + BUG_ON(len > 65536); + + if (len) { ++ /* work around for buffer across 128M boundary, split the buffer */ ++ if (((addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)) + len) > ++ SDHCI_DMA_BOUNDARY_SIZE) { ++ offset = SDHCI_DMA_BOUNDARY_SIZE - ++ (addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)); ++ sdhci_adma_write_desc(host, desc, addr, offset, ++ ADMA2_TRAN_VALID); ++ desc += host->desc_sz; ++ addr += offset; ++ len -= offset; ++ } + /* tran, valid */ + sdhci_adma_write_desc(host, desc, addr, len, + ADMA2_TRAN_VALID); +@@ -855,10 +927,14 @@ + ctrl &= ~SDHCI_CTRL_DMA_MASK; + if ((host->flags & SDHCI_REQ_USE_DMA) && + (host->flags & SDHCI_USE_ADMA)) { +- if (host->flags & SDHCI_USE_64_BIT_DMA) +- ctrl |= SDHCI_CTRL_ADMA64; +- else +- ctrl |= SDHCI_CTRL_ADMA32; ++ if (host->flags & SDHCI_USE_ADMA3) { ++ ctrl |= SDHCI_CTRL_ADMA3; ++ } else { ++ if (host->flags & SDHCI_USE_64_BIT_DMA) ++ ctrl |= SDHCI_CTRL_ADMA64; ++ else ++ ctrl |= SDHCI_CTRL_ADMA32; ++ } + } else { + ctrl |= SDHCI_CTRL_SDMA; + } +@@ -1121,7 +1197,8 @@ + + sdhci_prepare_data(host, cmd); + +- sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); ++ if (!(host->flags & SDHCI_USE_ADMA3) || !cmd->data) ++ sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); + + sdhci_set_transfer_mode(host, cmd); + +@@ -1152,10 +1229,29 @@ + cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) + flags |= SDHCI_CMD_DATA; + +- sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); ++ if (host->flags & SDHCI_USE_ADMA3 && cmd->data) { ++ sdhci_prep_adma3_desc(host, cmd, flags); ++ ++ sdhci_writel(host, (u32)host->adma3_addr, ++ SDHCI_ADMA3_ID_ADDR_LOW); ++ if (host->flags & SDHCI_USE_64_BIT_DMA) ++ sdhci_writel(host, (u32)((u64)host->adma3_addr >> 32), ++ SDHCI_ADMA3_ID_ADDR_HI); ++ } else { ++ sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), ++ SDHCI_COMMAND); ++ } + } + EXPORT_SYMBOL_GPL(sdhci_send_command); + ++#define CMD_ERRORS \ ++ (R1_OUT_OF_RANGE | /* Command argument out of range */ \ ++ R1_ADDRESS_ERROR | /* Misaligned address */ \ ++ R1_BLOCK_LEN_ERROR | /* Transferred block length incorrect */\ ++ R1_WP_VIOLATION | /* Tried to write to protected block */ \ ++ R1_CC_ERROR | /* Card controller error */ \ ++ R1_ERROR) /* General/unknown error */ ++ + static void sdhci_finish_command(struct sdhci_host *host) + { + struct mmc_command *cmd = host->cmd; +@@ -1177,6 +1273,15 @@ + } else { + cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE); + } ++ ++ if (((cmd->flags & MMC_RSP_R1) == MMC_RSP_R1) && ++ ((cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)) { ++ if ((cmd->resp[0] & CMD_ERRORS) && !host->is_tuning) { ++ host->error_count++; ++ cmd->mrq->cmd->error = -EACCES; ++ pr_err("The status of the card is abnormal, cmd->resp[0]: %x", cmd->resp[0]); ++ } ++ } + } + + if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd) +@@ -1430,6 +1535,12 @@ + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) + sdhci_runtime_pm_bus_off(host); ++ /* ++ * Controllers need an extra 100ms delay to ensure power off ++ * completely ++ */ ++ msleep(100); ++ + } else { + /* + * Spec says that we should clear the power reg before setting +@@ -1568,13 +1679,9 @@ + static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + { + struct sdhci_host *host = mmc_priv(mmc); +- unsigned long flags; + u8 ctrl; + +- spin_lock_irqsave(&host->lock, flags); +- + if (host->flags & SDHCI_DEVICE_DEAD) { +- spin_unlock_irqrestore(&host->lock, flags); + if (!IS_ERR(mmc->supply.vmmc) && + ios->power_mode == MMC_POWER_OFF) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); +@@ -1710,7 +1817,9 @@ + } + + /* Re-enable SD Clock */ +- host->ops->set_clock(host, host->clock); ++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ clk |= SDHCI_CLOCK_CARD_EN; ++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); + } else + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + +@@ -1723,7 +1832,6 @@ + sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + + mmiowb(); +- spin_unlock_irqrestore(&host->lock, flags); + } + + static int sdhci_get_cd(struct mmc_host *mmc) +@@ -1846,6 +1954,9 @@ + u16 ctrl; + int ret; + ++ if (host->ops->start_signal_voltage_switch) ++ return host->ops->start_signal_voltage_switch(host, ios); ++ + /* + * Signal Voltage Switching is only applicable for Host Controllers + * v3.00 and above. +@@ -2281,6 +2392,33 @@ + spin_unlock_irqrestore(&host->lock, flags); + } + ++static int sdhci_card_info_save(struct mmc_host *mmc) ++{ ++ struct mmc_card *card = mmc->card; ++ struct sdhci_host *host= mmc_priv(mmc); ++ struct card_info *c_info = &host->c_info; ++ ++ if (!card) { ++ memset(c_info,0,sizeof(struct card_info)); ++ c_info->card_connect = CARD_DISCONNECT; ++ goto out; ++ } ++ ++ c_info->card_type = card->type; ++ c_info->card_state = card->state; ++ ++ c_info->timing = mmc->ios.timing; ++ c_info->card_support_clock = mmc->ios.clock; ++ ++ c_info->sd_bus_speed = card->sd_bus_speed; ++ ++ memcpy(c_info->ssr, card->raw_ssr, ARRAY_SIZE(c_info->ssr)); ++ ++ c_info->card_connect = CARD_CONNECT; ++out: ++ return 0; ++} ++ + static const struct mmc_host_ops sdhci_ops = { + .request = sdhci_request, + .post_req = sdhci_post_req, +@@ -2296,6 +2434,7 @@ + .select_drive_strength = sdhci_select_drive_strength, + .card_event = sdhci_card_event, + .card_busy = sdhci_card_busy, ++ .card_info_save = sdhci_card_info_save, + }; + + /*****************************************************************************\ +@@ -2370,6 +2509,9 @@ + host->pending_reset = false; + } + ++ if (mrq->data && mrq->data->error && !host->is_tuning) ++ host->error_count++; ++ + if (!sdhci_has_requests(host)) + sdhci_led_deactivate(host); + +@@ -2460,17 +2602,32 @@ + */ + if (host->pending_reset) + return; +- pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", ++ ++ /*pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); +- sdhci_dumpregs(host); ++ sdhci_dumpregs(host);*/ ++ + return; + } + + if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | +- SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) { ++ SDHCI_INT_END_BIT | SDHCI_INT_INDEX | ++ SDHCI_INT_ACMD_ERR)) { + if (intmask & SDHCI_INT_TIMEOUT) + host->cmd->error = -ETIMEDOUT; +- else ++ else if (intmask & SDHCI_INT_ACMD_ERR) { ++ u16 acmd_stat = sdhci_readw(host, SDHCI_AUTO_CMD_ERR); ++ ++ if (acmd_stat & (SDHCI_AUTO_CMD12_NOT_EXEC | ++ SDHCI_AUTO_CMD_INDEX_ERR | ++ SDHCI_AUTO_CMD12_NOT_ISSUED)) ++ host->cmd->error = -EIO; ++ else if (acmd_stat & SDHCI_AUTO_CMD_TIMEOUT_ERR) ++ host->cmd->error = -ETIMEDOUT; ++ else ++ host->cmd->error = -EILSEQ; ++ ++ } else + host->cmd->error = -EILSEQ; + + /* +@@ -2533,6 +2690,8 @@ + + static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) + { ++ ++#ifndef SDHCI_GOKE_EDGE_TUNING + u32 command; + + /* CMD19 generates _only_ Buffer Read Ready interrupt */ +@@ -2545,6 +2704,7 @@ + return; + } + } ++#endif + + if (!host->data) { + struct mmc_command *data_cmd = host->data_cmd; +@@ -2584,6 +2744,9 @@ + if (host->pending_reset) + return; + ++ if (host->is_tuning) ++ return; ++ + pr_err("%s: Got data interrupt 0x%08x even though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + sdhci_dumpregs(host); +@@ -2655,6 +2818,58 @@ + } + } + ++#ifdef CONFIG_MMC_CQ_HCI ++static int sdhci_get_cmd_err(u32 intmask) ++{ ++ if (intmask & SDHCI_INT_TIMEOUT) ++ return -ETIMEDOUT; ++ else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT | ++ SDHCI_INT_INDEX)) ++ return -EILSEQ; ++ return 0; ++} ++ ++static int sdhci_get_data_err(u32 intmask) ++{ ++ if (intmask & SDHCI_INT_DATA_TIMEOUT) ++ return -ETIMEDOUT; ++ else if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) ++ return -EILSEQ; ++ else if (intmask & SDHCI_INT_ADMA_ERROR) ++ return -EIO; ++ return 0; ++} ++ ++static irqreturn_t sdhci_cmdq_irq(struct sdhci_host *host, u32 intmask) ++{ ++ int err = 0; ++ u32 mask = 0; ++ irqreturn_t ret; ++ ++ if (intmask & SDHCI_INT_CMD_MASK) ++ err = sdhci_get_cmd_err(intmask); ++ else if (intmask & SDHCI_INT_DATA_MASK) ++ err = sdhci_get_data_err(intmask); ++ ++ ret = cmdq_irq(host->mmc, err); ++ if (err) { ++ /* Clear the error interrupts */ ++ mask = intmask & SDHCI_INT_ERROR_MASK; ++ sdhci_writel(host, mask, SDHCI_INT_STATUS); ++ } ++ return ret; ++ ++} ++ ++#else ++static irqreturn_t sdhci_cmdq_irq(struct sdhci_host *host, u32 intmask) ++{ ++ pr_err("%s: Received cmdq-irq when disabled !!!!\n", ++ mmc_hostname(host->mmc)); ++ return IRQ_NONE; ++} ++#endif ++ + static irqreturn_t sdhci_irq(int irq, void *dev_id) + { + irqreturn_t result = IRQ_NONE; +@@ -2676,6 +2891,19 @@ + } + + do { ++ if (host->mmc->card && mmc_card_cmdq(host->mmc->card) && ++ !mmc_host_halt(host->mmc) && !mmc_host_cq_disable(host->mmc)) { ++ DBG("*** %s: cmdq intr: 0x%08x\n", ++ mmc_hostname(host->mmc), ++ intmask); ++ result = sdhci_cmdq_irq(host, intmask); ++ if (result == IRQ_HANDLED) { ++ mask = intmask & SDHCI_INT_CQE; ++ sdhci_writel(host, mask, SDHCI_INT_STATUS); ++ goto out; ++ } ++ } ++ + /* Clear selected interrupts. */ + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | + SDHCI_INT_BUS_POWER); +@@ -3093,7 +3321,7 @@ + + override_timeout_clk = host->timeout_clk; + +- if (host->version > SDHCI_SPEC_300) { ++ if (host->version > SDHCI_SPEC_420) { + pr_err("%s: Unknown controller version (%d). You may experience problems.\n", + mmc_hostname(mmc), host->version); + } +@@ -3121,6 +3349,15 @@ + host->flags &= ~SDHCI_USE_ADMA; + } + ++ if ((host->version >= SDHCI_SPEC_400) && ++ (host->caps1 & SDHCI_CAN_DO_ADMA3)) ++ host->flags |= SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE; ++ ++ if ((host->quirks2 & SDHCI_QUIRK2_BROKEN_ADMA3) && ++ (host->flags & SDHCI_USE_ADMA3)) { ++ DBG("Disabling ADMA3 as it is marked broken\n"); ++ host->flags &= ~(SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE); ++ } + /* + * It is assumed that a 64-bit capable device has set a 64-bit DMA mask + * and *must* do 64-bit DMA. A driver has the opportunity to change +@@ -3161,14 +3398,14 @@ + * all multipled by the descriptor size. + */ + if (host->flags & SDHCI_USE_64_BIT_DMA) { +- host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * +- SDHCI_ADMA2_64_DESC_SZ; +- host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; +- } else { +- host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * +- SDHCI_ADMA2_32_DESC_SZ; ++ if (host->flags & SDHCI_HOST_VER4_ENABLE) ++ host->desc_sz = 16; ++ else ++ host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; ++ } else + host->desc_sz = SDHCI_ADMA2_32_DESC_SZ; +- } ++ ++ host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * host->desc_sz; + + host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN; + buf = dma_alloc_coherent(mmc_dev(mmc), host->align_buffer_sz + +@@ -3191,6 +3428,36 @@ + host->adma_table = buf + host->align_buffer_sz; + host->adma_addr = dma + host->align_buffer_sz; + } ++ ++ if (!(host->flags & SDHCI_USE_ADMA)) ++ host->flags &= ~SDHCI_USE_ADMA3; ++ ++ if (host->flags & SDHCI_USE_ADMA3) { ++#define MAX_CMD_NUM 32 ++#define SDHCI_CMD_DESC_SZ 16 ++ if (host->flags & SDHCI_USE_64_BIT_DMA) ++ host->adma3_desc_sz = SDHCI_ADMA3_64_DESC_SZ; ++ else ++ host->adma3_desc_sz = SDHCI_ADMA3_32_DESC_SZ; ++ ++ host->adma3_table_sz = MAX_CMD_NUM * host->adma3_desc_sz; ++ host->cmd_table_sz = MAX_CMD_NUM * ++ (SDHCI_CMD_DESC_SZ + 16); ++ buf = dma_alloc_coherent(mmc_dev(mmc), host->adma3_table_sz + ++ host->cmd_table_sz, &dma, GFP_KERNEL); ++ if (!buf) { ++ pr_warn("%s: Unable to allocate ADMA3 buffers - falling back to standard DMA\n", ++ mmc_hostname(mmc)); ++ host->flags &= ~SDHCI_USE_ADMA3; ++ } else { ++ host->adma3_table = buf; ++ host->adma3_addr = dma; ++ ++ host->cmd_table = buf + host->adma3_desc_sz; ++ host->cmd_addr = dma + host->adma3_desc_sz; ++ } ++ } ++ + } + + /* +@@ -3557,10 +3824,165 @@ + host->adma_table = NULL; + host->align_buffer = NULL; + ++ if (host->adma3_table) ++ dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz + ++ host->cmd_table_sz, host->adma3_table, ++ host->adma3_addr); ++ ++ host->adma3_table = NULL; ++ host->cmd_table = NULL; ++ + return ret; + } + EXPORT_SYMBOL_GPL(sdhci_setup_host); + ++#ifdef CONFIG_MMC_CQ_HCI ++static void sdhci_cmdq_set_transfer_params(struct mmc_host *mmc) ++{ ++ struct sdhci_host *host = mmc_priv(mmc); ++ u8 ctrl; ++ u16 mode, ctrl2; ++ ++ if (host->version >= SDHCI_SPEC_200) { ++ ++ ctrl2 = sdhci_readw(host, SDHCI_CLOCK_CONTROL); ++ ctrl2 |= SDHCI_CLOCK_PLL_EN; ++ sdhci_writew(host, ctrl2, SDHCI_CLOCK_CONTROL); ++ ++ ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); ++ ctrl2 |= SDHCI_CTRL_ADDRESSING_64BIT; ++ ctrl2 |= SDHCI_CTRL_HOST_VER4_ENABLE; ++ sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2); ++ ++ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); ++ ctrl &= ~SDHCI_CTRL_DMA_MASK; ++ if (host->flags & SDHCI_USE_64_BIT_DMA) ++ ctrl |= SDHCI_CTRL_ADMA64; ++ else ++ ctrl |= SDHCI_CTRL_ADMA32; ++ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); ++ ++ mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); ++ sdhci_writew(host, mode | SDHCI_TRNS_MULTI, SDHCI_TRANSFER_MODE); ++ } ++} ++ ++static void sdhci_cmdq_clear_set_irqs(struct mmc_host *mmc, bool clear) ++{ ++ struct sdhci_host *host = mmc_priv(mmc); ++ u32 ier = 0; ++ ++ ier &= ~SDHCI_INT_ALL_MASK; ++ ++ if (clear) { ++ ier = SDHCI_INT_CQE | SDHCI_INT_ERROR_MASK; ++ sdhci_writel(host, ier, SDHCI_INT_ENABLE); ++ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); ++ } else { ++ ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | ++ SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | ++ SDHCI_INT_INDEX | SDHCI_INT_END_BIT | ++ SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | ++ SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE | ++ SDHCI_INT_ACMD_ERR; ++ sdhci_writel(host, ier, SDHCI_INT_ENABLE); ++ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); ++ } ++} ++ ++static void sdhci_cmdq_set_data_timeout(struct mmc_host *mmc, u32 val) ++{ ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ val = 0xe; ++ sdhci_writeb(host, val, SDHCI_TIMEOUT_CONTROL); ++} ++ ++static void sdhci_cmdq_dump_goke_regs(struct mmc_host *mmc) ++{ ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ sdhci_dumpregs(host); ++} ++ ++static int sdhci_cmdq_init(struct sdhci_host *host, struct mmc_host *mmc, ++ bool dma64) ++{ ++ struct cmdq_host *cq_host; ++ ++ cq_host = kzalloc(sizeof(*cq_host), GFP_KERNEL); ++ if (!cq_host) { ++ pr_err("failed to allocate memory for CMDQ\n"); ++ host->cq_host = NULL; ++ return -ENOMEM; ++ } else { ++ cq_host->mmio = host->ioaddr + 0x180; ++ host->cq_host = cq_host; ++ } ++ ++ return cmdq_init(host->cq_host, mmc, dma64); ++} ++ ++static void sdhci_cmdq_set_block_size(struct mmc_host *mmc) ++{ ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ sdhci_writew(host, SDHCI_MAKE_BLKSZ(0, 512), SDHCI_BLOCK_SIZE); ++} ++ ++static void sdhci_cmdq_post_cqe_halt(struct mmc_host *mmc) ++{ ++ struct sdhci_host *host = mmc_priv(mmc); ++ ++ sdhci_writel(host, sdhci_readl(host, SDHCI_INT_ENABLE) | ++ SDHCI_INT_RESPONSE, SDHCI_INT_ENABLE); ++ sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS); ++} ++#else ++static void sdhci_cmdq_set_transfer_params(struct mmc_host *mmc) ++{ ++ ++} ++static void sdhci_cmdq_clear_set_irqs(struct mmc_host *mmc, bool clear) ++{ ++ ++} ++ ++static void sdhci_cmdq_set_data_timeout(struct mmc_host *mmc, u32 val) ++{ ++ ++} ++ ++static void sdhci_cmdq_dump_goke_regs(struct mmc_host *mmc) ++{ ++ ++} ++ ++static int sdhci_cmdq_init(struct sdhci_host *host, struct mmc_host *mmc, ++ bool dma64) ++{ ++ return -ENOSYS; ++} ++ ++static void sdhci_cmdq_set_block_size(struct mmc_host *mmc) ++{ ++ ++} ++ ++static void sdhci_cmdq_post_cqe_halt(struct mmc_host *mmc) ++{ ++} ++#endif ++ ++static const struct cmdq_host_ops sdhci_cmdq_ops = { ++ .clear_set_irqs = sdhci_cmdq_clear_set_irqs, ++ .set_data_timeout = sdhci_cmdq_set_data_timeout, ++ .dump_goke_regs = sdhci_cmdq_dump_goke_regs, ++ .set_block_size = sdhci_cmdq_set_block_size, ++ .post_cqe_halt = sdhci_cmdq_post_cqe_halt, ++ .set_transfer_params = sdhci_cmdq_set_transfer_params, ++}; ++ + int __sdhci_add_host(struct sdhci_host *host) + { + struct mmc_host *mmc = host->mmc; +@@ -3605,11 +4027,25 @@ + if (ret) + goto unled; + +- pr_info("%s: SDHCI controller on %s [%s] using %s\n", ++ if (mmc->caps2 & MMC_CAP2_CMD_QUEUE) { ++ bool dma64 = (host->flags & SDHCI_USE_64_BIT_DMA) ? ++ true : false; ++ ret = sdhci_cmdq_init(host, mmc, dma64); ++ if (ret) ++ pr_err("%s: CMDQ init: failed (%d)\n", ++ mmc_hostname(host->mmc), ret); ++ else ++ host->cq_host->ops = &sdhci_cmdq_ops; ++ } ++ ++ pr_info("%s: SDHCI controller on %s [%s] using %s in %s mode\n", + mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), ++ (host->flags & SDHCI_USE_ADMA3) ? "ADMA3" : + (host->flags & SDHCI_USE_ADMA) ? + (host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" : +- (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); ++ ((host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"), ++ ((mmc->caps2 & MMC_CAP2_CMD_QUEUE) && !ret) ? ++ "CMDQ" : "legacy"); + + sdhci_enable_card_detection(host); + +@@ -3635,6 +4071,14 @@ + host->adma_table = NULL; + host->align_buffer = NULL; + ++ if (host->adma3_table) ++ dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz + ++ host->cmd_table_sz, host->adma3_table, ++ host->adma3_addr); ++ ++ host->adma3_table = NULL; ++ host->cmd_table = NULL; ++ + return ret; + } + EXPORT_SYMBOL_GPL(__sdhci_add_host); +@@ -3672,6 +4116,8 @@ + + sdhci_disable_card_detection(host); + ++ free_irq(host->irq, host); ++ + mmc_remove_host(mmc); + + sdhci_led_unregister(host); +@@ -3681,7 +4127,6 @@ + + sdhci_writel(host, 0, SDHCI_INT_ENABLE); + sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); +- free_irq(host->irq, host); + + del_timer_sync(&host->timer); + del_timer_sync(&host->data_timer); +@@ -3698,6 +4143,14 @@ + + host->adma_table = NULL; + host->align_buffer = NULL; ++ ++ if (host->adma3_table) ++ dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz + ++ host->cmd_table_sz, host->adma3_table, ++ host->adma3_addr); ++ ++ host->adma3_table = NULL; ++ host->cmd_table = NULL; + } + + EXPORT_SYMBOL_GPL(sdhci_remove_host); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci.h.patch new file mode 100644 index 00000000..9a678656 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mmc-host-sdhci.h.patch @@ -0,0 +1,284 @@ +--- linux-4.9.37/drivers/mmc/host/sdhci.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mmc/host/sdhci.h 2021-06-07 13:01:33.000000000 +0300 +@@ -20,6 +20,8 @@ + + #include + ++#define SDHCI_GOKE_EDGE_TUNING /* enable edge tuning */ ++ + /* + * Controller registers + */ +@@ -84,6 +86,7 @@ + #define SDHCI_CTRL_ADMA1 0x08 + #define SDHCI_CTRL_ADMA32 0x10 + #define SDHCI_CTRL_ADMA64 0x18 ++#define SDHCI_CTRL_ADMA3 0x18 + #define SDHCI_CTRL_8BITBUS 0x20 + #define SDHCI_CTRL_CDTEST_INS 0x40 + #define SDHCI_CTRL_CDTEST_EN 0x80 +@@ -108,6 +111,7 @@ + #define SDHCI_DIV_MASK_LEN 8 + #define SDHCI_DIV_HI_MASK 0x300 + #define SDHCI_PROG_CLOCK_MODE 0x0020 ++#define SDHCI_CLOCK_PLL_EN 0x0008 + #define SDHCI_CLOCK_CARD_EN 0x0004 + #define SDHCI_CLOCK_INT_STABLE 0x0002 + #define SDHCI_CLOCK_INT_EN 0x0001 +@@ -132,6 +136,7 @@ + #define SDHCI_INT_CARD_REMOVE 0x00000080 + #define SDHCI_INT_CARD_INT 0x00000100 + #define SDHCI_INT_RETUNE 0x00001000 ++#define SDHCI_INT_CQE 0x00004000 + #define SDHCI_INT_ERROR 0x00008000 + #define SDHCI_INT_TIMEOUT 0x00010000 + #define SDHCI_INT_CRC 0x00020000 +@@ -141,14 +146,16 @@ + #define SDHCI_INT_DATA_CRC 0x00200000 + #define SDHCI_INT_DATA_END_BIT 0x00400000 + #define SDHCI_INT_BUS_POWER 0x00800000 +-#define SDHCI_INT_ACMD12ERR 0x01000000 ++#define SDHCI_INT_ACMD_ERR 0x01000000 + #define SDHCI_INT_ADMA_ERROR 0x02000000 + + #define SDHCI_INT_NORMAL_MASK 0x00007FFF + #define SDHCI_INT_ERROR_MASK 0xFFFF8000 + + #define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ +- SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) ++ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX | \ ++ SDHCI_INT_ACMD_ERR) ++ + #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ +@@ -156,7 +163,13 @@ + SDHCI_INT_BLK_GAP) + #define SDHCI_INT_ALL_MASK ((unsigned int)-1) + +-#define SDHCI_ACMD12_ERR 0x3C ++#define SDHCI_AUTO_CMD_ERR 0x3C ++#define SDHCI_AUTO_CMD12_NOT_EXEC 0x0001 ++#define SDHCI_AUTO_CMD_TIMEOUT_ERR 0x0002 ++#define SDHCI_AUTO_CMD_CRC_ERR 0x0004 ++#define SDHCI_AUTO_CMD_ENDBIT_ERR 0x0008 ++#define SDHCI_AUTO_CMD_INDEX_ERR 0x0010 ++#define SDHCI_AUTO_CMD12_NOT_ISSUED 0x0080 + + #define SDHCI_HOST_CONTROL2 0x3E + #define SDHCI_CTRL_UHS_MASK 0x0007 +@@ -165,7 +178,7 @@ + #define SDHCI_CTRL_UHS_SDR50 0x0002 + #define SDHCI_CTRL_UHS_SDR104 0x0003 + #define SDHCI_CTRL_UHS_DDR50 0x0004 +-#define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ ++#define SDHCI_CTRL_HS400 0x0007 /* Non-standard */ + #define SDHCI_CTRL_VDD_180 0x0008 + #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 + #define SDHCI_CTRL_DRV_TYPE_B 0x0000 +@@ -174,6 +187,9 @@ + #define SDHCI_CTRL_DRV_TYPE_D 0x0030 + #define SDHCI_CTRL_EXEC_TUNING 0x0040 + #define SDHCI_CTRL_TUNED_CLK 0x0080 ++#define SDHCI_CTRL_HOST_VER4_ENABLE 0x1000 ++#define SDHCI_CTRL_ADDRESSING_64BIT 0x2000 ++#define SDHCI_CTRL_ASYNC_INT_ENABLE 0x4000 + #define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 + + #define SDHCI_CAPABILITIES 0x40 +@@ -195,6 +211,7 @@ + #define SDHCI_CAN_VDD_300 0x02000000 + #define SDHCI_CAN_VDD_180 0x04000000 + #define SDHCI_CAN_64BIT 0x10000000 ++#define SDHCI_CAN_ASYNC_INT 0x20000000 + + #define SDHCI_SUPPORT_SDR50 0x00000001 + #define SDHCI_SUPPORT_SDR104 0x00000002 +@@ -209,6 +226,7 @@ + #define SDHCI_RETUNING_MODE_SHIFT 14 + #define SDHCI_CLOCK_MUL_MASK 0x00FF0000 + #define SDHCI_CLOCK_MUL_SHIFT 16 ++#define SDHCI_CAN_DO_ADMA3 0x08000000 + #define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ + + #define SDHCI_CAPABILITIES_1 0x44 +@@ -250,6 +268,9 @@ + #define SDHCI_PRESET_SDCLK_FREQ_MASK 0x3FF + #define SDHCI_PRESET_SDCLK_FREQ_SHIFT 0 + ++#define SDHCI_ADMA3_ID_ADDR_LOW 0x78 ++#define SDHCI_ADMA3_ID_ADDR_HI 0x7C ++ + #define SDHCI_SLOT_INT_STATUS 0xFC + + #define SDHCI_HOST_VERSION 0xFE +@@ -260,7 +281,38 @@ + #define SDHCI_SPEC_100 0 + #define SDHCI_SPEC_200 1 + #define SDHCI_SPEC_300 2 +- ++#define SDHCI_SPEC_400 3 ++#define SDHCI_SPEC_410 4 ++#define SDHCI_SPEC_420 5 ++ ++#define SDHCI_MSHC_CTRL 0x508 ++#define SDHCI_CMD_CONFLIT_CHECK 0x01 ++ ++#define SDHCI_AXI_MBIIU_CTRL 0x510 ++#define SDHCI_GM_WR_OSRC_LMT_MASK (0x7 << 24) ++#define SDHCI_GM_WR_OSRC_LMT_SEL(x) ((x) << 24) ++#define SDHCI_GM_RD_OSRC_LMT_MASK (0x7 << 16) ++#define SDHCI_GM_RD_OSRC_LMT_SEL(x) ((x) << 16) ++#define SDHCI_UNDEFL_INCR_EN 0x1 ++ ++#define SDHCI_EMMC_CTRL 0x52c ++#define SDHCI_CARD_IS_EMMC 0x00000001 ++#define SDHCI_ENH_STROBE_EN 0x00000100 ++ ++#define SDHCI_EMMC_HW_RESET 0x534 ++ ++#define SDHCI_AT_CTRL 0x540 ++#define SDHCI_SAMPLE_EN 0x00000010 ++ ++#define SDHCI_AT_STAT 0x544 ++#define SDHCI_PHASE_SEL_MASK 0x000000ff ++ ++#define SDHCI_MULTI_CYCLE 0x54c ++#define SDHCI_FOUND_EDGE (0x1 << 11) ++#define SDHCI_EDGE_DETECT_EN (0x1 << 8) ++#define SDHCI_DOUT_EN_F_EDGE (0x1 << 6) ++#define SDHCI_DATA_DLY_EN (0x1 << 3) ++#define SDHCI_CMD_DLY_EN (0x1 << 2) + /* + * End of controller registers. + */ +@@ -273,6 +325,7 @@ + */ + #define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024) + #define SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12) ++#define SDHCI_DMA_BOUNDARY_SIZE (0x1 << 27) + + /* ADMA2 32-bit DMA descriptor size */ + #define SDHCI_ADMA2_32_DESC_SZ 8 +@@ -298,6 +351,12 @@ + /* ADMA2 64-bit DMA descriptor size */ + #define SDHCI_ADMA2_64_DESC_SZ 12 + ++/* ADMA3 32-bit DMA descriptor size */ ++#define SDHCI_ADMA3_32_DESC_SZ 8 ++ ++/* ADMA3 64-bit DMA descriptor size */ ++#define SDHCI_ADMA3_64_DESC_SZ 16 ++ + /* + * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte + * aligned. +@@ -312,6 +371,9 @@ + #define ADMA2_TRAN_VALID 0x21 + #define ADMA2_NOP_END_VALID 0x3 + #define ADMA2_END 0x2 ++#define ADMA2_LINK_VALID 0x31 ++#define ADMA3_CMD_VALID 0x9 ++#define ADMA3_END 0x3b + + /* + * Maximum segments assuming a 512KiB maximum requisition size and a minimum +@@ -328,6 +390,18 @@ + COOKIE_MAPPED, /* mapped by sdhci_prepare_data() */ + }; + ++struct card_info { ++ unsigned int card_type; ++ unsigned char timing; ++ unsigned char card_connect; ++#define CARD_CONNECT 1 ++#define CARD_DISCONNECT 0 ++ unsigned int card_support_clock; /* clock rate */ ++ unsigned int card_state; /* (our) card state */ ++ unsigned int sd_bus_speed; ++ unsigned int ssr[16]; ++}; ++ + struct sdhci_host { + /* Data set by hardware interface driver */ + const char *hw_name; /* Hardware bus name */ +@@ -425,6 +499,7 @@ + #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) + /* Broken Clock divider zero in controller */ + #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) ++#define SDHCI_QUIRK2_BROKEN_ADMA3 (1<<16) + + int irq; /* Device IRQ */ + void __iomem *ioaddr; /* Mapped address */ +@@ -458,6 +533,8 @@ + #define SDHCI_SIGNALING_330 (1<<14) /* Host is capable of 3.3V signaling */ + #define SDHCI_SIGNALING_180 (1<<15) /* Host is capable of 1.8V signaling */ + #define SDHCI_SIGNALING_120 (1<<16) /* Host is capable of 1.2V signaling */ ++#define SDHCI_USE_ADMA3 (1<<17) /* Host is ADMA3 capable */ ++#define SDHCI_HOST_VER4_ENABLE (1<<18) /* Host version 4 enable */ + + unsigned int version; /* SDHCI spec. version */ + +@@ -486,14 +563,21 @@ + + void *adma_table; /* ADMA descriptor table */ + void *align_buffer; /* Bounce buffer */ ++ void *adma3_table; /* ADMA3 integrated descriptor table */ ++ void *cmd_table; /* ADMA3 command descriptor table */ + + size_t adma_table_sz; /* ADMA descriptor table size */ + size_t align_buffer_sz; /* Bounce buffer size */ ++ size_t adma3_table_sz; /* ADMA3 integrated descriptor table size */ ++ size_t cmd_table_sz; /* ADMA3 command descriptor table size */ + + dma_addr_t adma_addr; /* Mapped ADMA descr. table */ + dma_addr_t align_addr; /* Mapped bounce buffer */ ++ dma_addr_t adma3_addr; /* Mapped ADMA3 integrated descr. table */ ++ dma_addr_t cmd_addr; /* Mapped ADMA3 command descr. table */ + + unsigned int desc_sz; /* ADMA descriptor size */ ++ unsigned int adma3_desc_sz; /* ADMA3 integrated descriptor size */ + + struct tasklet_struct finish_tasklet; /* Tasklet structures */ + +@@ -525,6 +609,10 @@ + #define SDHCI_TUNING_MODE_2 1 + #define SDHCI_TUNING_MODE_3 2 + ++ struct cmdq_host *cq_host; ++ unsigned int is_tuning; ++ unsigned int error_count; ++ struct card_info c_info; + unsigned long private[0] ____cacheline_aligned; + }; + +@@ -564,6 +652,10 @@ + struct mmc_card *card, + unsigned int max_dtr, int host_drv, + int card_drv, int *drv_type); ++ int (*start_signal_voltage_switch)(struct sdhci_host *host, ++ struct mmc_ios *ios); ++ void (*pre_init)(struct sdhci_host *host); ++ void (*extra_init)(struct sdhci_host *host); + }; + + #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS +@@ -698,4 +790,18 @@ + extern int sdhci_runtime_resume_host(struct sdhci_host *host); + #endif + ++#define UNSTUFF_BITS(resp,start,size) \ ++ ({ \ ++ const int __size = size; \ ++ const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ ++ const int __off = 3 - ((start) / 32); \ ++ const int __shft = (start) & 31; \ ++ u32 __res; \ ++ \ ++ __res = resp[__off] >> __shft; \ ++ if (__size + __shft > 32) \ ++ __res |= resp[__off-1] << ((32 - __shft) % 32); \ ++ __res & __mask; \ ++ }) ++ + #endif /* __SDHCI_HW_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-Makefile.patch new file mode 100644 index 00000000..bb31a8a1 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-Makefile.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/drivers/mtd/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -30,7 +30,7 @@ + nftl-objs := nftlcore.o nftlmount.o + inftl-objs := inftlcore.o inftlmount.o + ++obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ + obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/ + +-obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ + obj-$(CONFIG_MTD_UBI) += ubi/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-Kconfig.patch new file mode 100644 index 00000000..2283738f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-Kconfig.patch @@ -0,0 +1,31 @@ +--- linux-4.9.37/drivers/mtd/nand/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -569,4 +569,28 @@ + Enables support for NAND controller on MTK SoCs. + This controller is found on mt27xx, mt81xx, mt65xx SoCs. + ++config MTD_SPI_NAND_GOKE ++ tristate "Support for SPI NAND controller on Goke SoCs" ++ depends on MTD_NAND ++ help ++ Enables support for the SPI NAND device drivers. ++ ++config GOKE_NAND_ECC_STATUS_REPORT ++ tristate "Report the ecc status to MTD for Goke Nand Driver" ++ depends on MTD_NAND && ARCH_GOKE ++ default n ++ help ++ Flash Memory Controller reports the ecc status include ECC error ++ and ECC corrected to MTD to monitor the aging of devices. ++ ++config GOKE_NAND_FS_MAY_NO_YAFFS2 ++ bool "Remove the restraintion of 16bit ecc type on yaffs2 to Goke" ++ depends on MFD_GOKE_FMC ++ default n ++ help ++ The ecc type: 16bit is limited by the Goke flash memory controller, ++ as the yaffs2 tag of goke rootfs limits the min size of CTRL len is 28. ++ ++source "drivers/mtd/nand/gkfmc100/Kconfig" ++ + endif # MTD_NAND diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-Makefile.patch new file mode 100644 index 00000000..088bfdb0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-Makefile.patch @@ -0,0 +1,16 @@ +--- linux-4.9.37/drivers/mtd/nand/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -8,6 +8,7 @@ + obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o + obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o + ++obj-$(CONFIG_MTD_SPI_NAND_FMC100) += gkfmc100/ + obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o + obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o + obj-$(CONFIG_MTD_NAND_DENALI) += denali.o +@@ -59,4 +60,4 @@ + obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o + obj-$(CONFIG_MTD_NAND_MTK) += mtk_nand.o mtk_ecc.o + +-nand-objs := nand_base.o nand_bbt.o nand_timings.o ++nand-objs := nand_base.o nand_bbt.o nand_timings.o nfc_gen.o nfc_spl_ids.o match_table.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-Kconfig.patch new file mode 100644 index 00000000..5811f032 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-Kconfig.patch @@ -0,0 +1,20 @@ +--- linux-4.9.37/drivers/mtd/nand/gkfmc100/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/gkfmc100/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,17 @@ ++# ++# goke flash memory controller SPI nand device driver version 100 ++# drivers/mtd/nand/gkfmc100/Kconfig ++# add by goke 2017.8.7 ++# ++ ++config MTD_SPI_NAND_FMC100 ++ bool "Goke Flash Memory Controller v100 SPI Nand devices support" ++ depends on MFD_GOKE_FMC && MTD_SPI_NAND_GOKE ++ select MISC_FILESYSTEMS ++ select MTD_BLOCK ++ select YAFFS_FS ++ select YAFFS_YAFFS2 ++ help ++ Goke Flash Memory Controller version 100 is called fmc100 for ++ short. The controller driver support registers and DMA transfers ++ while reading or writing the SPI nand flash. diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-Makefile.patch new file mode 100644 index 00000000..47a89810 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-Makefile.patch @@ -0,0 +1,29 @@ +--- linux-4.9.37/drivers/mtd/nand/gkfmc100/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/gkfmc100/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,26 @@ ++# ++# The Flash Memory Controller v100 Device Driver for goke ++# ++# Copyright (c) 2016-2017 Goke Technologies Co., Ltd. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 2 of the License, or (at your ++# option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++# ++ ++# ++# drivers/mtd/nand/gkfmc100/Makefile ++# ++ ++obj-y += fmc_spi_nand_ids.o ++obj-y += fmc100.o fmc100_os.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100.c.patch new file mode 100644 index 00000000..c8401ea4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100.c.patch @@ -0,0 +1,1202 @@ +--- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,1199 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../nfc_gen.h" ++#include "fmc100.h" ++ ++/*****************************************************************************/ ++static void fmc100_switch_to_spi_nand(struct fmc_host *host) ++{ ++ u32 reg; ++ ++ reg = fmc_readl(host, FMC_CFG); ++ reg &= ~FLASH_TYPE_SEL_MASK; ++ reg |= FMC_CFG_FLASH_SEL(FLASH_TYPE_SPI_NAND); ++ fmc_writel(host, FMC_CFG, reg); ++} ++ ++/*****************************************************************************/ ++static void fmc100_set_str_mode(struct fmc_host *host) ++{ ++ u32 reg; ++ ++ reg = fmc_readl(host, FMC_GLOBAL_CFG); ++ reg &= (~FMC_GLOBAL_CFG_DTR_MODE); ++ fmc_writel(host, FMC_GLOBAL_CFG, reg); ++} ++ ++/*****************************************************************************/ ++static void fmc100_operation_config(struct fmc_host *host, int op) ++{ ++ int ret, clkrate = 0; ++ struct fmc_spi *spi = host->spi; ++ ++ fmc100_switch_to_spi_nand(host); ++ clk_prepare_enable(host->clk); ++ switch (op) { ++ case OP_STYPE_WRITE: ++ clkrate = min((u_long)host->clkrate, ++ (u_long)CLK_FMC_TO_CRG_MHZ(spi->write->clock)); ++ break; ++ case OP_STYPE_READ: ++ clkrate = min((u_long)host->clkrate, ++ (u_long)CLK_FMC_TO_CRG_MHZ(spi->read->clock)); ++ break; ++ case OP_STYPE_ERASE: ++ clkrate = min((u_long)host->clkrate, ++ (u_long)CLK_FMC_TO_CRG_MHZ(spi->erase->clock)); ++ break; ++ default: ++ break; ++ } ++ ++ ret = clk_set_rate(host->clk, clkrate); ++ if (WARN_ON(ret)) { ++ pr_err("clk_set_rate failed: %d\n", ret); ++ } ++} ++ ++/*****************************************************************************/ ++static void fmc100_send_cmd_write(struct fmc_host *host) ++{ ++ unsigned char pages_per_block_shift; ++ unsigned int reg, block_num, block_num_h, page_num; ++ struct fmc_spi *spi = host->spi; ++ struct nand_chip *chip = host->chip; ++#ifdef FMC100_SPI_NAND_SUPPORT_REG_WRITE ++ const char *op = "Reg"; ++#else ++ const char *op = "Dma"; ++#endif ++ ++ if (WR_DBG) { ++ pr_info("\n"); ++ } ++ FMC_PR(WR_DBG, "*-Start send %s page write command\n", op); ++ ++ mutex_lock(host->lock); ++ fmc100_operation_config(host, OP_STYPE_WRITE); ++ ++ reg = spi->driver->wait_ready(spi); ++ if (reg) { ++ DB_MSG("Error: %s program wait ready failed! status: %#x\n", ++ op, reg); ++ goto end; ++ } ++ ++ reg = spi->driver->write_enable(spi); ++ if (reg) { ++ DB_MSG("Error: %s program write enable failed! reg: %#x\n", ++ op, reg); ++ goto end; ++ } ++ ++ reg = FMC_INT_CLR_ALL; ++ fmc_writel(host, FMC_INT_CLR, reg); ++ FMC_PR(WR_DBG, "|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) ++ | OP_CFG_MEM_IF_TYPE(spi->write->iftype) ++ | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(WR_DBG, "|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ pages_per_block_shift = chip->phys_erase_shift - chip->page_shift; ++ block_num = host->addr_value[1] >> pages_per_block_shift; ++ block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT; ++ reg = FMC_ADDRH_SET(block_num_h); ++ fmc_writel(host, FMC_ADDRH, reg); ++ FMC_PR(WR_DBG, "|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); ++ ++ page_num = host->addr_value[1] - (block_num << pages_per_block_shift); ++ reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT) ++ | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT); ++ fmc_writel(host, FMC_ADDRL, reg); ++ FMC_PR(WR_DBG, "|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); ++ ++ *host->epm = 0x0000; ++ ++#ifndef FMC100_SPI_NAND_SUPPORT_REG_WRITE ++ reg = host->dma_buffer; ++ fmc_writel(host, FMC_DMA_SADDR_D0, reg); ++ FMC_PR(WR_DBG, "|-Set DMA_SADDR_D[0x40]%#x\n", reg); ++ ++#ifdef CONFIG_64BIT ++ reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32; ++ fmc_writel(host, FMC_DMA_SADDRH_D0, reg); ++ FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg); ++#endif ++ ++ reg = host->dma_oob; ++ fmc_writel(host, FMC_DMA_SADDR_OOB, reg); ++ FMC_PR(WR_DBG, "|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, reg); ++#ifdef CONFIG_64BIT ++ reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32; ++ fmc_writel(host, FMC_DMA_SADDRH_OOB, reg); ++ FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB, ++ reg); ++#endif ++#endif ++ ++ reg = OP_CTRL_WR_OPCODE(spi->write->cmd) ++#ifdef FMC100_SPI_NAND_SUPPORT_REG_WRITE ++ | OP_CTRL_DMA_OP(OP_TYPE_REG) ++#else ++ | OP_CTRL_DMA_OP(OP_TYPE_DMA) ++#endif ++ | OP_CTRL_RW_OP(RW_OP_WRITE) ++ | OP_CTRL_DMA_OP_READY; ++ fmc_writel(host, FMC_OP_CTRL, reg); ++ FMC_PR(WR_DBG, "|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg); ++ ++ FMC_DMA_WAIT_INT_FINISH(host); ++ ++end: ++ mutex_unlock(host->lock); ++ FMC_PR(WR_DBG, "*-End %s page program!\n", op); ++} ++ ++/*****************************************************************************/ ++static void fmc100_send_cmd_status(struct fmc_host *host) ++{ ++ unsigned char status, addr = STATUS_ADDR; ++ struct fmc_spi *spi = host->spi; ++ ++ if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) { ++ addr = PROTECT_ADDR; ++ } ++ ++ status = spi_nand_feature_op(spi, GET_OP, addr, 0); ++ FMC_PR((ER_DBG || WR_DBG), "\t*-Get status[%#x]: %#x\n", addr, status); ++} ++ ++/*****************************************************************************/ ++static void fmc100_send_cmd_read(struct fmc_host *host) ++{ ++ unsigned char pages_per_block_shift, only_oob = 0; ++ unsigned short wrap = 0; ++ unsigned int reg, block_num, block_num_h, page_num, addr_of = 0; ++ struct fmc_spi *spi = host->spi; ++ struct nand_chip *chip = host->chip; ++#ifdef FMC100_SPI_NAND_SUPPORT_REG_READ ++ char *op = "Reg"; ++#else ++ char *op = "Dma"; ++#endif ++ ++ if (RD_DBG) { ++ pr_info("\n"); ++ } ++ FMC_PR(RD_DBG, "\t*-Start %s page read\n", op); ++ ++ if ((host->addr_value[0] == host->cache_addr_value[0]) ++ && (host->addr_value[1] == host->cache_addr_value[1])) { ++ FMC_PR(RD_DBG, "\t*-%s read cache hit, addr[%#x %#x]\n", ++ op, host->addr_value[1], host->addr_value[0]); ++ return; ++ } ++ ++ mutex_lock(host->lock); ++ fmc100_operation_config(host, OP_STYPE_READ); ++ ++ FMC_PR(RD_DBG, "\t|-Wait ready before %s page read\n", op); ++ reg = spi->driver->wait_ready(spi); ++ if (reg) { ++ DB_MSG("Error: %s read wait ready fail! reg: %#x\n", op, reg); ++ goto end; ++ } ++ ++ reg = FMC_INT_CLR_ALL; ++ fmc_writel(host, FMC_INT_CLR, reg); ++ FMC_PR(RD_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); ++ ++ if (host->cmd_op.l_cmd == NAND_CMD_READOOB) { ++ only_oob = 1; ++ host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_OOB); ++ } else { ++ host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_ALL_PAGE); ++ } ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) ++ | OP_CFG_MEM_IF_TYPE(spi->read->iftype) ++ | OP_CFG_DUMMY_NUM(spi->read->dummy) ++ | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(RD_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ pages_per_block_shift = chip->phys_erase_shift - chip->page_shift; ++ block_num = host->addr_value[1] >> pages_per_block_shift; ++ block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT; ++ ++ reg = FMC_ADDRH_SET(block_num_h); ++ fmc_writel(host, FMC_ADDRH, reg); ++ FMC_PR(RD_DBG, "\t|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); ++ ++ page_num = host->addr_value[1] - (block_num << pages_per_block_shift); ++ if (only_oob) ++ switch (host->ecctype) { ++ case NAND_ECC_8BIT: ++ addr_of = REG_CNT_ECC_8BIT_OFFSET; ++ break; ++ case NAND_ECC_16BIT: ++ addr_of = REG_CNT_ECC_16BIT_OFFSET; ++ break; ++ case NAND_ECC_24BIT: ++ addr_of = REG_CNT_ECC_24BIT_OFFSET; ++ break; ++ case NAND_ECC_0BIT: ++ default: ++ break; ++ } ++ ++ reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT) ++ | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT) ++ | ((wrap & REG_CNT_WRAP_MASK) << REG_CNT_WRAP_SHIFT) ++ | (addr_of & REG_CNT_ECC_OFFSET_MASK); ++ fmc_writel(host, FMC_ADDRL, reg); ++ FMC_PR(RD_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); ++ ++#ifndef FMC100_SPI_NAND_SUPPORT_REG_READ ++ reg = host->dma_buffer; ++ fmc_writel(host, FMC_DMA_SADDR_D0, reg); ++ FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_D0[%#x]%#x\n", FMC_DMA_SADDR_D0, reg); ++ ++#ifdef CONFIG_64BIT ++ reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32; ++ fmc_writel(host, FMC_DMA_SADDRH_D0, reg); ++ FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg); ++#endif ++ ++ reg = host->dma_oob; ++ fmc_writel(host, FMC_DMA_SADDR_OOB, reg); ++ FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, ++ reg); ++ ++#ifdef CONFIG_64BIT ++ reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32; ++ fmc_writel(host, FMC_DMA_SADDRH_OOB, reg); ++ FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB, ++ reg); ++#endif ++#endif ++ ++ reg = OP_CTRL_RD_OPCODE(spi->read->cmd) | host->cmd_op.op_cfg ++#ifdef FMC100_SPI_NAND_SUPPORT_REG_READ ++ | OP_CTRL_DMA_OP(OP_TYPE_REG) ++#else ++ | OP_CTRL_DMA_OP(OP_TYPE_DMA) ++#endif ++ | OP_CTRL_RW_OP(RW_OP_READ) | OP_CTRL_DMA_OP_READY; ++ fmc_writel(host, FMC_OP_CTRL, reg); ++ FMC_PR(RD_DBG, "\t|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg); ++ ++ FMC_DMA_WAIT_INT_FINISH(host); ++ ++ host->cache_addr_value[0] = host->addr_value[0]; ++ host->cache_addr_value[1] = host->addr_value[1]; ++ ++end: ++ mutex_unlock(host->lock); ++ FMC_PR(RD_DBG, "\t*-End %s page read\n", op); ++} ++ ++/*****************************************************************************/ ++static void fmc100_send_cmd_erase(struct fmc_host *host) ++{ ++ unsigned int reg; ++ struct fmc_spi *spi = host->spi; ++ ++ if (ER_DBG) { ++ pr_info("\n"); ++ } ++ FMC_PR(ER_DBG, "\t*-Start send cmd erase!\n"); ++ ++ mutex_lock(host->lock); ++ fmc100_operation_config(host, OP_STYPE_ERASE); ++ ++ reg = spi->driver->wait_ready(spi); ++ FMC_PR(ER_DBG, "\t|-Erase wait ready, reg: %#x\n", reg); ++ if (reg) { ++ DB_MSG("Error: Erase wait ready fail! status: %#x\n", reg); ++ goto end; ++ } ++ ++ reg = spi->driver->write_enable(spi); ++ if (reg) { ++ DB_MSG("Error: Erase write enable failed! reg: %#x\n", reg); ++ goto end; ++ } ++ ++ reg = FMC_INT_CLR_ALL; ++ fmc_writel(host, FMC_INT_CLR, reg); ++ FMC_PR(ER_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); ++ ++ reg = spi->erase->cmd; ++ fmc_writel(host, FMC_CMD, FMC_CMD_CMD1(reg)); ++ FMC_PR(ER_DBG, "\t|-Set CMD[%#x]%#x\n", FMC_CMD, reg); ++ ++ reg = FMC_ADDRL_BLOCK_H_MASK(host->addr_value[1]) ++ | FMC_ADDRL_BLOCK_L_MASK(host->addr_value[0]); ++ fmc_writel(host, FMC_ADDRL, reg); ++ FMC_PR(ER_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) ++ | OP_CFG_MEM_IF_TYPE(spi->erase->iftype) ++ | OP_CFG_ADDR_NUM(STD_OP_ADDR_NUM) ++ | OP_CFG_DUMMY_NUM(spi->erase->dummy) ++ | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(ER_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ reg = FMC_OP_CMD1_EN ++ | FMC_OP_ADDR_EN ++ | FMC_OP_REG_OP_START; ++ fmc_writel(host, FMC_OP, reg); ++ FMC_PR(ER_DBG, "\t|-Set OP[%#x]%#x\n", FMC_OP, reg); ++ ++ FMC_CMD_WAIT_CPU_FINISH(host); ++ ++end: ++ mutex_unlock(host->lock); ++ FMC_PR(ER_DBG, "\t*-End send cmd erase!\n"); ++} ++ ++/*****************************************************************************/ ++void fmc100_ecc0_switch(struct fmc_host *host, unsigned char op) ++{ ++ unsigned int config; ++#if EC_DBG ++ unsigned int cmp_cfg; ++ ++ config = fmc_readl(host, FMC_CFG); ++ FMC_PR(EC_DBG, "\t *-Get CFG[%#x]%#x\n", FMC_CFG, config); ++ ++ if (op) { ++ cmp_cfg = host->fmc_cfg; ++ } else { ++ cmp_cfg = host->fmc_cfg_ecc0; ++ } ++ ++ if (cmp_cfg != config) ++ DB_MSG("Warning: FMC config[%#x] is different.\n", ++ cmp_cfg); ++#endif ++ ++ if (op == ENABLE) { ++ config = host->fmc_cfg_ecc0; ++ } else if (op == DISABLE) { ++ config = host->fmc_cfg; ++ } else { ++ DB_MSG("Error: Invalid opcode: %d\n", op); ++ return; ++ } ++ ++ fmc_writel(host, FMC_CFG, config); ++ FMC_PR(EC_DBG, "\t *-Set CFG[%#x]%#x\n", FMC_CFG, config); ++} ++ ++/*****************************************************************************/ ++static void fmc100_send_cmd_readid(struct fmc_host *host) ++{ ++ unsigned int reg; ++ ++ FMC_PR(BT_DBG, "\t|*-Start send cmd read ID\n"); ++ ++ fmc100_ecc0_switch(host, ENABLE); ++ ++ reg = FMC_CMD_CMD1(SPI_CMD_RDID); ++ fmc_writel(host, FMC_CMD, reg); ++ FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); ++ ++ reg = READ_ID_ADDR; ++ fmc_writel(host, FMC_ADDRL, reg); ++ FMC_PR(BT_DBG, "\t||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) ++ | OP_CFG_ADDR_NUM(READ_ID_ADDR_NUM) ++ | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ reg = FMC_DATA_NUM_CNT(MAX_SPI_NAND_ID_LEN); ++ fmc_writel(host, FMC_DATA_NUM, reg); ++ FMC_PR(BT_DBG, "\t||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg); ++ ++ reg = FMC_OP_CMD1_EN ++ | FMC_OP_ADDR_EN ++ | FMC_OP_READ_DATA_EN ++ | FMC_OP_REG_OP_START; ++ fmc_writel(host, FMC_OP, reg); ++ FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); ++ ++ host->addr_cycle = 0x0; ++ ++ FMC_CMD_WAIT_CPU_FINISH(host); ++ ++ fmc100_ecc0_switch(host, DISABLE); ++ ++ FMC_PR(BT_DBG, "\t|*-End read flash ID\n"); ++} ++ ++/*****************************************************************************/ ++static void fmc100_send_cmd_reset(struct fmc_host *host) ++{ ++ unsigned int reg; ++ ++ FMC_PR(BT_DBG, "\t|*-Start send cmd reset\n"); ++ ++ reg = FMC_CMD_CMD1(SPI_CMD_RESET); ++ fmc_writel(host, FMC_CMD, reg); ++ FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START; ++ fmc_writel(host, FMC_OP, reg); ++ FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); ++ ++ FMC_CMD_WAIT_CPU_FINISH(host); ++ ++ FMC_PR(BT_DBG, "\t|*-End send cmd reset\n"); ++} ++ ++/*****************************************************************************/ ++static void fmc100_host_init(struct fmc_host *host) ++{ ++ unsigned int reg; ++ ++ FMC_PR(BT_DBG, "\t||*-Start SPI Nand host init\n"); ++ ++ reg = fmc_readl(host, FMC_CFG); ++ if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) { ++ reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL); ++ fmc_writel(host, FMC_CFG, reg); ++ FMC_PR(BT_DBG, "\t|||-Set CFG[%#x]%#x\n", FMC_CFG, reg); ++ } ++ ++ host->fmc_cfg = reg; ++ host->fmc_cfg_ecc0 = (reg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; ++ ++ reg = fmc_readl(host, FMC_GLOBAL_CFG); ++ if (reg & FMC_GLOBAL_CFG_WP_ENABLE) { ++ reg &= ~FMC_GLOBAL_CFG_WP_ENABLE; ++ fmc_writel(host, FMC_GLOBAL_CFG, reg); ++ } ++ ++ host->addr_cycle = 0; ++ host->addr_value[0] = 0; ++ host->addr_value[1] = 0; ++ host->cache_addr_value[0] = ~0; ++ host->cache_addr_value[1] = ~0; ++ ++ host->send_cmd_write = fmc100_send_cmd_write; ++ host->send_cmd_status = fmc100_send_cmd_status; ++ host->send_cmd_read = fmc100_send_cmd_read; ++ host->send_cmd_erase = fmc100_send_cmd_erase; ++ host->send_cmd_readid = fmc100_send_cmd_readid; ++ host->send_cmd_reset = fmc100_send_cmd_reset; ++#ifdef CONFIG_PM ++ host->suspend = fmc100_suspend; ++ host->resume = fmc100_resume; ++#endif ++ ++ reg = TIMING_CFG_TCSH(CS_HOLD_TIME) ++ | TIMING_CFG_TCSS(CS_SETUP_TIME) ++ | TIMING_CFG_TSHSL(CS_DESELECT_TIME); ++ fmc_writel(host, FMC_SPI_TIMING_CFG, reg); ++ ++ reg = ALL_BURST_ENABLE; ++ fmc_writel(host, FMC_DMA_AHB_CTRL, reg); ++ ++ FMC_PR(BT_DBG, "\t||*-End SPI Nand host init\n"); ++} ++ ++/*****************************************************************************/ ++static unsigned char fmc100_read_byte(struct mtd_info *mtd) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ unsigned char value, ret_val = 0; ++ ++ if (host->cmd_op.l_cmd == NAND_CMD_READID) { ++ value = fmc_readb(host->iobase + host->offset); ++ host->offset++; ++ if (host->cmd_op.data_no == host->offset) { ++ host->cmd_op.l_cmd = 0; ++ } ++ return value; ++ } ++ ++ if (host->cmd_op.cmd == NAND_CMD_STATUS) { ++ value = fmc_readl(host, FMC_STATUS); ++ if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) { ++ FMC_PR((ER_DBG || WR_DBG), "\t\tRead BP status:%#x\n", ++ value); ++ if (ANY_BP_ENABLE(value)) { ++ ret_val |= NAND_STATUS_WP; ++ } ++ ++ host->cmd_op.l_cmd = NAND_CMD_STATUS; ++ } ++ ++ if (!(value & STATUS_OIP_MASK)) { ++ ret_val |= NAND_STATUS_READY; ++ } ++ ++ if (value & STATUS_E_FAIL_MASK) { ++ FMC_PR(ER_DBG, "\t\tGet erase status: %#x\n", value); ++ ret_val |= NAND_STATUS_FAIL; ++ } ++ ++ if (value & STATUS_P_FAIL_MASK) { ++ FMC_PR(WR_DBG, "\t\tGet write status: %#x\n", value); ++ ret_val |= NAND_STATUS_FAIL; ++ } ++ ++ return ret_val; ++ } ++ ++ if (host->cmd_op.l_cmd == NAND_CMD_READOOB) { ++ value = fmc_readb(host->buffer + host->pagesize + host->offset); ++ host->offset++; ++ return value; ++ } ++ ++ host->offset++; ++ ++ return fmc_readb(host->buffer + host->column + host->offset - 1); ++} ++ ++/*****************************************************************************/ ++static unsigned short fmc100_read_word(struct mtd_info *mtd) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ ++ host->offset += 2; ++ return fmc_readw(host->buffer + host->column + host->offset - 2); ++} ++ ++/*****************************************************************************/ ++static void fmc100_write_buf(struct mtd_info *mtd, ++ const u_char *buf, int len) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ ++#ifdef FMC100_SPI_NAND_SUPPORT_REG_WRITE ++ if (buf == chip->oob_poi) { ++ memcpy((char *)host->iobase + host->pagesize, buf, len); ++ } else { ++ memcpy((char *)host->iobase, buf, len); ++ } ++#else ++ if (buf == chip->oob_poi) { ++ memcpy((char *)(host->buffer + host->pagesize), buf, len); ++ } else { ++ memcpy((char *)host->buffer, buf, len); ++ } ++#endif ++ return; ++} ++ ++/*****************************************************************************/ ++static void fmc100_read_buf(struct mtd_info *mtd, u_char *buf, int len) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ ++#ifdef FMC100_SPI_NAND_SUPPORT_REG_READ ++ if (buf == chip->oob_poi) { ++ memcpy(buf, (char *)host->iobase + host->pagesize, len); ++ } else { ++ memcpy(buf, (char *)host->iobase, len); ++ } ++#else ++ if (buf == chip->oob_poi) { ++ memcpy(buf, (char *)host->buffer + host->pagesize, len); ++ } else { ++ memcpy(buf, (char *)host->buffer, len); ++ } ++#endif ++ ++#ifdef CONFIG_GOKE_NAND_ECC_STATUS_REPORT ++ if (buf != chip->oob_poi) { ++ u_int reg, ecc_step = host->pagesize >> 10; ++ ++ reg = fmc_readl(host, FMC100_ECC_ERR_NUM0_BUF0); ++ while (ecc_step) { ++ u_char err_num; ++ ++ err_num = GET_ECC_ERR_NUM(--ecc_step, reg); ++ if (err_num == 0xff) { ++ mtd->ecc_stats.failed++; ++ } else { ++ mtd->ecc_stats.corrected += err_num; ++ } ++ } ++ } ++#endif ++ ++ return; ++} ++ ++/*****************************************************************************/ ++static void fmc100_select_chip(struct mtd_info *mtd, int chipselect) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ ++ if (chipselect < 0) { ++ mutex_unlock(&fmc_switch_mutex); ++ return; ++ } ++ ++ mutex_lock(&fmc_switch_mutex); ++ ++ if (chipselect > CONFIG_SPI_NAND_MAX_CHIP_NUM) { ++ DB_BUG("Error: Invalid chipselect: %d\n", chipselect); ++ } ++ ++ if (host->mtd != mtd) { ++ host->mtd = mtd; ++ host->cmd_op.cs = chipselect; ++ } ++ ++ if (!(chip->options & NAND_BROKEN_XD)) { ++ if ((chip->state == FL_ERASING) || (chip->state == FL_WRITING)) { ++ host->cmd_op.l_cmd = NAND_CMD_GET_FEATURES; ++ } ++ } ++} ++ ++/*****************************************************************************/ ++static void fmc100_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned ctrl) ++{ ++ unsigned char cmd; ++ int is_cache_invalid = 1; ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ unsigned int udat = (unsigned int)dat; ++ ++ if (ctrl & NAND_ALE) { ++ unsigned int addr_value = 0; ++ unsigned int addr_offset = 0; ++ ++ if (ctrl & NAND_CTRL_CHANGE) { ++ host->addr_cycle = 0x0; ++ host->addr_value[0] = 0x0; ++ host->addr_value[1] = 0x0; ++ } ++ addr_offset = host->addr_cycle << 3; ++ ++ if (host->addr_cycle >= FMC100_ADDR_CYCLE_MASK) { ++ addr_offset = (host->addr_cycle - ++ FMC100_ADDR_CYCLE_MASK) << 3; ++ addr_value = 1; ++ } ++ host->addr_value[addr_value] |= ++ ((udat & 0xff) << addr_offset); ++ ++ host->addr_cycle++; ++ } ++ ++ if ((ctrl & NAND_CLE) && (ctrl & NAND_CTRL_CHANGE)) { ++ cmd = udat & 0xff; ++ host->cmd_op.cmd = cmd; ++ switch (cmd) { ++ case NAND_CMD_PAGEPROG: ++ host->offset = 0; ++ host->send_cmd_write(host); ++ break; ++ ++ case NAND_CMD_READSTART: ++ is_cache_invalid = 0; ++ if (host->addr_value[0] == host->pagesize) { ++ host->cmd_op.l_cmd = NAND_CMD_READOOB; ++ } ++ host->send_cmd_read(host); ++ break; ++ ++ case NAND_CMD_ERASE2: ++ host->send_cmd_erase(host); ++ break; ++ ++ case NAND_CMD_READID: ++ memset((u_char *)(host->iobase), 0, ++ MAX_SPI_NAND_ID_LEN); ++ host->cmd_op.l_cmd = cmd; ++ host->cmd_op.data_no = MAX_SPI_NAND_ID_LEN; ++ host->send_cmd_readid(host); ++ break; ++ ++ case NAND_CMD_STATUS: ++ host->send_cmd_status(host); ++ break; ++ ++ case NAND_CMD_READ0: ++ host->cmd_op.l_cmd = cmd; ++ break; ++ ++ case NAND_CMD_RESET: ++ host->send_cmd_reset(host); ++ break; ++ ++ case NAND_CMD_SEQIN: ++ case NAND_CMD_ERASE1: ++ default: ++ break; ++ } ++ } ++ ++ if ((dat == NAND_CMD_NONE) && host->addr_cycle) { ++ if (host->cmd_op.cmd == NAND_CMD_SEQIN ++ || host->cmd_op.cmd == NAND_CMD_READ0 ++ || host->cmd_op.cmd == NAND_CMD_READID) { ++ host->offset = 0x0; ++ host->column = (host->addr_value[0] & 0xffff); ++ } ++ } ++ ++ if (is_cache_invalid) { ++ host->cache_addr_value[0] = ~0; ++ host->cache_addr_value[1] = ~0; ++ } ++} ++ ++/*****************************************************************************/ ++static int fmc100_dev_ready(struct mtd_info *mtd) ++{ ++ unsigned int reg; ++ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ ++ do { ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ ++ reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START; ++ fmc_writel(host, FMC_OP, reg); ++ ++ FMC_CMD_WAIT_CPU_FINISH(host); ++ ++ reg = fmc_readl(host, FMC_STATUS); ++ ++ if (!(reg & STATUS_OIP_MASK)) { ++ return NAND_STATUS_READY; ++ } ++ ++ cond_resched(); ++ ++ } while (!time_after_eq(jiffies, deadline)); ++ ++ if (!(chip->options & NAND_SCAN_SILENT_NODEV)) { ++ pr_warn("Wait SPI nand ready timeout, status: %#x\n", reg); ++ } ++ ++ return 0; ++} ++ ++/*****************************************************************************/ ++/* ++ * 'host->epm' only use the first oobfree[0] field, it looks very simple, But... ++ */ ++/* Default OOB area layout */ ++static int fmc_ooblayout_ecc_default(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) { ++ return -ERANGE; ++ } ++ ++ oobregion->length = 32; ++ oobregion->offset = 32; ++ ++ return 0; ++} ++ ++static int fmc_ooblayout_free_default(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) { ++ return -ERANGE; ++ } ++ ++ oobregion->length = 30; ++ oobregion->offset = 2; ++ ++ return 0; ++} ++ ++static struct mtd_ooblayout_ops fmc_ooblayout_default_ops = { ++ .ecc = fmc_ooblayout_ecc_default, ++ .free = fmc_ooblayout_free_default, ++}; ++ ++#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 ++static int fmc_ooblayout_ecc_4k16bit(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) { ++ return -ERANGE; ++ } ++ ++ oobregion->length = 14; ++ oobregion->offset = 14; ++ ++ return 0; ++} ++ ++static int fmc_ooblayout_free_4k16bit(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) { ++ return -ERANGE; ++ } ++ ++ oobregion->length = 14; ++ oobregion->offset = 2; ++ ++ return 0; ++} ++ ++static struct mtd_ooblayout_ops fmc_ooblayout_4k16bit_ops = { ++ .ecc = fmc_ooblayout_ecc_4k16bit, ++ .free = fmc_ooblayout_free_4k16bit, ++}; ++ ++static int fmc_ooblayout_ecc_2k16bit(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) { ++ return -ERANGE; ++ } ++ ++ oobregion->length = 6; ++ oobregion->offset = 6; ++ ++ return 0; ++} ++ ++static int fmc_ooblayout_free_2k16bit(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *oobregion) ++{ ++ if (section) { ++ return -ERANGE; ++ } ++ ++ oobregion->length = 6; ++ oobregion->offset = 2; ++ ++ return 0; ++} ++ ++static struct mtd_ooblayout_ops fmc_ooblayout_2k16bit_ops = { ++ .ecc = fmc_ooblayout_ecc_2k16bit, ++ .free = fmc_ooblayout_free_2k16bit, ++}; ++#endif ++ ++/*****************************************************************************/ ++static struct nand_config_info fmc_spi_nand_config_table[] = { ++ {NAND_PAGE_4K, NAND_ECC_24BIT, 24, 200, &fmc_ooblayout_default_ops}, ++#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 ++ {NAND_PAGE_4K, NAND_ECC_16BIT, 16, 128, &fmc_ooblayout_4k16bit_ops}, ++#endif ++ {NAND_PAGE_4K, NAND_ECC_8BIT, 8, 128, &fmc_ooblayout_default_ops}, ++ {NAND_PAGE_4K, NAND_ECC_0BIT, 0, 32, &fmc_ooblayout_default_ops}, ++ ++ {NAND_PAGE_2K, NAND_ECC_24BIT, 24, 128, &fmc_ooblayout_default_ops}, ++#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 ++ {NAND_PAGE_2K, NAND_ECC_16BIT, 16, 64, &fmc_ooblayout_2k16bit_ops}, ++#endif ++ {NAND_PAGE_2K, NAND_ECC_8BIT, 8, 64, &fmc_ooblayout_default_ops}, ++ {NAND_PAGE_2K, NAND_ECC_0BIT, 0, 32, &fmc_ooblayout_default_ops}, ++ ++ {0, 0, 0, 0, NULL}, ++}; ++ ++/* ++ * Auto-sensed the page size and ecc type value. driver will try each of page ++ * size and ecc type one by one till flash can be read and wrote accurately. ++ * so the page size and ecc type is match adaptively without switch on the board ++ */ ++static struct nand_config_info *fmc100_get_config_type_info( ++ struct mtd_info *mtd, struct nand_dev_t *nand_dev) ++{ ++ struct nand_config_info *best = NULL; ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct nand_config_info *info = fmc_spi_nand_config_table; ++ ++ nand_dev->start_type = "Auto"; ++ ++ for (; info->ooblayout_ops; info++) { ++ if (match_page_type_to_size(info->pagetype) != mtd->writesize) { ++ continue; ++ } ++ ++ if (mtd->oobsize < info->oobsize) { ++ continue; ++ } ++ ++ if (!best || (best->ecctype < info->ecctype)) { ++ best = info; ++ } ++ } ++ ++ /* All SPI NAND are small-page, SLC */ ++ chip->bits_per_cell = 1; ++ ++ return best; ++} ++ ++/*****************************************************************************/ ++static void fmc100_chip_init(struct nand_chip *chip) ++{ ++ chip->read_byte = fmc100_read_byte; ++ chip->read_word = fmc100_read_word; ++ chip->write_buf = fmc100_write_buf; ++ chip->read_buf = fmc100_read_buf; ++ ++ chip->select_chip = fmc100_select_chip; ++ ++ chip->cmd_ctrl = fmc100_cmd_ctrl; ++ chip->dev_ready = fmc100_dev_ready; ++ ++ chip->chip_delay = FMC_CHIP_DELAY; ++ ++ chip->options = NAND_SKIP_BBTSCAN | NAND_BROKEN_XD ++ | NAND_SCAN_SILENT_NODEV; ++ ++ chip->ecc.mode = NAND_ECC_NONE; ++} ++ ++/*****************************************************************************/ ++static void fmc100_set_oob_info(struct mtd_info *mtd, ++ struct nand_config_info *info, struct nand_dev_t *nand_dev) ++{ ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ struct mtd_oob_region fmc_oobregion = {0, 0}; ++ ++ if (info->ecctype != NAND_ECC_0BIT) { ++ mtd->oobsize = info->oobsize; ++ } ++ ++ host->oobsize = mtd->oobsize; ++ nand_dev->oobsize = host->oobsize; ++ ++ host->dma_oob = host->dma_buffer + host->pagesize; ++ host->bbm = (u_char *)(host->buffer + host->pagesize ++ + FMC_BAD_BLOCK_POS); ++ ++ info->ooblayout_ops->free(mtd, 0, &fmc_oobregion); ++ ++ mtd_set_ooblayout(mtd, info->ooblayout_ops); ++ ++ /* EB bits locate in the bottom two of CTRL(30) */ ++ host->epm = (u_short *)(host->buffer + host->pagesize ++ + fmc_oobregion.offset + 28); ++ ++#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 ++ if (best->ecctype == NAND_ECC_16BIT) { ++ if (host->pagesize == _2K) { ++ /* EB bits locate in the bottom two of CTRL(4) */ ++ host->epm = (u_short *)(host->buffer + host->pagesize ++ + fmc_oobregion.offset + 4); ++ } else if (host->pagesize == _4K) { ++ /* EB bit locate in the bottom two of CTRL(14) */ ++ host->epm = (u_short *)(host->buffer + host->pagesize ++ + fmc_oobregion.offset + 12); ++ } ++ } ++#endif ++} ++ ++/*****************************************************************************/ ++static unsigned int fmc100_get_ecc_reg(struct fmc_host *host, ++ struct nand_config_info *info, struct nand_dev_t *nand_dev) ++{ ++ host->ecctype = info->ecctype; ++ nand_dev->ecctype = host->ecctype; ++ ++ return FMC_CFG_ECC_TYPE(match_ecc_type_to_reg(info->ecctype)); ++} ++ ++/*****************************************************************************/ ++static unsigned int fmc100_get_page_reg(struct fmc_host *host, ++ struct nand_config_info *info) ++{ ++ host->pagesize = match_page_type_to_size(info->pagetype); ++ ++ return FMC_CFG_PAGE_SIZE(match_page_type_to_reg(info->pagetype)); ++} ++ ++/*****************************************************************************/ ++static unsigned int fmc100_get_block_reg(struct fmc_host *host, ++ struct nand_config_info *info) ++{ ++ unsigned int block_reg = 0, page_per_block; ++ struct mtd_info *mtd = host->mtd; ++ ++ host->block_page_mask = ((mtd->erasesize / mtd->writesize) - 1); ++ page_per_block = mtd->erasesize / match_page_type_to_size(info->pagetype); ++ switch (page_per_block) { ++ case 64: ++ block_reg = BLOCK_SIZE_64_PAGE; ++ break; ++ case 128: ++ block_reg = BLOCK_SIZE_128_PAGE; ++ break; ++ case 256: ++ block_reg = BLOCK_SIZE_256_PAGE; ++ break; ++ case 512: ++ block_reg = BLOCK_SIZE_512_PAGE; ++ break; ++ default: ++ DB_MSG("Can't support block %#x and page %#x size\n", ++ mtd->erasesize, mtd->writesize); ++ } ++ ++ return FMC_CFG_BLOCK_SIZE(block_reg); ++} ++ ++/*****************************************************************************/ ++static void fmc100_set_fmc_cfg_reg(struct fmc_host *host, ++ struct nand_config_info *type_info, struct nand_dev_t *nand_dev) ++{ ++ unsigned int page_reg, ecc_reg, block_reg, reg_fmc_cfg; ++ ++ ecc_reg = fmc100_get_ecc_reg(host, type_info, nand_dev); ++ page_reg = fmc100_get_page_reg(host, type_info); ++ block_reg = fmc100_get_block_reg(host, type_info); ++ ++ reg_fmc_cfg = fmc_readl(host, FMC_CFG); ++ reg_fmc_cfg &= ~(PAGE_SIZE_MASK | ECC_TYPE_MASK | BLOCK_SIZE_MASK); ++ reg_fmc_cfg |= ecc_reg | page_reg | block_reg; ++ fmc_writel(host, FMC_CFG, reg_fmc_cfg); ++ ++ /* Save value of FMC_CFG and FMC_CFG_ECC0 to turn on/off ECC */ ++ host->fmc_cfg = reg_fmc_cfg; ++ host->fmc_cfg_ecc0 = (host->fmc_cfg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; ++ FMC_PR(BT_DBG, "\t|-Save FMC_CFG[%#x]: %#x and FMC_CFG_ECC0: %#x\n", ++ FMC_CFG, host->fmc_cfg, host->fmc_cfg_ecc0); ++} ++ ++/*****************************************************************************/ ++static int fmc100_set_config_info(struct mtd_info *mtd, ++ struct nand_chip *chip, struct nand_dev_t *nand_dev) ++{ ++ struct fmc_host *host = chip->priv; ++ struct nand_config_info *type_info = NULL; ++ ++ FMC_PR(BT_DBG, "\t*-Start config Block Page OOB and Ecc\n"); ++ ++ type_info = fmc100_get_config_type_info(mtd, nand_dev); ++ BUG_ON(!type_info); ++ ++ FMC_PR(BT_DBG, "\t|-%s Config, PageSize %s EccType %s OOBSize %d\n", ++ nand_dev->start_type, nand_page_name(type_info->pagetype), ++ nand_ecc_name(type_info->ecctype), type_info->oobsize); ++ ++ /* Set the page_size, ecc_type, block_size of FMC_CFG[0x0] register */ ++ fmc100_set_fmc_cfg_reg(host, type_info, nand_dev); ++ ++ fmc100_set_oob_info(mtd, type_info, nand_dev); ++ ++ FMC_PR(BT_DBG, "\t*-End config Block Page Oob and Ecc\n"); ++ ++ return 0; ++} ++ ++/*****************************************************************************/ ++int fmc100_spi_nand_init(struct nand_chip *chip) ++{ ++ struct fmc_host *host = chip->priv; ++ ++ FMC_PR(BT_DBG, "\t|*-Start fmc100 SPI Nand init\n"); ++ ++ /* Set system clock and enable controller */ ++ clk_prepare_enable(host->clk); ++ ++ /* Switch SPI type to SPI nand */ ++ fmc100_switch_to_spi_nand(host); ++ ++ /* hold on STR mode */ ++ fmc100_set_str_mode(host); ++ ++ /* fmc host init */ ++ fmc100_host_init(host); ++ host->chip = chip; ++ ++ /* fmc nand_chip struct init */ ++ fmc100_chip_init(chip); ++ ++ fmc_spi_nand_ids_register(); ++ nfc_param_adjust = fmc100_set_config_info; ++ ++ FMC_PR(BT_DBG, "\t|*-End fmc100 SPI Nand init\n"); ++ ++ return 0; ++} ++#ifdef CONFIG_PM ++/*****************************************************************************/ ++int fmc100_suspend(struct platform_device *pltdev, pm_message_t state) ++{ ++ unsigned int ret; ++ struct fmc_host *host = platform_get_drvdata(pltdev); ++ struct fmc_spi *spi = host->spi; ++ ++ mutex_lock(host->lock); ++ fmc100_switch_to_spi_nand(host); ++ ++ ret = spi->driver->wait_ready(spi); ++ if (ret) ++ DB_MSG("Error: wait ready failed!"); ++ ++ clk_disable_unprepare(host->clk); ++ mutex_unlock(host->lock); ++ ++ return 0; ++} ++/*****************************************************************************/ ++int fmc100_resume(struct platform_device *pltdev) ++{ ++ int cs; ++ struct fmc_host *host = platform_get_drvdata(pltdev); ++ struct nand_chip *chip = host->chip; ++ ++ mutex_lock(host->lock); ++ fmc100_switch_to_spi_nand(host); ++ clk_prepare_enable(host->clk); ++ ++ for (cs = 0; cs < chip->numchips; cs++) { ++ host->send_cmd_reset(host); ++ } ++ ++ fmc100_spi_nand_config(host); ++ ++ mutex_unlock(host->lock); ++ return 0; ++} ++#endif ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100.h.patch new file mode 100644 index 00000000..44e54478 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100.h.patch @@ -0,0 +1,378 @@ +--- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,375 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __FMC100_H__ ++#define __FMC100_H__ ++ ++/*****************************************************************************/ ++#include ++#include ++ ++/*****************************************************************************/ ++#define INFINITE (0xFFFFFFFF) ++ ++/*****************************************************************************/ ++#define SPI_IF_READ_STD (0x01) ++#define SPI_IF_READ_FAST (0x02) ++#define SPI_IF_READ_DUAL (0x04) ++#define SPI_IF_READ_DUAL_ADDR (0x08) ++#define SPI_IF_READ_QUAD (0x10) ++#define SPI_IF_READ_QUAD_ADDR (0x20) ++ ++#define SPI_IF_WRITE_STD (0x01) ++#define SPI_IF_WRITE_DUAL (0x02) ++#define SPI_IF_WRITE_DUAL_ADDR (0x04) ++#define SPI_IF_WRITE_QUAD (0x08) ++#define SPI_IF_WRITE_QUAD_ADDR (0x10) ++ ++#define SPI_IF_ERASE_SECTOR_4K (0x01) ++#define SPI_IF_ERASE_SECTOR_32K (0x02) ++#define SPI_IF_ERASE_SECTOR_64K (0x04) ++#define SPI_IF_ERASE_SECTOR_128K (0x08) ++#define SPI_IF_ERASE_SECTOR_256K (0x10) ++ ++/******************************************************************************/ ++#define FMC_SPI_NAND_SUPPORT_READ (SPI_IF_READ_STD \ ++ | SPI_IF_READ_FAST \ ++ | SPI_IF_READ_DUAL \ ++ | SPI_IF_READ_DUAL_ADDR \ ++ | SPI_IF_READ_QUAD \ ++ | SPI_IF_READ_QUAD_ADDR) ++ ++#define FMC_SPI_NAND_SUPPORT_WRITE (SPI_IF_WRITE_STD | SPI_IF_WRITE_QUAD) ++ ++#define FMC_SPI_NAND_SUPPORT_MAX_DUMMY 8 ++ ++/*****************************************************************************/ ++#define SPI_CMD_READ_STD 0x03 /* Standard read cache */ ++#define SPI_CMD_READ_FAST 0x0B /* Higher speed read cache */ ++#define SPI_CMD_READ_DUAL 0x3B /* 2 IO read cache only date */ ++#define SPI_CMD_READ_DUAL_ADDR 0xBB /* 2 IO read cache date&addr */ ++#define SPI_CMD_READ_QUAD 0x6B /* 4 IO read cache only date */ ++#define SPI_CMD_READ_QUAD_ADDR 0xEB /* 4 IO read cache date&addr */ ++ ++#define SPI_CMD_WRITE_STD 0x02 /* Standard page program */ ++#define SPI_CMD_WRITE_DUAL 0xA2 /* 2 IO program only date */ ++#define SPI_CMD_WRITE_DUAL_ADDR 0xD2 /* 2 IO program date&addr */ ++#define SPI_CMD_WRITE_QUAD 0x32 /* 4 IO program only date */ ++#define SPI_CMD_WRITE_QUAD_ADDR 0x12 /* 4 IO program date&addr */ ++ ++#define SPI_CMD_SE_4K 0x20 /* 4KB sector Erase */ ++#define SPI_CMD_SE_32K 0x52 /* 32KB sector Erase */ ++#define SPI_CMD_SE_64K 0xD8 /* 64KB sector Erase */ ++#define SPI_CMD_SE_128K 0xD8 /* 128KB sector Erase */ ++#define SPI_CMD_SE_256K 0xD8 /* 256KB sector Erase */ ++ ++/*****************************************************************************/ ++#define SET_READ_STD(_dummy_, _size_, _clk_) \ ++ static struct spi_op read_std_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_READ_STD, SPI_CMD_READ_STD, _dummy_, _size_, _clk_ } ++ ++#define SET_READ_FAST(_dummy_, _size_, _clk_) \ ++ static struct spi_op read_fast_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_READ_FAST, SPI_CMD_READ_FAST, _dummy_, _size_, _clk_ } ++ ++#define SET_READ_DUAL(_dummy_, _size_, _clk_) \ ++ static struct spi_op read_dual_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_READ_DUAL, SPI_CMD_READ_DUAL, _dummy_, _size_, _clk_ } ++ ++#define SET_READ_DUAL_ADDR(_dummy_, _size_, _clk_) \ ++ static struct spi_op read_dual_addr_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_READ_DUAL_ADDR, SPI_CMD_READ_DUAL_ADDR, _dummy_, _size_, _clk_ } ++ ++#define SET_READ_QUAD(_dummy_, _size_, _clk_) \ ++ static struct spi_op read_quad_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_READ_QUAD, SPI_CMD_READ_QUAD, _dummy_, _size_, _clk_ } ++ ++#define SET_READ_QUAD_ADDR(_dummy_, _size_, _clk_) \ ++ static struct spi_op read_quad_addr_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_READ_QUAD_ADDR, SPI_CMD_READ_QUAD_ADDR, _dummy_, _size_, _clk_ } ++ ++/*****************************************************************************/ ++#define SET_WRITE_STD(_dummy_, _size_, _clk_) \ ++ static struct spi_op write_std_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_WRITE_STD, SPI_CMD_WRITE_STD, _dummy_, _size_, _clk_ } ++ ++#define SET_WRITE_DUAL(_dummy_, _size_, _clk_) \ ++ static struct spi_op write_dual_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_WRITE_DUAL, SPI_CMD_WRITE_DUAL, _dummy_, _size_, _clk_ } ++ ++#define SET_WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \ ++ static struct spi_op write_dual_addr_##_dummy_##_size_##_clk_ = { \ ++SPI_IF_WRITE_DUAL_ADDR, SPI_CMD_WRITE_DUAL_ADDR, _dummy_, _size_, _clk_ } ++ ++#define SET_WRITE_QUAD(_dummy_, _size_, _clk_) \ ++ static struct spi_op write_quad_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_WRITE_QUAD, SPI_CMD_WRITE_QUAD, _dummy_, _size_, _clk_ } ++ ++#define SET_WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \ ++ static struct spi_op write_quad_addr_##_dummy_##_size_##_clk_ = { \ ++SPI_IF_WRITE_QUAD_ADDR, SPI_CMD_WRITE_QUAD_ADDR, _dummy_, _size_, _clk_ } ++ ++/*****************************************************************************/ ++#define SET_ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \ ++ static struct spi_op erase_sector_4k_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_ERASE_SECTOR_4K, SPI_CMD_SE_4K, _dummy_, _size_, _clk_ } ++ ++#define SET_ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \ ++ static struct spi_op erase_sector_32k_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_ERASE_SECTOR_32K, SPI_CMD_SE_32K, _dummy_, _size_, _clk_ } ++ ++#define SET_ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \ ++ static struct spi_op erase_sector_64k_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_ERASE_SECTOR_64K, SPI_CMD_SE_64K, _dummy_, _size_, _clk_ } ++ ++#define SET_ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \ ++ static struct spi_op erase_sector_128k_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_ERASE_SECTOR_128K, SPI_CMD_SE_128K, _dummy_, _size_, _clk_ } ++ ++#define SET_ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \ ++ static struct spi_op erase_sector_256k_##_dummy_##_size_##_clk_ = { \ ++ SPI_IF_ERASE_SECTOR_256K, SPI_CMD_SE_256K, _dummy_, _size_, _clk_ } ++ ++/*****************************************************************************/ ++#define READ_STD(_dummy_, _size_, _clk_) read_std_##_dummy_##_size_##_clk_ ++#define READ_FAST(_dummy_, _size_, _clk_) read_fast_##_dummy_##_size_##_clk_ ++#define READ_DUAL(_dummy_, _size_, _clk_) read_dual_##_dummy_##_size_##_clk_ ++#define READ_DUAL_ADDR(_dummy_, _size_, _clk_) \ ++ read_dual_addr_##_dummy_##_size_##_clk_ ++#define READ_QUAD(_dummy_, _size_, _clk_) read_quad_##_dummy_##_size_##_clk_ ++#define READ_QUAD_ADDR(_dummy_, _size_, _clk_) \ ++ read_quad_addr_##_dummy_##_size_##_clk_ ++ ++/*****************************************************************************/ ++#define WRITE_STD(_dummy_, _size_, _clk_) write_std_##_dummy_##_size_##_clk_ ++#define WRITE_DUAL(_dummy_, _size_, _clk_) write_dual_##_dummy_##_size_##_clk_ ++#define WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \ ++ write_dual_addr_##_dummy_##_size_##_clk_ ++#define WRITE_QUAD(_dummy_, _size_, _clk_) write_quad_##_dummy_##_size_##_clk_ ++#define WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \ ++ write_quad_addr_##_dummy_##_size_##_clk_ ++ ++/*****************************************************************************/ ++#define ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \ ++ erase_sector_4k_##_dummy_##_size_##_clk_ ++#define ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \ ++ erase_sector_32k_##_dummy_##_size_##_clk_ ++#define ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \ ++ erase_sector_64k_##_dummy_##_size_##_clk_ ++#define ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \ ++ erase_sector_128k_##_dummy_##_size_##_clk_ ++#define ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \ ++ erase_sector_256k_##_dummy_##_size_##_clk_ ++ ++/*****************************************************************************/ ++#define SPI_CMD_WREN 0x06 /* Write Enable */ ++#define SPI_CMD_WRDI 0x04 /* Write Disable */ ++ ++#define SPI_CMD_RDID 0x9F /* Read Identification */ ++ ++/*****************************************************************************/ ++#define SPI_CMD_GET_FEATURES 0x0F /* Get Features */ ++#define SPI_CMD_SET_FEATURE 0x1F /* Set Feature */ ++ ++#define SPI_CMD_PAGE_READ 0x13 /* Page Read to Cache */ ++ ++#define SPI_CMD_RESET 0xff /* Reset the device */ ++ ++/*****************************************************************************/ ++/* These macroes are for debug only, reg option is slower then dma option */ ++#undef FMC100_SPI_NAND_SUPPORT_REG_READ ++/* #define FMC100_SPI_NAND_SUPPORT_REG_READ */ ++ ++#undef FMC100_SPI_NAND_SUPPORT_REG_WRITE ++/* #define FMC100_SPI_NAND_SUPPORT_REG_WRITE */ ++ ++#ifdef CONFIG_GOKE_NAND_ECC_STATUS_REPORT ++/*****************************************************************************/ ++#define FMC100_ECC_ERR_NUM0_BUF0 0xc0 ++ ++#define GET_ECC_ERR_NUM(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) ++#endif ++/*****************************************************************************/ ++#define REG_CNT_HIGH_BLOCK_NUM_SHIFT 10 ++ ++#define REG_CNT_BLOCK_NUM_MASK 0x3ff ++#define REG_CNT_BLOCK_NUM_SHIFT 22 ++ ++#define REG_CNT_PAGE_NUM_MASK 0x3f ++#define REG_CNT_PAGE_NUM_SHIFT 16 ++ ++#define REG_CNT_WRAP_MASK 0xf ++#define REG_CNT_WRAP_SHIFT 12 ++ ++#define REG_CNT_ECC_OFFSET_MASK 0xfff ++#define REG_CNT_ECC_8BIT_OFFSET 1054 ++#define REG_CNT_ECC_16BIT_OFFSET 1056 ++#define REG_CNT_ECC_24BIT_OFFSET 1082 ++ ++#define ERR_STR_DRIVER "Driver does not support this configure " ++#define ERR_STR_CHECK "Please make sure the hardware configuration is correct" ++ ++/*****************************************************************************/ ++#define FMC100_ADDR_CYCLE_MASK 0x2 ++ ++/*****************************************************************************/ ++#define OP_STYPE_NONE 0x0 ++#define OP_STYPE_READ 0x01 ++#define OP_STYPE_WRITE 0x02 ++#define OP_STYPE_ERASE 0x04 ++#define CLK_FMC_TO_CRG_MHZ(_clk) ((_clk) * 2000000) ++ ++/*****************************************************************************/ ++#define MAX_SPI_OP 8 ++ ++/*****************************************************************************/ ++/* SPI general operation parameter */ ++struct spi_op { ++ unsigned char iftype; ++ unsigned char cmd; ++ unsigned char dummy; ++ unsigned int size; ++ unsigned int clock; ++}; ++ ++struct spi_drv; ++ ++/* SPI interface all operation */ ++struct fmc_spi { ++ char *name; ++ int chipselect; ++ unsigned long long chipsize; ++ unsigned int erasesize; ++#define SPI_NOR_3BYTE_ADDR_LEN 3 /* address len 3Bytes */ ++#define SPI_NOR_4BYTE_ADDR_LEN 4 /* address len 4Bytes for 32MB */ ++ unsigned int addrcycle; ++ ++ struct spi_op read[1]; ++ struct spi_op write[1]; ++ struct spi_op erase[MAX_SPI_OP]; ++ ++ void *host; ++ ++ struct spi_drv *driver; ++}; ++ ++/* SPI interface special operation function hook */ ++struct spi_drv { ++ int (*wait_ready)(struct fmc_spi *spi); ++ int (*write_enable)(struct fmc_spi *spi); ++ int (*qe_enable)(struct fmc_spi *spi); ++ int (*bus_prepare)(struct fmc_spi *spi, int op); ++ int (*entry_4addr)(struct fmc_spi *spi, int en); ++}; ++ ++struct spi_nand_info { ++ char *name; ++ unsigned char id[MAX_SPI_NAND_ID_LEN]; ++ unsigned char id_len; ++ unsigned long long chipsize; ++ unsigned int erasesize; ++ unsigned int pagesize; ++ unsigned int oobsize; ++#define BBP_LAST_PAGE 0x01 ++#define BBP_FIRST_PAGE 0x02 ++ unsigned int badblock_pos; ++ struct spi_op *read[MAX_SPI_OP]; ++ struct spi_op *write[MAX_SPI_OP]; ++ struct spi_op *erase[MAX_SPI_OP]; ++ struct spi_drv *driver; ++}; ++ ++/*****************************************************************************/ ++extern u_char spi_nand_feature_op(struct fmc_spi *spi, u_char op, u_char addr, ++ u_char val); ++ ++/*****************************************************************************/ ++struct fmc_host { ++ struct mtd_info *mtd; ++ struct nand_chip *chip; ++ struct fmc_spi spi[CONFIG_SPI_NAND_MAX_CHIP_NUM]; ++ struct fmc_cmd_op cmd_op; ++ ++ void __iomem *iobase; ++ void __iomem *regbase; ++ struct clk *clk; ++ u32 clkrate; ++ ++ unsigned int fmc_cfg; ++ unsigned int fmc_cfg_ecc0; ++ ++ unsigned int offset; ++ ++ struct device *dev; ++ struct mutex *lock; ++ ++ /* This is maybe an un-aligment address, only for malloc or free */ ++ char *buforg; ++ char *buffer; ++ ++#ifdef CONFIG_64BIT ++ unsigned long long dma_buffer; ++ unsigned long long dma_oob; ++#else ++ unsigned int dma_buffer; ++ unsigned int dma_oob; ++#endif ++ ++ unsigned int addr_cycle; ++ unsigned int addr_value[2]; ++ unsigned int cache_addr_value[2]; ++ ++ unsigned int column; ++ unsigned int block_page_mask; ++ ++ unsigned int ecctype; ++ unsigned int pagesize; ++ unsigned int oobsize; ++ ++ int add_partition; ++ ++ int need_rr_data; ++#define FMC100_READ_RETRY_DATA_LEN 128 ++ char rr_data[FMC100_READ_RETRY_DATA_LEN]; ++ struct read_retry_t *read_retry; ++ ++ int version; ++ ++ /* BOOTROM read two bytes to detect the bad block flag */ ++#define FMC_BAD_BLOCK_POS 0 ++ unsigned char *bbm; /* nand bad block mark */ ++ unsigned short *epm; /* nand empty page mark */ ++ ++ unsigned int uc_er; ++ ++ void (*send_cmd_write)(struct fmc_host *host); ++ void (*send_cmd_status)(struct fmc_host *host); ++ void (*send_cmd_read)(struct fmc_host *host); ++ void (*send_cmd_erase)(struct fmc_host *host); ++ void (*send_cmd_readid)(struct fmc_host *host); ++ void (*send_cmd_reset)(struct fmc_host *host); ++#ifdef CONFIG_PM ++ int (*suspend)(struct platform_device *pltdev, pm_message_t state); ++ int (*resume)(struct platform_device *pltdev); ++#endif ++}; ++ ++/*****************************************************************************/ ++void fmc100_ecc0_switch(struct fmc_host *host, unsigned char op); ++ ++int fmc100_spi_nand_init(struct nand_chip *chip); ++ ++/*****************************************************************************/ ++extern void fmc_spi_nand_ids_register(void); ++ ++extern void fmc_set_nand_system_clock(struct spi_op *op, int clk_en); ++ ++/*****************************************************************************/ ++#ifdef CONFIG_PM ++int fmc100_suspend(struct platform_device *pltdev, pm_message_t state); ++int fmc100_resume(struct platform_device *pltdev); ++void fmc100_spi_nand_config(struct fmc_host *host); ++#endif ++ ++#endif /* End of __FMC100_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100_os.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100_os.c.patch new file mode 100644 index 00000000..c45da79a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100_os.c.patch @@ -0,0 +1,226 @@ +--- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100_os.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100_os.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,223 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../../mtdcore.h" ++#include "fmc100.h" ++ ++/*****************************************************************************/ ++static int fmc100_spi_nand_pre_probe(struct nand_chip *chip) ++{ ++ uint8_t nand_maf_id; ++ struct fmc_host *host = chip->priv; ++ ++ /* Reset the chip first */ ++ host->send_cmd_reset(host); ++ udelay(1000); ++ ++ /* Check the ID */ ++ host->offset = 0; ++ memset((unsigned char *)(chip->IO_ADDR_R), 0, 0x10); ++ host->send_cmd_readid(host); ++ nand_maf_id = fmc_readb(chip->IO_ADDR_R); ++ ++ if (nand_maf_id == 0x00 || nand_maf_id == 0xff) { ++ printk("Cannot found a valid SPI Nand Device\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++/*****************************************************************************/ ++static int fmc_nand_scan(struct mtd_info *mtd) ++{ ++ int result = 0; ++ unsigned char cs, chip_num = CONFIG_SPI_NAND_MAX_CHIP_NUM; ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ ++ for (cs = 0; chip_num && (cs < FMC_MAX_CHIP_NUM); cs++) { ++ if (fmc_cs_user[cs]) { ++ FMC_PR(BT_DBG, "\t\t*-Current CS(%d) is occupied.\n", ++ cs); ++ continue; ++ } ++ ++ host->cmd_op.cs = cs; ++ ++ if (fmc100_spi_nand_pre_probe(chip)) { ++ return -ENODEV; ++ } ++ ++ FMC_PR(BT_DBG, "\t\t*-Scan SPI nand flash on CS: %d\n", cs); ++ if (nand_scan(mtd, chip_num)) { ++ continue; ++ } ++ chip_num--; ++ } ++ ++ if (chip_num == CONFIG_SPI_NAND_MAX_CHIP_NUM) { ++ result = -ENXIO; ++ } else { ++ result = 0; ++ } ++ ++ return result; ++} ++ ++/*****************************************************************************/ ++static int bsp_spi_nand_probe(struct platform_device *pltdev) ++{ ++ int len, result = 0; ++ struct fmc_host *host = NULL; ++ struct nand_chip *chip = NULL; ++ struct mtd_info *mtd = NULL; ++ struct device *dev = &pltdev->dev; ++ struct device_node *np = NULL; ++ struct bsp_fmc *fmc = dev_get_drvdata(dev->parent); ++ ++ FMC_PR(BT_DBG, "\t*-Start SPI Nand flash driver probe\n"); ++ ++ if (!fmc) { ++ dev_err(dev, "get mfd fmc devices failed\n"); ++ return -ENXIO; ++ } ++ ++ len = sizeof(struct fmc_host) + sizeof(struct nand_chip) ++ + sizeof(struct mtd_info); ++ host = devm_kzalloc(dev, len, GFP_KERNEL); ++ if (!host) { ++ return -ENOMEM; ++ } ++ memset((char *)host, 0, len); ++ ++ platform_set_drvdata(pltdev, host); ++ host->dev = &pltdev->dev; ++ ++ host->chip = chip = (struct nand_chip *)&host[1]; ++ host->mtd = mtd = nand_to_mtd(chip); ++ ++ host->regbase = fmc->regbase; ++ host->iobase = fmc->iobase; ++ host->clk = fmc->clk; ++ host->lock = &fmc->lock; ++ host->buffer = fmc->buffer; ++ host->dma_buffer = fmc->dma_buffer; ++ ++ memset((char *)host->iobase, 0xff, fmc->dma_len); ++ chip->IO_ADDR_R = chip->IO_ADDR_W = host->iobase; ++ ++ chip->priv = host; ++ result = fmc100_spi_nand_init(chip); ++ if (result) { ++ FMC_PR(BT_DBG, "\t|-SPI Nand init failed, ret: %d\n", result); ++ result = -ENODEV; ++ goto fail; ++ } ++ ++ np = of_get_next_available_child(dev->of_node, NULL); ++ mtd->name = np->name; ++ mtd->type = MTD_NANDFLASH; ++ mtd->priv = chip; ++ mtd->owner = THIS_MODULE; ++ ++ result = of_property_read_u32(np, "spi-max-frequency", &host->clkrate); ++ if (result) { ++ goto fail; ++ } ++ ++ result = fmc_nand_scan(mtd); ++ if (result) { ++ FMC_PR(BT_DBG, "\t|-Scan SPI Nand failed.\n"); ++ goto fail; ++ } ++ ++ result = mtd_device_register(mtd, NULL, 0); ++ if (!result) { ++ FMC_PR(BT_DBG, "\t*-End driver probe !!\n"); ++ return 0; ++ } ++ ++ result = -ENODEV; ++fail: ++ clk_disable_unprepare(host->clk); ++ nand_release(mtd); ++ ++ DB_MSG("Error: driver probe, result: %d\n", result); ++ return result; ++} ++ ++/*****************************************************************************/ ++static int bsp_spi_nand_remove(struct platform_device *pltdev) ++{ ++ struct fmc_host *host = platform_get_drvdata(pltdev); ++ if (host == NULL){ ++ FMC_PR(BT_DBG, "\t*host is NULL ,remove err !!\n"); ++ return 0; ++ } ++ clk_disable_unprepare(host->clk); ++ nand_release(host->mtd); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++/*****************************************************************************/ ++static int fmc100_os_suspend(struct platform_device *pltdev, ++ pm_message_t state) ++{ ++ struct fmc_host *host = platform_get_drvdata(pltdev); ++ ++ if (host && host->suspend) { ++ return (host->suspend)(pltdev, state); ++ } ++ ++ return 0; ++} ++ ++/*****************************************************************************/ ++static int fmc100_os_resume(struct platform_device *pltdev) ++{ ++ struct fmc_host *host = platform_get_drvdata(pltdev); ++ ++ if (host && host->resume) { ++ return (host->resume)(pltdev); ++ } ++ ++ return 0; ++} ++#endif /* End of CONFIG_PM */ ++/*****************************************************************************/ ++static const struct of_device_id bsp_spi_nand_dt_ids[] = { ++ { .compatible = "goke,fmc-spi-nand"}, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, bsp_spi_nand_dt_ids); ++ ++static struct platform_driver bsp_spi_nand_driver = { ++ .driver = { ++ .name = "bsp_spi_nand", ++ .of_match_table = bsp_spi_nand_dt_ids, ++ }, ++ .probe = bsp_spi_nand_probe, ++ .remove = bsp_spi_nand_remove, ++#ifdef CONFIG_PM ++ .suspend = fmc100_os_suspend, ++ .resume = fmc100_os_resume, ++#endif ++}; ++module_platform_driver(bsp_spi_nand_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Goke Flash Memory Controller V100 SPI Nand Driver"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100_spi_general.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100_spi_general.c.patch new file mode 100644 index 00000000..8970fe8d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc100_spi_general.c.patch @@ -0,0 +1,249 @@ +--- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100_spi_general.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100_spi_general.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,246 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++/* ++ Send set/get features command to SPI Nand flash ++*/ ++u_char spi_nand_feature_op(struct fmc_spi *spi, u_char op, u_char addr, ++ u_char val) ++{ ++ unsigned int reg; ++ const char *str[] = {"Get", "Set"}; ++ struct fmc_host *host = (struct fmc_host *)spi->host; ++ ++ if ((op == GET_OP) && (STATUS_ADDR == addr)) { ++ if (SR_DBG) { ++ pr_info("\n"); ++ } ++ FMC_PR(SR_DBG, "\t\t|*-Start Get Status\n"); ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(SR_DBG, "\t\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START; ++ fmc_writel(host, FMC_OP, reg); ++ FMC_PR(SR_DBG, "\t\t||-Set OP[%#x]%#x\n", FMC_OP, reg); ++ ++ FMC_CMD_WAIT_CPU_FINISH(host); ++ ++ val = fmc_readl(host, FMC_STATUS); ++ FMC_PR(SR_DBG, "\t\t|*-End Get Status, result: %#x\n", val); ++ ++ return val; ++ } ++ ++ FMC_PR(FT_DBG, "\t|||*-Start %s feature, addr[%#x]\n", str[op], addr); ++ ++ fmc100_ecc0_switch(host, ENABLE); ++ ++ reg = FMC_CMD_CMD1(op ? SPI_CMD_SET_FEATURE : SPI_CMD_GET_FEATURES); ++ fmc_writel(host, FMC_CMD, reg); ++ FMC_PR(FT_DBG, "\t||||-Set CMD[%#x]%#x\n", FMC_CMD, reg); ++ ++ fmc_writel(host, FMC_ADDRL, addr); ++ FMC_PR(FT_DBG, "\t||||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, addr); ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) ++ | OP_CFG_ADDR_NUM(FEATURES_OP_ADDR_NUM) ++ | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(FT_DBG, "\t||||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ reg = FMC_DATA_NUM_CNT(FEATURES_DATA_LEN); ++ fmc_writel(host, FMC_DATA_NUM, reg); ++ FMC_PR(FT_DBG, "\t||||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg); ++ ++ reg = FMC_OP_CMD1_EN ++ | FMC_OP_ADDR_EN ++ | FMC_OP_REG_OP_START; ++ ++ if (op == SET_OP) { ++ reg |= FMC_OP_WRITE_DATA_EN; ++ fmc_writeb(val, host->iobase); ++ FMC_PR(FT_DBG, "\t||||-Write IO[%#lx]%#x\n", (long)host->iobase, ++ *(u_char *)host->iobase); ++ } else { ++ reg |= FMC_OP_READ_DATA_EN; ++ } ++ ++ fmc_writel(host, FMC_OP, reg); ++ FMC_PR(FT_DBG, "\t||||-Set OP[%#x]%#x\n", FMC_OP, reg); ++ ++ FMC_CMD_WAIT_CPU_FINISH(host); ++ ++ if (op == GET_OP) { ++ val = fmc_readb(host->iobase); ++ FMC_PR(FT_DBG, "\t||||-Read IO[%#lx]%#x\n", (long)host->iobase, ++ *(u_char *)host->iobase); ++ } ++ ++ fmc100_ecc0_switch(host, DISABLE); ++ ++ FMC_PR(FT_DBG, "\t|||*-End %s Feature[%#x]:%#x\n", str[op], addr, val); ++ ++ return val; ++} ++ ++/*****************************************************************************/ ++/* ++ Read status[C0H]:[0]bit OIP, judge whether the device is busy or not ++*/ ++static int spi_general_wait_ready(struct fmc_spi *spi) ++{ ++ unsigned char status; ++ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; ++ struct fmc_host *host = (struct fmc_host *)spi->host; ++ ++ do { ++ status = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, 0); ++ if (!(status & STATUS_OIP_MASK)) { ++ if ((host->cmd_op.l_cmd == NAND_CMD_ERASE2) ++ && (status & STATUS_E_FAIL_MASK)) { ++ return status; ++ } ++ if ((host->cmd_op.l_cmd == NAND_CMD_PAGEPROG) ++ && (status & STATUS_P_FAIL_MASK)) { ++ return status; ++ } ++ return 0; ++ } ++ ++ cond_resched(); ++ ++ } while (!time_after_eq(jiffies, deadline)); ++ ++ DB_MSG("Error: SPI Nand wait ready timeout, status: %#x\n", status); ++ ++ return 1; ++} ++ ++/*****************************************************************************/ ++/* ++ Send write enable cmd to SPI Nand, status[C0H]:[2]bit WEL must be set 1 ++*/ ++static int spi_general_write_enable(struct fmc_spi *spi) ++{ ++ unsigned int reg; ++ struct fmc_host *host = (struct fmc_host *)spi->host; ++ ++ if (WE_DBG) { ++ pr_info("\n"); ++ } ++ FMC_PR(WE_DBG, "\t|*-Start Write Enable\n"); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, 0); ++ if (reg & STATUS_WEL_MASK) { ++ FMC_PR(WE_DBG, "\t||-Write Enable was opened! reg: %#x\n", ++ reg); ++ return 0; ++ } ++ ++ reg = fmc_readl(host, FMC_GLOBAL_CFG); ++ FMC_PR(WE_DBG, "\t||-Get GLOBAL_CFG[%#x]%#x\n", FMC_GLOBAL_CFG, reg); ++ if (reg & FMC_GLOBAL_CFG_WP_ENABLE) { ++ reg &= ~FMC_GLOBAL_CFG_WP_ENABLE; ++ fmc_writel(host, FMC_GLOBAL_CFG, reg); ++ FMC_PR(WE_DBG, "\t||-Set GLOBAL_CFG[%#x]%#x\n", ++ FMC_GLOBAL_CFG, reg); ++ } ++ ++ reg = FMC_CMD_CMD1(SPI_CMD_WREN); ++ fmc_writel(host, FMC_CMD, reg); ++ FMC_PR(WE_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); ++ ++ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ FMC_PR(WE_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); ++ ++ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START; ++ fmc_writel(host, FMC_OP, reg); ++ FMC_PR(WE_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); ++ ++ FMC_CMD_WAIT_CPU_FINISH(host); ++ ++#if WE_DBG ++ spi->driver->wait_ready(spi); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, 0); ++ if (reg & STATUS_WEL_MASK) { ++ FMC_PR(WE_DBG, "\t||-Write Enable success. reg: %#x\n", reg); ++ } else { ++ DB_MSG("Error: Write Enable failed! reg: %#x\n", reg); ++ return reg; ++ } ++#endif ++ ++ FMC_PR(WE_DBG, "\t|*-End Write Enable\n"); ++ return 0; ++} ++ ++/*****************************************************************************/ ++/* ++ judge whether SPI Nand support QUAD read/write or not ++*/ ++static int spi_is_quad(struct fmc_spi *spi) ++{ ++ const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; ++ ++ FMC_PR(QE_DBG, "\t\t|||*-SPI read iftype: %s write iftype: %s\n", ++ if_str[spi->read->iftype], if_str[spi->write->iftype]); ++ ++ if ((spi->read->iftype == IF_TYPE_QUAD) ++ || (spi->read->iftype == IF_TYPE_QIO) ++ || (spi->write->iftype == IF_TYPE_QUAD) ++ || (spi->write->iftype == IF_TYPE_QIO)) { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/*****************************************************************************/ ++/* ++ Send set features cmd to SPI Nand, feature[B0H]:[0]bit QE would be set ++*/ ++static int spi_general_qe_enable(struct fmc_spi *spi) ++{ ++ unsigned int reg, op; ++ const char *str[] = {"Disable", "Enable"}; ++ ++ FMC_PR(QE_DBG, "\t||*-Start SPI Nand flash QE\n"); ++ ++ op = spi_is_quad(spi); ++ ++ FMC_PR(QE_DBG, "\t|||*-End Quad check, SPI Nand %s Quad.\n", str[op]); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); ++ FMC_PR(QE_DBG, "\t|||-Get [%#x]feature: %#x\n", FEATURE_ADDR, reg); ++ if ((reg & FEATURE_QE_ENABLE) == op) { ++ FMC_PR(QE_DBG, "\t||*-SPI Nand quad was %sd!\n", str[op]); ++ return op; ++ } ++ ++ if (op == ENABLE) { ++ reg |= FEATURE_QE_ENABLE; ++ } else { ++ reg &= ~FEATURE_QE_ENABLE; ++ } ++ ++ spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, reg); ++ FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad\n", str[op]); ++ ++ spi->driver->wait_ready(spi); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); ++ if ((reg & FEATURE_QE_ENABLE) == op) { ++ FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad succeed!\n", str[op]); ++ } else { ++ DB_MSG("Error: %s Quad failed! reg: %#x\n", str[op], reg); ++ } ++ ++ FMC_PR(QE_DBG, "\t||*-End SPI Nand %s Quad.\n", str[op]); ++ ++ return op; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc_spi_nand_ids.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc_spi_nand_ids.c.patch new file mode 100644 index 00000000..6e5ded9b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-gkfmc100-fmc_spi_nand_ids.c.patch @@ -0,0 +1,2273 @@ +--- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc_spi_nand_ids.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc_spi_nand_ids.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,2270 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../nfc_gen.h" ++#include "fmc100.h" ++ ++/*****************************************************************************/ ++SET_READ_STD(1, INFINITE, 24); ++ ++SET_READ_FAST(1, INFINITE, 80); ++SET_READ_FAST(1, INFINITE, 100); ++SET_READ_FAST(1, INFINITE, 104); ++SET_READ_FAST(1, INFINITE, 108); ++SET_READ_FAST(1, INFINITE, 120); ++SET_READ_FAST(1, INFINITE, 133); ++ ++SET_READ_DUAL(1, INFINITE, 80); ++SET_READ_DUAL(1, INFINITE, 100); ++SET_READ_DUAL(1, INFINITE, 104); ++SET_READ_DUAL(1, INFINITE, 108); ++SET_READ_DUAL(1, INFINITE, 120); ++SET_READ_DUAL(1, INFINITE, 133); ++ ++SET_READ_DUAL_ADDR(1, INFINITE, 40); ++SET_READ_DUAL_ADDR(1, INFINITE, 80); ++SET_READ_DUAL_ADDR(2, INFINITE, 80); ++SET_READ_DUAL_ADDR(1, INFINITE, 100); ++SET_READ_DUAL_ADDR(1, INFINITE, 104); ++SET_READ_DUAL_ADDR(1, INFINITE, 108); ++SET_READ_DUAL_ADDR(1, INFINITE, 120); ++SET_READ_DUAL_ADDR(2, INFINITE, 104); ++ ++SET_READ_QUAD(1, INFINITE, 80); ++SET_READ_QUAD(1, INFINITE, 100); ++SET_READ_QUAD(1, INFINITE, 104); ++SET_READ_QUAD(1, INFINITE, 108); ++SET_READ_QUAD(1, INFINITE, 120); ++SET_READ_QUAD(1, INFINITE, 133); ++ ++SET_READ_QUAD_ADDR(2, INFINITE, 40); ++SET_READ_QUAD_ADDR(1, INFINITE, 80); ++SET_READ_QUAD_ADDR(2, INFINITE, 80); ++SET_READ_QUAD_ADDR(4, INFINITE, 80); ++SET_READ_QUAD_ADDR(1, INFINITE, 100); ++SET_READ_QUAD_ADDR(1, INFINITE, 104); ++SET_READ_QUAD_ADDR(2, INFINITE, 104); ++SET_READ_QUAD_ADDR(1, INFINITE, 108); ++SET_READ_QUAD_ADDR(1, INFINITE, 120); ++SET_READ_QUAD_ADDR(4, INFINITE, 104); ++ ++/*****************************************************************************/ ++SET_WRITE_STD(0, 256, 24); ++SET_WRITE_STD(0, 256, 75); ++SET_WRITE_STD(0, 256, 80); ++SET_WRITE_STD(0, 256, 100); ++SET_WRITE_STD(0, 256, 104); ++SET_WRITE_STD(0, 256, 133); ++ ++SET_WRITE_QUAD(0, 256, 80); ++SET_WRITE_QUAD(0, 256, 100); ++SET_WRITE_QUAD(0, 256, 104); ++SET_WRITE_QUAD(0, 256, 108); ++SET_WRITE_QUAD(0, 256, 120); ++SET_WRITE_QUAD(0, 256, 133); ++ ++/*****************************************************************************/ ++SET_ERASE_SECTOR_128K(0, _128K, 24); ++SET_ERASE_SECTOR_128K(0, _128K, 75); ++SET_ERASE_SECTOR_128K(0, _128K, 80); ++SET_ERASE_SECTOR_128K(0, _128K, 104); ++SET_ERASE_SECTOR_128K(0, _128K, 133); ++ ++SET_ERASE_SECTOR_256K(0, _256K, 24); ++SET_ERASE_SECTOR_256K(0, _256K, 75); ++SET_ERASE_SECTOR_256K(0, _256K, 80); ++SET_ERASE_SECTOR_256K(0, _256K, 100); ++SET_ERASE_SECTOR_256K(0, _256K, 104); ++SET_ERASE_SECTOR_256K(0, _256K, 133); ++ ++/*****************************************************************************/ ++#include "fmc100_spi_general.c" ++static struct spi_drv spi_driver_general = { ++ .wait_ready = spi_general_wait_ready, ++ .write_enable = spi_general_write_enable, ++ .qe_enable = spi_general_qe_enable, ++}; ++ ++/* some spi nand flash default QUAD enable, needn't to set qe enable */ ++static struct spi_drv spi_driver_no_qe = { ++ .wait_ready = spi_general_wait_ready, ++ .write_enable = spi_general_write_enable, ++}; ++ ++/*****************************************************************************/ ++#define SPI_NAND_ID_TAB_VER "2.7" ++ ++/******* SPI Nand ID Table *************************************************** ++ * Version Manufacturer Chip Name Size Operation ++ * 1.0 ESMT F50L512M41A 64MB Add 5 chip ++ * GD 5F1GQ4UAYIG 128MB ++ * GD 5F2GQ4UAYIG 256MB ++ * GD GD5F2GQ5UEYIG 256MB ++ * GD 5F4GQ4UAYIG 512MB ++ * GD 5F4GQ4UBYIG 512MB ++ * GD 5F1GQ4RB9IG 128MB ++ * GD 5F1GQ4UEYIHY 128MB ++ * 1.1 ESMT F50L1G41A 128MB Add 2 chip ++ * Winbond W25N01GV 128MB ++ * Winbond W25N02JWZEIF 256MB ++ * 1.2 GD 5F1GQ4UBYIG 128MB Add 2 chip ++ * GD 5F2GQ4U9IGR/BYIG 256MB ++ * GD 1.8V 5F4GQ6RE9IG 512MB ++ * 1.3 ATO ATO25D1GA 128MB Add 1 chip ++ * 1.4 MXIC MX35LF1GE4AB 128MB Add 2 chip ++ * MXIC MX35LF2GE4AB 256MB (SOP-16Pin) ++ * 1.5 Paragon PN26G01A 128MB Add 1 chip ++ * 1.6 All-flash AFS1GQ4UAC 128MB Add 1 chip ++ * 1.7 TOSHIBA TC58CVG0S3H 128MB Add 2 chip ++ * TOSHIBA TC58CVG2S0H 512MB ++ * 1.8 ALL-flash AFS2GQ4UAD 256MB Add 2 chip ++ * Paragon PN26G02A 256MB ++ * 1.9 TOSHIBA TC58CVG1S3H 256MB Add 1 chip ++ * 2.0 HeYangTek HYF1GQ4UAACAE 128MB Add 3 chip ++ * HeYangTek HYF2GQ4UAACAE 256MB ++ * HeYangTek HYF4GQ4UAACBE 512MB ++ * 2.1 Micron MT29F1G01ABA 128MB Add 5 chip ++ TOSHIBA 1.8V TC58CYG0S3H 128MB ++ TOSHIBA 1.8V TC58CYG1S3H 256MB ++ TOSHIBA 1.8V TC58CYG2S0H 512MB ++ Winbond 1.8V W25N01GWZEIG 128MB ++ * 2.2 Micron MT29F2G01ABA 256MB Add 1 chip ++ * 2.3 MXIC MX35LF2G14AC 256MB Add 1 chip ++ * 2.4 GD 1.8V 5F4GQ4RAYIG 512MB Add 1 chip ++ * 2.5 GD 1.8V 5F2GQ4RB9IGR 256MB Add 1 chip ++ * 2.6 MXIC 1.8V MX35UF1G14AC 128MB Add 4 chip ++ * MXIC 1.8V MX35UF2G14AC 256MB ++ * Micron 1.8V MT29F1G01ABB 128MB ++ * Micron 1.8V MT29F2G01ABB 256MB ++ * 2.7 Dosilicon DS35Q1GA-IB 128MB Add 2 chip ++ * Dosilicon DS35Q2GA-IB 256MB ++ * GD 5F1GQ4RB9IGR 128MB ++ * Micron MT29F4G01ADAG 512MB 3.3V Add 1 chip ++ * GD 1.8V 5F4GQ4RBYIG 512MB Add 1 chip ++ * Etron 1.8V EM78D044VCF-H 256MB ++ * Etron 3.3V EM73C044VCC-H 128MB ++ * XTX 3.3V XT26G01B 1Gbit 128MB ++ * Micron MT29F4G01ABBFDW 512MB 1.8V ++ * FM FM25S01-DND-A-G 128MB 3.3V ++ * FM FM25S01A 128MB 3.3V ++ ******************************************************************************/ ++struct spi_nand_info fmc_spi_nand_flash_table[] = { ++ /* Micron MT29F1G01ABA 1GBit */ ++ { ++ .name = "MT29F1G01ABA", ++ .id = {0x2C, 0x14}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(2, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* Micron MT29F1G01ABB 1GBit 1.8V */ ++ { ++ .name = "MT29F1G01ABB", ++ .id = {0x2C, 0x15}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(2, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* Micron MT29F2G01ABA 2GBit */ ++ { ++ .name = "MT29F2G01ABA", ++ .id = {0x2C, 0x24}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 108), ++ &READ_DUAL(1, INFINITE, 108), ++ &READ_DUAL_ADDR(1, INFINITE, 108), ++ &READ_QUAD(1, INFINITE, 108), ++ &READ_QUAD_ADDR(2, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 108), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* Micron MT29F2G01ABB 2GBit 1.8V */ ++ { ++ .name = "MT29F2G01ABB", ++ .id = {0x2C, 0x25}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(2, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* Micron MT29F4G01ADAG 4GBit 3.3V */ ++ { ++ .name = "MT29F4G01ADAG", ++ .id = {0x2C, 0x36}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 108), ++ &READ_DUAL(1, INFINITE, 108), ++ &READ_DUAL_ADDR(1, INFINITE, 108), ++ &READ_QUAD(1, INFINITE, 108), ++ &READ_QUAD_ADDR(2, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 108), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* ESMT F50L512M41A 512Mbit */ ++ { ++ .name = "F50L512M41A", ++ .id = {0xC8, 0x20}, ++ .id_len = 2, ++ .chipsize = _64M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* ESMT F50L1G41A 1Gbit */ ++ { ++ .name = "F50L1G41A", ++ .id = {0xC8, 0x21}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* ESMT F50L1G41LB-104YG2ME 1Gbit */ ++ { ++ .name = "F50L1G41LB-104YG2ME", ++ .id = {0xC8, 0x01, 0X7F}, ++ .id_len = 3, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* GD 3.3v GD5F1GQ4UAYIG 1Gbit */ ++ { ++ .name = "GD5F1GQ4UAYIG", ++ .id = {0xc8, 0xf1}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 3.3v GD5F1GQ4UEYIHY 1Gbit */ ++ { ++ .name = "GD5F1GQ4UEYIHY", ++ .id = {0xc8, 0xd9}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 1.8v GD5F1GQ4RB9IG 1Gbit */ ++ { ++ .name = "GD5F1GQ4RB9IG", ++ .id = {0xc8, 0xc1}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 3.3v GD5F1GQ4UBYIG 1Gbit */ ++ { ++ .name = "GD5F1GQ4UBYIG", ++ .id = {0xc8, 0xd1}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 3.3v GD5F2GQ4UAYIG 2Gbit */ ++ { ++ .name = "GD5F2GQ4UAYIG", ++ .id = {0xc8, 0xf2}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 3.3v GD5F2GQ4U9IGR/BYIG 2Gbit */ ++ { ++ .name = "GD5F2GQ4U9IGR/BYIG", ++ .id = {0xc8, 0xd2}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ /* GD 3.3v GD5F2GQ5UEYIG 2Gbit */ ++ { ++ .name = "GD5F2GQ5UEYIG", ++ .id = {0xc8, 0x52}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_DUAL_ADDR(2, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ &READ_QUAD_ADDR(4, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 3.3v GD5F4GQ4UAYIG 4Gbit */ ++ { ++ .name = "GD5F4GQ4UAYIG", ++ .id = {0xc8, 0xf4}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 3.3v GD5F4GQ4UBYIG 4Gbit */ ++ { ++ .name = "GD5F4GQ4UBYIG", ++ .id = {0xc8, 0xd4}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 3.3v GD5F4GQ6UEYIG 4Gbit */ ++ { ++ .name = "GD5F4GQ6UEYIG", ++ .id = {0xc8, 0x55}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), /* 24MHz */ ++ &READ_FAST(1, INFINITE, 104), /* 104MHz */ ++ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ ++ &READ_DUAL_ADDR(2, INFINITE, 104), /* 104MHz */ ++ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ ++ &READ_QUAD_ADDR(4, INFINITE, 104), /* 104MHz */ ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), /* 24MHz */ ++ &WRITE_QUAD(0, 256, 104), /* 104MHz */ ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 1.8V GD5F1GQ4RB9IGR 1Gbit */ ++ { ++ .name = "GD5F1GQ4RB9IGR", ++ .id = {0xc8, 0xc1}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_DUAL_ADDR(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ &READ_QUAD_ADDR(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 1.8V GD5F2GQ4RB9IGR 2Gbit */ ++ { ++ .name = "GD5F2GQ4RB9IGR", ++ .id = {0xc8, 0xc2}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_DUAL_ADDR(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ &READ_QUAD_ADDR(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ /* GD 1.8V 5F4GQ6RE9IG 4Gbit */ ++ { ++ .name = "GD5F4GQ6RE9IG", ++ .id = {0xc8, 0x45}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(2, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(4, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ /* GD 1.8V GD5F4GQ4RAYIG 4Gbit */ ++ { ++ .name = "GD5F4GQ4RAYIG", ++ .id = {0xc8, 0xe4}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_DUAL_ADDR(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ &READ_QUAD_ADDR(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Winbond 1.8V W25N02JWZEIF 2Gbit */ ++ { ++ .name = "W25N02JWZEIF", ++ .id = {0xef, 0xbf, 0x22}, ++ .id_len = 3, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(2, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* GD 1.8V 5F4GQ4RBYIG 4Gbit */ ++ { ++ .name = "5F4GQ4RBYIG", ++ .id = {0xc8, 0xc4}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Winbond W25N01GV 1Gbit 3.3V */ ++ { ++ .name = "W25N01GV", ++ .id = {0xef, 0xaa, 0x21}, ++ .id_len = 3, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_DUAL_ADDR(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ &READ_QUAD_ADDR(2, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* Winbond W25N01GWZEIG 1Gbit 1.8V */ ++ { ++ .name = "W25N01GWZEIG", ++ .id = {0xef, 0xba, 0x21}, ++ .id_len = 3, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_DUAL_ADDR(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ &READ_QUAD_ADDR(2, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* ATO ATO25D1GA 1Gbit */ ++ { ++ .name = "ATO25D1GA", ++ .id = {0x9b, 0x12}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* MXIC MX35LF1GE4AB 1Gbit */ ++ { ++ .name = "MX35LF1GE4AB", ++ .id = {0xc2, 0x12}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* MXIC MX35UF1G14AC 1Gbit 1.8V */ ++ { ++ .name = "MX35UF1G14AC", ++ .id = {0xc2, 0x90}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* MXIC MX35LF2GE4AB 2Gbit SOP-16Pin */ ++ { ++ .name = "MX35LF2GE4AB", ++ .id = {0xc2, 0x22}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* MXIC MX35LF2G14AC 2GBit */ ++ { ++ .name = "MX35LF2G14AC", ++ .id = {0xc2, 0x20}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* MXIC MX35UF2G14AC 2Gbit 1.8V */ ++ { ++ .name = "MX35UF2G14AC", ++ .id = {0xc2, 0xa0}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Paragon PN26G01A 1Gbit */ ++ { ++ .name = "PN26G01A", ++ .id = {0xa1, 0xe1}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 108), ++ &READ_DUAL(1, INFINITE, 108), ++ &READ_DUAL_ADDR(1, INFINITE, 108), ++ &READ_QUAD(1, INFINITE, 108), ++ &READ_QUAD_ADDR(1, INFINITE, 108), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 108), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Paragon PN26G02A 2Gbit */ ++ { ++ .name = "PN26G02A", ++ .id = {0xa1, 0xe2}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 108), ++ &READ_DUAL(1, INFINITE, 108), ++ &READ_DUAL_ADDR(1, INFINITE, 108), ++ &READ_QUAD(1, INFINITE, 108), ++ &READ_QUAD_ADDR(1, INFINITE, 108), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 108), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* All-flash AFS1GQ4UAC 1Gbit */ ++ { ++ .name = "AFS1GQ4UAC", ++ .id = {0xc1, 0x51}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(1, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* All-flash AFS2GQ4UAD 2Gbit */ ++ { ++ .name = "AFS2GQ4UAD", ++ .id = {0xc1, 0x52}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(1, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 24), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 24), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* TOSHIBA TC58CVG0S3H 1Gbit */ ++ { ++ .name = "TC58CVG0S3H", ++ .id = {0x98, 0xc2}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CVG0S3HRAIJ 1Gbit */ ++ { ++ .name = "TC58CVG0S3HRAIJ", ++ .id = {0x98, 0xe2, 0x40}, ++ .id_len = 3, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 133), ++ &READ_DUAL(1, INFINITE, 133), ++ &READ_QUAD(1, INFINITE, 133), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 133), ++ &WRITE_QUAD(0, 256, 133), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 133), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CYG0S3H 1.8V 1Gbit */ ++ { ++ .name = "TC58CYG0S3H", ++ .id = {0x98, 0xb2}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CYG0S3HRAIJ 1.8V 1Gbit */ ++ { ++ .name = "TC58CYG0S3HRAIJ", ++ .id = {0x98, 0xD2, 0x40}, ++ .id_len = 3, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 133), ++ &READ_DUAL(1, INFINITE, 133), ++ &READ_QUAD(1, INFINITE, 133), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 133), ++ &WRITE_QUAD(0, 256, 133), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 133), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CVG1S3H 2Gbit */ ++ { ++ .name = "TC58CVG1S3H", ++ .id = {0x98, 0xcb}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CVG1S3HRAIJ 2Gbit */ ++ { ++ .name = "TC58CVG1S3HRAIJ", ++ .id = {0x98, 0xeb, 0x40}, ++ .id_len = 3, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 133), ++ &READ_DUAL(1, INFINITE, 133), ++ &READ_QUAD(1, INFINITE, 133), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 133), ++ &WRITE_QUAD(0, 256, 133), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 133), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CYG1S3H 1.8V 2Gbit */ ++ { ++ .name = "TC58CYG1S3H", ++ .id = {0x98, 0xbb}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 75), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 75), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CVG2S0H 4Gbit */ ++ { ++ .name = "TC58CVG2S0H", ++ .id = {0x98, 0xcd}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CVG2S0HRAIJ 4Gbit */ ++ { ++ .name = "TC58CVG2S0HRAIJ", ++ .id = {0x98, 0xed, 0x51}, ++ .id_len = 3, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 133), ++ &READ_DUAL(1, INFINITE, 133), ++ &READ_QUAD(1, INFINITE, 133), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 133), ++ &WRITE_QUAD(0, 256, 133), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 133), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* TOSHIBA TC58CYG2S0H 1.8V 4Gbit */ ++ { ++ .name = "TC58CYG2S0H", ++ .id = {0x98, 0xbd}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 75), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 75), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* KIOXIA TC58CYG2S0HRAIJ 1.8V 4Gbit */ ++ { ++ .name = "TC58CYG2S0HRAIJ", ++ .id = {0x98, 0xdd, 0x51}, ++ .id_len = 3, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), /* 24MHz */ ++ &READ_FAST(1, INFINITE, 133), /* 133MHz */ ++ &READ_DUAL(1, INFINITE, 133), /* 133MHz */ ++ &READ_QUAD(1, INFINITE, 133), /* 133MHz */ ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 133), /* 133MHz */ ++ &WRITE_QUAD(0, 256, 133), /* 133MHz */ ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */ ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ /* KIOXIA TH58CYG3S0H 1.8V 8Gbit */ ++ { ++ .name = "TH58CYG3S0H", ++ .id = {0x98, 0xd4, 0x51}, ++ .id_len = 3, ++ .chipsize = _1G, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), /* 24MHz */ ++ &READ_FAST(1, INFINITE, 133), /* 133MHz */ ++ &READ_DUAL(1, INFINITE, 133), /* 133MHz */ ++ &READ_QUAD(1, INFINITE, 133), /* 133MHz */ ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 133), /* 133MHz */ ++ &WRITE_QUAD(0, 256, 133), /* 133MHz */ ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */ ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* HeYangTek HYF1GQ4UAACAE 1Gbit */ ++ { ++ .name = "HYF1GQ4UAACAE", ++ .id = {0xc9, 0x51}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(1, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* HeYangTek HYF2GQ4UAACAE 2Gbit */ ++ { ++ .name = "HYF2GQ4UAACAE", ++ .id = {0xc9, 0x52}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(1, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* HeYangTek HYF4GQ4UAACBE 4Gbit */ ++ { ++ .name = "HYF4GQ4UAACBE", ++ .id = {0xc9, 0xd4}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(1, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Dosilicon 3.3V DS35Q1GA-IB 1Gbit */ ++ { ++ .name = "DS35Q1GA-IB", ++ .id = {0xe5, 0x71}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* XTX 3.3V XT26G01B 1Gbit */ ++ { ++ .name = "XT26G01B", ++ .id = {0x0B, 0xF1}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_DUAL_ADDR(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ &READ_QUAD_ADDR(1, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Etron 1.8V EM78F044VCA-H 8Gbit */ ++ { ++ .name = "EM78F044VCA-H", ++ .id = {0xD5, 0x8D}, ++ .id_len = 2, ++ .chipsize = _512M*2, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 100), ++ &READ_DUAL(1, INFINITE, 100), ++ &READ_DUAL_ADDR(1, INFINITE, 100), ++ &READ_QUAD(1, INFINITE, 100), ++ &READ_QUAD_ADDR(1, INFINITE, 100), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 100), ++ &WRITE_QUAD(0, 256, 100), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 100), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Etron 1.8V EM78E044VCA-H 4Gbit */ ++ { ++ .name = "EM78E044VCA-H", ++ .id = {0xD5, 0x8C}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 100), ++ &READ_DUAL(1, INFINITE, 100), ++ &READ_DUAL_ADDR(1, INFINITE, 100), ++ &READ_QUAD(1, INFINITE, 100), ++ &READ_QUAD_ADDR(1, INFINITE, 100), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 100), ++ &WRITE_QUAD(0, 256, 100), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 100), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Etron 1.8V EM78D044VCF-H 2Gbit */ ++ { ++ .name = "EM78D044VCF-H", ++ .id = {0xd5, 0x81}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_DUAL_ADDR(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ &READ_QUAD_ADDR(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Etron 3.3V EM73C044VCC-H 1Gbit */ ++ { ++ .name = "EM73C044VCC-H", ++ .id = {0xd5, 0x22}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 120), ++ &READ_DUAL(1, INFINITE, 120), ++ &READ_DUAL_ADDR(1, INFINITE, 120), ++ &READ_QUAD(1, INFINITE, 120), ++ &READ_QUAD_ADDR(1, INFINITE, 120), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), ++ &WRITE_QUAD(0, 256, 120), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* Micron MT29F4G01ABBFDWB 4GBit 1.8V */ ++ { ++ .name = "MT29F4G01ABBFDWB", ++ .id = {0x2C, 0x35}, ++ .id_len = 2, ++ .chipsize = _512M, ++ .erasesize = _256K, ++ .pagesize = _4K, ++ .oobsize = 256, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 80), ++ &READ_DUAL(1, INFINITE, 80), ++ &READ_QUAD(1, INFINITE, 80), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 80), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_256K(0, _256K, 80), ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* Dosilicon 3.3V DS35Q2GA-IB 1Gb */ ++ { ++ .name = "DS35Q2GA-IB", ++ .id = {0xe5, 0x72}, ++ .id_len = 2, ++ .chipsize = _256M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), ++ &READ_FAST(1, INFINITE, 104), ++ &READ_DUAL(1, INFINITE, 104), ++ &READ_QUAD(1, INFINITE, 104), ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 80), ++ &WRITE_QUAD(0, 256, 104), ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), ++ 0 ++ }, ++ .driver = &spi_driver_general, ++ }, ++ ++ /* FM 3.3v FM25S01-DND-A-G 1Gbit */ ++ { ++ .name = "FM25S01-DND-A-G", ++ .id = {0xa1, 0xa1}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 128, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), /* 24MHz */ ++ &READ_FAST(1, INFINITE, 104), /* 104MHz */ ++ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ ++ &READ_DUAL_ADDR(1, INFINITE, 40), /* 40MHz */ ++ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ ++ &READ_QUAD_ADDR(2, INFINITE, 40), /* 40MHz */ ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), /* 104MHz */ ++ &WRITE_QUAD(0, 256, 104), /* 104MHz */ ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ /* FM 3.3v FM25S01A 1Gbit */ ++ { ++ .name = "FM25S01A", ++ .id = {0xa1, 0xe4}, ++ .id_len = 2, ++ .chipsize = _128M, ++ .erasesize = _128K, ++ .pagesize = _2K, ++ .oobsize = 64, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .read = { ++ &READ_STD(1, INFINITE, 24), /* 104MHz */ ++ &READ_FAST(1, INFINITE, 104), /* 104MHz */ ++ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ ++ &READ_DUAL_ADDR(1, INFINITE, 40), /* 70MHz */ ++ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ ++ &READ_QUAD_ADDR(2, INFINITE, 40), /* 70MHz */ ++ 0 ++ }, ++ .write = { ++ &WRITE_STD(0, 256, 104), /* 104MHz */ ++ &WRITE_QUAD(0, 256, 104), /* 104MHz */ ++ 0 ++ }, ++ .erase = { ++ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ ++ 0 ++ }, ++ .driver = &spi_driver_no_qe, ++ }, ++ ++ { .id_len = 0, }, ++}; ++ ++/*****************************************************************************/ ++static void fmc100_spi_nand_search_rw(struct spi_nand_info *spiinfo, ++ struct spi_op *spiop_rw, u_int iftype, u_int max_dummy, int rw_type) ++{ ++ int ix = 0; ++ struct spi_op **spiop, **fitspiop; ++ ++ for (fitspiop = spiop = (rw_type ? spiinfo->write : spiinfo->read); ++ (*spiop) && ix < MAX_SPI_OP; spiop++, ix++) { ++ if (((*spiop)->iftype & iftype) ++ && ((*spiop)->dummy <= max_dummy) ++ && (*fitspiop)->iftype < (*spiop)->iftype) { ++ fitspiop = spiop; ++ } ++ } ++ memcpy(spiop_rw, (*fitspiop), sizeof(struct spi_op)); ++} ++ ++/*****************************************************************************/ ++static void fmc100_spi_nand_get_erase(struct spi_nand_info *spiinfo, ++ struct spi_op *spiop_erase) ++{ ++ int ix; ++ ++ spiop_erase->size = 0; ++ for (ix = 0; ix < MAX_SPI_OP; ix++) { ++ if (spiinfo->erase[ix] == NULL) { ++ break; ++ } ++ if (spiinfo->erasesize == spiinfo->erase[ix]->size) { ++ memcpy(&spiop_erase[ix], spiinfo->erase[ix], ++ sizeof(struct spi_op)); ++ break; ++ } ++ } ++} ++ ++/*****************************************************************************/ ++static void fmc100_map_spi_op(struct fmc_spi *spi) ++{ ++ unsigned char ix; ++ const int iftype_read[] = { ++ SPI_IF_READ_STD, IF_TYPE_STD, ++ SPI_IF_READ_FAST, IF_TYPE_STD, ++ SPI_IF_READ_DUAL, IF_TYPE_DUAL, ++ SPI_IF_READ_DUAL_ADDR, IF_TYPE_DIO, ++ SPI_IF_READ_QUAD, IF_TYPE_QUAD, ++ SPI_IF_READ_QUAD_ADDR, IF_TYPE_QIO, ++ 0, 0, ++ }; ++ const int iftype_write[] = { ++ SPI_IF_WRITE_STD, IF_TYPE_STD, ++ SPI_IF_WRITE_QUAD, IF_TYPE_QUAD, ++ 0, 0, ++ }; ++ const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; ++ ++ FMC_PR(BT_DBG, "\t||*-Start Get SPI operation iftype\n"); ++ ++ for (ix = 0; iftype_write[ix]; ix += 2) { ++ if (spi->write->iftype == iftype_write[ix]) { ++ spi->write->iftype = iftype_write[ix + 1]; ++ break; ++ } ++ } ++ FMC_PR(BT_DBG, "\t|||-Get best write iftype: %s \n", ++ if_str[spi->write->iftype]); ++ ++ for (ix = 0; iftype_read[ix]; ix += 2) { ++ if (spi->read->iftype == iftype_read[ix]) { ++ spi->read->iftype = iftype_read[ix + 1]; ++ break; ++ } ++ } ++ FMC_PR(BT_DBG, "\t|||-Get best read iftype: %s \n", ++ if_str[spi->read->iftype]); ++ ++ spi->erase->iftype = IF_TYPE_STD; ++ FMC_PR(BT_DBG, "\t|||-Get best erase iftype: %s \n", ++ if_str[spi->erase->iftype]); ++ ++ FMC_PR(BT_DBG, "\t||*-End Get SPI operation iftype \n"); ++} ++ ++/*****************************************************************************/ ++static void fmc100_spi_ids_probe(struct mtd_info *mtd, ++ struct spi_nand_info *spi_dev) ++{ ++ unsigned int reg; ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ struct fmc_spi *spi = host->spi; ++ ++ FMC_PR(BT_DBG, "\t|*-Start match SPI operation & chip init\n"); ++ ++ spi->host = host; ++ spi->name = spi_dev->name; ++ spi->driver = spi_dev->driver; ++ ++ fmc100_spi_nand_search_rw(spi_dev, spi->read, ++ FMC_SPI_NAND_SUPPORT_READ, ++ FMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_READ); ++ FMC_PR(BT_DBG, "\t||-Save spi->read op cmd:%#x\n", spi->read->cmd); ++ ++ fmc100_spi_nand_search_rw(spi_dev, spi->write, ++ FMC_SPI_NAND_SUPPORT_WRITE, ++ FMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_WRITE); ++ FMC_PR(BT_DBG, "\t||-Save spi->write op cmd:%#x\n", spi->write->cmd); ++ ++ fmc100_spi_nand_get_erase(spi_dev, spi->erase); ++ FMC_PR(BT_DBG, "\t||-Save spi->erase op cmd:%#x\n", spi->erase->cmd); ++ ++ fmc100_map_spi_op(spi); ++ ++ if (spi->driver->qe_enable) { ++ spi->driver->qe_enable(spi); ++ } ++ ++ /* Disable write protection */ ++ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); ++ FMC_PR(BT_DBG, "\t||-Get protect status[%#x]: %#x\n", PROTECT_ADDR, ++ reg); ++ if (ANY_BP_ENABLE(reg)) { ++ reg &= ~ALL_BP_MASK; ++ spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, reg); ++ FMC_PR(BT_DBG, "\t||-Set [%#x]FT %#x\n", PROTECT_ADDR, reg); ++ ++ spi->driver->wait_ready(spi); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); ++ FMC_PR(BT_DBG, "\t||-Check BP disable result: %#x\n", reg); ++ if (ANY_BP_ENABLE(reg)) { ++ DB_MSG("Error: Write protection disable failed!\n"); ++ } ++ } ++ ++ /* Disable chip internal ECC */ ++ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); ++ FMC_PR(BT_DBG, "\t||-Get feature status[%#x]: %#x\n", FEATURE_ADDR, ++ reg); ++ if (reg & FEATURE_ECC_ENABLE) { ++ reg &= ~FEATURE_ECC_ENABLE; ++ spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, reg); ++ FMC_PR(BT_DBG, "\t||-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg); ++ ++ spi->driver->wait_ready(spi); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); ++ FMC_PR(BT_DBG, "\t||-Check internal ECC disable result: %#x\n", ++ reg); ++ if (reg & FEATURE_ECC_ENABLE) { ++ DB_MSG("Error: Chip internal ECC disable failed!\n"); ++ } ++ } ++ ++ fmc_cs_user[host->cmd_op.cs]++; ++ ++ FMC_PR(BT_DBG, "\t|*-End match SPI operation & chip init\n"); ++} ++ ++static struct nand_flash_dev spi_nand_dev; ++/*****************************************************************************/ ++static struct nand_flash_dev *spi_nand_get_flash_info(struct mtd_info *mtd, ++ unsigned char *id) ++{ ++ unsigned char ix, len = 0; ++ char buffer[100]; ++ struct nand_chip *chip = mtd_to_nand(mtd); ++ struct fmc_host *host = chip->priv; ++ struct spi_nand_info *spi_dev = fmc_spi_nand_flash_table; ++ struct nand_flash_dev *type = &spi_nand_dev; ++ ++ FMC_PR(BT_DBG, "\t*-Start find SPI Nand flash\n"); ++ ++ len = sprintf(buffer, "SPI Nand(cs %d) ID: %#x %#x", ++ host->cmd_op.cs, id[0], id[1]); ++ ++ for (; spi_dev->id_len; spi_dev++) { ++ if (memcmp(id, spi_dev->id, spi_dev->id_len)) { ++ continue; ++ } ++ ++ for (ix = 2; ix < spi_dev->id_len; ix++) { ++ len += sprintf(buffer + len, " %#x", id[ix]); ++ } ++ pr_info("%s\n", buffer); ++ ++ FMC_PR(BT_DBG, "\t||-CS(%d) found SPI Nand: %s\n", ++ host->cmd_op.cs, spi_dev->name); ++ ++ type->name = spi_dev->name; ++ memcpy(type->id, spi_dev->id, spi_dev->id_len); ++ type->pagesize = spi_dev->pagesize; ++ type->chipsize = spi_dev->chipsize >> 20; ++ type->erasesize = spi_dev->erasesize; ++ type->id_len = spi_dev->id_len; ++ type->oobsize = spi_dev->oobsize; ++ FMC_PR(BT_DBG, "\t|-Save struct nand_flash_dev info\n"); ++ ++ mtd->oobsize = spi_dev->oobsize; ++ mtd->erasesize = spi_dev->erasesize; ++ mtd->writesize = spi_dev->pagesize; ++ chip->chipsize = spi_dev->chipsize; ++ ++ fmc100_spi_ids_probe(mtd, spi_dev); ++ ++ FMC_PR(BT_DBG, "\t*-Found SPI nand: %s\n", spi_dev->name); ++ ++ return type; ++ } ++ ++ FMC_PR(BT_DBG, "\t*-Not found SPI nand flash, %s\n", buffer); ++ ++ return NULL; ++} ++ ++/*****************************************************************************/ ++void fmc_spi_nand_ids_register(void) ++{ ++ pr_info("SPI Nand ID Table Version %s\n", SPI_NAND_ID_TAB_VER); ++ get_spi_nand_flash_type_hook = spi_nand_get_flash_info; ++} ++ ++#ifdef CONFIG_PM ++/*****************************************************************************/ ++void fmc100_spi_nand_config(struct fmc_host *host) ++{ ++ unsigned int reg; ++ struct fmc_spi *spi = host->spi; ++ static const char *str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; ++ ++ /* judge whether support QUAD read/write or not, set it if yes */ ++ FMC_PR(PM_DBG, "\t|-SPI read iftype: %s write iftype: %s\n", ++ str[spi->read->iftype], str[spi->write->iftype]); ++ ++ if (spi->driver->qe_enable) { ++ spi->driver->qe_enable(spi); ++ } ++ ++ /* Disable write protection */ ++ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); ++ FMC_PR(PM_DBG, "\t|-Get protect status[%#x]: %#x\n", PROTECT_ADDR, ++ reg); ++ if (ANY_BP_ENABLE(reg)) { ++ reg &= ~ALL_BP_MASK; ++ spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, reg); ++ FMC_PR(PM_DBG, "\t|-Set [%#x]FT %#x\n", PROTECT_ADDR, reg); ++ ++ spi->driver->wait_ready(spi); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); ++ FMC_PR(PM_DBG, "\t|-Check BP disable result: %#x\n", reg); ++ if (ANY_BP_ENABLE(reg)) { ++ DB_MSG("Error: Write protection disable failed!\n"); ++ } ++ } ++ ++ /* Disable chip internal ECC */ ++ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); ++ FMC_PR(PM_DBG, "\t|-Get feature status[%#x]: %#x\n", FEATURE_ADDR, ++ reg); ++ if (reg & FEATURE_ECC_ENABLE) { ++ reg &= ~FEATURE_ECC_ENABLE; ++ spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, reg); ++ FMC_PR(PM_DBG, "\t|-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg); ++ ++ spi->driver->wait_ready(spi); ++ ++ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); ++ FMC_PR(PM_DBG, "\t|-Check internal ECC disable result: %#x\n", ++ reg); ++ if (reg & FEATURE_ECC_ENABLE) { ++ DB_MSG("Error: Chip internal ECC disable failed!\n"); ++ } ++ } ++} ++/*****************************************************************************/ ++#endif /* CONFIG_PM */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-match_table.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-match_table.c.patch new file mode 100644 index 00000000..e104330e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-match_table.c.patch @@ -0,0 +1,102 @@ +--- linux-4.9.37/drivers/mtd/nand/match_table.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/match_table.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,99 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include "match_table.h" ++ ++/*****************************************************************************/ ++int reg2type(struct match_reg_type *table, int length, int reg, int def) ++{ ++ while (length-- > 0) { ++ if (table->reg == reg) { ++ return table->type; ++ } ++ table++; ++ } ++ return def; ++} ++ ++int type2reg(struct match_reg_type *table, int length, int type, int def) ++{ ++ while (length-- > 0) { ++ if (table->type == type) { ++ return table->reg; ++ } ++ table++; ++ } ++ return def; ++} ++ ++int str2type(struct match_type_str *table, int length, const char *str, ++ int size, int def) ++{ ++ while (length-- > 0) { ++ if (!strncmp(table->str, str, size)) { ++ return table->type; ++ } ++ table++; ++ } ++ return def; ++} ++ ++const char *type2str(struct match_type_str *table, int length, int type, ++ const char *def) ++{ ++ while (length-- > 0) { ++ if (table->type == type) { ++ return table->str; ++ } ++ table++; ++ } ++ return def; ++} ++ ++int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def) ++{ ++ while (nr_table-- > 0) { ++ if (table->reg == reg) { ++ return table->type; ++ } ++ table++; ++ } ++ return def; ++} ++ ++int match_type_to_reg(struct match_t *table, int nr_table, int type, int def) ++{ ++ while (nr_table-- > 0) { ++ if (table->type == type) { ++ return table->reg; ++ } ++ table++; ++ } ++ return def; ++} ++ ++int match_data_to_type(struct match_t *table, int nr_table,const char *data, ++ int size, int def) ++{ ++ while (nr_table-- > 0) { ++ if (!memcmp(table->data, data, size)) { ++ return table->type; ++ } ++ table++; ++ } ++ return def; ++} ++ ++void *match_type_to_data(struct match_t *table, int nr_table, int type, ++ const void *def) ++{ ++ while (nr_table-- > 0) { ++ if (table->type == type) { ++ return table->data; ++ } ++ table++; ++ } ++ return (void *)def; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-match_table.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-match_table.h.patch new file mode 100644 index 00000000..ae52d615 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-match_table.h.patch @@ -0,0 +1,56 @@ +--- linux-4.9.37/drivers/mtd/nand/match_table.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/match_table.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __MATCH_TABLE_H__ ++#define __MATCH_TABLE_H__ ++ ++/*****************************************************************************/ ++struct match_reg_type { ++ int reg; ++ int type; ++}; ++ ++struct match_type_str { ++ int type; ++ const char *str; ++}; ++ ++struct match_t { ++ int type; ++ int reg; ++ void *data; ++}; ++ ++/*****************************************************************************/ ++#define MATCH_SET_TYPE_REG(_type, _reg) {(_type), (_reg), (void *)0} ++#define MATCH_SET_TYPE_DATA(_type, _data) {(_type), 0, (void *)(_data)} ++#define MATCH_SET(_type, _reg, _data) {(_type), (_reg), (void *)(_data)} ++ ++/*****************************************************************************/ ++int reg2type(struct match_reg_type *table, int length, int reg, int def); ++ ++int type2reg(struct match_reg_type *table, int length, int type, int def); ++ ++int str2type(struct match_type_str *table, int length, const char *str, ++ int size, int def); ++ ++const char *type2str(struct match_type_str *table, int length, int type, ++ const char *def); ++ ++int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def); ++ ++int match_type_to_reg(struct match_t *table, int nr_table, int type, int def); ++ ++int match_data_to_type(struct match_t *table, int nr_table,const char *data, ++ int size, int def); ++ ++void *match_type_to_data(struct match_t *table, int nr_table, int type, ++ const void *def); ++ ++/*****************************************************************************/ ++ ++#endif /* End of __MATCH_TABLE_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nand_base.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nand_base.c.patch new file mode 100644 index 00000000..0223defa --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nand_base.c.patch @@ -0,0 +1,111 @@ +--- linux-4.9.37/drivers/mtd/nand/nand_base.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/nand_base.c 2021-06-07 13:01:33.000000000 +0300 +@@ -47,6 +47,8 @@ + #include + #include + ++#include "nfc_gen.h" ++ + static int nand_get_device(struct mtd_info *mtd, int new_state); + + static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, +@@ -2808,6 +2810,10 @@ + int ret; + int oob_required = oob ? 1 : 0; + ++#ifdef CONFIG_ARCH_GOKE ++ oob_required = 1; ++#endif ++ + ops->retlen = 0; + if (!writelen) + return 0; +@@ -4058,7 +4064,7 @@ + int *maf_id, int *dev_id, + struct nand_flash_dev *type) + { +- int busw; ++ int busw = 0; + int i, maf_idx; + u8 id_data[8]; + +@@ -4097,6 +4103,30 @@ + return ERR_PTR(-ENODEV); + } + ++#ifdef CONFIG_ARCH_GOKE ++ ++#ifndef CONFIG_MTD_SPI_NAND_GOKE ++ /* Parallel Nand Flash */ ++ ++ /* The 3rd id byte holds MLC / multichip data */ ++ chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]); ++#endif ++ ++ if (get_spi_nand_flash_type_hook) ++ type = get_spi_nand_flash_type_hook(mtd, id_data); ++ ++ if (type) ++ goto ident_done; ++#ifdef CONFIG_MTD_SPI_NAND_GOKE ++ else { ++ pr_info("This device[%02x,%02x] cannot found in spi nand id table!!\n", ++ *maf_id, *dev_id); ++ return ERR_PTR(-ENODEV); ++ } ++#endif ++ ++#endif /* endif CONFIG_ARCH_GOKE */ ++ + if (!type) + type = nand_flash_ids; + +@@ -4144,6 +4174,9 @@ + if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) + chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; + ident_done: ++#ifdef CONFIG_ARCH_GOKE ++ nfc_nand_param_adjust(mtd, chip); ++#endif + + /* Try to identify manufacturer */ + for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { +@@ -4205,9 +4238,13 @@ + pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, + type->name); + +- pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", ++ pr_info("%dMiB, %s, page size: %d\n", + (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", +- mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); ++ mtd->writesize); ++ ++ /* Print ecc type and ecc mode about goke flash controller */ ++ nfc_show_info(mtd, nand_manuf_ids[maf_idx].name, type->name); ++ + return type; + } + +@@ -4727,7 +4764,7 @@ + break; + + case NAND_ECC_NONE: +- pr_warn("NAND_ECC_NONE selected by board driver. This is not recommended!\n"); ++ pr_warn(" ECC provided by Flash Memory Controller\n"); + ecc->read_page = nand_read_page_raw; + ecc->write_page = nand_write_page_raw; + ecc->read_oob = nand_read_oob_std; +@@ -4814,8 +4851,13 @@ + break; + } + ++#ifdef CONFIG_MTD_UBI ++ /* mtd->type = MTD_MLCNANDFLASH isn't support by mtd_util ubi tools jet */ ++ mtd->type = MTD_NANDFLASH; ++#else + /* Fill in remaining MTD driver data */ + mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH; ++#endif + mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : + MTD_CAP_NANDFLASH; + mtd->_erase = nand_erase; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nand_ids.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nand_ids.c.patch new file mode 100644 index 00000000..2b810239 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nand_ids.c.patch @@ -0,0 +1,29 @@ +--- linux-4.9.37/drivers/mtd/nand/nand_ids.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/nand_ids.c 2021-06-07 13:01:33.000000000 +0300 +@@ -168,7 +168,7 @@ + /* Manufacturer IDs */ + struct nand_manufacturers nand_manuf_ids[] = { + {NAND_MFR_TOSHIBA, "Toshiba"}, +- {NAND_MFR_ESMT, "ESMT"}, ++ {NAND_MFR_GD_ESMT, "GD/ESMT"}, + {NAND_MFR_SAMSUNG, "Samsung"}, + {NAND_MFR_FUJITSU, "Fujitsu"}, + {NAND_MFR_NATIONAL, "National"}, +@@ -179,9 +179,17 @@ + {NAND_MFR_AMD, "AMD/Spansion"}, + {NAND_MFR_MACRONIX, "Macronix"}, + {NAND_MFR_EON, "Eon"}, ++ {NAND_MFR_WINBOND, "Winbond"}, ++ {NAND_MFR_ATO, "ATO"}, ++ {NAND_MFR_MXIC, "MXIC"}, ++ {NAND_MFR_ALL_FLASH, "All-flash"}, ++ {NAND_MFR_PARAGON, "Paragon"}, + {NAND_MFR_SANDISK, "SanDisk"}, + {NAND_MFR_INTEL, "Intel"}, + {NAND_MFR_ATO, "ATO"}, ++ {NAND_MFR_HEYANGTEK, "HeYangTek"}, ++ {NAND_MFR_DOSILICON, "Dosilicon"}, ++ {NAND_MFR_FIDELIX, "Fidelix/Dosi"}, /* Fidelix was purchased by Dosilicon */ + {0x0, "Unknown"} + }; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_gen.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_gen.c.patch new file mode 100644 index 00000000..f1d1edbd --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_gen.c.patch @@ -0,0 +1,236 @@ +--- linux-4.9.37/drivers/mtd/nand/nfc_gen.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/nfc_gen.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,233 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include "match_table.h" ++#include "nfc_gen.h" ++ ++/*****************************************************************************/ ++struct nand_flash_dev *(*get_spi_nand_flash_type_hook)(struct mtd_info *mtd, ++ unsigned char *id) = NULL; ++ ++/*****************************************************************************/ ++static struct match_t match_ecc[] = { ++ MATCH_SET_TYPE_DATA(NAND_ECC_NONE, "none"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_0BIT, "none"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_1BIT_512, "1bit/512"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_4BIT, "4bit/512"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_4BIT_512, "4bit/512"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_4BYTE, "4byte/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_8BIT, "4bit/512"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_8BIT_512, "8bit/512"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_8BYTE, "8byte/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_13BIT, "13bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_16BIT, "8bit/512"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_18BIT, "18bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_24BIT, "24bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_27BIT, "27bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_32BIT, "32bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_40BIT, "40bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_41BIT, "41bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_48BIT, "48bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_60BIT, "60bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_72BIT, "72bit/1k"), ++ MATCH_SET_TYPE_DATA(NAND_ECC_80BIT, "80bit/1k"), ++}; ++ ++const char *nand_ecc_name(int type) ++{ ++ return (char *)match_type_to_data(match_ecc, ARRAY_SIZE(match_ecc), ++ type, "unknown"); ++} ++ ++char *get_ecctype_str(enum ecc_type ecctype) ++{ ++ static char *ecctype_string[] = { ++ "None", "1bit/512Byte", "4bits/512Byte", "8bits/512Byte", ++ "24bits/1K", "40bits/1K", "unknown", "unknown" ++ }; ++ return ecctype_string[((unsigned int)ecctype & 0x07)]; ++} ++ ++/*****************************************************************************/ ++static struct match_type_str page2name[] = { ++ { NAND_PAGE_512B, "512" }, ++ { NAND_PAGE_2K, "2K" }, ++ { NAND_PAGE_4K, "4K" }, ++ { NAND_PAGE_8K, "8K" }, ++ { NAND_PAGE_16K, "16K" }, ++ { NAND_PAGE_32K, "32K" }, ++}; ++ ++const char *nand_page_name(int type) ++{ ++ return type2str(page2name, ARRAY_SIZE(page2name), type, "unknown"); ++} ++ ++char *get_pagesize_str(enum page_type pagetype) ++{ ++ static char *pagesize_str[] = { ++ "512", "2K", "4K", "8K", "16K", "unknown", ++ "unknown", "unknown" ++ }; ++ return pagesize_str[((unsigned int)pagetype & 0x07)]; ++} ++ ++/*****************************************************************************/ ++static struct match_reg_type page2size[] = { ++ { _512B, NAND_PAGE_512B }, ++ { _2K, NAND_PAGE_2K }, ++ { _4K, NAND_PAGE_4K }, ++ { _8K, NAND_PAGE_8K }, ++ { _16K, NAND_PAGE_16K }, ++ { _32K, NAND_PAGE_32K }, ++}; ++ ++unsigned int get_pagesize(enum page_type pagetype) ++{ ++ unsigned int pagesize[] = { ++ _512B, _2K, _4K, _8K, _16K, 0, 0, 0 ++ }; ++ return pagesize[((unsigned int)pagetype & 0x07)]; ++} ++ ++int nandpage_size2type(int size) ++{ ++ return reg2type(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K); ++} ++ ++int nandpage_type2size(int size) ++{ ++ return type2reg(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K); ++} ++ ++char *nand_dbgfs_options; ++ ++static int __init dbgfs_options_setup(char *s) ++{ ++ nand_dbgfs_options = s; ++ return 1; ++} ++__setup("nanddbgfs=", dbgfs_options_setup); ++ ++/*****************************************************************************/ ++ ++int get_bits(unsigned int n) ++{ ++ int loop; ++ int ret = 0; ++ ++ if (!n) ++ return 0; ++ ++ if (n > 0xFFFF) ++ loop = n > 0xFFFFFF ? 32 : 24; ++ else ++ loop = n > 0xFF ? 16 : 8; ++ ++ while (loop-- > 0 && n) { ++ if (n & 1) ++ ret++; ++ n >>= 1; ++ } ++ return ret; ++} ++ ++/*****************************************************************************/ ++#define et_ecc_none 0x00 ++#define et_ecc_4bit 0x02 ++#define et_ecc_8bit 0x03 ++#define et_ecc_24bit1k 0x04 ++#define et_ecc_40bit1k 0x05 ++#define et_ecc_64bit1k 0x06 ++ ++static struct match_reg_type ecc_yaffs_type_t[] = { ++ {et_ecc_none, NAND_ECC_0BIT}, ++ {et_ecc_4bit, NAND_ECC_8BIT}, ++ {et_ecc_8bit, NAND_ECC_16BIT}, ++ {et_ecc_24bit1k, NAND_ECC_24BIT}, ++ {et_ecc_40bit1k, NAND_ECC_40BIT}, ++ {et_ecc_64bit1k, NAND_ECC_64BIT} ++}; ++ ++unsigned char match_ecc_type_to_yaffs(unsigned char type) ++{ ++ return type2reg(ecc_yaffs_type_t, ARRAY_SIZE(ecc_yaffs_type_t), type, ++ et_ecc_4bit); ++} ++ ++/*****************************************************************************/ ++static struct match_t page_table[] = { ++ {NAND_PAGE_2K, PAGE_SIZE_2KB, "2K"}, ++ {NAND_PAGE_4K, PAGE_SIZE_4KB, "4K"}, ++ {NAND_PAGE_8K, PAGE_SIZE_8KB, "8K"}, ++ {NAND_PAGE_16K, PAGE_SIZE_16KB, "16K"}, ++}; ++ ++unsigned char match_page_reg_to_type(unsigned char reg) ++{ ++ return match_reg_to_type(page_table, ARRAY_SIZE(page_table), reg, ++ NAND_PAGE_2K); ++} ++ ++unsigned char match_page_type_to_reg(unsigned char type) ++{ ++ return match_type_to_reg(page_table, ARRAY_SIZE(page_table), type, ++ PAGE_SIZE_2KB); ++} ++ ++const char *match_page_type_to_str(unsigned char type) ++{ ++ return match_type_to_data(page_table, ARRAY_SIZE(page_table), type, ++ "unknown"); ++} ++ ++/*****************************************************************************/ ++static struct match_t ecc_table[] = { ++ {NAND_ECC_0BIT, ECC_TYPE_0BIT, "none"}, ++ {NAND_ECC_8BIT, ECC_TYPE_8BIT, "4bit/512"}, ++ {NAND_ECC_16BIT, ECC_TYPE_16BIT, "8bit/512"}, ++ {NAND_ECC_24BIT, ECC_TYPE_24BIT, "24bit/1K"}, ++ {NAND_ECC_28BIT, ECC_TYPE_28BIT, "28bit/1K"}, ++ {NAND_ECC_40BIT, ECC_TYPE_40BIT, "40bit/1K"}, ++ {NAND_ECC_64BIT, ECC_TYPE_64BIT, "64bit/1K"}, ++}; ++ ++unsigned char match_ecc_reg_to_type(unsigned char reg) ++{ ++ return match_reg_to_type(ecc_table, ARRAY_SIZE(ecc_table), reg, ++ NAND_ECC_8BIT); ++} ++ ++unsigned char match_ecc_type_to_reg(unsigned char type) ++{ ++ return match_type_to_reg(ecc_table, ARRAY_SIZE(ecc_table), type, ++ ECC_TYPE_8BIT); ++} ++ ++const char *match_ecc_type_to_str(unsigned char type) ++{ ++ return match_type_to_data(ecc_table, ARRAY_SIZE(ecc_table), type, ++ "unknown"); ++} ++ ++/*****************************************************************************/ ++static struct match_t page_type_size_table[] = { ++ {NAND_PAGE_2K, _2K, NULL}, ++ {NAND_PAGE_4K, _4K, NULL}, ++ {NAND_PAGE_8K, _8K, NULL}, ++ {NAND_PAGE_16K, _16K, NULL}, ++}; ++ ++unsigned char match_page_size_to_type(unsigned int size) ++{ ++ return match_reg_to_type(page_type_size_table, ++ ARRAY_SIZE(page_type_size_table), size, NAND_PAGE_2K); ++} ++ ++unsigned int match_page_type_to_size(unsigned char type) ++{ ++ return match_type_to_reg(page_type_size_table, ++ ARRAY_SIZE(page_type_size_table), type, _2K); ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_gen.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_gen.h.patch new file mode 100644 index 00000000..f2debfe8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_gen.h.patch @@ -0,0 +1,283 @@ +--- linux-4.9.37/drivers/mtd/nand/nfc_gen.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/nfc_gen.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,280 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __NFC_GEN_H__ ++#define __NFC_GEN_H__ ++ ++/*****************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++ ++/*****************************************************************************/ ++#define NFC_VER_300 (0x300) ++#define NFC_VER_301 (0x301) ++#define NFC_VER_310 (0x310) ++#define NFC_VER_504 (0x504) ++#define NFC_VER_505 (0x505) ++#define NFC_VER_600 (0x600) ++#define NFC_VER_610 (0x610) ++#define NFC_VER_620 (0x620) ++ ++#define SNFC_VER_100 (0x400) ++ ++/*****************************************************************************/ ++#define NAND_PAGE_512B 0 ++#define NAND_PAGE_1K 1 ++#define NAND_PAGE_2K 2 ++#define NAND_PAGE_4K 3 ++#define NAND_PAGE_8K 4 ++#define NAND_PAGE_16K 5 ++#define NAND_PAGE_32K 6 ++ ++/*****************************************************************************/ ++#define NAND_ECC_NONE 0 ++#define NAND_ECC_0BIT 0 ++#define NAND_ECC_1BIT 1 ++#define NAND_ECC_1BIT_512 1 ++#define NAND_ECC_4BIT 2 ++#define NAND_ECC_4BIT_512 2 ++#define NAND_ECC_4BYTE 2 ++#define NAND_ECC_8BIT 2 ++#define NAND_ECC_8BIT_512 3 ++#define NAND_ECC_8BYTE 3 ++#define NAND_ECC_13BIT 4 ++#define NAND_ECC_16BIT 5 ++#define NAND_ECC_18BIT 6 ++#define NAND_ECC_24BIT 7 ++#define NAND_ECC_27BIT 8 ++#define NAND_ECC_28BIT 9 ++#define NAND_ECC_32BIT 10 ++#define NAND_ECC_40BIT 11 ++#define NAND_ECC_41BIT 12 ++#define NAND_ECC_42BIT 13 ++#define NAND_ECC_48BIT 14 ++#define NAND_ECC_60BIT 15 ++#define NAND_ECC_64BIT 16 ++#define NAND_ECC_72BIT 17 ++#define NAND_ECC_80BIT 18 ++ ++enum ecc_type { ++ et_ecc_none = 0x00, ++ et_ecc_1bit = 0x01, ++ et_ecc_4bit = 0x02, ++ et_ecc_8bit = 0x03, ++ et_ecc_24bit1k = 0x04, ++ et_ecc_40bit1k = 0x05, ++ et_ecc_64bit1k = 0x06, ++}; ++ ++enum page_type { ++ pt_pagesize_512 = 0x00, ++ pt_pagesize_2K = 0x01, ++ pt_pagesize_4K = 0x02, ++ pt_pagesize_8K = 0x03, ++ pt_pagesize_16K = 0x04, ++}; ++ ++/*****************************************************************************/ ++struct nand_config_info { ++ unsigned int pagetype; ++ unsigned int ecctype; ++ unsigned int ecc_strength; ++ unsigned int oobsize; ++ struct mtd_ooblayout_ops *ooblayout_ops; ++}; ++ ++struct nfc_host; ++ ++struct nand_sync { ++ ++#define SET_NAND_SYNC_TYPE(_mfr, _onfi, _version) \ ++ ((((_mfr) & 0xFF) << 16) | (((_version) & 0xFF) << 8) \ ++ | ((_onfi) & 0xFF)) ++ ++#define GET_NAND_SYNC_TYPE_MFR(_type) (((_type) >> 16) & 0xFF) ++#define GET_NAND_SYNC_TYPE_VER(_type) (((_type) >> 8) & 0xFF) ++#define GET_NAND_SYNC_TYPE_INF(_type) ((_type) & 0xFF) ++ ++#define NAND_TYPE_ONFI_23_MICRON \ ++ SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x23) ++#define NAND_TYPE_ONFI_30_MICRON \ ++ SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x30) ++#define NAND_TYPE_TOGGLE_TOSHIBA \ ++ SET_NAND_SYNC_TYPE(NAND_MFR_TOSHIBA, 0, 0) ++#define NAND_TYPE_TOGGLE_SAMSUNG \ ++ SET_NAND_SYNC_TYPE(NAND_MFR_SAMSUNG, 0, 0) ++ ++#define NAND_TYPE_TOGGLE_10 SET_NAND_SYNC_TYPE(0, 0, 0x10) ++#define NAND_TYPE_ONFI_30 SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x30) ++#define NAND_TYPE_ONFI_23 SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x23) ++ ++ int type; ++ int (*enable)(struct nand_chip *chip); ++ int (*disable)(struct nand_chip *chip); ++}; ++ ++struct read_retry_t { ++ int type; ++ int count; ++ int (*set_rr_param)(struct nfc_host *host, int param); ++ int (*get_rr_param)(struct nfc_host *host); ++ int (*reset_rr_param)(struct nfc_host *host); ++}; ++ ++struct ecc_info_t { ++ int pagesize; ++ int ecctype; ++ int threshold; ++ int section; ++ void (*dump)(struct nfc_host *host, unsigned char ecc[], ++ int *max_bitsflag); ++}; ++ ++struct nand_dev_t { ++ struct nand_flash_dev flash_dev; ++ ++ char *start_type; ++ unsigned char ids[8]; ++ int oobsize; ++ int ecctype; ++ ++ /* (Controller) support ecc/page detect, driver don't need detect */ ++#define NANDC_HW_AUTO 0x01 ++ /* (Controller) support ecc/page detect, ++ * and current ecc/page config finish */ ++#define NANDC_CONFIG_DONE 0x02 ++ /* (Controller) is sync, default is async */ ++#define NANDC_IS_SYNC_BOOT 0x04 ++ ++ /* (NAND) need randomizer */ ++#define NAND_RANDOMIZER 0x10 ++ /* (NAND) is ONFI interface, combine with sync/async symble */ ++#define NAND_IS_ONFI 0x20 ++ /* (NAND) support async and sync, such micron onfi, toshiba toggle 1.0 */ ++#define NAND_MODE_SYNC_ASYNC 0x40 ++ /* (NAND) support only sync, such samsung sync. */ ++#define NAND_MODE_ONLY_SYNC 0x80 ++ ++#define NAND_CHIP_MICRON (NAND_MODE_SYNC_ASYNC | NAND_IS_ONFI) ++ /* This NAND is async, or sync/async, default is async mode, ++ * toggle1.0 interface */ ++#define NAND_CHIP_TOSHIBA_TOGGLE_10 (NAND_MODE_SYNC_ASYNC) ++ /* This NAND is only sync mode, toggle2.0 interface */ ++#define NAND_CHIP_TOSHIBA_TOGGLE_20 (NAND_MODE_ONLY_SYNC) ++ /* This NAND is only sync mode */ ++#define NAND_CHIP_SAMSUNG (NAND_MODE_ONLY_SYNC) ++ ++ unsigned int flags; ++ ++#define NAND_RR_NONE 0x00 ++#define NAND_RR_HYNIX_BG_BDIE 0x10 ++#define NAND_RR_HYNIX_BG_CDIE 0x11 ++#define NAND_RR_HYNIX_CG_ADIE 0x12 ++#define NAND_RR_MICRON 0x20 ++#define NAND_RR_SAMSUNG 0x30 ++#define NAND_RR_TOSHIBA_24nm 0x40 ++#define NAND_RR_TOSHIBA_19nm 0x41 ++ int read_retry_type; ++}; ++ ++/*****************************************************************************/ ++ ++#define IS_NANDC_HW_AUTO(_host) ((_host)->flags & NANDC_HW_AUTO) ++#define IS_NANDC_CONFIG_DONE(_host) ((_host)->flags & NANDC_CONFIG_DONE) ++#define IS_NANDC_SYNC_BOOT(_host) ((_host)->flags & NANDC_IS_SYNC_BOOT) ++ ++#define IS_NAND_RANDOM(_dev) ((_dev)->flags & NAND_RANDOMIZER) ++#define IS_NAND_ONLY_SYNC(_dev) ((_dev)->flags & NAND_MODE_ONLY_SYNC) ++#define IS_NAND_SYNC_ASYNC(_dev) ((_dev)->flags & NAND_MODE_SYNC_ASYNC) ++#define IS_NAND_ONFI(_dev) ((_dev)->flags & NAND_IS_ONFI) ++ ++#define ERSTR_HARDWARE "Hardware configuration error. " ++#define ERSTR_DRIVER "Driver does not support. " ++ ++#define ENABLE 1 ++#define DISABLE 0 ++ ++/*****************************************************************************/ ++ ++char *get_ecctype_str(enum ecc_type ecctype); ++ ++char *get_pagesize_str(enum page_type pagetype); ++ ++unsigned int get_pagesize(enum page_type pagetype); ++ ++const char *nand_ecc_name(int type); ++ ++const char *nand_page_name(int type); ++ ++int nandpage_size2type(int size); ++ ++int nandpage_type2size(int size); ++ ++/*****************************************************************************/ ++extern int (*nfc_param_adjust)(struct mtd_info *mtd, struct nand_chip *chip, ++ struct nand_dev_t *nand_dev); ++ ++extern struct nand_flash_dev *(*nand_get_flash_type_func)(struct mtd_info *mtd, ++ struct nand_chip *chip, struct nand_dev_t *spinand_dev_t); ++ ++extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook) ++(struct mtd_info *mtd, unsigned char *id); ++ ++extern int (*nfc_param_adjust)(struct mtd_info *, ++ struct nand_chip *, struct nand_dev_t *); ++ ++/*****************************************************************************/ ++struct nand_flash_dev *nfc_get_flash_type(struct mtd_info *mtd, ++ struct nand_chip *chip, u8 *id_data, int *busw); ++ ++extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook) ++(struct mtd_info *mtd, unsigned char *id); ++ ++void nfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip); ++ ++void nfc_show_info(struct mtd_info *mtd, char *goke, char *chipname); ++ ++void nfc_show_chipsize(struct nand_chip *chip); ++ ++int get_bits(unsigned int n); ++ ++/*****************************************************************************/ ++#define nfc_pr_msg(_fmt, arg...) printk(_fmt, ##arg) ++ ++#define nfc_pr_bug(fmt, args...) do { \ ++ printk("%s(%d): bug " fmt, __FILE__, __LINE__, ##args); \ ++ while (1) \ ++ ; \ ++} while (0) ++ ++#define PR_MSG(_fmt, arg...) \ ++ printk(_fmt, ##arg) ++ ++extern char *nand_dbgfs_options; ++/*****************************************************************************/ ++extern unsigned char match_page_reg_to_type(unsigned char reg); ++ ++extern unsigned char match_page_type_to_reg(unsigned char type); ++ ++extern const char *match_page_type_to_str(unsigned char type); ++ ++/*****************************************************************************/ ++extern unsigned char match_ecc_reg_to_type(unsigned char reg); ++ ++extern unsigned char match_ecc_type_to_reg(unsigned char type); ++ ++extern const char *match_ecc_type_to_str(unsigned char type); ++ ++/*****************************************************************************/ ++extern unsigned char match_page_size_to_type(unsigned int size); ++ ++extern unsigned int match_page_type_to_size(unsigned char type); ++ ++const char *nand_ecc_name(int type); ++/*****************************************************************************/ ++ ++#endif /* End of __NFC_GEN_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_spl_ids.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_spl_ids.c.patch new file mode 100644 index 00000000..27cb8198 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-nand-nfc_spl_ids.c.patch @@ -0,0 +1,969 @@ +--- linux-4.9.37/drivers/mtd/nand/nfc_spl_ids.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/nand/nfc_spl_ids.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,966 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include "nfc_gen.h" ++ ++/*****************************************************************************/ ++ ++struct nand_flash_special_dev { ++ unsigned char id[8]; ++ int length; /* length of id. */ ++ unsigned long long chipsize; ++ struct nand_flash_dev *(*probe)(struct nand_dev_t *nand_dev); ++ char *name; ++ ++ unsigned long pagesize; ++ unsigned long erasesize; ++ unsigned long oobsize; ++ unsigned long options; ++ unsigned int read_retry_type; ++ ++#define BBP_LAST_PAGE 0x01 ++#define BBP_FIRST_PAGE 0x02 ++ unsigned int badblock_pos; ++ unsigned int flags; ++}; ++ ++/*****************************************************************************/ ++/* this is nand probe function. */ ++/*****************************************************************************/ ++ ++static struct nand_flash_dev *hynix_probe_v02( ++ struct nand_dev_t *nand_dev) ++{ ++ unsigned char *id = nand_dev->ids; ++ struct nand_flash_dev *type = &nand_dev->flash_dev; ++ ++ int pagesizes[] = {SZ_2K, SZ_4K, SZ_8K, 0}; ++ int oobsizes[] = {128, 224, 448, 0, 0, 0, 0, 0}; ++ int blocksizes[] = {SZ_128K, SZ_256K, SZ_512K, ++ (SZ_256K + SZ_512K), SZ_1M, SZ_2M, 0, 0 ++ }; ++ ++ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); ++ int oobtype = (((id[3] >> 2) & 0x03) | ((id[3] >> 4) & 0x04)); ++ ++ type->options = 0; ++ type->pagesize = pagesizes[(id[3] & 0x03)]; ++ type->erasesize = blocksizes[blocktype]; ++ nand_dev->oobsize = oobsizes[oobtype]; ++ ++ return type; ++} ++/*****************************************************************************/ ++ ++static struct nand_flash_dev *samsung_probe_v02( ++ struct nand_dev_t *nand_dev) ++{ ++ unsigned char *id = nand_dev->ids; ++ struct nand_flash_dev *type = &nand_dev->flash_dev; ++ ++ int pagesizes[] = {SZ_2K, SZ_4K, SZ_8K, 0}; ++ int oobsizes[] = {0, 128, 218, 400, 436, 0, 0, 0}; ++ int blocksizes[] = {SZ_128K, SZ_256K, SZ_512K, SZ_1M, 0, 0, 0, 0}; ++ ++ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); ++ int oobtype = (((id[3] >> 4) & 0x04) | ((id[3] >> 2) & 0x03)); ++ ++ type->options = 0; ++ type->pagesize = pagesizes[(id[3] & 0x03)]; ++ type->erasesize = blocksizes[blocktype]; ++ nand_dev->oobsize = oobsizes[oobtype]; ++ ++ return type; ++} ++/*****************************************************************************/ ++ ++#define DRV_VERSION "1.38" ++ ++/*****************************************************************************/ ++/* ++ * samsung: 27nm need randomizer, 21nm need read retry; ++ * micron: 25nm need read retry, datasheet will explain read retry. ++ * toshaba 32nm need randomizer, 24nm need read retry. ++ * hynix: 2xnm need read retry. ++ * ++ * The special nand flash ID table version 1.37 ++ * ++ * manufactory | type | name | ecc_type | version_tag ++ * Micron | MLC | MT29F64G08CBABA | 40bit/1k | 1.36 ++ * Micron | MLC | MT29F32G08CBADA | 40bit/1k | ++ * Micron | SLC | MT29F8G08ABxBA | 4bit/512 | ++ * Micron | MLC | MT29F16G08CBABx | 12bit/512 | ++ * Micron | MLC | MT29F16G08CBACA | 24bit/1k | ++ * Micron | MLC | MT29F32G08CBACA | 24bit/1k | ++ * Micron | MLC | MT29F64G08CxxAA | 24bit/1k | ++ * Micron | MLC | MT29F256G08CJAAA | 24bit/1k | 2CE ++ * Micron | MLC | MT29F256G08CMCBB | 24bit/1k | ++ * Micron | SLC | MT29F8G08ABACA | 8bit/512 | ++ * Micron | SLC | MT29F4G08ABAEA | 8bit/512 | ++ * Micron | SLC | MT29F2G08ABAFA | 8bit/512 | ++ * Micron | SLC | MT29F16G08ABACA | 8bit/512 | ++ * Toshiba | MLC | TC58NVG4D2FTA00 | 24bit/1k | ++ * Toshiba | MLC | TH58NVG6D2FTA20 | 24bit/1k | 2CE ++ * Toshiba | MLC | TC58NVG5D2HTA00 | 40bit/1k | ++ * Toshiba | MLC | TC58NVG6D2GTA00 | 40bit/1k | ++ * Toshiba | MLC | TC58NVG6DCJTA00 | | ++ * Toshiba | MLC | TC58TEG5DCJTA00 | | ++ * Toshiba | SLC | TC58NVG0S3HTA00 | 8bit/512 | ++ * Toshiba | SLC | TC58NVG1S3HTA00 | 8bit/512 | ++ * Toshiba | SLC | TC58NVG1S3ETA00 | 4bit/512 | ++ * Toshiba | SLC | TC58NVG3S0FTA00 | 4bit/512 | ++ * Toshiba | SLC | TC58NVG2S0FTA00 | 4bit/512 | ++ * Toshiba | SLC | TH58NVG2S3HTA00 | 4bit/512 | ++ * Toshiba | TLC | TC58NVG5T2JTA00 | 60bit/1k | ++ * Toshiba | TLC | TC58TEG5DCKTAx0 | 60bit/1k | ++ * Toshiba | MLC | Tx58TEGxDDKTAx0 | | ++ * Samsung | MLC | K9LB(HC/PD/MD)G08U0(1)D | 8bit/512B | ++ * Samsung | MLC | K9GAG08U0E | 24bit/1KB | ++ * Samsung | MLC | K9LBG08U0E | 24bit/1KB | ++ * Samsung | MLC | K9G8G08U0C | 24bit/1KB | ++ * Samsung | MLC | K9GAG08U0F | 24bit/1KB | ++ * Samsung | MLC | K9LBG08U0M | | ++ * Samsung | MLC | K9GBG08U0A | 24bit/1KB | ++ * Samsung | MLC | K9GBG08U0B | 40bit/1KB | ++ * Hynix | MLC | H27UAG8T2A | | ++ * Hynix | MLC | H27UAG8T2B | | ++ * Hynix | MLC | H27UBG8T2A | | ++ * Hynix | MLC | H27UBG8T2BTR | 24bit/1KB | ++ * Hynix | MLC | H27UCG8T2A | 40bit/1KB | ++ * Hynix | MLC | H27UBG8T2C | 40bit/1KB | ++ * MISC | MLC | P1UAGA30AT-GCA | 8bit/512 | ++ * MISC | MLC | PSU8GA30AT-GIA/ASU8GA30IT-G30CA | 4bit/512 | ++ * MISC | SLC | PSU2GA30AT | 1bit/512 | 1.36 ++ * Toshiba | SLC | TC58NVG2S0HTA00 | 24bit/1K | 1.37 ++ * Toshiba | SLC | TC58NVG3S0HTA00 | 24bit/1K | 1.37 ++ * Micron | SLC | MT29F2G08ABAEA | 4bit/512 | ++ * Spansion | SLC | S34ML02G200TFI000 | 24bit/1K | ++ * Spansion | SLC | S34ML04G200TFI000 | 24bit/1K | 1.38 ++ * ++ */ ++ ++static struct nand_flash_special_dev nand_flash_special_dev[] = { ++ ++ /****************************** Spansion *******************************/ ++ ++ { /* SLC S34ML02G200TFI000 */ ++ .name = "S34ML02G200TFI000", ++ .id = {0x01, 0xDA, 0x90, 0x95, 0x46, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = _256M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 128, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ ++ { /* SLC S34ML04G200TFI000 */ ++ .name = "S34ML04G200TFI000", ++ .id = {0x01, 0xDC, 0x90, 0x95, 0x56, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = _512M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 128, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ ++ /****************************** Micron *******************************/ ++ { /* MLC 40bit/1k */ ++ .name = "MT29F64G08CBABA", ++ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = _8G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 744, ++ .options = 0, ++ .read_retry_type = NAND_RR_MICRON, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = NAND_RANDOMIZER | NAND_CHIP_MICRON, ++ }, ++ { /* MLC 40bit/1k */ ++ .name = "MT29F32G08CBADA", ++ .id = {0x2C, 0x44, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 744, ++ .options = 0, ++ .read_retry_type = NAND_RR_MICRON, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { /* SLC 4bit/512 */ ++ .name = "MT29F8G08ABxBA", ++ .id = {0x2C, 0x38, 0x00, 0x26, 0x85, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = SZ_1G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_512K, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 12bit/512 */ ++ .name = "MT29F16G08CBABx", ++ .id = {0x2C, 0x48, 0x04, 0x46, 0x85, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = SZ_2G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_1M, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1k */ ++ .name = "MT29F16G08CBACA", ++ .id = {0x2C, 0x48, 0x04, 0x4A, 0xA5, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = SZ_2G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_1M, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1k */ ++ .name = "MT29F32G08CBACA", ++ .id = {0x2C, 0x68, 0x04, 0x4A, 0xA9, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_1M, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1k */ ++ .name = "MT29F64G08CxxAA", ++ .id = {0x2C, 0x88, 0x04, 0x4B, 0xA9, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = _8G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 448, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1k 2CE */ ++ .name = "MT29F256G08CJAAA", ++ .id = {0x2C, 0xA8, 0x05, 0xCB, 0xA9, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = _16G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 448, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 40bit/1k */ ++ .name = "MT29F256G08CMCBB", ++ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, ++ .length = 8, ++ .chipsize = _8G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 744, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 8bit/512 */ ++ .name = "MT29F8G08ABACA", ++ .id = {0x2C, 0xD3, 0x90, 0xA6, 0x64, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = SZ_1G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_256K, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 8bit/512 */ ++ .name = "MT29F4G08ABAEA", ++ .id = {0x2C, 0xDC, 0x90, 0xA6, 0x54, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = SZ_512M, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_256K, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 8bit/512 */ ++ .name = "MT29F2G08ABAFA", ++ .id = {0x2C, 0xDA, 0x90, 0x95, 0x04, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = SZ_256M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC MT29F2G08ABAEA */ ++ .name = "MT29F2G08ABAEA", ++ .id = {0x2C, 0xDA, 0x90, 0x95, 0x06, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = _256M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 64, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 8bit/512 */ ++ .name = "MT29F16G08ABACA", ++ .id = {0x2C, 0x48, 0x00, 0x26, 0xA9, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = SZ_2G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_512K, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ ++ /****************************** Toshaba *******************************/ ++ ++ { /* MLC 24bit/1k 32nm */ ++ .name = "TC58NVG4D2FTA00", ++ .id = {0x98, 0xD5, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = SZ_2G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_1M, ++ .oobsize = 448, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1k 32nm 2CE*/ ++ .name = "TH58NVG6D2FTA20", ++ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_1M, ++ .oobsize = 448, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 40bit/1k 24nm */ ++ .name = "TC58NVG5D2HTA00 24nm", ++ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x56, 0x08, 0x00}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_1M, ++ .oobsize = 640, ++ .options = 0, ++ .read_retry_type = NAND_RR_TOSHIBA_24nm, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { /* MLC 40bit/1k */ ++ .name = "TC58NVG6D2GTA00", ++ .id = {0x98, 0xDE, 0x94, 0x82, 0x76, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = _8G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 640, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 19nm */ ++ .name = "TC58NVG6DCJTA00 19nm", ++ .id = {0x98, 0xDE, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, ++ .length = 8, ++ .chipsize = _8G, ++ .probe = NULL, ++ .pagesize = SZ_16K, ++ .erasesize = SZ_4M, ++ .oobsize = 1280, ++ .options = 0, ++ .read_retry_type = NAND_RR_TOSHIBA_24nm, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { /* MLC 19nm */ ++ .name = "TC58TEG5DCJTA00 19nm", ++ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_16K, ++ .erasesize = SZ_4M, ++ .oobsize = 1280, ++ .options = 0, ++ .read_retry_type = NAND_RR_TOSHIBA_24nm, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER | NAND_CHIP_TOSHIBA_TOGGLE_10, ++ }, ++ { /* SLC 8bit/512 */ ++ .name = "TC58NVG0S3HTA00", ++ .id = {0x98, 0xF1, 0x80, 0x15, 0x72, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = SZ_128M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 128, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ /* ++ * Datasheet: read one column of any page in each block. If the ++ * data of the column is 00 (Hex), define the block as a bad ++ * block. ++ */ ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 8bit/512 */ ++ .name = "TC58NVG1S3HTA00", ++ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x16, 0x08, 0x00}, ++ .length = 7, ++ .chipsize = SZ_256M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 128, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 4bit/512 */ ++ .name = "TC58NVG1S3ETA00", ++ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x14, 0x03, 0x00}, ++ .length = 7, ++ .chipsize = SZ_256M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 64, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 4bit/512 */ ++ .name = "TC58NVG3S0FTA00", ++ .id = {0x98, 0xD3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08}, ++ .length = 8, ++ .chipsize = SZ_1G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_256K, ++ .oobsize = 232, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 4bit/512 */ ++ .name = "TC58NVG3S0HTA00", ++ .id = {0x98, 0xD3, 0x91, 0x26, 0x76, 0x16, 0x08, 0x00}, ++ .length = 8, ++ .chipsize = SZ_1G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_256K, ++ .oobsize = 256, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 24bit/1k */ ++ .name = "TC58NVG2S0HTA00", ++ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00}, ++ .length = 8, ++ .chipsize = SZ_512M, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_256K, ++ .oobsize = 256, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 4bit/512 */ ++ .name = "TC58NVG2S0FTA00", ++ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08}, ++ .length = 8, ++ .chipsize = SZ_512M, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_256K, ++ .oobsize = 224, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 4bit/512 */ ++ .name = "TH58NVG2S3HTA00", ++ .id = {0x98, 0xDC, 0x91, 0x15, 0x76}, ++ .length = 5, ++ .chipsize = SZ_512M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 128, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE, ++ .flags = 0, ++ }, ++ { /* TLC 60bit/1k 19nm */ ++ .name = "TC58NVG5T2JTA00 19nm TLC", ++ .id = {0x98, 0xD7, 0x98, 0x92, 0x72, 0x57, 0x08, 0x10}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_4M, ++ .oobsize = 1024, ++ .options = 0, ++ .read_retry_type = NAND_RR_TOSHIBA_24nm, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { /* TLC 60bit/1k 19nm */ ++ .name = "TC58TEG5DCKTAx0 19nm MLC", ++ /* datasheet says 6 ids id data, but really has 8 ids. */ ++ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x50, 0x08, 0x04}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_16K, ++ .erasesize = SZ_4M, ++ .oobsize = 1280, ++ .options = 0, ++ .read_retry_type = NAND_RR_TOSHIBA_19nm, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { ++ .name = "Tx58TEGxDDKTAx0 19nm MLC", ++ .id = {0x98, 0xDE, 0x94, 0x93, 0x76, 0x50}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_16K, ++ .erasesize = SZ_4M, ++ .oobsize = 1280, ++ .options = 0, ++ .read_retry_type = NAND_RR_TOSHIBA_19nm, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ /******************************* Samsung ******************************/ ++ { /* MLC 8bit/512B */ ++ .name = "K9LB(HC/PD/MD)G08U0(1)D", ++ .id = {0xEC, 0xD7, 0xD5, 0x29, 0x38, 0x41, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = samsung_probe_v02, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1KB */ ++ .name = "K9GAG08U0E", ++ .id = {0xEC, 0xD5, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = SZ_2G, ++ .probe = samsung_probe_v02, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1KB */ ++ .name = "K9LBG08U0E", ++ .id = {0xEC, 0xD7, 0xC5, 0x72, 0x54, 0x42, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = samsung_probe_v02, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1KB */ ++ .name = "K9G8G08U0C", ++ .id = {0xEC, 0xD3, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = SZ_1G, ++ .probe = samsung_probe_v02, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1k */ ++ .name = "K9GAG08U0F", ++ .id = {0xEC, 0xD5, 0x94, 0x76, 0x54, 0x43, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = SZ_2G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_1M, ++ .oobsize = 512, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC */ ++ .name = "K9LBG08U0M", ++ .id = {0xEC, 0xD7, 0x55, 0xB6, 0x78, 0x00, 0x00, 0x00}, ++ .length = 5, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_512K, ++ .oobsize = 128, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1k */ ++ .name = "K9GBG08U0A 20nm", ++ .id = {0xEC, 0xD7, 0x94, 0x7A, 0x54, 0x43, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_1M, ++ .oobsize = 640, ++ .options = 0, ++ .read_retry_type = NAND_RR_SAMSUNG, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { /* MLC 40bit/1k */ ++ .name = "K9GBG08U0B", ++ .id = {0xEC, 0xD7, 0x94, 0x7E, 0x64, 0x44, 0x00, 0x00}, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_1M, ++ .oobsize = 1024, ++ .options = 0, ++ .read_retry_type = NAND_RR_SAMSUNG, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ ++ /*********************************** Hynix ****************************/ ++ { /* MLC */ ++ .name = "H27UAG8T2A", ++ .id = {0xAD, 0xD5, 0x94, 0x25, 0x44, 0x41, }, ++ .length = 6, ++ .chipsize = SZ_2G, ++ .probe = hynix_probe_v02, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC */ ++ .name = "H27UAG8T2B", ++ .id = {0xAD, 0xD5, 0x94, 0x9A, 0x74, 0x42, }, ++ .length = 6, ++ .chipsize = SZ_2G, ++ .probe = hynix_probe_v02, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC */ ++ .name = "H27UBG8T2A", ++ .id = {0xAD, 0xD7, 0x94, 0x9A, 0x74, 0x42, }, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = hynix_probe_v02, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 24bit/1K, 26nm TODO: Need read retry, chip is EOS */ ++ .name = "H27UBG8T2BTR 26nm", ++ .id = {0xAD, 0xD7, 0x94, 0xDA, 0x74, 0xC3, }, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 640, ++ .options = 0, ++ .read_retry_type = NAND_RR_HYNIX_BG_BDIE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { /* MLC 40bit/1k */ ++ .name = "H27UCG8T2A", ++ .id = {0xAD, 0xDE, 0x94, 0xDA, 0x74, 0xC4, }, ++ .length = 6, ++ .chipsize = _8G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 640, ++ .options = 0, ++ .read_retry_type = NAND_RR_HYNIX_CG_ADIE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ { /* MLC 40bit/1k */ ++ .name = "H27UBG8T2C", ++ .id = {0xAD, 0xD7, 0x94, 0x91, 0x60, 0x44, }, ++ .length = 6, ++ .chipsize = _4G, ++ .probe = NULL, ++ .pagesize = SZ_8K, ++ .erasesize = SZ_2M, ++ .oobsize = 640, ++ .options = 0, ++ .read_retry_type = NAND_RR_HYNIX_BG_CDIE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = NAND_RANDOMIZER, ++ }, ++ ++ /********************** MISC ******************************************/ ++ { /* MLC 8bit/512 */ ++ .name = "P1UAGA30AT-GCA", ++ .id = {0xC8, 0xD5, 0x14, 0x29, 0x34, 0x01, }, ++ .length = 6, ++ .chipsize = SZ_2G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_512K, ++ .oobsize = 218, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* MLC 4bit/512 */ ++ /* ++ * PowerFlash ASU8GA30IT-G30CA ID and MIRA PSU8GA30AT-GIA ID are ++ * the same ID ++ */ ++ .name = "PSU8GA30AT-GIA/ASU8GA30IT-G30CA", ++ .id = {0xC8, 0xD3, 0x90, 0x19, 0x34, 0x01, }, ++ .length = 6, ++ .chipsize = SZ_1G, ++ .probe = NULL, ++ .pagesize = SZ_4K, ++ .erasesize = SZ_256K, ++ .oobsize = 218, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ { /* SLC 1bit/512 */ ++ .name = "PSU2GA30AT", ++ .id = {0x7F, 0x7F, 0x7F, 0x7F, 0xC8, 0xDA, 0x00, 0x15, }, ++ .length = 8, ++ .chipsize = SZ_256M, ++ .probe = NULL, ++ .pagesize = SZ_2K, ++ .erasesize = SZ_128K, ++ .oobsize = 64, ++ .options = 0, ++ .read_retry_type = NAND_RR_NONE, ++ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, ++ .flags = 0, ++ }, ++ {{0}, 0, 0, 0, 0, 0, 0, 0, 0}, ++}; ++ ++#define NUM_OF_SPECIAL_DEVICE \ ++ (sizeof(nand_flash_special_dev)/sizeof(struct nand_flash_special_dev)) ++ ++int (*nfc_param_adjust)(struct mtd_info *, struct nand_chip *, ++ struct nand_dev_t *) = NULL; ++ ++static struct nand_dev_t __nand_dev; ++/*****************************************************************************/ ++ ++static struct nand_flash_dev *nfc_nand_probe(struct mtd_info *mtd, ++ struct nand_chip *chip, ++ struct nand_dev_t *nand_dev) ++{ ++ struct nand_flash_special_dev *spl_dev = NULL; ++ unsigned char *byte = nand_dev->ids; ++ struct nand_flash_dev *type = &nand_dev->flash_dev; ++ ++ nfc_pr_msg("Nand ID: 0x%02X 0x%02X 0x%02X 0x%02X", ++ byte[0], byte[1], byte[2], byte[3]); ++ nfc_pr_msg(" 0x%02X 0x%02X 0x%02X 0x%02X\n", ++ byte[4], byte[5], byte[6], byte[7]); ++ ++ for (spl_dev = nand_flash_special_dev; spl_dev->length; spl_dev++) { ++ if (memcmp(byte, spl_dev->id, spl_dev->length)) ++ continue; ++ ++ nfc_pr_msg("The Special NAND id table Version: %s\n", DRV_VERSION); ++ ++ if (spl_dev->probe) { ++ type = spl_dev->probe(nand_dev); ++ } else { ++ type->options = spl_dev->options; ++ type->pagesize = spl_dev->pagesize; ++ type->erasesize = spl_dev->erasesize; ++ nand_dev->oobsize = spl_dev->oobsize; ++ } ++ ++ nand_dev->read_retry_type = spl_dev->read_retry_type; ++ nand_dev->flags = spl_dev->flags; ++ ++ type->id[1] = byte[1]; ++ type->chipsize = (unsigned long)(spl_dev->chipsize >> 20); ++ type->name = spl_dev->name; ++ return type; ++ } ++ nand_dev->read_retry_type = NAND_RR_NONE; ++ ++ return NULL; ++} ++/*****************************************************************************/ ++ ++struct nand_flash_dev *nfc_get_flash_type(struct mtd_info *mtd, ++ struct nand_chip *chip, ++ u8 *id_data, int *busw) ++{ ++ struct nand_flash_dev *type = NULL; ++ struct nand_dev_t *nand_dev = &__nand_dev; ++ ++ memset(nand_dev, 0, sizeof(struct nand_dev_t)); ++ memcpy(nand_dev->ids, id_data, 8); ++ ++ if (!nfc_nand_probe(mtd, chip, nand_dev)) ++ return NULL; ++ ++ type = &nand_dev->flash_dev; ++ ++ if (!mtd->name) ++ mtd->name = type->name; ++ ++ chip->chipsize = (uint64_t)type->chipsize << 20; ++ mtd->erasesize = type->erasesize; ++ mtd->writesize = type->pagesize; ++ mtd->oobsize = nand_dev->oobsize; ++ *busw = (type->options & NAND_BUSWIDTH_16); ++ ++ return type; ++} ++/*****************************************************************************/ ++ ++void nfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip) ++{ ++ struct nand_dev_t *nand_dev = &__nand_dev; ++ ++ if (!nand_dev->oobsize) ++ nand_dev->oobsize = mtd->oobsize; ++ ++ if (nfc_param_adjust) ++ nfc_param_adjust(mtd, chip, nand_dev); ++} ++/*****************************************************************************/ ++ ++void nfc_show_info(struct mtd_info *mtd, char *goke, char *chipname) ++{ ++ /* char buf[20]; */ ++ struct nand_dev_t *nand_dev = &__nand_dev; ++ ++ /* nfc_pr_msg("Nand: %s %s ", goke, chipname); */ ++ ++ if (IS_NAND_RANDOM(nand_dev)) ++ nfc_pr_msg("Randomizer \n"); ++ ++ if (nand_dev->read_retry_type != NAND_RR_NONE) ++ nfc_pr_msg("Read-Retry \n"); ++ ++ if (nand_dev->start_type) ++ nfc_pr_msg("Nand(%s): ", nand_dev->start_type); ++ else ++ nfc_pr_msg("Nand: "); ++ ++ nfc_pr_msg("OOB:%dB ", nand_dev->oobsize); ++ nfc_pr_msg("ECC:%s ", nand_ecc_name(nand_dev->ecctype)); ++} ++/*****************************************************************************/ ++ ++void nfc_show_chipsize(struct nand_chip *chip) ++{ ++ /*char buf[20];*/ ++ ++ /*nfc_pr_msg("Chip:%sB*%d\n", ++ ultohstr(chip->chipsize, buf, sizeof(buf)), ++ chip->numchips);*/ ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-Kconfig.patch new file mode 100644 index 00000000..e3cf345c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-Kconfig.patch @@ -0,0 +1,37 @@ +--- linux-4.9.37/drivers/mtd/spi-nor/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/spi-nor/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -65,6 +65,34 @@ + help + This enables support for hisilicon SPI-NOR flash controller. + ++config SPI_GOKE_SFC ++ tristate "Goke FMCV100 SPI-NOR Flash Controller(SFC)" ++ depends on ARCH_GOKE || ARCH_GOKE || COMPILE_TEST ++ depends on HAS_IOMEM && HAS_DMA ++ help ++ This enables support for goke flash memory contrller ver100 ++ (FMCV100)- SPI-NOR flash controller. ++ ++config CLOSE_SPI_8PIN_4IO ++ bool "Close SPI device Quad SPI mode for some 8PIN chip" ++ default y if ARCH_GOKE ++ help ++ fmcv100 and sfcv350 support Quad SPI mode and Quad&addr SPI mode. ++ But some 8PIN chip does not support this mode when HOLD/IO3 PIN ++ was used by reset operation. ++ Usually, your should not config this option. ++ ++config GOKE_SPI_BLOCK_PROTECT ++ bool "Goke Spi Nor Device BP(Block Protect) Support" ++ depends on SPI_GOKE_SFC ++ default y if SPI_GOKE_SFC ++ help ++ GOKE SFC supports BP(Block Protect) feature to preestablish a series ++ area to avoid writing and erasing, except to reading. With this macro ++ definition we can get the BP info which was setted before. The ++ BOTTOM/TOP bit is setted to BOTTOM, it means the lock area starts ++ from 0 address. ++ + config SPI_NXP_SPIFI + tristate "NXP SPI Flash Interface (SPIFI)" + depends on OF && (ARCH_LPC18XX || COMPILE_TEST) diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-Makefile.patch new file mode 100644 index 00000000..7598f4de --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/mtd/spi-nor/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/spi-nor/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -2,6 +2,7 @@ + obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o + obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o + obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o ++obj-$(CONFIG_SPI_GOKE_SFC) += goke-sfc.o + obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o + obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o + obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-goke-sfc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-goke-sfc.c.patch new file mode 100644 index 00000000..928c9ef4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-goke-sfc.c.patch @@ -0,0 +1,595 @@ +--- linux-4.9.37/drivers/mtd/spi-nor/goke-sfc.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/spi-nor/goke-sfc.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,592 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../mtdcore.h" ++ ++#define FMC_OP_DMA 0x68 ++ ++struct fmc_priv { ++ u32 chipselect; ++ u32 clkrate; ++ struct fmc_host *host; ++}; ++ ++struct fmc_host { ++ struct device *dev; ++ struct mutex *lock; ++ ++ void __iomem *regbase; ++ void __iomem *iobase; ++ struct clk *clk; ++ void *buffer; ++ dma_addr_t dma_buffer; ++ ++ struct spi_nor *nor[FMC_MAX_CHIP_NUM]; ++ struct fmc_priv priv[FMC_MAX_CHIP_NUM]; ++ u32 num_chip; ++ unsigned int dma_len; ++}; ++ ++/******************************************************************************/ ++static inline int wait_op_finish(struct fmc_host *host) ++{ ++ u32 reg; ++ ++ return readl_poll_timeout(host->regbase + FMC_INT, reg, ++ (reg & FMC_INT_OP_DONE), 0, FMC_WAIT_TIMEOUT); ++} ++ ++static int get_if_type(enum spi_nor_protocol mode) ++{ ++ enum fmc_iftype if_type; ++ ++ switch (mode) { ++ case SNOR_PROTO_1_1_2: ++ if_type = IF_TYPE_DUAL; ++ break; ++ case SNOR_PROTO_1_2_2: ++ if_type = IF_TYPE_DIO; ++ break; ++ case SNOR_PROTO_1_1_4: ++ if_type = IF_TYPE_QUAD; ++ break; ++ case SNOR_PROTO_1_4_4: ++ if_type = IF_TYPE_QIO; ++ break; ++ case SNOR_PROTO_1_1_1: ++ default: ++ if_type = IF_TYPE_STD; ++ break; ++ } ++ ++ return if_type; ++} ++ ++/******************************************************************************/ ++static void spi_nor_switch_spi_type(struct fmc_host *host) ++{ ++ unsigned int reg; ++ ++ reg = fmc_readl(host, FMC_CFG); ++ reg &= ~FLASH_TYPE_SEL_MASK; ++ reg |= FMC_CFG_FLASH_SEL(0); ++ fmc_writel(host, FMC_CFG, reg); ++} ++ ++/******************************************************************************/ ++static void bsp_spi_nor_init(struct fmc_host *host) ++{ ++ unsigned int reg; ++ ++ /* switch the flash type to spi nor */ ++ spi_nor_switch_spi_type(host); ++ ++ /* set the boot mode to normal */ ++ reg = fmc_readl(host, FMC_CFG); ++ if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) { ++ reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL); ++ fmc_writel(host, FMC_CFG, reg); ++ } ++ ++ /* hold on STR mode */ ++ reg = fmc_readl(host, FMC_GLOBAL_CFG); ++ reg &= (~FMC_GLOBAL_CFG_DTR_MODE); ++ fmc_writel(host, FMC_GLOBAL_CFG, reg); ++ ++ /* set timming */ ++ reg = TIMING_CFG_TCSH(CS_HOLD_TIME) ++ | TIMING_CFG_TCSS(CS_SETUP_TIME) ++ | TIMING_CFG_TSHSL(CS_DESELECT_TIME); ++ fmc_writel(host, FMC_SPI_TIMING_CFG, reg); ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_prep(struct spi_nor *nor, enum spi_nor_ops ops) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ u32 clkrate; ++ int ret; ++ ++ mutex_lock(&fmc_switch_mutex); ++ mutex_lock(host->lock); ++ ++ clkrate = min_t(u32, priv->clkrate, nor->clkrate); ++ ret = clk_set_rate(host->clk, clkrate); ++ if (ret) ++ goto out; ++ ++ ret = clk_prepare_enable(host->clk); ++ if (ret) ++ goto out; ++ ++ spi_nor_switch_spi_type(host); ++ ++ return 0; ++ ++out: ++ mutex_unlock(host->lock); ++ return ret; ++} ++ ++/******************************************************************************/ ++static void bsp_spi_nor_unprep(struct spi_nor *nor, enum spi_nor_ops ops) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ ++ clk_disable_unprepare(host->clk); ++ mutex_unlock(host->lock); ++ mutex_unlock(&fmc_switch_mutex); ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_op_reg(struct spi_nor *nor, ++ u8 opcode, u32 len, u8 optype) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ u32 reg; ++ ++ reg = FMC_CMD_CMD1(opcode); ++ fmc_writel(host, FMC_CMD, reg); ++ ++ reg = FMC_DATA_NUM_CNT(len); ++ fmc_writel(host, FMC_DATA_NUM, reg); ++ ++ reg = OP_CFG_FM_CS(priv->chipselect) | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ ++ fmc_writel(host, FMC_INT_CLR, 0xff); ++ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START | optype; ++ fmc_writel(host, FMC_OP, reg); ++ ++ return wait_op_finish(host); ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, ++ int len) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ int ret; ++ ++ ret = bsp_spi_nor_op_reg(nor, opcode, len, FMC_OP_READ_DATA_EN); ++ if (ret) ++ return ret; ++ ++ memcpy_fromio(buf, host->iobase, len); ++ return 0; ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_write_reg(struct spi_nor *nor, u8 opcode, ++ u8 *buf, int len) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ ++ if (len) ++ memcpy_toio(host->iobase, buf, len); ++ ++ return bsp_spi_nor_op_reg(nor, opcode, len, FMC_OP_WRITE_DATA_EN); ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_dma_transfer(struct spi_nor *nor, loff_t start_off, ++ dma_addr_t dma_buf, size_t len, u8 op_type) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ u8 if_type = 0, dummy = 0; ++ u32 reg; ++ ++ reg = fmc_readl(host, FMC_CFG); ++ reg &= ~(FMC_CFG_OP_MODE_MASK | SPI_NOR_ADDR_MODE_MASK); ++ reg |= FMC_CFG_OP_MODE_NORMAL; ++ reg |= (nor->addr_width == 4) ? SPI_NOR_ADDR_MODE_4BYTES ++ : SPI_NOR_ADDR_MODE_3BYTES; ++ fmc_writel(host, FMC_CFG, reg); ++ ++ fmc_writel(host, FMC_ADDRL, start_off); ++ ++ reg = (unsigned int)dma_buf; ++ fmc_writel(host, FMC_DMA_SADDR_D0, reg); ++ ++#ifdef CONFIG_64BIT ++ reg = (dma_buf & FMC_DMA_SADDRH_MASK) >> 32; ++ fmc_writel(host, FMC_DMA_SADDRH_D0, reg); ++#endif ++ ++ fmc_writel(host, FMC_DMA_LEN, FMC_DMA_LEN_SET(len)); ++ ++ reg = OP_CFG_FM_CS(priv->chipselect); ++ if (op_type == FMC_OP_READ) { ++ if_type = get_if_type(nor->read_proto); ++ dummy = nor->read_dummy >> 3; ++ } else { ++ if_type = get_if_type(nor->write_proto); ++ } ++ reg |= OP_CFG_MEM_IF_TYPE(if_type) ++ | OP_CFG_DUMMY_NUM(dummy) ++ | OP_CFG_OEN_EN; ++ fmc_writel(host, FMC_OP_CFG, reg); ++ ++ fmc_writel(host, FMC_INT_CLR, 0xff); ++ reg = OP_CTRL_RW_OP(op_type) | OP_CTRL_DMA_OP_READY; ++ reg |= (op_type == FMC_OP_READ) ++ ? OP_CTRL_RD_OPCODE(nor->read_opcode) ++ : OP_CTRL_WR_OPCODE(nor->program_opcode); ++ fmc_writel(host, FMC_OP_DMA, reg); ++ ++ return wait_op_finish(host); ++} ++ ++static ssize_t bsp_spi_nor_read(struct spi_nor *nor, loff_t from, size_t len, ++ u_char *read_buf) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ size_t offset; ++ int ret; ++ ++ for (offset = 0; offset < len; offset += host->dma_len) { ++ size_t trans = min_t(size_t, host->dma_len, len - offset); ++ ++ ret = bsp_spi_nor_dma_transfer(nor, ++ from + offset, host->dma_buffer, trans, FMC_OP_READ); ++ if (ret) { ++ dev_warn(nor->dev, "DMA read timeout\n"); ++ return ret; ++ } ++ memcpy(read_buf + offset, host->buffer, trans); ++ } ++ ++ return len; ++} ++ ++static ssize_t bsp_spi_nor_write(struct spi_nor *nor, loff_t to, ++ size_t len, const u_char *write_buf) ++{ ++ struct fmc_priv *priv = nor->priv; ++ struct fmc_host *host = priv->host; ++ size_t offset; ++ int ret; ++ ++ for (offset = 0; offset < len; offset += host->dma_len) { ++ size_t trans = min_t(size_t, host->dma_len, len - offset); ++ ++ memcpy(host->buffer, write_buf + offset, trans); ++ ret = bsp_spi_nor_dma_transfer(nor, ++ to + offset, host->dma_buffer, trans, FMC_OP_WRITE); ++ if (ret) { ++ dev_warn(nor->dev, "DMA write timeout\n"); ++ return ret; ++ } ++ } ++ ++ return len; ++} ++ ++/** ++ * parse partitions info and register spi flash device as mtd device. ++ */ ++static int bsp_snor_device_register(struct mtd_info *mtd) ++{ ++ int ret; ++ struct mtd_partitions parsed; ++ ++ /* ++ * We do not add the whole spi flash as a mtdblock device, ++ * To avoid the number of nand partition +1. ++ */ ++ memset(&parsed, 0, sizeof(parsed)); ++ ret = parse_mtd_partitions(mtd, NULL, &parsed, NULL); ++ if (ret) ++ return ret; ++ ++ return parsed.nr_parts ? mtd_device_register(mtd, NULL, 0) : parsed.nr_parts; ++} ++ ++/** ++ * Get spi flash device information and register it as a mtd device. ++ */ ++static int bsp_spi_nor_register(struct device_node *np, ++ struct fmc_host *host) ++{ ++ struct device *dev = host->dev; ++ struct spi_nor *nor; ++ struct fmc_priv *priv = &host->priv[host->num_chip]; ++ struct mtd_info *mtd; ++ int ret; ++ struct spi_nor_modes modes = { ++ .rd_modes = SNOR_MODE_SLOW, ++ .wr_modes = SNOR_MODE_1_1_1, ++ }; ++ ++ nor = devm_kzalloc(dev, sizeof(*nor), GFP_KERNEL); ++ if (!nor) ++ return -ENOMEM; ++ ++ nor->dev = dev; ++ spi_nor_set_flash_node(nor, np); ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ ret = of_property_read_u32(np, "reg", &priv->chipselect); ++ if (ret) { ++ dev_err(dev, "There's no reg property for %s\n", ++ np->full_name); ++ return ret; ++ } ++ ++ if (priv->chipselect != host->num_chip) { ++ dev_warn(dev, " The CS: %d states in device trees isn't real " \ ++ "chipselect on board\n, using CS: %d instead. ", ++ priv->chipselect, host->num_chip); ++ priv->chipselect = host->num_chip; ++ } ++ ++ ret = of_property_read_u32(np, "spi-max-frequency", ++ &priv->clkrate); ++ if (ret) { ++ dev_err(dev, "There's no spi-max-frequency property for %s\n", ++ np->full_name); ++ return ret; ++ } ++ priv->host = host; ++ nor->priv = priv; ++ ++ nor->prepare = bsp_spi_nor_prep; ++ nor->unprepare = bsp_spi_nor_unprep; ++ nor->read_reg = bsp_spi_nor_read_reg; ++ nor->write_reg = bsp_spi_nor_write_reg; ++ nor->read = bsp_spi_nor_read; ++ nor->write = bsp_spi_nor_write; ++ ++ modes.rd_modes |= SNOR_MODE_1_1_1 ++ | SNOR_MODE_1_1_2 ++ | SNOR_MODE_1_2_2; ++#ifndef CONFIG_CLOSE_SPI_8PIN_4IO ++ modes.rd_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; ++ modes.wr_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; ++#endif ++ ret = spi_nor_scan(nor, NULL, &modes); ++ if (ret) ++ return ret; ++ ++ mtd = &nor->mtd; ++ mtd->name = np->name; ++ ret = bsp_snor_device_register(mtd); ++ if (ret) ++ return ret; ++ ++ /* current chipselect has scanned, to detect next chipselect */ ++ fmc_cs_user[host->num_chip]++; ++ host->nor[host->num_chip] = nor; ++ return 0; ++} ++ ++static void bsp_spi_nor_unregister_all(struct fmc_host *host) ++{ ++ int i; ++ ++ for (i = 0; i < host->num_chip; i++) ++ mtd_device_unregister(&host->nor[i]->mtd); ++} ++ ++static int bsp_spi_nor_register_all(struct fmc_host *host) ++{ ++ struct device *dev = host->dev; ++ struct device_node *np = NULL; ++ int ret; ++ ++ for_each_available_child_of_node(dev->of_node, np) { ++ if (fmc_cs_user[host->num_chip]) { ++ dev_warn(dev, "Current CS(%d) is occupied.\n", ++ host->num_chip); ++ continue; ++ } ++ ret = bsp_spi_nor_register(np, host); ++ if (ret) ++ goto fail; ++ ++ if (host->num_chip == FMC_MAX_CHIP_NUM) { ++ dev_warn(dev, "Flash device number exceeds the " ++ "maximum chipselect number\n"); ++ break; ++ } ++ ++ host->num_chip++; ++ ++ } ++ ++ return 0; ++ ++fail: ++ bsp_spi_nor_unregister_all(host); ++ return ret; ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct bsp_fmc *fmc = dev_get_drvdata(dev->parent); ++ struct fmc_host *host; ++ int ret; ++ ++ if (!fmc) { ++ dev_err(&pdev->dev, "get mfd fmc devices failed\n"); ++ return -ENXIO; ++ } ++ ++ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); ++ if (!host) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, host); ++ host->dev = dev; ++ ++ host->regbase = fmc->regbase; ++ host->iobase = fmc->iobase; ++ host->clk = fmc->clk; ++ host->lock = &fmc->lock; ++ host->buffer = fmc->buffer; ++ host->dma_buffer = fmc->dma_buffer; ++ host->dma_len = fmc->dma_len; ++ ++ clk_prepare_enable(host->clk); ++ bsp_spi_nor_init(host); ++ ret = bsp_spi_nor_register_all(host); ++ if (ret) ++ dev_warn(dev, "spi nor register fail!\n"); ++ ++ clk_disable_unprepare(host->clk); ++ ++ return ret; ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_remove(struct platform_device *pdev) ++{ ++ struct fmc_host *host = platform_get_drvdata(pdev); ++ if (host == NULL){ ++ dev_err(&pdev->dev, "host is NULL ,remove err !!\n"); ++ return 0; ++ } ++ ++ bsp_spi_nor_unregister_all(host); ++ clk_disable_unprepare(host->clk); ++ return 0; ++} ++ ++/******************************************************************************/ ++static void bsp_spi_nor_driver_shutdown(struct platform_device *pdev) ++{ ++ int i; ++ struct fmc_host *host = platform_get_drvdata(pdev); ++ ++ if (!host) ++ return; ++ ++ mutex_lock(host->lock); ++ clk_prepare_enable(host->clk); ++ ++ spi_nor_switch_spi_type(host); ++ for (i = 0; i < host->num_chip; i++) ++ spi_nor_driver_shutdown(host->nor[i]); ++ ++ clk_disable_unprepare(host->clk); ++ mutex_unlock(host->lock); ++ dev_dbg(host->dev, "End of driver shutdown\n"); ++} ++ ++#ifdef CONFIG_PM ++/******************************************************************************/ ++static int bsp_spi_nor_driver_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ int i; ++ struct fmc_host *host = platform_get_drvdata(pdev); ++ ++ if (!host) ++ return 0; ++ ++ mutex_lock(host->lock); ++ clk_prepare_enable(host->clk); ++ ++ spi_nor_switch_spi_type(host); ++ for (i = 0; i < host->num_chip; i++) ++ spi_nor_suspend(host->nor[i], state); ++ ++ clk_disable_unprepare(host->clk); ++ mutex_unlock(host->lock); ++ dev_dbg(host->dev, "End of suspend\n"); ++ ++ return 0; ++} ++ ++/******************************************************************************/ ++static int bsp_spi_nor_driver_resume(struct platform_device *pdev) ++{ ++ int i; ++ struct fmc_host *host = platform_get_drvdata(pdev); ++ ++ if (!host) ++ return 0; ++ ++ mutex_lock(host->lock); ++ clk_prepare_enable(host->clk); ++ ++ spi_nor_switch_spi_type(host); ++ for (i = 0; i < host->num_chip; i++) ++ spi_nor_resume(host->nor[i]); ++ ++ mutex_unlock(host->lock); ++ dev_dbg(host->dev, "End of resume\n"); ++ ++ return 0; ++} ++#endif /* End of CONFIG_PM */ ++ ++/******************************************************************************/ ++static const struct of_device_id bsp_spi_nor_dt_ids[] = { ++ { .compatible = "goke,fmc-spi-nor"}, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, bsp_spi_nor_dt_ids); ++ ++/******************************************************************************/ ++static struct platform_driver bsp_spi_nor_driver = { ++ .driver = { ++ .name = "bsp-sfc", ++ .of_match_table = bsp_spi_nor_dt_ids, ++ }, ++ .probe = bsp_spi_nor_probe, ++ .remove = bsp_spi_nor_remove, ++ .shutdown = bsp_spi_nor_driver_shutdown, ++#ifdef CONFIG_PM ++ .suspend = bsp_spi_nor_driver_suspend, ++ .resume = bsp_spi_nor_driver_resume, ++#endif ++}; ++module_platform_driver(bsp_spi_nor_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Goke SPI Nor Flash Controller Driver"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-spi-nor.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-spi-nor.c.patch new file mode 100644 index 00000000..41730927 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-mtd-spi-nor-spi-nor.c.patch @@ -0,0 +1,1984 @@ +--- linux-4.9.37/drivers/mtd/spi-nor/spi-nor.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/mtd/spi-nor/spi-nor.c 2021-06-07 13:01:33.000000000 +0300 +@@ -75,6 +75,13 @@ + * bit. Must be used with + * SPI_NOR_HAS_LOCK. + */ ++#define SPI_NOR_4B_OPCODES BIT(10) /* ++ * Use dedicated 4byte address op codes ++ * to support memory size above 128Mib. ++ */ ++ ++ const struct spi_nor_basic_flash_parameter *params; ++ u32 clkrate; + }; + + #define JEDEC_MFR(info) ((info)->id[0]) +@@ -139,31 +146,24 @@ + } + + /* +- * Dummy Cycle calculation for different type of read. +- * It can be used to support more commands with +- * different dummy cycle requirements. ++ * Write status register 1 byte ++ * Returns negative if error occurred. + */ +-static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor) ++static inline int write_sr(struct spi_nor *nor, u8 val) + { +- switch (nor->flash_read) { +- case SPI_NOR_FAST: +- case SPI_NOR_DUAL: +- case SPI_NOR_QUAD: +- return 8; +- case SPI_NOR_NORMAL: +- return 0; +- } +- return 0; ++ nor->cmd_buf[0] = val; ++ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1); + } + ++ + /* +- * Write status register 1 byte ++ * Write status register-2 1 byte + * Returns negative if error occurred. + */ +-static inline int write_sr(struct spi_nor *nor, u8 val) ++static inline int write_sr2(struct spi_nor *nor, u8 val) + { + nor->cmd_buf[0] = val; +- return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1); ++ return nor->write_reg(nor, SPINOR_OP_WRSR2, nor->cmd_buf, 1); + } + + /* +@@ -188,9 +188,83 @@ + return mtd->priv; + } + ++struct spi_nor_address_entry { ++ u8 src_opcode; ++ u8 dst_opcode; ++}; ++ ++static u8 spi_nor_convert_opcode(u8 opcode, ++ const struct spi_nor_address_entry *entries, ++ size_t num_entries) ++{ ++ unsigned int min, max; ++ ++ min = 0; ++ max = num_entries - 1; ++ while (min <= max) { ++ int mid = (min + max) >> 1; ++ const struct spi_nor_address_entry *entry = &entries[mid]; ++ ++ if (opcode == entry->src_opcode) ++ return entry->dst_opcode; ++ ++ if (opcode < entry->src_opcode) ++ max = mid - 1; ++ else ++ min = mid + 1; ++ } ++ ++ /* No conversion found */ ++ return opcode; ++} ++ ++static u8 spi_nor_3to4_opcode(u8 opcode) ++{ ++ /* MUST be sorted by 3byte opcode */ ++#define ENTRY_3TO4(_opcode) { _opcode, _opcode##_4B } ++ static const struct spi_nor_address_entry spi_nor_3to4_table[] = { ++ ENTRY_3TO4(SPINOR_OP_PP), /* 0x02 */ ++ ENTRY_3TO4(SPINOR_OP_READ), /* 0x03 */ ++ ENTRY_3TO4(SPINOR_OP_READ_FAST), /* 0x0b */ ++ ENTRY_3TO4(SPINOR_OP_BE_4K), /* 0x20 */ ++ ENTRY_3TO4(SPINOR_OP_PP_1_1_4), /* 0x32 */ ++ ENTRY_3TO4(SPINOR_OP_PP_1_4_4), /* 0x38 */ ++ ENTRY_3TO4(SPINOR_OP_READ_1_1_2), /* 0x3b */ ++ ENTRY_3TO4(SPINOR_OP_BE_32K), /* 0x52 */ ++ ENTRY_3TO4(SPINOR_OP_READ_1_1_4), /* 0x6b */ ++ ENTRY_3TO4(SPINOR_OP_READ_1_2_2), /* 0xbb */ ++ ENTRY_3TO4(SPINOR_OP_SE), /* 0xd8 */ ++ ENTRY_3TO4(SPINOR_OP_READ_1_4_4), /* 0xeb */ ++ }; ++#undef ENTRY_3TO4 ++ ++ return spi_nor_convert_opcode(opcode, spi_nor_3to4_table, ++ ARRAY_SIZE(spi_nor_3to4_table)); ++} ++ ++static void spi_nor_set_4byte_opcodes(struct spi_nor *nor, ++ const struct flash_info *info) ++{ ++ /* Do some manufacturer fixups first */ ++ switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_SPANSION: ++ /* No small sector erase for 4-byte command set */ ++ nor->erase_opcode = SPINOR_OP_SE; ++ nor->mtd.erasesize = info->sector_size; ++ break; ++ ++ default: ++ break; ++ } ++ ++ nor->read_opcode = spi_nor_3to4_opcode(nor->read_opcode); ++ nor->program_opcode = spi_nor_3to4_opcode(nor->program_opcode); ++ nor->erase_opcode = spi_nor_3to4_opcode(nor->erase_opcode); ++} ++ + /* Enable/disable 4-byte addressing mode. */ + static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info, +- int enable) ++ u32 enable) + { + int status; + bool need_wren = false; +@@ -201,16 +275,26 @@ + /* Some Micron need WREN command; all will accept it */ + need_wren = true; + case SNOR_MFR_MACRONIX: +- case SNOR_MFR_WINBOND: + if (need_wren) + write_enable(nor); + + cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B; + status = nor->write_reg(nor, cmd, NULL, 0); ++ + if (need_wren) + write_disable(nor); + + return status; ++ case SNOR_MFR_WINBOND: ++ if (enable) ++ return nor->write_reg(nor, SPINOR_OP_EN4B, NULL, 0); ++ else { ++ /* w25q256fvfg must send reset to disable 4 byte mode */ ++ nor->write_reg(nor, SPINOR_ENABLE_RESET, NULL, 0); ++ nor->write_reg(nor, SPINOR_OP_RESET, NULL, 0); ++ udelay(30); ++ } ++ return 0; + default: + /* Spansion style */ + nor->cmd_buf[0] = enable << 7; +@@ -220,24 +304,28 @@ + static inline int spi_nor_sr_ready(struct spi_nor *nor) + { + int sr = read_sr(nor); ++ + if (sr < 0) + return sr; + else +- return !(sr & SR_WIP); ++ return !((unsigned int)sr & SR_WIP); + } + +-static inline int spi_nor_fsr_ready(struct spi_nor *nor) ++static inline unsigned int spi_nor_fsr_ready(struct spi_nor *nor) + { + int fsr = read_fsr(nor); ++ unsigned int ufsr = (unsigned int)fsr; ++ + if (fsr < 0) + return fsr; + else +- return fsr & FSR_READY; ++ return ufsr & FSR_READY; + } + + static int spi_nor_ready(struct spi_nor *nor) + { + int sr, fsr; ++ + sr = spi_nor_sr_ready(nor); + if (sr < 0) + return sr; +@@ -282,7 +370,31 @@ + return spi_nor_wait_till_ready_with_timeout(nor, + DEFAULT_READY_WAIT_JIFFIES); + } ++static int issi_spi_nor_wait_till_ready(struct spi_nor *nor) ++{ ++ unsigned long deadline; ++ int timeout = 0; ++ int ret; + ++ deadline = jiffies + DEFAULT_READY_WAIT_JIFFIES; ++ ++ while (!timeout) { ++ if (time_after_eq(jiffies, deadline)) ++ timeout = 1; ++ ++ ret = spi_nor_sr_ready(nor); ++ if (ret < 0) ++ return ret; ++ if (ret) ++ return 0; ++ ++ cond_resched(); ++ } ++ ++ dev_err(nor->dev, "flash operation timed out\n"); ++ ++ return -ETIMEDOUT; ++} + /* + * Erase the whole flash memory + * +@@ -367,6 +479,12 @@ + if (ret) + return ret; + ++#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT ++ if ((nor->level) && (addr < nor->end_addr)) { ++ dev_err(nor->dev, "Error: The erase area was locked\n"); ++ return -EINVAL; ++ } ++#endif + /* whole-chip erase? */ + if (len == mtd->size) { + unsigned long timeout; +@@ -745,6 +863,280 @@ + return ret; + } + ++#define SNOR_RD_MODES \ ++ (SNOR_MODE_SLOW | \ ++ SNOR_MODE_1_1_1 | \ ++ SNOR_MODE_1_1_2 | \ ++ SNOR_MODE_1_2_2 | \ ++ SNOR_MODE_1_1_4 | \ ++ SNOR_MODE_1_4_4) ++ ++#define SNOR_WR_MODES \ ++ (SNOR_MODE_1_1_1 | \ ++ SNOR_MODE_1_1_4) ++ ++static int spansion_quad_enable(struct spi_nor *nor); ++static int macronix_quad_enable(struct spi_nor *nor); ++static int gd_quad_enable(struct spi_nor *nor); ++static int xtx_quad_enable(struct spi_nor *nor); ++static int issi_quad_enable(struct spi_nor *nor); ++static int puya_quad_enable(struct spi_nor *nor); ++static int puya_quad_enable(struct spi_nor *nor); ++ ++#define SNOR_EON_RD_MODES \ ++ (SNOR_MODE_SLOW | \ ++ SNOR_MODE_1_1_1 | \ ++ SNOR_MODE_1_1_2 | \ ++ SNOR_MODE_1_2_2) ++ ++#define SNOR_EON_WR_MODES \ ++ (SNOR_MODE_1_1_1) ++ ++static const struct spi_nor_basic_flash_parameter eon_params = { ++ .rd_modes = SNOR_EON_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_EON_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter esmt_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = macronix_quad_enable, ++ ++}; ++ ++#define SNOR_PARAGON_WR_MODES \ ++ (SNOR_MODE_1_1_1) ++ ++static const struct spi_nor_basic_flash_parameter paragon_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_PARAGON_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = spansion_quad_enable, ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter gd_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = gd_quad_enable, ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter winbond_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = spansion_quad_enable, ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter spansion_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = spansion_quad_enable, ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter issi_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = issi_quad_enable, ++ ++}; ++ ++#define SNOR_MXIC_WR_MODES \ ++ (SNOR_MODE_1_1_1 | \ ++ SNOR_MODE_1_4_4) ++ ++static const struct spi_nor_basic_flash_parameter mxic_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_MXIC_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_4_4] = SPINOR_OP_PP_1_4_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = macronix_quad_enable, ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter xmc_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter micron_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 8, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(0, 40, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter micron_4k_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(1, 9, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ .erase_types[1] = SNOR_OP_ERASE_4K(SPINOR_OP_BE_4K), ++}; ++ ++static const struct spi_nor_basic_flash_parameter xtx_params = { ++ .rd_modes = SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes = SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = xtx_quad_enable, ++ ++}; ++ ++static const struct spi_nor_basic_flash_parameter puya_params = { ++ .rd_modes= SNOR_RD_MODES, ++ .reads[SNOR_MIDX_SLOW]= SNOR_OP_READ(0, 0, SPINOR_OP_READ), ++ .reads[SNOR_MIDX_1_1_1]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), ++ .reads[SNOR_MIDX_1_1_2]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), ++ .reads[SNOR_MIDX_1_2_2]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), ++ .reads[SNOR_MIDX_1_1_4]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), ++ .reads[SNOR_MIDX_1_4_4]= SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4), ++ ++ .wr_modes= SNOR_WR_MODES, ++ .page_programs[SNOR_MIDX_1_1_1]= SPINOR_OP_PP, ++ .page_programs[SNOR_MIDX_1_1_4]= SPINOR_OP_PP_1_1_4, ++ ++ .erase_types[0]= SNOR_OP_ERASE_64K(SPINOR_OP_SE), ++ ++ .enable_quad_io = puya_quad_enable, ++}; ++ ++#define PARAMS(_name) .params = &_name##_params ++ + /* Used when the "_ext_id" is two bytes at most */ + #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ + .id = { \ +@@ -758,7 +1150,7 @@ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = 256, \ +- .flags = (_flags), ++ .flags = (_flags) + + #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ + .id = { \ +@@ -782,6 +1174,10 @@ + .addr_width = (_addr_width), \ + .flags = (_flags), + ++/* Different from spi-max-frequency in DTS, the clk here stands for the clock ++ * rate on SPI interface, it is half of the FMC CRG configuration */ ++#define CLK_MHZ_2X(clk) .clkrate = (clk * 2000000), ++ + /* NOTE: double check command sets and memory organization when you add + * more nor chips. This current list focusses on newer chips, which + * have been converging on command sets which including JEDEC ID. +@@ -793,6 +1189,63 @@ + * For historical (and compatibility) reasons (before we got above config) some + * old entries may be missing 4K flag. + */ ++#define SPI_NOR_IDS_VER "1.2" ++ ++/******* SPI Nor ID Table ************************************************************************ ++ * Version Manufacturer Chip Name Chipsize Block Vol Operation ++ * Macronix/MXIC MX25V1635F 2M 64K 3V3 ++ * 1.0 Macronix/MXIC MX25L1606E 2M 64K 3V3 ++ * Macronix/MXIC MX25L6436F 8M 64K 3V3 ++ * Macronix/MXIC MX25R6435F 8M 64K 1V8/3V3 Add 14chips ++ * Macronix/MXIC MX25U6435F 8M 64K 1V8 ++ * Macronix/MXIC MX25U12835F 16M 64K 1V8 ++ * Macronix/MXIC MX25F128XXX 16M 64K 3V3 ++ * Macronix/MXIC MX25U25635F/45G 32M 64K 1V8 25645G-DTR ++ * Macronix/MXIC MX25L(256/257) 32M 64K 3V3 25645G-DTR ++ * Macronix/MXIC MX25U51245G 64M 64K 1V8 51245G-DTR ++ * Macronix/MXIC MX25L51245G 64M 64K 3V3 ++ * Macronix/MXIC MX66U1G45GM 128M 64K 1V8 ++ * Spansion S25FL129P1 16M 64K 3V3 ++ * Spansion S25FL256S 32M 64K 3V3 ++ * Micron N25Q064A 8M 64K 3V3 ++ * Micron N25QL064A 8M 64K 3V3 ++ * Micron N25Q128A11/MT25QU128AB 16M 64K 1V8 ++ * Micron N25QL128A 16M 64K 3V3 ++ * Micron MT25QU256A 32M 64K 1V8 ++ * Micron MT25QL256A 32M 64K 3V3 ++ * Winbond W25Q16(B/C)V/S25FL016K 2M 64K 3V3 ++ * Winbond W25Q32(B/F)V 4M 64K 3V3 ++ * Winbond W25Q32FW 4M 64K 1V8 ++ * Winbond W25Q64FW 8M 64K 1V8 ++ * Winbond W25Q64FV(SPI)/W25Q64JV_IQ 8M 64K 3V3 ++ * Winbond W25Q128FW 16M 64K 1V8 ++ * Winbond W25Q128(B/F)V 16M 64K 3V3 ++ * Winbond W25Q128JV_IM 16M 64K 3V3 DTR ++ * Winbond W25Q256JWEIQ 32M 64K 1V8 ++ * Winbond W25Q256JWFIM 32M 64K 1V8 ++ * ESMT/CFEON EN25Q32B 4M 64K 3V3 ++ * ESMT/CFEON EN25Q64 8M 64K 3V3 ++ * ESMT/CFEON EN25Q128 16M 64K 3V3 ++ * ESMT/CFEON F25L64QA 8M 64K 3V3 ++ * GD GD25Q16C 2M 64K 3V3 ++ * GD GD25Q64 8M 64K 3V3 ++ * GD GD25LQ128 16M 64K 1V8 ++ * GD GD25Q128 16M 64K 3V3 ++ * GD GD25Q256 32M 64K 3V3 ++ * GD GD25LQ64C 8M 64K 1V8 ++ * GD GD25Q32 4M 64K 3V3 ++ * Paragon PN25F16S 2M 64K 3V3 ++ * Paragon PN25F32S 4M 64K 3V3 ++ * 1.1 ESMT/CFEON EN25QH64A 8M 64K 3V3 ++ * 1.2 XMC XM25QH64AHIG 8M 64K 3V3 ++ * XMC XM25QH128A 16M 64K 3V3 ++ * XMC XM25QH128B 16M 64K 3V3 ++ * Puya P25Q128H-SUH-IT 16M 64K 3V3 ++ * FM FM25Q64-SOB-T-G 8M 64K 3V3 ++ * FM FM25Q128-SOB-T-G 16M 64K 3V3 ++ * HUAHONG H25S64 8M 64K 3V3 ++ * HUAHONG H25S128 16M 64K 3V3 ++ ********************************************************************************************/ + static const struct flash_info spi_nor_ids[] = { + /* Atmel -- some are (confusingly) marketed as "DataFlash" */ + { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, +@@ -812,44 +1265,55 @@ + /* EON -- en25xxx */ + { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, + { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, +- { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, ++ { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, ++ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, + { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, +- { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, ++ { "en25qh32b-104hip2b", INFO(0x1c7016, 0, 64 * 1024, 64, ++ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(133) }, ++ { "en25qh64a", INFO(0x1c7017, 0, 64 * 1024, 128, ++ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, ++ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, + { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, ++ { "en25qh128a", INFO(0x1c7018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, + { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, + { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, + + /* ESMT */ + { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) }, ++ { "f25l64qa", INFO(0x8c4117, 0, 64 * 1024, 128, ++ SPI_NOR_QUAD_READ), PARAMS(esmt), CLK_MHZ_2X(84) }, + + /* Everspin */ +- { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, +- { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { "mr25h256", CAT25_INFO(32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE ++ | SPI_NOR_NO_FR) }, ++ { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE ++ | SPI_NOR_NO_FR) }, + + /* Fujitsu */ + { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, + +- /* GigaDevice */ +- { +- "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, +- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) +- }, +- { +- "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, +- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) +- }, +- { +- "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128, +- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) +- }, +- { +- "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, +- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) +- }, ++ /* GigaDevice 3.3V */ ++ { "gd25q16c", INFO(0xc84015, 0, 64 * 1024, 32, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(120) }, ++ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(120) }, ++ { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(120) }, ++ { "gd25q128/gd25q127", INFO(0xc84018, 0, 64 * 1024, 256, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(80) }, ++ { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512, ++ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(gd), CLK_MHZ_2X(80) }, ++ /* GigaDevice 1.8V */ ++ { "gd25lq16c", INFO(0xc86015, 0, 64 * 1024, 32, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(104) }, ++ { "gd25lq64", INFO(0xc86017, 0, 64 * 1024, 128, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(133) }, ++ { "gd25lq128", INFO(0xc86018, 0, 64 * 1024, 256, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(133) }, + + /* Intel/Numonyx -- xxxs33b */ + { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, +@@ -859,68 +1323,132 @@ + /* ISSI */ + { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, + +- /* Macronix */ ++ { "IS25WP512M-RMLA3", INFO(0x9d701a, 0, 64 * 1024, 1024, ++ SPI_NOR_QUAD_READ), PARAMS(issi), CLK_MHZ_2X(80) }, ++ ++ /* Macronix/MXIC 3.3V */ + { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, + { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, + { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, + { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, +- { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, +- { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, ++ { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K ++ | SPI_NOR_DUAL_READ), CLK_MHZ_2X(80) }, ++ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, + { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, +- { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, +- { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, +- { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, ++ { "mx25l6436f", INFO(0xc22017, 0, 64 * 1024, 128, ++ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(133) }, ++ { "mx25l12835f", INFO(0xc22018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(84) }, + { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, +- { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, ++ { "mx25l25635f", INFO(0xc22019, 0, 64 * 1024, 512, ++ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(84) }, ++ { "mx25l25673g", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_QUAD_READ ++ | SPI_NOR_4B_OPCODES) }, + { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, +- { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, +- { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, +- +- /* Micron */ +- { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, +- { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, +- { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, +- { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, +- { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, +- { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, +- { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, +- { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, +- { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, +- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, +- { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, ++ { "mx66l51235l/mx25l51245g", INFO(0xc2201a, 0, 64 * 1024, 1024, ++ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(133)}, ++ { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ)}, ++ { "mx25v1635f", INFO(0xc22315, 0, 64 * 1024, 32 , ++ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(80) }, ++ /* Macronix/MXIC Wide Voltage Range 1.65~3.6V */ ++ { "mx25r6435f", INFO(0xc22817, 0, 64 * 1024, 128, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ), CLK_MHZ_2X(80) }, ++ /* Macronix/MXIC 1.8V */ ++ { "mx25u1633f", INFO(0xc22535, 0, 64 * 1024, 32, ++ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(80) }, ++ { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(84) }, ++ { "mx25u12835f/mx25u12832f", INFO(0xc22538, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(84) }, ++ { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, ++ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(84) }, ++ { "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024, ++ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(166) }, ++ { "mx66u1g45gm", INFO(0xc2253b, 0, 64 * 1024, 2048, ++ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(133) }, ++ ++ /* Micron 3.3V */ ++ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ), ++ PARAMS(micron), CLK_MHZ_2X(84) }, ++ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), ++ PARAMS(micron_4k), CLK_MHZ_2X(108) }, ++ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), ++ PARAMS(micron), CLK_MHZ_2X(108) }, ++ { "mt25ql256a", INFO(0x20ba19, 0x1044, 64 * 1024, 512, SPI_NOR_QUAD_READ), ++ PARAMS(micron), CLK_MHZ_2X(108) }, ++ { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR), ++ PARAMS(micron_4k) }, ++ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR | SPI_NOR_QUAD_READ), ++ PARAMS(micron_4k), CLK_MHZ_2X(80) }, ++ /* Micron 1.8V */ ++ { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ), ++ PARAMS(micron), CLK_MHZ_2X(108) }, ++ { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), ++ PARAMS(micron), CLK_MHZ_2X(108) }, ++ { "mt25qu128a/n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), ++ PARAMS(micron), CLK_MHZ_2X(108) }, ++ { "mt25qu256a", INFO(0x20bb19, 0, 64 * 1024, 512, ++ SPI_NOR_4B_OPCODES | SPI_NOR_QUAD_READ), PARAMS(micron), CLK_MHZ_2X(108) }, ++ { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, USE_FSR | SPI_NOR_QUAD_READ), ++ PARAMS(micron_4k), CLK_MHZ_2X(80) }, ++ ++ /* XMC */ ++ { "xm25qh64a", INFO(0x207017, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), ++ PARAMS(xmc), CLK_MHZ_2X(104) }, ++ { "xm25qh64b", INFO(0x206017, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), ++ PARAMS(xmc), CLK_MHZ_2X(104) }, ++ { "xm25qh128a", INFO(0x207018, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), ++ PARAMS(xmc), CLK_MHZ_2X(104) }, ++ { "xm25qh128b", INFO(0x206018, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), ++ PARAMS(xmc), CLK_MHZ_2X(104) }, + + /* PMC */ +- { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, +- { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, +- { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, ++ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, ++ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, ++ { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, + + /* Spansion -- single (large) sector size only, at least + * for the chips listed here (without boot sectors). + */ +- { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, +- { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, ++ { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, ++ SPI_NOR_4B_OPCODES | SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(104) }, ++ { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, ++ { "s25fl127s/129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(108) }, + { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, + { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, +- { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, +- { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, +- { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, +- { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, +- { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, +- { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, +- { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, +- { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +- { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, +- { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, +- { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, ++ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K ++ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl128lagmfi010z", INFO(0x016018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ)}, ++ { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, ++ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, ++ { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, ++ { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, ++ { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, ++ { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, ++ { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K ++ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K ++ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++ { "w25Q16jv-iq/s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(84) }, ++ /* { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K ++ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, */ ++ { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, ++ { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, ++ { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K ++ | SPI_NOR_DUAL_READ) }, + + /* SST -- large erase sizes are "overlays", "sectors" are 4K */ + { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, +@@ -972,43 +1500,101 @@ + { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, + { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, + +- /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ ++ /* Winbond 3.3V-- w25x "blocks" are 64K, "sectors" are 4KiB */ + { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, + { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, + { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, + { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, + { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, +- { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, ++ { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K ++ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, +- { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, +- { +- "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, +- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) +- }, ++ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, + { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, +- { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, +- { +- "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, +- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) +- }, +- { +- "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, +- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) +- }, ++ { "w25q64fv(spi)/w25q64jv_iq", INFO(0xef4017, 0, 64 * 1024, 128, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, + { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, + { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, +- { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, +- { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, ++ { "w25q128(b/f)v", INFO(0xef4018, 0, 64 * 1024, 256, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(104) }, ++ { "w25q128jv_im", INFO(0xef7018, 0, 64 * 1024, 256, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, ++#ifdef CONFIG_AUTOMOTIVE_GRADE ++ { "w25q256(f/j)v", INFO(0xef4019, 0, 64 * 1024, 512, ++ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, ++#else ++ { "w25q256(f/j)v", INFO(0xef4019, 0, 64 * 1024, 512, ++ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(winbond), CLK_MHZ_2X(80) }, ++#endif ++ /* Winbond 1.8V */ ++ { "w25q32fw", INFO(0xef6016, 0, 64 * 1024, 64, ++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | ++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB), PARAMS(winbond), CLK_MHZ_2X(80) }, ++ { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, ++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | ++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB), PARAMS(winbond), CLK_MHZ_2X(80) }, ++ { "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, ++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | ++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB), PARAMS(winbond), CLK_MHZ_2X(80) }, ++ { "w25q256jw-im", INFO(0xef8019, 0, 64 * 1024, 512, ++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | ++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES), ++ PARAMS(winbond), CLK_MHZ_2X(80) }, ++ { "w25q256jw-iq", INFO(0xef6019, 0, 64 * 1024, 512, ++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | ++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES), ++ PARAMS(winbond), CLK_MHZ_2X(133) }, + + /* Catalyst / On Semiconductor -- non-JEDEC */ +- { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, +- { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, +- { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, +- { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, +- { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, ++ { "cat25c11", CAT25_INFO(16, 8, 16, 1, SPI_NOR_NO_ERASE ++ | SPI_NOR_NO_FR) }, ++ { "cat25c03", CAT25_INFO(32, 8, 16, 2, SPI_NOR_NO_ERASE ++ | SPI_NOR_NO_FR) }, ++ { "cat25c09", CAT25_INFO(28, 8, 32, 2, SPI_NOR_NO_ERASE ++ | SPI_NOR_NO_FR) }, ++ { "cat25c17", CAT25_INFO(256, 8, 32, 2, SPI_NOR_NO_ERASE ++ | SPI_NOR_NO_FR) }, ++ { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE ++ | SPI_NOR_NO_FR) }, ++ /* Paragon 3.3V */ ++ { "pn25f16s", INFO(0xe04015, 0, 64 * 1024, 32, ++ SPI_NOR_QUAD_READ), PARAMS(paragon), CLK_MHZ_2X(80) }, ++ { "pn25f32s", INFO(0xe04016, 0, 64 * 1024, 64, ++ SPI_NOR_QUAD_READ), PARAMS(paragon), CLK_MHZ_2X(80) }, ++ ++ /* XTX */ ++ { "xt25f16bssigu", INFO(0x0b4015, 0, 64 * 1024, 32, ++ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(120) }, ++ ++ { "xt25f32bssigu-s", INFO(0x0b4016, 0, 64 * 1024, 64, ++ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(120) }, ++ ++ { "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(70) }, ++ ++ { "xt25f64b", INFO(0x0b4017, 0, 64 * 1024, 128, ++ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(70) }, ++ ++ /*puya 3.3V */ ++ {"p25q128h", INFO(0x856018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(puya), CLK_MHZ_2X(104) }, ++ ++ /* FM 3.3v */ ++ { "FM25Q64-SOB-T-G",INFO(0xa14017, 0, 64 * 1024, 128, ++ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, ++ { "FM25Q128-SOB-T-G",INFO(0xa14018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, ++ ++ /* HUAHONG 3.3v */ ++ { "H25S64",INFO(0x684017, 0, 64 * 1024, 128, ++ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, ++ ++ { "H25S128",INFO(0x684018, 0, 64 * 1024, 256, ++ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, ++ ++ { "ZB25VQ64A",INFO(0x5e4017, 0, 64 * 1024, 128, ++ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(104) }, + { }, + }; + +@@ -1024,6 +1610,11 @@ + return ERR_PTR(tmp); + } + ++ if ((id[0] == 0xff) || (id[0] == 0x00)) { ++ dev_err(nor->dev, "unrecognized Manufacturer ID\n"); ++ return ERR_PTR(-ENODEV); ++ } ++ + for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { + info = &spi_nor_ids[tmp]; + if (info->id_len) { +@@ -1036,6 +1627,36 @@ + return ERR_PTR(-ENODEV); + } + ++static int puya_quad_enable(struct spi_nor *nor) ++{ ++ int ret; ++ u8 val; ++ ++ ret = read_cr(nor); ++ if ((unsigned int)ret & CR_QUAD_EN_SPAN) ++ return 0; ++ ++ val = (((unsigned int)ret & 0xff) | CR_QUAD_EN_SPAN); ++ write_enable(nor); ++ ++ ret = write_sr2(nor, val); ++ if (ret < 0) { ++ dev_err(nor->dev, ++ "error while writing status register-2\n"); ++ return -EINVAL; ++ } ++ ++ if (spi_nor_wait_till_ready(nor)) ++ return 1; ++ ++ /* read back and check it */ ++ ret = read_cr(nor); ++ if ((unsigned int)ret & CR_QUAD_EN_SPAN) ++ return 0; ++ else ++ return 1; ++} ++ + static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) + { +@@ -1167,14 +1788,22 @@ + ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); + if (ret) + return ret; ++#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT ++ if (nor->level && (to < nor->end_addr)) { ++ dev_err(nor->dev, "Error: The DMA write area was locked\n"); ++ return -EINVAL; ++ } ++#endif + + for (i = 0; i < len; ) { + ssize_t written; + + page_offset = (to + i) & (nor->page_size - 1); ++#ifndef CONFIG_SPI_GOKE_SFC + WARN_ONCE(page_offset, + "Writing at offset %zu into a NOR page. Writing partial pages may decrease reliability and increase wear of NOR flash.", + page_offset); ++#endif + /* the size of data remaining on the first page */ + page_remain = min_t(size_t, + nor->page_size - page_offset, len - i); +@@ -1211,15 +1840,22 @@ + val = read_sr(nor); + if (val < 0) + return val; ++ ++ if ((unsigned int)val & SR_QUAD_EN_MX) ++ return 0; ++ ++ /* Update the Quad Enable bit. */ ++ dev_dbg(nor->dev, "setting Macronix Quad Enable (non-volatile) bit\n"); ++ + write_enable(nor); + +- write_sr(nor, val | SR_QUAD_EN_MX); ++ write_sr(nor, (u8)val | SR_QUAD_EN_MX); + + if (spi_nor_wait_till_ready(nor)) + return 1; + + ret = read_sr(nor); +- if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) { ++ if (!(ret > 0 && ((unsigned int)ret & SR_QUAD_EN_MX))) { + dev_err(nor->dev, "Macronix Quad bit not set\n"); + return -EINVAL; + } +@@ -1227,6 +1863,41 @@ + return 0; + } + ++static int xtx_quad_enable(struct spi_nor *nor) ++{ ++ u8 ret, val_h,val_l; ++ /* read SR high 8bit*/ ++ val_h = read_cr(nor); ++ if (val_h < 0) ++ return val_h; ++ ++ if (val_h & SR_QUAD_EN_XTX) ++ return 0; ++ ++ /* Update the Quad Enable bit. */ ++ dev_dbg(nor->dev, "setting xtx Quad Enable (non-volatile) bit\n"); ++ ++ write_enable(nor); ++ ++ /* read SR low 8bit*/ ++ val_l = read_sr(nor); ++ ++ /* write SR */ ++ nor->cmd_buf[0] = val_l; ++ nor->cmd_buf[1] = val_h; ++ nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2); ++ ++ if (spi_nor_wait_till_ready(nor)) ++ return 1; ++ ++ ret = read_cr(nor); ++ if (!(ret > 0 && (ret & SR_QUAD_EN_XTX))) { ++ dev_err(nor->dev, "xtx Quad bit not set\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} + /* + * Write status Register and configuration register with 2 bytes + * The first byte will be written to the status register, while the +@@ -1243,29 +1914,168 @@ + + static int spansion_quad_enable(struct spi_nor *nor) + { +- int ret; +- int quad_en = CR_QUAD_EN_SPAN << 8; ++ unsigned int ret; ++ u16 val; ++ ++ ret = read_cr(nor); ++ if (ret & CR_QUAD_EN_SPAN) ++ return 0; ++ ++ /* Update the Quad Enable bit. */ ++ dev_dbg(nor->dev, "setting Quad Enable (non-volatile) bit\n"); ++ ++ val = ((ret & 0xff) | CR_QUAD_EN_SPAN) << 8; ++ ++ ret = read_sr(nor); ++ val |= (ret & 0xff); ++ ++ write_enable(nor); ++ ++ ret = write_sr_cr(nor, val); ++ if (ret < 0) { ++ dev_err(nor->dev, ++ "error while writing configuration register\n"); ++ return -EINVAL; ++ } ++ ++ if (spi_nor_wait_till_ready(nor)) ++ return 1; ++ ++ /* read back and check it */ ++ ret = read_cr(nor); ++ if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { ++ dev_err(nor->dev, "Spansion Quad bit not set\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int issi_quad_enable(struct spi_nor *nor) ++{ ++ unsigned int ret; ++ u16 val; ++ ++ ret = read_sr(nor); ++ if (ret & QUAD_EN_ISSI) ++ return 0; ++ ++ /* Update the Quad Enable bit. */ ++ dev_dbg(nor->dev, "setting Quad Enable (non-volatile) bit\n"); ++ ++ val = ((ret & 0xff) | QUAD_EN_ISSI); + + write_enable(nor); + +- ret = write_sr_cr(nor, quad_en); ++ ret = write_sr(nor, val); + if (ret < 0) { + dev_err(nor->dev, + "error while writing configuration register\n"); + return -EINVAL; + } + ++ if (issi_spi_nor_wait_till_ready(nor)) ++ return 1; ++ ++ /* read back and check it */ ++ ret = read_sr(nor); ++ if (!(ret > 0 && (ret & QUAD_EN_ISSI))) { ++ dev_err(nor->dev, "ISSI Quad bit not set\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int micron_quad_enable(struct spi_nor *nor) ++{ ++ int ret; ++ u8 val; ++ ++ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error %d reading EVCR\n", ret); ++ return ret; ++ } ++ ++ write_enable(nor); ++ ++ /* set EVCR, enable quad I/O */ ++ nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON; ++ ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error while writing EVCR register\n"); ++ return ret; ++ } ++ + ret = spi_nor_wait_till_ready(nor); +- if (ret) { ++ if (ret) ++ return ret; ++ ++ /* read EVCR and check it */ ++ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error %d reading EVCR\n", ret); ++ return ret; ++ } ++ if (val & EVCR_QUAD_EN_MICRON) { ++ dev_err(nor->dev, "Micron EVCR Quad bit not clear\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int gd_quad_enable(struct spi_nor *nor) ++{ ++ int ret; ++ u16 val; ++ ++ /* First, Quad Enable for 16-Pin GD flash, use WRSR[01h] cmd */ ++ ret = read_cr(nor); ++ val = (((unsigned int)ret & 0xff) | CR_QUAD_EN_SPAN) << 8; ++ ++ ret = read_sr(nor); ++ val |= ((unsigned int)ret & 0xff); ++ ++ write_enable(nor); ++ ++ ret = write_sr_cr(nor, val); ++ if (ret < 0) { + dev_err(nor->dev, +- "timeout while writing configuration register\n"); ++ "error while writing config and status register\n"); ++ return -EINVAL; ++ } ++ ++ if (spi_nor_wait_till_ready(nor)) ++ return 1; ++ ++ /* read back and check it */ ++ ret = read_cr(nor); ++ if ((unsigned int)ret & CR_QUAD_EN_SPAN) ++ return 0; ++ ++ /* Second, Quad Enable for 8-Pin GD flash, use WRCR[31h] cmd */ ++ ret = read_sr(nor); ++ if (!((unsigned int)ret & SR_WEL)) ++ write_enable(nor); ++ ++ ret = read_cr(nor); ++ nor->cmd_buf[0] = ((unsigned int)ret & 0xff) | CR_QUAD_EN_SPAN; ++ ++ ret = nor->write_reg(nor, SPINOR_OP_WRCR, nor->cmd_buf, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error while writing config register\n"); + return ret; + } + ++ if (spi_nor_wait_till_ready(nor)) ++ return 1; ++ + /* read back and check it */ + ret = read_cr(nor); +- if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { +- dev_err(nor->dev, "Spansion Quad bit not set\n"); ++ if (!(ret > 0 && ((unsigned int)ret & CR_QUAD_EN_SPAN))) { ++ dev_err(nor->dev, "GigaDevice Quad bit not set\n"); + return -EINVAL; + } + +@@ -1277,6 +2087,7 @@ + int status; + + switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_ESMT: + case SNOR_MFR_MACRONIX: + status = macronix_quad_enable(nor); + if (status) { +@@ -1285,7 +2096,40 @@ + } + return status; + case SNOR_MFR_MICRON: +- return 0; ++ status = micron_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "Micron quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; ++ case SNOR_MFR_GD: ++ status = gd_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "GD quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; ++ case SNOR_MFR_XTX: ++ status = xtx_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "xtx quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; ++ case SNOR_MFR_PUYA: ++ status = puya_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "puya quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; ++ case SNOR_MFR_ISSI: ++ status = issi_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "puya quad-read not enabled\n"); ++ return -EINVAL; ++ } ++ return status; + default: + status = spansion_quad_enable(nor); + if (status) { +@@ -1307,8 +2151,375 @@ + return 0; + } + +-int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) ++#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT ++static void spi_lock_update_address(struct spi_nor *nor, const struct flash_info *info) ++{ ++ unsigned int lock_level_max, sectorsize, chipsize; ++ ++ if (!nor->level) { ++ nor->end_addr = 0; ++ dev_warn(nor->dev, "all blocks is unlocked.\n"); ++ return; ++ } ++ ++ sectorsize = info->sector_size; ++ chipsize = sectorsize * info->n_sectors; ++ lock_level_max = nor->lock_level_max; ++ ++ switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_MACRONIX: ++ if (chipsize == _2M) { ++ if ((nor->level != lock_level_max) ++ && (nor->level != 1)) ++ nor->end_addr = chipsize - (sectorsize << ++ (lock_level_max - nor->level - 1)); ++ else ++ nor->end_addr = chipsize; ++ return; ++ } ++ ++ if (chipsize != _8M) ++ break; ++ case SNOR_MFR_ESMT: ++ /* this case is for ESMT and MXIC 8M devices */ ++ if (nor->level != lock_level_max) ++ nor->end_addr = chipsize - (sectorsize ++ << (lock_level_max - nor->level)); ++ else ++ nor->end_addr = chipsize; ++ return; ++ case SNOR_MFR_EON: ++ if (nor->level != lock_level_max) ++ nor->end_addr = chipsize - (sectorsize ++ << (nor->level - 1)); ++ else ++ nor->end_addr = chipsize; ++ return; ++ default: ++ break; ++ } ++ ++ /* general case */ ++ nor->end_addr = chipsize >> (lock_level_max - nor->level); ++} ++ ++static unsigned char bsp_bp_to_level(struct spi_nor *nor, ++ const struct flash_info *info, unsigned int bp_num) ++{ ++ int ret; ++ unsigned char val; ++ unsigned char level; ++ unsigned int chipsize; ++ ++ ret = spi_nor_wait_till_ready(nor); ++ BUG_ON(ret); ++ ++ ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error %d reading SR\n", ret); ++ return ret; ++ } ++ ++ if (bp_num == BP_NUM_3) ++ level = (val & SPI_NOR_SR_BP_MASK_3) >> SPI_NOR_SR_BP0_SHIFT; ++ else ++ level = (val & SPI_NOR_SR_BP_MASK_4) >> SPI_NOR_SR_BP0_SHIFT; ++ ++ dev_dbg(nor->dev, "the current level[%d]\n", level); ++ ++ if (bp_num == BP_NUM_4) { ++ nor->lock_level_max = LOCK_LEVEL_MAX(bp_num) - 5; ++ chipsize = info->sector_size * info->n_sectors; ++ if ((JEDEC_MFR(info) == SNOR_MFR_MACRONIX) ++ && (chipsize == _16M)) ++ nor->lock_level_max--; ++ } else ++ nor->lock_level_max = LOCK_LEVEL_MAX(bp_num); ++ dev_dbg(nor->dev, "Get the max bp level: [%d]\n", ++ nor->lock_level_max); ++ ++ return level; ++} ++ ++static void bsp_get_spi_lock_info(struct spi_nor *nor, const struct flash_info *info) ++{ ++ unsigned int chipsize; ++ struct device *dev = nor->dev; ++ ++ chipsize = info->sector_size * info->n_sectors; ++ ++ /* read the BP bit in RDSR to check whether nor is lock or not */ ++ switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_GD: ++ case SNOR_MFR_ESMT: ++ case SNOR_MFR_EON: ++ case SNOR_MFR_SPANSION: ++ /* BP bit convert to lock level */ ++ nor->level = bsp_bp_to_level(nor, info, BP_NUM_3); ++ break; ++ case SNOR_MFR_WINBOND: ++ /* BP bit convert to lock level */ ++ if (chipsize <= _16M) ++ nor->level = bsp_bp_to_level(nor, info, BP_NUM_3); ++ else ++ nor->level = bsp_bp_to_level(nor, info, BP_NUM_4); ++ break; ++ case SNOR_MFR_MACRONIX: ++ /* BP bit convert to lock level */ ++ if (chipsize <= _8M) ++ nor->level = bsp_bp_to_level(nor, info, BP_NUM_3); ++ else ++ nor->level = bsp_bp_to_level(nor, info, BP_NUM_4); ++ break; ++ default: ++ goto usage; ++ } ++ ++ spi_lock_update_address(nor, info); ++ if (nor->end_addr) ++ dev_info(dev, "Address range [0 => %#x] is locked.\n", ++ nor->end_addr); ++ return; ++usage: ++ dev_err(dev, "The ID: %#x isn't in the BP table," ++ " Current device can't not protect\n", ++ JEDEC_MFR(info)); ++} ++#endif/* CONFIG_GOKE_SPI_BLOCK_PROTECT */ ++ ++static int spi_nor_midx2proto(int midx, enum spi_nor_protocol *proto) ++{ ++ switch (midx) { ++ case SNOR_MIDX_SLOW: ++ case SNOR_MIDX_1_1_1: ++ *proto = SNOR_PROTO_1_1_1; ++ break; ++ ++ case SNOR_MIDX_1_1_2: ++ *proto = SNOR_PROTO_1_1_2; ++ break; ++ ++ case SNOR_MIDX_1_2_2: ++ *proto = SNOR_PROTO_1_2_2; ++ break; ++ case SNOR_MIDX_1_1_4: ++ *proto = SNOR_PROTO_1_1_4; ++ break; ++ ++ case SNOR_MIDX_1_4_4: ++ *proto = SNOR_PROTO_1_4_4; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int spi_nor_sr3_to_reset(struct spi_nor *nor) + { ++ int ret; ++ unsigned char val; ++ ++ ret = nor->read_reg(nor, SPINOR_OP_RDSR3, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error %d reading Status Reg 3.\n", ret); ++ return ret; ++ } ++ ++ if (SPI_NOR_GET_RST(val)) { ++ dev_dbg(nor->dev, "Device has worked on RESET#.\n"); ++ return 0; ++ } ++ ++ dev_dbg(nor->dev, "Start to enable RESET# function.\n"); ++ val = SPI_NOR_SET_RST(val); ++ ++ nor->write_reg(nor, SPINOR_OP_WRSR3, &val, 1); ++ if (ret < 0) { ++ dev_err(nor->dev, "error while writing Status Reg 3.\n"); ++ return ret; ++ } ++ ++ dev_dbg(nor->dev, "Enable RESET# function success.\n"); ++ ++ return 0; ++} ++ ++static int spi_nor_reset_pin_enable(struct spi_nor *nor, ++ const struct flash_info *info) ++{ ++ switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_WINBOND: ++ case SNOR_MFR_GD: ++ return spi_nor_sr3_to_reset(nor); ++ default: ++ return 0; ++ } ++} ++ ++static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, ++ const struct spi_nor_basic_flash_parameter *params, ++ const struct spi_nor_modes *modes) ++{ ++ bool enable_quad_io; ++ u32 rd_modes, wr_modes; ++ const struct spi_nor_erase_type *erase_type; ++ const struct spi_nor_read_op *read; ++ int rd_midx, wr_midx, err = 0; ++#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS ++ int i = 0; ++#endif ++ rd_modes = modes->rd_modes; ++ wr_modes = modes->wr_modes; ++ ++ /* Setup read operation. */ ++ rd_midx = fls(params->rd_modes & rd_modes) - 1; ++ if (spi_nor_midx2proto(rd_midx, &nor->read_proto)) { ++ dev_err(nor->dev, "invalid (fast) read\n"); ++ return -EINVAL; ++ } ++ read = ¶ms->reads[rd_midx]; ++ nor->read_opcode = read->opcode; ++ nor->read_dummy = read->num_mode_clocks + read->num_wait_states; ++ ++ /* Set page program op code and protocol. */ ++ wr_midx = fls(params->wr_modes & wr_modes) - 1; ++ if (spi_nor_midx2proto(wr_midx, &nor->write_proto)) { ++ dev_err(nor->dev, "invalid page program\n"); ++ return -EINVAL; ++ } ++ nor->program_opcode = params->page_programs[wr_midx]; ++ ++ /* Set sector erase op code and size. */ ++ erase_type = ¶ms->erase_types[0]; ++#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS ++ for (i = 1; i < SNOR_MAX_ERASE_TYPES; ++i) ++ if (params->erase_types[i].size == 0x0c) ++ erase_type = ¶ms->erase_types[i]; ++#endif ++ nor->erase_opcode = erase_type->opcode; ++ nor->mtd.erasesize = (1 << erase_type->size); ++ ++ enable_quad_io = (SNOR_PROTO_DATA_FROM_PROTO(nor->read_proto) == 4 || ++ SNOR_PROTO_DATA_FROM_PROTO(nor->write_proto) == 4); ++ ++ /* Enable Quad I/O if needed. */ ++ if (enable_quad_io && params->enable_quad_io) { ++ err = params->enable_quad_io(nor); ++ if (err) { ++ dev_err(nor->dev, ++ "failed to enable the Quad I/O mode\n"); ++ return err; ++ } ++ } ++ ++ /* ++ * Fix erase protocol if needed, read and write protocols should ++ * already be valid. ++ */ ++ nor->erase_proto = SNOR_PROTO_1_1_1; ++ ++ dev_dbg(nor->dev, ++ "(Fast) Read: opcode=%02Xh, protocol=%03x, mode=%u, wait=%u\n", ++ nor->read_opcode, nor->read_proto, ++ read->num_mode_clocks, read->num_wait_states); ++ dev_dbg(nor->dev, ++ "Page Program: opcode=%02Xh, protocol=%03x\n", ++ nor->program_opcode, nor->write_proto); ++ dev_dbg(nor->dev, ++ "Sector Erase: opcode=%02Xh, protocol=%03x, sector size=%zu\n", ++ nor->erase_opcode, nor->erase_proto, (size_t)nor->mtd.erasesize); ++ ++ return 0; ++} ++ ++static int spi_nor_config(struct spi_nor *nor, const struct flash_info *info, ++ const struct spi_nor_basic_flash_parameter *params, ++ struct spi_nor_modes *modes) ++{ ++ int ret; ++ unsigned char cval,val; ++ ++ if (JEDEC_MFR(info) == SNOR_MFR_MACRONIX){ ++ val = read_sr(nor); ++ if (val < 0) ++ return val; ++ ++ /* read Configuration Register for macronix's spi nor flash */ ++ ret = nor->read_reg(nor, SPINOR_OP_RDSR3, &cval, 1); ++ if(ret < 0){ ++ dev_err(nor->dev, "error %d reading config Reg.\n", ret); ++ return ret; ++ } ++ ++ /* check the bit[6:7] whether is set in uboot when use DTR mode;if it was set and clear it. */ ++ /* pay attention to sequence of issuing WRSR instruction */ ++ if (cval & CR_DUMMY_CYCLE){ ++ write_enable(nor); ++ nor->cmd_buf[0]=val; ++ nor->cmd_buf[1]=(cval & (~CR_DUMMY_CYCLE)); ++ ret = nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2); ++ } ++ } ++ ++ if (params) { ++ ret = spi_nor_setup(nor, info, params, modes); ++ if (ret) ++ return ret; ++ } else if (modes->rd_modes & SNOR_MODE_1_1_4 && ++ info->flags & SPI_NOR_QUAD_READ) { ++ /* ++ * This branch is spcially for some devices which can ++ * not be stated by params, but only SPI_NOR_QUAD_READ, ++ * it just supports the protocol 1_1_4. ++ */ ++ if (spi_nor_wait_till_ready(nor)) ++ return 1; ++ ++ ret = set_quad_mode(nor, info); ++ if (ret) { ++ dev_err(nor->dev, "quad mode not supported\n"); ++ return ret; ++ } ++ nor->read_proto = SNOR_PROTO_1_1_4; ++ nor->read_opcode = SPINOR_OP_READ_1_1_4; ++ nor->read_dummy = 8; ++ } else if (modes->rd_modes & SNOR_MODE_1_1_2 && ++ info->flags & SPI_NOR_DUAL_READ) { ++ /* ++ * This branch is spcially for some devices which can ++ * not be stated by params, but only SPI_NOR_DUAL_READ, ++ * it just supports the protocol 1_1_2. ++ */ ++ nor->read_proto = SNOR_PROTO_1_1_2; ++ nor->read_opcode = SPINOR_OP_READ_1_1_2; ++ nor->read_dummy = 8; ++ } else { ++ if (modes->rd_modes & SNOR_MODE_1_1_1) { ++ nor->read_opcode = SPINOR_OP_READ_FAST; ++ nor->read_dummy = 8; ++ } else { ++ nor->read_opcode = SPINOR_OP_READ; ++ nor->read_dummy = 0; ++ } ++ } ++ ++ if (!(modes->rd_modes & (SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4))) { ++ ret = spi_nor_reset_pin_enable(nor, info); ++ if (ret < 0) { ++ dev_err(nor->dev, "Enable RESET# fail.\n"); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++int spi_nor_scan(struct spi_nor *nor, const char *name, ++ struct spi_nor_modes *modes) ++{ ++ const struct spi_nor_basic_flash_parameter *params = NULL; + const struct flash_info *info = NULL; + struct device *dev = nor->dev; + struct mtd_info *mtd = &nor->mtd; +@@ -1320,11 +2531,19 @@ + if (ret) + return ret; + ++ /* Reset SPI protocol for all commands */ ++ nor->erase_proto = SNOR_PROTO_1_1_1; ++ nor->read_proto = SNOR_PROTO_1_1_1; ++ nor->write_proto = SNOR_PROTO_1_1_1; ++ + if (name) + info = spi_nor_match_id(name); + /* Try to auto-detect if chip name wasn't specified or not found */ +- if (!info) ++ if (!info) { ++ dev_info(dev, "SPI Nor ID Table Version %s\n", SPI_NOR_IDS_VER); + info = spi_nor_read_id(nor); ++ } ++ + if (IS_ERR_OR_NULL(info)) + return -ENOENT; + +@@ -1351,9 +2570,15 @@ + info = jinfo; + } + } ++ if (info->params) ++ params = info->params; + + mutex_init(&nor->lock); + ++#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT ++ /* NOR block protection support */ ++ bsp_get_spi_lock_info(nor, info); ++#else + /* + * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up + * with the software protection bits set +@@ -1367,6 +2592,7 @@ + write_sr(nor, 0); + spi_nor_wait_till_ready(nor); + } ++#endif + + if (!mtd->name) + mtd->name = dev_name(dev); +@@ -1380,7 +2606,8 @@ + + /* NOR protection support for STmicro/Micron chips and similar */ + if (JEDEC_MFR(info) == SNOR_MFR_MICRON || +- info->flags & SPI_NOR_HAS_LOCK) { ++ JEDEC_MFR(info) == SNOR_MFR_WINBOND || ++ info->flags & SPI_NOR_HAS_LOCK) { + nor->flash_lock = stm_lock; + nor->flash_unlock = stm_unlock; + nor->flash_is_locked = stm_is_locked; +@@ -1428,92 +2655,61 @@ + if (np) { + /* If we were instantiated by DT, use it */ + if (of_property_read_bool(np, "m25p,fast-read")) +- nor->flash_read = SPI_NOR_FAST; ++ modes->rd_modes |= SNOR_MODE_1_1_1; + else +- nor->flash_read = SPI_NOR_NORMAL; ++ modes->rd_modes &= ~SNOR_MODE_1_1_1; + } else { + /* If we weren't instantiated by DT, default to fast-read */ +- nor->flash_read = SPI_NOR_FAST; ++ modes->rd_modes |= SNOR_MODE_1_1_1; + } + + /* Some devices cannot do fast-read, no matter what DT tells us */ + if (info->flags & SPI_NOR_NO_FR) +- nor->flash_read = SPI_NOR_NORMAL; +- +- /* Quad/Dual-read mode takes precedence over fast/normal */ +- if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) { +- ret = set_quad_mode(nor, info); +- if (ret) { +- dev_err(dev, "quad mode not supported\n"); +- return ret; +- } +- nor->flash_read = SPI_NOR_QUAD; +- } else if (mode == SPI_NOR_DUAL && info->flags & SPI_NOR_DUAL_READ) { +- nor->flash_read = SPI_NOR_DUAL; +- } +- +- /* Default commands */ +- switch (nor->flash_read) { +- case SPI_NOR_QUAD: +- nor->read_opcode = SPINOR_OP_READ_1_1_4; +- break; +- case SPI_NOR_DUAL: +- nor->read_opcode = SPINOR_OP_READ_1_1_2; +- break; +- case SPI_NOR_FAST: +- nor->read_opcode = SPINOR_OP_READ_FAST; +- break; +- case SPI_NOR_NORMAL: +- nor->read_opcode = SPINOR_OP_READ; +- break; +- default: +- dev_err(dev, "No Read opcode defined\n"); +- return -EINVAL; +- } ++ modes->rd_modes &= ~SNOR_MODE_1_1_1; + + nor->program_opcode = SPINOR_OP_PP; + ++ /* ++ * Configure the SPI memory: ++ * - select op codes for (Fast) Read, Page Program and Sector Erase. ++ * - set the number of dummy cycles (mode cycles + wait states). ++ * - set the SPI protocols for register and memory accesses. ++ * - set the Quad Enable bit if needed (required by SPI x-y-4 protos). ++ */ ++ ret = spi_nor_config(nor, info, params, modes); ++ if (ret) ++ return ret; ++ + if (info->addr_width) + nor->addr_width = info->addr_width; + else if (mtd->size > 0x1000000) { + /* enable 4-byte addressing if the device exceeds 16MiB */ + nor->addr_width = 4; +- if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) { +- /* Dedicated 4-byte command set */ +- switch (nor->flash_read) { +- case SPI_NOR_QUAD: +- nor->read_opcode = SPINOR_OP_READ4_1_1_4; +- break; +- case SPI_NOR_DUAL: +- nor->read_opcode = SPINOR_OP_READ4_1_1_2; +- break; +- case SPI_NOR_FAST: +- nor->read_opcode = SPINOR_OP_READ4_FAST; +- break; +- case SPI_NOR_NORMAL: +- nor->read_opcode = SPINOR_OP_READ4; +- break; +- } +- nor->program_opcode = SPINOR_OP_PP_4B; +- /* No small sector erase for 4-byte command set */ +- nor->erase_opcode = SPINOR_OP_SE_4B; +- mtd->erasesize = info->sector_size; +- } else ++ if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || ++ info->flags & SPI_NOR_4B_OPCODES) ++ spi_nor_set_4byte_opcodes(nor, info); ++ else + set_4byte(nor, info, 1); + } else { + nor->addr_width = 3; + } + ++ /* choose the suitable clockrate */ ++ if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) /* device supports dual or quad */ ++ && (modes->rd_modes & (~SNOR_MODE_SLOW)) /* controller supports fast mode */ ++ && info->clkrate) ++ nor->clkrate = info->clkrate; ++ else ++ nor->clkrate = 24000000; ++ + if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) { + dev_err(dev, "address width is too large: %u\n", + nor->addr_width); + return -EINVAL; + } + +- nor->read_dummy = spi_nor_read_dummy_cycles(nor); +- +- dev_info(dev, "%s (%lld Kbytes)\n", info->name, +- (long long)mtd->size >> 10); ++ dev_info(dev, "%s (Chipsize %lld Mbytes, Blocksize %uKiB)\n", ++ info->name, (long long)mtd->size >> 20, mtd->erasesize / 1024); + + dev_dbg(dev, + "mtd .name = %s, .size = 0x%llx (%lldMiB), " +@@ -1547,6 +2743,64 @@ + return NULL; + } + ++/******************************************************************************/ ++void spi_nor_driver_shutdown(struct spi_nor *nor) ++{ ++ /* disable 4-byte addressing if the device exceeds 16MiB */ ++ if (nor->addr_width == 4) { ++ const struct flash_info *info = NULL; ++ ++ info = spi_nor_read_id(nor); ++ set_4byte(nor, info, 0); ++ } ++ return; ++} ++ ++#ifdef CONFIG_PM ++/******************************************************************************/ ++int spi_nor_suspend(struct spi_nor *nor, pm_message_t state) ++{ ++ return spi_nor_wait_till_ready(nor); ++} ++ ++/******************************************************************************/ ++int spi_nor_resume(struct spi_nor *nor) ++{ ++ int ret; ++ const struct flash_info *info = NULL; ++ const struct spi_nor_basic_flash_parameter *params = NULL; ++ struct spi_nor_modes modes = { ++ .rd_modes = SNOR_MODE_SLOW, ++ .wr_modes = SNOR_MODE_1_1_1, ++ }; ++ ++ modes.rd_modes |= SNOR_MODE_1_1_1 ++ | SNOR_MODE_1_1_2 ++ | SNOR_MODE_1_2_2; ++#ifndef CONFIG_CLOSE_SPI_8PIN_4IO ++ modes.rd_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; ++ modes.wr_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; ++#endif ++ ++ if (!info) ++ info = spi_nor_read_id(nor); ++ ++ /* Quad mode takes precedence over fast/normal */ ++ if (info->params) ++ params = info->params; ++ ++ ret = spi_nor_config(nor, info, params, &modes); ++ if (ret) ++ return ret; ++ ++ /* enable 4-byte addressing if the device exceeds 16MiB */ ++ if (nor->addr_width == 4 && JEDEC_MFR(info) != SNOR_MFR_SPANSION) ++ set_4byte(nor, info, 1); ++ ++ return 0; ++} ++#endif /* End of CONFIG_PM */ ++ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Huang Shijie "); + MODULE_AUTHOR("Mike Lavender"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-Kconfig.patch new file mode 100644 index 00000000..531993dd --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-Kconfig.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/net/ethernet/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -75,6 +75,7 @@ + source "drivers/net/ethernet/freescale/Kconfig" + source "drivers/net/ethernet/fujitsu/Kconfig" + source "drivers/net/ethernet/hisilicon/Kconfig" ++source "drivers/net/ethernet/goke/Kconfig" + source "drivers/net/ethernet/hp/Kconfig" + source "drivers/net/ethernet/ibm/Kconfig" + source "drivers/net/ethernet/intel/Kconfig" diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-Makefile.patch new file mode 100644 index 00000000..705fc156 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/net/ethernet/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -38,6 +38,7 @@ + obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/ + obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/ + obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/ ++obj-$(CONFIG_NET_VENDOR_GOKE) += goke/ + obj-$(CONFIG_NET_VENDOR_HP) += hp/ + obj-$(CONFIG_NET_VENDOR_IBM) += ibm/ + obj-$(CONFIG_NET_VENDOR_INTEL) += intel/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-Kconfig.patch new file mode 100644 index 00000000..ea3a8eb4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-Kconfig.patch @@ -0,0 +1,35 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,32 @@ ++# ++# Goke device configuration ++# ++ ++config NET_VENDOR_GOKE ++ bool "Goke devices" ++ default y ++ depends on (OF || ACPI) && HAS_DMA ++ depends on ARM || ARM64 || COMPILE_TEST ++ ---help--- ++ If you have a network (Ethernet) card belonging to this class, say Y. ++ ++ Note that the answer to this question doesn't directly affect the ++ kernel: saying N will just cause the configurator to skip all ++ the questions about Goke devices. If you say Y, you will be asked ++ for your specific card in the following questions. ++ ++if NET_VENDOR_GOKE ++ ++config GOKE_FEMAC ++ tristate "Goke Fast Ethernet MAC device support" ++ depends on HAS_IOMEM ++ select PHYLIB ++ select RESET_CONTROLLER ++ help ++ This selects the Goke Fast Ethernet MAC device(FEMAC). ++ The FEMAC receives and transmits data over Ethernet ++ ports at 10/100 Mbps in full-duplex or half-duplex mode. ++ The FEMAC exchanges data with the CPU, and supports ++ the energy efficient Ethernet (EEE). ++ ++endif # NET_VENDOR_GOKE diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-Makefile.patch new file mode 100644 index 00000000..a8e2f58b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-Makefile.patch @@ -0,0 +1,8 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,5 @@ ++# ++# Makefile for the network device drivers. ++# ++ ++obj-$(CONFIG_GOKE_FEMAC) += femac/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-Makefile.patch new file mode 100644 index 00000000..d6114315 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-Makefile.patch @@ -0,0 +1,8 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,5 @@ ++# ++# Makefile for the Fast Ethernet network device drivers. ++# ++ ++obj-$(CONFIG_GOKE_FEMAC) += femac.o phy_fix.o util.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-femac.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-femac.c.patch new file mode 100644 index 00000000..800131af --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-femac.c.patch @@ -0,0 +1,1563 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/femac.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/femac.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,1560 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "phy_fix.h" ++#include "femac.h" ++#include "util.h" ++ ++static void femac_irq_enable(const struct femac_priv *priv, u32 irqs) ++{ ++ u32 val; ++ ++ val = readl(priv->glb_base + GLB_IRQ_ENA); ++ writel(val | irqs, priv->glb_base + GLB_IRQ_ENA); ++} ++ ++static void femac_irq_disable(const struct femac_priv *priv, u32 irqs) ++{ ++ u32 val; ++ ++ val = readl(priv->glb_base + GLB_IRQ_ENA); ++ writel(val & (~irqs), priv->glb_base + GLB_IRQ_ENA); ++} ++ ++#ifdef CONFIG_FEPHY_OPT ++static u32 highflag = 0; ++static u32 lowflag = 0; ++static void femac_trim_phy(struct phy_device *phy_dev, u32 val) ++{ ++ u32 val1; ++ /* 32 pieces of data */ ++ int table[32] = {0x11, 0x10, 0x10, 0xf, 0xe, 0xd, 0xd, 0xc, ++ 0xb, 0xa, 0xa, 0x9, 0x8, 0x7, 0x7, 0x6, ++ 0x5, 0x5, 0x4, 0x3, 0x2, 0x2, 0x1, 0x0, ++ 0x3f, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a ++ }; ++ ++ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE); ++ phy_write(phy_dev, MII_EXPMD, val); ++ val &= 0x1f; ++ val1 = table[val]; ++ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE); ++ val = phy_read(phy_dev, MII_EXPMD); ++ val = (val1 << 2) | (val & 0x3); /* shift left 2 bits */ ++ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE); ++ phy_write(phy_dev, MII_EXPMD, val); ++} ++ ++static void femac_trim(struct net_device *dev) ++{ ++ struct phy_device *phy_dev = NULL; ++ int temp; ++ u32 val; ++ ++ phy_dev = dev->phydev; ++ if (phy_dev == NULL) { ++ pr_err("get phy device failed \n"); ++ return; ++ } ++ ++ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE); ++ val = phy_read(phy_dev, MII_EXPMD); ++ temp = regval_to_temp(val); ++ if ((temp > HIGH_TEMP) && (highflag == 0)) { ++ highflag = 1; ++ if ((val & 0x1f) > 1) ++ val = (val & 0xe0) | ((val & 0x1f) - 1); ++ else ++ return; ++ femac_trim_phy(phy_dev, val); ++ } ++ if ((temp < NORMAL_TEMP1) && (highflag == 1)) { ++ highflag = 0; ++ if ((val & 0x1f) < 0x1f) ++ val = (val & 0xe0) | ((val & 0x1f) + 1); ++ else ++ return; ++ femac_trim_phy(phy_dev, val); ++ } ++ if ((temp > NORMAL_TEMP2) && (lowflag == 0)) { ++ lowflag = 1; ++ if ((val & 0x1f) > 1) ++ val = (val & 0xe0) | ((val & 0x1f) - 1); ++ else ++ return; ++ femac_trim_phy(phy_dev, val); ++ } ++ if ((temp < LOW_TEMP) && (lowflag == 1)) { ++ lowflag = 0; ++ if ((val & 0x1f) < 0x1f) ++ val = (val & 0xe0) | ((val & 0x1f) + 1); ++ else ++ return; ++ femac_trim_phy(phy_dev, val); ++ } ++} ++ ++static void femac_watchdog(struct work_struct *work) ++{ ++ struct delayed_work *dwork = to_delayed_work(work); ++ struct femac_priv *priv = container_of(dwork, struct femac_priv, watchdog_queue); ++ void __iomem *sys_reg_addr; ++ struct net_device *dev = NULL; ++ u32 val; ++ ++ dev = priv->ndev; ++ if (dev == NULL) { ++ pr_err("get net device failed \n"); ++ return; ++ } ++ ++ sys_reg_addr = (void __iomem *)ioremap_nocache(SYS_REG_ADDR, 0x100); ++ if (!sys_reg_addr) { ++ pr_err("iomap failed \n"); ++ return; ++ } ++ val = readl(sys_reg_addr + MISC_CTRL45); ++ if ((val >> 30) != 0x3) { /* bit[30 31] */ ++ val |= TSENSOR_EN; ++ writel(val, sys_reg_addr + MISC_CTRL45); ++ mdelay(10); /* wait 10ms */ ++ } ++ val = readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT0; ++ /* high 16bit */ ++ val += (readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT1) >> 16; ++ val += readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT2; ++ /* high 16bit */ ++ val += (readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT3) >> 16; ++ val = val / 4; /* average value of the 4 values */ ++ if (val < LOW_TEM_VALUE || val > HIGH_TEM_VALUE) { ++ goto out; ++ } ++ femac_trim(dev); ++out: ++ iounmap(sys_reg_addr); ++ schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER); ++} ++#endif ++ ++static void femac_tx_sg_dma_unmap(const struct femac_priv *priv, ++ const struct sk_buff *skb, unsigned int pos) ++{ ++ struct tx_desc *desc_cur; ++ dma_addr_t addr; ++ u32 len; ++ int i; ++ ++ desc_cur = priv->tx_ring.desc + pos; ++ ++ addr = desc_cur->linear_addr; ++ len = desc_cur->linear_len; ++ dma_unmap_single(priv->dev, addr, len, DMA_TO_DEVICE); ++ ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ addr = desc_cur->frags[i].addr; ++ len = desc_cur->frags[i].size; ++ dma_unmap_page(priv->dev, addr, len, DMA_TO_DEVICE); ++ } ++} ++ ++static void femac_tx_dma_unmap(const struct femac_priv *priv, ++ const struct sk_buff *skb, unsigned int pos) ++{ ++ if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) { ++ dma_addr_t dma_addr; ++ ++ dma_addr = priv->txq.dma_phys[pos]; ++ dma_unmap_single(priv->dev, dma_addr, skb->len, DMA_TO_DEVICE); ++ } else { ++ femac_tx_sg_dma_unmap(priv, skb, pos); ++ } ++} ++ ++static void femac_xmit_reclaim(struct net_device *dev) ++{ ++ struct sk_buff *skb = NULL; ++ struct femac_priv *priv = netdev_priv(dev); ++ struct femac_queue *txq = &priv->txq; ++ unsigned int bytes_compl = 0; ++ unsigned int pkts_compl = 0; ++ u32 val; ++ ++ netif_tx_lock(dev); ++ ++ val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK; ++ while (val < priv->tx_fifo_used_cnt) { ++ skb = txq->skb[txq->tail]; ++ if (unlikely(skb == NULL)) { ++ netdev_err(dev, "xmitq_cnt_inuse=%d, tx_fifo_used=%d\n", ++ val, priv->tx_fifo_used_cnt); ++ break; ++ } ++ femac_tx_dma_unmap(priv, skb, txq->tail); ++ pkts_compl++; ++ bytes_compl += skb->len; ++ dev_kfree_skb_any(skb); ++ ++ priv->tx_fifo_used_cnt--; ++ ++ val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK; ++ txq->skb[txq->tail] = NULL; ++ txq->tail = (txq->tail + 1) % txq->num; ++ } ++ ++ netdev_completed_queue(dev, pkts_compl, bytes_compl); ++ ++ if (unlikely(netif_queue_stopped(dev)) && pkts_compl) ++ netif_wake_queue(dev); ++ ++ netif_tx_unlock(dev); ++} ++ ++static void femac_get_tso_err_info(const struct femac_priv *priv) ++{ ++ unsigned int reg_addr, reg_tx_info, reg_tx_err; ++ unsigned int sg_index; ++ struct tx_desc *sg_desc = NULL; ++ int *sg_word = NULL; ++ int i; ++ ++ reg_addr = readl(priv->port_base + TSO_DBG_ADDR); ++ reg_tx_info = readl(priv->port_base + TSO_DBG_TX_INFO); ++ reg_tx_err = readl(priv->port_base + TSO_DBG_TX_ERR); ++ ++ WARN(1, "tx err=0x%x, tx_info=0x%x, addr=0x%x\n", ++ reg_tx_err, reg_tx_info, reg_addr); ++ ++ sg_index = (reg_addr - priv->tx_ring.dma_phys) / sizeof(struct tx_desc); ++ sg_desc = priv->tx_ring.desc + sg_index; ++ sg_word = (int *)sg_desc; ++ for (i = 0; i < sizeof(struct tx_desc) / sizeof(int); i++) ++ pr_err("%s,%d: sg_desc word[%d]=0x%x\n", ++ __func__, __LINE__, i, sg_word[i]); ++ ++ /* restart MAC to transmit next packet */ ++ femac_irq_disable(priv, INT_TX_ERR); ++ /* ++ * If we need allow netcard transmit packet again. ++ * we should readl TSO_DBG_STATE and enable irq. ++ */ ++} ++ ++static netdev_tx_t femac_net_xmit(struct sk_buff *skb, ++ struct net_device *dev); ++ ++static netdev_tx_t femac_sw_gso(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct sk_buff *segs = NULL; ++ struct sk_buff *curr_skb = NULL; ++ netdev_features_t features = dev->features; ++ ++ features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | ++ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO); ++ segs = skb_gso_segment(skb, features); ++ if (IS_ERR_OR_NULL(segs)) { ++ goto drop; ++ } ++ ++ do { ++ curr_skb = segs; ++ segs = segs->next; ++ curr_skb->next = NULL; ++ if (femac_net_xmit(curr_skb, dev)) { ++ dev_kfree_skb(curr_skb); ++ while (segs != NULL) { ++ curr_skb = segs; ++ segs = segs->next; ++ curr_skb->next = NULL; ++ dev_kfree_skb_any(curr_skb); ++ } ++ goto drop; ++ } ++ } while (segs != NULL); ++ ++ dev_kfree_skb_any(skb); ++ return NETDEV_TX_OK; ++ ++drop: ++ dev_kfree_skb_any(skb); ++ dev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++} ++ ++static int femac_fill_sg_desc(const struct femac_priv *priv, ++ const struct sk_buff *skb, unsigned int pos) ++{ ++ struct tx_desc *desc_cur; ++ dma_addr_t addr; ++ int ret; ++ int i; ++ ++ desc_cur = priv->tx_ring.desc + pos; ++ ++ desc_cur->ipv6_id = ntohl(skb_shinfo(skb)->ip6_frag_id); ++ ++ desc_cur->total_len = skb->len; ++ addr = dma_map_single(priv->dev, skb->data, skb_headlen(skb), ++ DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(priv->dev, addr))) { ++ return -EINVAL; ++ } ++ desc_cur->linear_addr = addr; ++ desc_cur->linear_len = skb_headlen(skb); ++ ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ int len = frag->size; ++ ++ addr = skb_frag_dma_map(priv->dev, frag, 0, len, DMA_TO_DEVICE); ++ ret = dma_mapping_error(priv->dev, addr); ++ if (unlikely(ret)) { ++ return -EINVAL; ++ } ++ desc_cur->frags[i].addr = addr; ++ desc_cur->frags[i].size = len; ++ } ++ ++ return 0; ++} ++ ++static void femac_adjust_link(struct net_device *dev) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct phy_device *phy = dev->phydev; ++ u32 status = 0; ++ ++ if (phy->link) ++ status |= MAC_PORTSET_LINKED; ++ if (phy->duplex == DUPLEX_FULL) ++ status |= MAC_PORTSET_DUPLEX_FULL; ++ if (phy->speed == SPEED_100) ++ status |= MAC_PORTSET_SPEED_100M; ++ ++ if ((status != priv->link_status) && ++ ((status | priv->link_status) & MAC_PORTSET_LINKED)) { ++ writel(status, priv->port_base + MAC_PORTSET); ++ priv->link_status = status; ++ phy_print_status(phy); ++ ++ priv->tx_pause_en = phy->pause; ++ femac_set_flow_ctrl(priv); ++ } ++} ++ ++static void femac_rx_refill(struct femac_priv *priv) ++{ ++ struct femac_queue *rxq = &priv->rxq; ++ struct sk_buff *skb = NULL; ++ u32 pos; ++ u32 len; ++ dma_addr_t addr; ++ u32 alloc_rxbuf_align; ++ int reserve_room; ++ ++ pos = rxq->head; ++ while (readl(priv->port_base + ADDRQ_STAT) & BIT_RX_READY) { ++ if (!CIRC_SPACE(pos, rxq->tail, rxq->num)) { ++ break; ++ } ++ if (unlikely(rxq->skb[pos])) { ++ netdev_err(priv->ndev, "err skb[%d]=%p\n", ++ pos, rxq->skb[pos]); ++ break; ++ } ++ len = MAX_FRAME_SIZE + RXBUF_ADDR_ALIGN_SIZE; ++ skb = netdev_alloc_skb_ip_align(priv->ndev, len); ++ if (unlikely(skb == NULL)) { ++ break; ++ } ++ ++ alloc_rxbuf_align = ((uintptr_t)skb->data - NET_IP_ALIGN) & ++ (RXBUF_ADDR_ALIGN_SIZE - 1); ++ if (alloc_rxbuf_align) { ++ reserve_room = RXBUF_ADDR_ALIGN_SIZE - ++ alloc_rxbuf_align; ++ len -= reserve_room; ++ skb_reserve(skb, reserve_room); ++ } ++ ++ addr = dma_map_single(priv->dev, skb->data, len, ++ DMA_FROM_DEVICE); ++ if (dma_mapping_error(priv->dev, addr)) { ++ dev_kfree_skb_any(skb); ++ break; ++ } ++ rxq->dma_phys[pos] = addr; ++ rxq->skb[pos] = skb; ++ writel(addr, priv->port_base + IQ_ADDR); ++ pos = (pos + 1) % rxq->num; ++ } ++ rxq->head = pos; ++} ++ ++#ifdef FEMAC_RX_REFILL_IN_IRQ ++static void femac_recv_queue(struct net_device *dev, struct sk_buff *skb, ++ u32 rx_pkt_info) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ int hdr_csum_done, hdr_csum_err; ++ int payload_csum_done, payload_csum_err; ++ ++ skb->ip_summed = CHECKSUM_NONE; ++ if (dev->features & NETIF_F_RXCSUM) { ++ hdr_csum_done = ++ (rx_pkt_info >> BITS_HEADER_DONE_OFFSET) & ++ BITS_HEADER_DONE_MASK; ++ payload_csum_done = ++ (rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) & ++ BITS_PAYLOAD_DONE_MASK; ++ hdr_csum_err = ++ (rx_pkt_info >> BITS_HEADER_ERR_OFFSET) & ++ BITS_HEADER_ERR_MASK; ++ payload_csum_err = ++ (rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) & ++ BITS_PAYLOAD_ERR_MASK; ++ ++ if (hdr_csum_done && payload_csum_done) { ++ if (unlikely(hdr_csum_err)) { ++ dev->stats.rx_errors++; ++ dev->stats.rx_crc_errors++; ++ dev_kfree_skb_any(skb); ++ return; ++ } else if (!payload_csum_err) { ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ } ++ } ++ } ++ skb_queue_tail(&priv->rx_head, skb); ++} ++ ++static void femac_pre_receive(struct net_device *dev) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct femac_queue *rxq = &priv->rxq; ++ struct sk_buff *skb = NULL; ++ u32 rx_pkt_info, pos, len; ++ unsigned long rxflags; ++ ++ spin_lock_irqsave(&priv->rxlock, rxflags); ++ pos = rxq->tail; ++ while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) { ++ rx_pkt_info = readl(priv->port_base + IQFRM_DES); ++ len = rx_pkt_info & RX_FRAME_LEN_MASK; ++ len -= ETH_FCS_LEN; ++ ++ /* tell hardware we will deal with this packet */ ++ writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW); ++ ++ skb = rxq->skb[pos]; ++ if (unlikely(skb == NULL)) { ++ netdev_err(dev, "rx skb NULL. pos=%d\n", pos); ++ break; ++ } ++ rxq->skb[pos] = NULL; ++ ++ dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE, ++ DMA_FROM_DEVICE); ++ skb_put(skb, len); ++ if (unlikely(skb->len > MAX_FRAME_SIZE)) { ++ netdev_err(dev, "rcv len err, len = %d\n", skb->len); ++ dev->stats.rx_errors++; ++ dev->stats.rx_length_errors++; ++ dev_kfree_skb_any(skb); ++ goto next; ++ } ++ ++ femac_recv_queue(dev, skb, rx_pkt_info); ++next: ++ pos = (pos + 1) % rxq->num; ++ } ++ rxq->tail = pos; ++ ++ femac_rx_refill(priv); ++ spin_unlock_irqrestore(&priv->rxlock, rxflags); ++} ++ ++static u32 femac_rx(struct net_device *dev, int limit) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct sk_buff *skb = skb_dequeue(&priv->rx_head); ++ u32 rx_pkts_num = 0; ++ ++ while (skb != NULL) { ++ skb->protocol = eth_type_trans(skb, dev); ++ napi_gro_receive(&priv->napi, skb); ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += skb->len; ++ rx_pkts_num++; ++ ++ if (rx_pkts_num >= limit) { ++ break; ++ } ++ skb = skb_dequeue(&priv->rx_head); ++ } ++ ++ return rx_pkts_num; ++} ++#else ++static int femac_recv_queue(struct net_device *dev, struct sk_buff *skb, ++ u32 rx_pkt_info) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ int hdr_csum_done, hdr_csum_err; ++ int payload_csum_done, payload_csum_err; ++ ++ skb->ip_summed = CHECKSUM_NONE; ++ if (dev->features & NETIF_F_RXCSUM) { ++ hdr_csum_done = ++ (rx_pkt_info >> BITS_HEADER_DONE_OFFSET) & ++ BITS_HEADER_DONE_MASK; ++ payload_csum_done = ++ (rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) & ++ BITS_PAYLOAD_DONE_MASK; ++ hdr_csum_err = ++ (rx_pkt_info >> BITS_HEADER_ERR_OFFSET) & ++ BITS_HEADER_ERR_MASK; ++ payload_csum_err = ++ (rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) & ++ BITS_PAYLOAD_ERR_MASK; ++ ++ if (hdr_csum_done && payload_csum_done) { ++ if (unlikely(hdr_csum_err)) { ++ dev->stats.rx_errors++; ++ dev->stats.rx_crc_errors++; ++ dev_kfree_skb_any(skb); ++ return -1; ++ } else if (!payload_csum_err) { ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ } ++ } ++ } ++ return 0; ++} ++ ++static u32 femac_rx(struct net_device *dev, int limit) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct femac_queue *rxq = &priv->rxq; ++ struct sk_buff *skb; ++ u32 rx_pkt_info, pos, len; ++ u32 rx_pkts_num = 0; ++ ++ pos = rxq->tail; ++ while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) { ++ rx_pkt_info = readl(priv->port_base + IQFRM_DES); ++ len = rx_pkt_info & RX_FRAME_LEN_MASK; ++ len -= ETH_FCS_LEN; ++ ++ /* tell hardware we will deal with this packet */ ++ writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW); ++ ++ rx_pkts_num++; ++ ++ skb = rxq->skb[pos]; ++ if (unlikely(!skb)) { ++ netdev_err(dev, "rx skb NULL. pos=%d\n", pos); ++ break; ++ } ++ rxq->skb[pos] = NULL; ++ ++ dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE, ++ DMA_FROM_DEVICE); ++ skb_put(skb, len); ++ if (unlikely(skb->len > MAX_FRAME_SIZE)) { ++ netdev_err(dev, "rcv len err, len = %d\n", skb->len); ++ dev->stats.rx_errors++; ++ dev->stats.rx_length_errors++; ++ dev_kfree_skb_any(skb); ++ goto next; ++ } ++ ++ if (femac_recv_queue(dev, skb, rx_pkt_info) < 0) ++ goto next; ++ ++ skb->protocol = eth_type_trans(skb, dev); ++ napi_gro_receive(&priv->napi, skb); ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += len; ++next: ++ pos = (pos + 1) % rxq->num; ++ if (rx_pkts_num >= limit) { ++ break; ++ } ++ } ++ rxq->tail = pos; ++ ++ femac_rx_refill(priv); ++ ++ return rx_pkts_num; ++} ++#endif ++ ++static int femac_poll(struct napi_struct *napi, int budget) ++{ ++ struct femac_priv *priv = container_of(napi, ++ struct femac_priv, napi); ++ struct net_device *dev = priv->ndev; ++ int work_done = 0; ++ int task = budget; ++ u32 ints, num; ++ ++ do { ++#ifdef FEMAC_RX_REFILL_IN_IRQ ++ femac_pre_receive(dev); ++#endif ++ femac_xmit_reclaim(dev); ++ num = femac_rx(dev, task); ++ work_done += num; ++ task -= num; ++ if (work_done >= budget) { ++ break; ++ } ++ ++ ints = readl(priv->glb_base + GLB_IRQ_RAW); ++ writel(ints & DEF_INT_MASK, ++ priv->glb_base + GLB_IRQ_RAW); ++ } while (ints & DEF_INT_MASK); ++ ++ if (work_done < budget) { ++ napi_complete(napi); ++ femac_irq_enable(priv, DEF_INT_MASK & ++ (~IRQ_INT_TX_PER_PACKET)); ++ } ++ ++ return work_done; ++} ++ ++static irqreturn_t femac_interrupt(int irq, void *dev_id) ++{ ++ u32 ints; ++ struct net_device *dev = (struct net_device *)dev_id; ++ struct femac_priv *priv = netdev_priv(dev); ++ ++ ints = readl(priv->glb_base + GLB_IRQ_RAW); ++ if (likely(ints & DEF_INT_MASK)) { ++#ifdef FEMAC_RX_REFILL_IN_IRQ ++ femac_pre_receive(dev); ++#endif ++ writel(ints & DEF_INT_MASK, ++ priv->glb_base + GLB_IRQ_RAW); ++ femac_irq_disable(priv, DEF_INT_MASK); ++ napi_schedule(&priv->napi); ++ } ++ ++ if (has_tso_cap(priv->hw_cap) && unlikely(ints & INT_TX_ERR)) ++ femac_get_tso_err_info(priv); ++ ++ return IRQ_HANDLED; ++} ++ ++static int femac_init_tx_descriptor_ring(struct femac_priv *priv) ++{ ++ priv->tx_ring.desc = (struct tx_desc *)dma_zalloc_coherent(priv->dev, ++ TXQ_NUM * sizeof(struct tx_desc), &priv->tx_ring.dma_phys, GFP_KERNEL); ++ if (!priv->tx_ring.desc) { ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static void femac_destroy_tx_descriptor_ring(struct femac_priv *priv) ++{ ++ if (priv->tx_ring.desc) ++ dma_free_coherent(priv->dev, TXQ_NUM * sizeof(struct tx_desc), ++ priv->tx_ring.desc, priv->tx_ring.dma_phys); ++ priv->tx_ring.desc = NULL; ++} ++ ++static int femac_init_queue(struct device *dev, ++ struct femac_queue *queue, unsigned int num) ++{ ++ queue->skb = devm_kcalloc(dev, num, sizeof(struct sk_buff *), GFP_KERNEL); ++ if (queue->skb == NULL) { ++ return -ENOMEM; ++ } ++ ++ queue->dma_phys = devm_kcalloc(dev, num, sizeof(dma_addr_t), GFP_KERNEL); ++ if (queue->dma_phys == NULL) { ++ return -ENOMEM; ++ } ++ ++ queue->num = num; ++ queue->head = 0; ++ queue->tail = 0; ++ ++ return 0; ++} ++ ++static int femac_init_tx_and_rx_queues(struct femac_priv *priv) ++{ ++ int ret; ++ ++ ret = femac_init_queue(priv->dev, &priv->txq, TXQ_NUM); ++ if (ret) { ++ return ret; ++ } ++ ++ ret = femac_init_queue(priv->dev, &priv->rxq, RXQ_NUM); ++ if (ret) { ++ return ret; ++ } ++ ++ priv->tx_fifo_used_cnt = 0; ++ ++ return 0; ++} ++ ++static void femac_free_skb_rings(struct femac_priv *priv) ++{ ++ struct femac_queue *txq = &priv->txq; ++ struct femac_queue *rxq = &priv->rxq; ++ struct sk_buff *skb = NULL; ++ dma_addr_t dma_addr; ++ u32 pos; ++ ++ pos = rxq->tail; ++ while (pos != rxq->head) { ++ skb = rxq->skb[pos]; ++ if (unlikely(skb == NULL)) { ++ netdev_err(priv->ndev, "NULL rx skb. pos=%d, head=%d\n", ++ pos, rxq->head); ++ pos = (pos + 1) % rxq->num; ++ continue; ++ } ++ ++ dma_addr = rxq->dma_phys[pos]; ++ dma_unmap_single(priv->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE); ++ ++ dev_kfree_skb_any(skb); ++ rxq->skb[pos] = NULL; ++ pos = (pos + 1) % rxq->num; ++ } ++ rxq->tail = pos; ++ ++ pos = txq->tail; ++ while (pos != txq->head) { ++ skb = txq->skb[pos]; ++ if (unlikely(skb == NULL)) { ++ netdev_err(priv->ndev, "NULL tx skb. pos=%d, head=%d\n", ++ pos, txq->head); ++ pos = (pos + 1) % txq->num; ++ continue; ++ } ++ femac_tx_dma_unmap(priv, skb, pos); ++ dev_kfree_skb_any(skb); ++ txq->skb[pos] = NULL; ++ pos = (pos + 1) % txq->num; ++ } ++ txq->tail = pos; ++ priv->tx_fifo_used_cnt = 0; ++} ++ ++static int femac_set_hw_mac_addr(const struct femac_priv *priv, ++ const unsigned char *mac) ++{ ++ u32 reg; ++ ++ reg = mac[1] | (mac[0] << 8); /* mac0 is high 8 bits */ ++ writel(reg, priv->glb_base + GLB_HOSTMAC_H16); ++ /* addr2 [24 31] addr3 [16 23] addr4 [8 15] addr5 [0 7] */ ++ reg = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24); ++ writel(reg, priv->glb_base + GLB_HOSTMAC_L32); ++ ++ return 0; ++} ++ ++static int femac_port_reset(const struct femac_priv *priv) ++{ ++ u32 val; ++ ++ val = readl(priv->glb_base + GLB_SOFT_RESET); ++ val |= SOFT_RESET_ALL; ++ writel(val, priv->glb_base + GLB_SOFT_RESET); ++ ++ usleep_range(500, 800); /* wait 500-800us */ ++ ++ val &= ~SOFT_RESET_ALL; ++ writel(val, priv->glb_base + GLB_SOFT_RESET); ++ ++ return 0; ++} ++ ++static int femac_net_open(struct net_device *dev) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ ++ femac_set_hw_mac_addr(priv, dev->dev_addr); ++ /* ++ * clear interrupts will drop the first packet MAC have received, ++ * so do it before refill the rx free skbs. ++ */ ++ writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW); ++ femac_rx_refill(priv); ++ ++ netif_carrier_off(dev); ++ netdev_reset_queue(dev); ++ netif_start_queue(dev); ++ napi_enable(&priv->napi); ++ ++ priv->link_status = 0; ++ if (dev->phydev) ++ phy_start(dev->phydev); ++ ++ femac_irq_enable(priv, IRQ_ENA_ALL | IRQ_ENA_PORT0 | DEF_INT_MASK); ++ if (has_tso_cap(priv->hw_cap)) ++ femac_irq_enable(priv, INT_TX_ERR); ++ ++ return 0; ++} ++ ++static void femac_port_init(struct femac_priv *priv); ++ ++static int femac_net_close(struct net_device *dev) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ ++ femac_irq_disable(priv, IRQ_ENA_PORT0); ++ ++ if (dev->phydev) ++ phy_stop(dev->phydev); ++ ++ netif_stop_queue(dev); ++ napi_disable(&priv->napi); ++ ++ /* ++ * reset MAC port first before free skb rings ++ * to prevent potential risk of use-after-free. ++ */ ++ femac_port_reset(priv); ++ femac_port_init(priv); ++ ++ priv->tx_pause_en = false; ++ femac_set_flow_ctrl(priv); ++ femac_free_skb_rings(priv); ++#ifdef FEMAC_RX_REFILL_IN_IRQ ++ skb_queue_purge(&priv->rx_head); ++#endif ++ ++ return 0; ++} ++ ++static bool femac_net_isready(struct net_device *dev) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct femac_queue *txq = &priv->txq; ++ u32 val; ++ ++ val = readl(priv->port_base + ADDRQ_STAT); ++ val &= BIT_TX_READY; ++ if (!val) { ++ femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET); ++ dev->stats.tx_dropped++; ++ dev->stats.tx_fifo_errors++; ++ netif_stop_queue(dev); ++ return false; ++ } ++ ++ if (unlikely(!CIRC_SPACE(txq->head, txq->tail, ++ txq->num))) { ++ femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET); ++ dev->stats.tx_dropped++; ++ dev->stats.tx_fifo_errors++; ++ netif_stop_queue(dev); ++ return false; ++ } ++ ++ return true; ++} ++ ++static netdev_tx_t femac_net_xmit(struct sk_buff *skb, ++ struct net_device *dev) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct femac_queue *txq = &priv->txq; ++ dma_addr_t addr; ++ int ret; ++ u32 pkt_info; ++ ++ if (!femac_net_isready(dev)) ++ return NETDEV_TX_BUSY; ++ ++ ret = femac_check_hw_capability(skb); ++ if (unlikely(ret)) { ++ if (ret == -ENOTSUPP) ++ return femac_sw_gso(skb, dev); ++ ++ dev_kfree_skb_any(skb); ++ dev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } ++ ++ pkt_info = femac_get_pkt_info(skb); ++ ++ if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) { ++ addr = dma_map_single(priv->dev, skb->data, ++ skb->len, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(priv->dev, addr))) { ++ dev_kfree_skb_any(skb); ++ dev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } ++ } else { ++ ret = femac_fill_sg_desc(priv, skb, txq->head); ++ if (unlikely(ret)) { ++ dev_kfree_skb_any(skb); ++ dev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } ++ ++ addr = priv->tx_ring.dma_phys + ++ txq->head * sizeof(struct tx_desc); ++ ++ /* Ensure desc info writen to memory before config hardware */ ++ wmb(); ++ } ++ txq->dma_phys[txq->head] = addr; ++ ++ skb_tx_timestamp(skb); ++ ++ txq->skb[txq->head] = skb; ++ txq->head = (txq->head + 1) % txq->num; ++ ++ writel(addr, priv->port_base + EQ_ADDR); ++ writel(pkt_info, priv->port_base + EQFRM_LEN); ++ ++ priv->tx_fifo_used_cnt++; ++ ++ dev->stats.tx_packets++; ++ dev->stats.tx_bytes += skb->len; ++ netdev_sent_queue(dev, skb->len); ++ ++ return NETDEV_TX_OK; ++} ++ ++static int femac_set_mac_address(struct net_device *dev, void *p) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct sockaddr *skaddr = p; ++ ++ if (!is_valid_ether_addr(skaddr->sa_data)) { ++ return -EADDRNOTAVAIL; ++ } ++ ++ memcpy(dev->dev_addr, skaddr->sa_data, dev->addr_len); ++ dev->addr_assign_type &= ~NET_ADDR_RANDOM; ++ ++ femac_set_hw_mac_addr(priv, dev->dev_addr); ++ ++ return 0; ++} ++ ++static void femac_enable_hw_addr_filter(const struct femac_priv *priv, ++ unsigned int reg_n, bool enable) ++{ ++ u32 val; ++ ++ val = readl(priv->glb_base + glb_mac_h16(reg_n)); ++ if (enable) { ++ val |= BIT_MACFLT_ENA; ++ } else { ++ val &= ~BIT_MACFLT_ENA; ++ } ++ writel(val, priv->glb_base + glb_mac_h16(reg_n)); ++} ++ ++static void femac_set_hw_addr_filter(const struct femac_priv *priv, ++ const unsigned char *addr, unsigned int reg_n) ++{ ++ unsigned int high, low; ++ u32 val; ++ ++ high = glb_mac_h16(reg_n); ++ low = glb_mac_l32(reg_n); ++ /* addr2 [24 31] addr3 [16 23] addr4 [8 15] addr5 [0 7] */ ++ val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; ++ writel(val, priv->glb_base + low); ++ ++ val = readl(priv->glb_base + high); ++ val &= ~MACFLT_HI16_MASK; ++ val |= ((addr[0] << 8) | addr[1]); /* addr0 is high 8 bits */ ++ val |= (BIT_MACFLT_ENA | BIT_MACFLT_FW2CPU); ++ writel(val, priv->glb_base + high); ++} ++ ++static void femac_set_promisc_mode(const struct femac_priv *priv, ++ bool promisc_mode) ++{ ++ u32 val; ++ ++ val = readl(priv->glb_base + GLB_FWCTRL); ++ if (promisc_mode) { ++ val |= FWCTRL_FWALL2CPU; ++ } else { ++ val &= ~FWCTRL_FWALL2CPU; ++ } ++ writel(val, priv->glb_base + GLB_FWCTRL); ++} ++ ++/* Handle multiple multicast addresses (perfect filtering) */ ++static void femac_set_mc_addr_filter(const struct femac_priv *priv) ++{ ++ struct net_device *dev = priv->ndev; ++ u32 val; ++ ++ val = readl(priv->glb_base + GLB_MACTCTRL); ++ if ((netdev_mc_count(dev) > MAX_MULTICAST_ADDRESSES) || ++ (dev->flags & IFF_ALLMULTI)) { ++ val |= MACTCTRL_MULTI2CPU; ++ } else { ++ int reg = MAX_UNICAST_ADDRESSES; ++ int i; ++ struct netdev_hw_addr *ha = NULL; ++ ++ for (i = reg; i < MAX_MAC_FILTER_NUM; i++) ++ femac_enable_hw_addr_filter(priv, i, false); ++ ++ netdev_for_each_mc_addr(ha, dev) ++ { ++ femac_set_hw_addr_filter(priv, ha->addr, reg); ++ reg++; ++ } ++ val &= ~MACTCTRL_MULTI2CPU; ++ } ++ writel(val, priv->glb_base + GLB_MACTCTRL); ++} ++ ++/* Handle multiple unicast addresses (perfect filtering) */ ++static void femac_set_uc_addr_filter(const struct femac_priv *priv) ++{ ++ struct net_device *dev = priv->ndev; ++ u32 val; ++ ++ val = readl(priv->glb_base + GLB_MACTCTRL); ++ if (netdev_uc_count(dev) > MAX_UNICAST_ADDRESSES) { ++ val |= MACTCTRL_UNI2CPU; ++ } else { ++ int reg = 0; ++ int i; ++ struct netdev_hw_addr *ha = NULL; ++ ++ for (i = reg; i < MAX_UNICAST_ADDRESSES; i++) ++ femac_enable_hw_addr_filter(priv, i, false); ++ ++ netdev_for_each_uc_addr(ha, dev) ++ { ++ femac_set_hw_addr_filter(priv, ha->addr, reg); ++ reg++; ++ } ++ val &= ~MACTCTRL_UNI2CPU; ++ } ++ writel(val, priv->glb_base + GLB_MACTCTRL); ++} ++ ++static void femac_net_set_rx_mode(struct net_device *dev) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ ++ if (dev->flags & IFF_PROMISC) { ++ femac_set_promisc_mode(priv, true); ++ } else { ++ femac_set_promisc_mode(priv, false); ++ femac_set_mc_addr_filter(priv); ++ femac_set_uc_addr_filter(priv); ++ } ++} ++ ++static int femac_net_ioctl(struct net_device *dev, ++ struct ifreq *ifreq, int cmd) ++{ ++ if (!netif_running(dev)) { ++ return -EINVAL; ++ } ++ ++ if (!dev->phydev) { ++ return -EINVAL; ++ } ++ ++ return phy_mii_ioctl(dev->phydev, ifreq, cmd); ++} ++ ++static const struct ethtool_ops femac_ethtools_ops = { ++ .get_link = ethtool_op_get_link, ++ .get_link_ksettings = phy_ethtool_get_link_ksettings, ++ .set_link_ksettings = phy_ethtool_set_link_ksettings, ++ .get_pauseparam = femac_get_pauseparam, ++ .set_pauseparam = femac_set_pauseparam, ++ .get_ts_info = ethtool_op_get_ts_info, ++}; ++ ++static const struct net_device_ops femac_netdev_ops = { ++ .ndo_open = femac_net_open, ++ .ndo_stop = femac_net_close, ++ .ndo_start_xmit = femac_net_xmit, ++ .ndo_do_ioctl = femac_net_ioctl, ++ .ndo_set_mac_address = femac_set_mac_address, ++ .ndo_set_rx_mode = femac_net_set_rx_mode, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_features = femac_set_features, ++}; ++ ++static void femac_verify_flow_ctrl_args(struct femac_priv *priv) ++{ ++ if (priv->tx_pause_active_thresh < FC_ACTIVE_MIN || ++ priv->tx_pause_active_thresh > FC_ACTIVE_MAX) ++ priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT; ++ ++ if (priv->tx_pause_deactive_thresh < FC_DEACTIVE_MIN || ++ priv->tx_pause_deactive_thresh > FC_DEACTIVE_MAX) ++ priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT; ++ ++ if (priv->tx_pause_active_thresh >= priv->tx_pause_deactive_thresh) { ++ priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT; ++ priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT; ++ } ++} ++ ++static void femac_core_reset(const struct femac_priv *priv) ++{ ++ reset_control_assert(priv->mac_rst); ++ reset_control_deassert(priv->mac_rst); ++} ++ ++static void femac_phy_reset(const struct femac_priv *priv) ++{ ++ /* ++ * To make sure PHY hardware reset success, ++ * we must keep PHY in deassert state first and ++ * then complete the hardware reset operation ++ */ ++ reset_control_deassert(priv->phy_rst); ++ femac_sleep_us(priv->phy_reset_delays[PRE_DELAY]); ++ ++ reset_control_assert(priv->phy_rst); ++ /* ++ * delay some time to ensure reset ok, ++ * this depends on PHY hardware feature ++ */ ++ femac_sleep_us(priv->phy_reset_delays[PULSE]); ++ reset_control_deassert(priv->phy_rst); ++ /* delay some time to ensure later MDIO access */ ++ femac_sleep_us(priv->phy_reset_delays[POST_DELAY]); ++} ++ ++static void femac_port_init(struct femac_priv *priv) ++{ ++ u32 val; ++ ++ /* MAC gets link status info and phy mode by software config */ ++ val = MAC_PORTSEL_STAT_CPU; ++ if (priv->ndev->phydev->interface == PHY_INTERFACE_MODE_RMII) ++ val |= MAC_PORTSEL_RMII; ++ writel(val, priv->port_base + MAC_PORTSEL); ++ ++ /* clear all interrupt status */ ++ writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW); ++ femac_irq_disable(priv, IRQ_ENA_PORT0_MASK | IRQ_ENA_PORT0); ++ ++ if (has_tso_cap(priv->hw_cap)) { ++ /* enable TSO debug for error handle */ ++ val = readl(priv->port_base + TSO_DBG_EN); ++ val |= BITS_TSO_DBG_EN; ++ writel(val, priv->port_base + TSO_DBG_EN); ++ } ++ ++ val = readl(priv->glb_base + GLB_FWCTRL); ++ val &= ~(FWCTRL_VLAN_ENABLE | FWCTRL_FWALL2CPU); ++ val |= FWCTRL_FW2CPU_ENA; ++ writel(val, priv->glb_base + GLB_FWCTRL); ++ ++ val = readl(priv->glb_base + GLB_MACTCTRL); ++ val |= (MACTCTRL_BROAD2CPU | MACTCTRL_MACT_ENA); ++ writel(val, priv->glb_base + GLB_MACTCTRL); ++ ++ val = readl(priv->port_base + MAC_SET); ++ val &= ~MAX_FRAME_SIZE_MASK; ++ val |= MAX_FRAME_SIZE; ++ writel(val, priv->port_base + MAC_SET); ++ ++ val = RX_COALESCED_TIMER | ++ (RX_COALESCED_FRAMES << RX_COALESCED_FRAME_OFFSET); ++ writel(val, priv->port_base + RX_COALESCE_SET); ++ ++ val = (HW_RX_FIFO_DEPTH << RX_DEPTH_OFFSET) | HW_TX_FIFO_DEPTH; ++ writel(val, priv->port_base + QLEN_SET); ++ ++ femac_set_flow_ctrl(priv); ++} ++ ++static int femac_drv_res(struct platform_device *pdev, ++ struct femac_priv *priv) ++{ ++ struct resource *res = NULL; ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ int ret; ++ ++ if (of_device_is_compatible(node, "goke,femac-v2")) ++ priv->hw_cap |= HW_CAP_TSO | HW_CAP_RXCSUM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ priv->port_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(priv->port_base)) { ++ ret = PTR_ERR(priv->port_base); ++ return ret; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ priv->glb_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(priv->glb_base)) { ++ ret = PTR_ERR(priv->glb_base); ++ return ret; ++ } ++ ++ priv->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(priv->clk)) { ++ dev_err(dev, "failed to get clk\n"); ++ ret = -ENODEV; ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) { ++ dev_err(dev, "failed to enable clk %d\n", ret); ++ return ret; ++ } ++ return 0; ++} ++ ++static int femac_drv_mac(struct platform_device *pdev, ++ struct femac_priv *priv) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ const char *mac_addr = NULL; ++ struct net_device *ndev = priv->ndev; ++ ++ priv->mac_rst = devm_reset_control_get(dev, "mac"); ++ if (IS_ERR(priv->mac_rst)) ++ return PTR_ERR(priv->mac_rst); ++ ++ femac_core_reset(priv); ++ ++ mac_addr = of_get_mac_address(node); ++ if (mac_addr != NULL) ++ ether_addr_copy(ndev->dev_addr, mac_addr); ++ if (!is_valid_ether_addr(ndev->dev_addr)) { ++ eth_hw_addr_random(ndev); ++ dev_warn(dev, "using random MAC address %pM\n", ++ ndev->dev_addr); ++ } ++ return 0; ++} ++ ++static struct phy_device* femac_drv_phy(struct platform_device *pdev, ++ struct femac_priv *priv, int *ret) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ struct phy_device* phy = NULL; ++ ++ priv->phy_rst = devm_reset_control_get(dev, "phy"); ++ if (IS_ERR(priv->phy_rst)) { ++ priv->phy_rst = NULL; ++ } else { ++ *ret = of_property_read_u32_array(node, PHY_RESET_DELAYS_PROPERTY, ++ priv->phy_reset_delays, DELAYS_NUM); ++ if (*ret) ++ return phy; ++ femac_phy_reset(priv); ++ } ++ ++ phy_register_fixups(); ++ ++ phy = of_phy_get_and_connect(priv->ndev, node, femac_adjust_link); ++ if (phy == NULL) { ++ /* check if a fixed-link is defined in device-tree */ ++ if (of_phy_is_fixed_link(node)) { ++ *ret = of_phy_register_fixed_link(node); ++ if (*ret < 0) { ++ dev_err(dev, "cannot regitster fixed link phy %d \n", *ret); ++ return phy; ++ } ++ /* ++ * In case of a fixed link phy, the DT node associated ++ * to the phy is the Ethernet MAC DT node. ++ */ ++ phy = of_phy_connect(priv->ndev, of_node_get(node), &femac_adjust_link, 0, of_get_phy_mode(node)); ++ if (phy == NULL) { ++ dev_err(dev, "fixed_link didnot connect successfully.\n"); ++ return phy; ++ } ++ } else { ++ dev_err(dev, "connect to PHY failed!\n"); ++ *ret = -ENODEV; ++ return phy; ++ } ++ } ++ ++ phy->advertising |= ADVERTISED_Pause; ++ phy->supported |= ADVERTISED_Pause; ++ phy->advertising &= ~(ADVERTISED_1000baseT_Full | ++ ADVERTISED_1000baseT_Half); ++ ++ phy_attached_print(phy, "phy_id=0x%.8lx, phy_mode=%s\n", ++ (unsigned long)phy->phy_id, phy_modes(phy->interface)); ++ ++ return phy; ++} ++ ++static void femac_drv_napi(struct platform_device *pdev, ++ struct femac_priv *priv) ++{ ++ struct net_device *ndev = priv->ndev; ++ ++ ndev->watchdog_timeo = 6 * HZ; /* 6HZ */ ++ ndev->priv_flags |= IFF_UNICAST_FLT; ++ ndev->netdev_ops = &femac_netdev_ops; ++ ndev->ethtool_ops = &femac_ethtools_ops; ++ netif_napi_add(ndev, &priv->napi, femac_poll, FEMAC_POLL_WEIGHT); ++ ++#ifdef CONFIG_FEPHY_OPT ++ INIT_DELAYED_WORK(&priv->watchdog_queue, femac_watchdog); ++ schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER); ++#endif ++ ++ if (has_tso_cap(priv->hw_cap)) ++ ndev->hw_features |= NETIF_F_SG | ++ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | ++ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO; ++ ++ if (has_rxcsum_cap(priv->hw_cap)) ++ ndev->hw_features |= NETIF_F_RXCSUM; ++ ndev->features |= ndev->hw_features; ++ ndev->vlan_features |= ndev->features; ++ ++ device_set_wakeup_capable(priv->dev, true); ++ device_set_wakeup_enable(priv->dev, true); ++ ++ priv->tx_pause_en = true; ++ priv->tx_pause_active_thresh = TX_FLOW_CTRL_ACTIVE_THRESHOLD; ++ priv->tx_pause_deactive_thresh = TX_FLOW_CTRL_DEACTIVE_THRESHOLD; ++ ++ femac_verify_flow_ctrl_args(priv); ++ ++ femac_port_init(priv); ++ ++ if (has_rxcsum_cap(priv->hw_cap)) ++ femac_enable_rxcsum_drop(priv, true); ++} ++ ++static int femac_drv_queues(struct platform_device *pdev, ++ struct femac_priv *priv) ++{ ++ int ret; ++ ++#ifdef FEMAC_RX_REFILL_IN_IRQ ++ skb_queue_head_init(&priv->rx_head); ++ spin_lock_init(&priv->rxlock); ++#endif ++ ret = femac_init_tx_and_rx_queues(priv); ++ if (ret) ++ return ret; ++ ++ if (has_tso_cap(priv->hw_cap)) { ++ ret = femac_init_tx_descriptor_ring(priv); ++ if (ret) ++ return ret; ++ } ++ return 0; ++} ++ ++static int femac_drv_register(struct platform_device *pdev, ++ struct femac_priv *priv) ++{ ++ struct device *dev = &pdev->dev; ++ struct net_device *ndev = priv->ndev; ++ int ret; ++ ++ ndev->irq = platform_get_irq(pdev, 0); ++ if (ndev->irq <= 0) { ++ dev_err(dev, "No irq resource\n"); ++ ret = -ENODEV; ++ return ret; ++ } ++ ++ ret = devm_request_irq(dev, ndev->irq, femac_interrupt, ++ IRQF_SHARED, pdev->name, ndev); ++ if (ret) { ++ dev_err(dev, "devm_request_irq %d failed!\n", ndev->irq); ++ return ret;; ++ } ++ ++ ret = register_netdev(ndev); ++ if (ret) { ++ dev_err(dev, "register_netdev failed!\n"); ++ return ret;; ++ } ++ return 0; ++} ++ ++static int femac_drv_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct net_device *ndev = NULL; ++ struct femac_priv *priv = NULL; ++ struct phy_device *phy = NULL; ++ int ret; ++ ++ ndev = alloc_etherdev(sizeof(*priv)); ++ if (ndev == NULL) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, ndev); ++ SET_NETDEV_DEV(ndev, &pdev->dev); ++ ++ priv = netdev_priv(ndev); ++ priv->dev = dev; ++ priv->ndev = ndev; ++ ++ ret = femac_drv_res(pdev, priv); ++ if (ret) ++ goto out_free_netdev; ++ ++ ret = femac_drv_mac(pdev, priv); ++ if (ret) ++ goto out_disable_clk; ++ ++ phy = femac_drv_phy(pdev, priv, &ret); ++ if (phy == NULL) ++ goto out_disable_clk; ++ ++ femac_drv_napi(pdev, priv); ++ ++ ret = femac_drv_queues(pdev, priv); ++ if (ret) ++ goto out_disconnect_phy; ++ ++ ret = femac_drv_register(pdev, priv); ++ if (ret) ++ goto out_destroy_descriptor; ++ ++ return ret; ++ ++out_destroy_descriptor: ++ if (has_tso_cap(priv->hw_cap)) ++ femac_destroy_tx_descriptor_ring(priv); ++out_disconnect_phy: ++ netif_napi_del(&priv->napi); ++ phy_disconnect(phy); ++out_disable_clk: ++ clk_disable_unprepare(priv->clk); ++out_free_netdev: ++ free_netdev(ndev); ++ ++ return ret; ++} ++ ++static int femac_drv_remove(struct platform_device *pdev) ++{ ++ struct net_device *ndev = platform_get_drvdata(pdev); ++ struct femac_priv *priv = netdev_priv(ndev); ++ ++ netif_napi_del(&priv->napi); ++ unregister_netdev(ndev); ++ if (has_tso_cap(priv->hw_cap)) ++ femac_destroy_tx_descriptor_ring(priv); ++ ++ phy_disconnect(ndev->phydev); ++#ifdef CONFIG_FEPHY_OPT ++ cancel_delayed_work_sync(&priv->watchdog_queue); ++#endif ++ clk_disable_unprepare(priv->clk); ++ free_netdev(ndev); ++ ++ phy_unregister_fixups(); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int femac_drv_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ struct net_device *ndev = platform_get_drvdata(pdev); ++ struct femac_priv *priv = netdev_priv(ndev); ++ ++ disable_irq(ndev->irq); ++ if (netif_running(ndev)) { ++ femac_net_close(ndev); ++ netif_device_detach(ndev); ++ } ++ ++ clk_disable_unprepare(priv->clk); ++ ++ return 0; ++} ++ ++static int femac_drv_resume(struct platform_device *pdev) ++{ ++ struct net_device *ndev = platform_get_drvdata(pdev); ++ struct femac_priv *priv = netdev_priv(ndev); ++ ++ clk_prepare_enable(priv->clk); ++ if (priv->phy_rst != NULL) ++ femac_phy_reset(priv); ++ ++ if (netif_running(ndev)) { ++ femac_port_init(priv); ++ femac_net_open(ndev); ++ netif_device_attach(ndev); ++ } ++ enable_irq(ndev->irq); ++ ++ return 0; ++} ++#endif ++ ++static const struct of_device_id femac_match[] = { ++ { ++ .compatible = "goke,femac", ++ }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, femac_match); ++ ++static struct platform_driver femac_driver = { ++ .driver = { ++ .name = "femac", ++ .of_match_table = femac_match, ++ }, ++ .probe = femac_drv_probe, ++ .remove = femac_drv_remove, ++#ifdef CONFIG_PM ++ .suspend = femac_drv_suspend, ++ .resume = femac_drv_resume, ++#endif ++}; ++ ++module_platform_driver(femac_driver); ++ ++MODULE_DESCRIPTION("Goke Fast Ethernet MAC driver"); ++MODULE_AUTHOR("Goke"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:femac"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-femac.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-femac.h.patch new file mode 100644 index 00000000..34a121fa --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-femac.h.patch @@ -0,0 +1,265 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/femac.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/femac.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,262 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __ETH_GOKE_FEMAC_H__ ++#define __ETH_GOKE_FEMAC_H__ ++ ++/* MAC control register list */ ++#define MAC_PORTSEL 0x0200 ++#define MAC_PORTSEL_STAT_CPU BIT(0) ++#define MAC_PORTSEL_RMII BIT(1) ++#define MAC_PORTSET 0x0208 ++#define MAC_PORTSET_DUPLEX_FULL BIT(0) ++#define MAC_PORTSET_LINKED BIT(1) ++#define MAC_PORTSET_SPEED_100M BIT(2) ++#define MAC_SET 0x0210 ++#define MAX_FRAME_SIZE 1600 ++#define MAX_FRAME_SIZE_MASK GENMASK(10, 0) ++#define BIT_PAUSE_EN BIT(18) ++#define RX_COALESCE_SET 0x0340 ++#define RX_COALESCED_FRAME_OFFSET 24 ++#define RX_COALESCED_FRAMES 8 ++#define RX_COALESCED_TIMER 0x74 ++#define QLEN_SET 0x0344 ++#define RX_DEPTH_OFFSET 8 ++#define MAX_HW_FIFO_DEPTH 64 ++#define HW_TX_FIFO_DEPTH 12 ++#define HW_RX_FIFO_DEPTH (MAX_HW_FIFO_DEPTH - HW_TX_FIFO_DEPTH) ++#define FC_LEVEL 0x0348 ++#define BITS_FC_ACTIVE_THR_OFFSET 8 ++#define FC_DEACTIVE_THR_MASK GENMASK(5, 0) ++#define FC_ACTIVE_THR_MASK GENMASK(13, 8) ++#define BIT_FC_EN BIT(14) ++#define IQFRM_DES 0x0354 ++#define RX_FRAME_LEN_MASK GENMASK(11, 0) ++#define BITS_PAYLOAD_ERR_OFFSET 28 ++#define BITS_PAYLOAD_ERR_MASK 0x1 ++#define BITS_HEADER_ERR_OFFSET 29 ++#define BITS_HEADER_ERR_MASK 0x1 ++#define BITS_PAYLOAD_DONE_OFFSET 30 ++#define BITS_PAYLOAD_DONE_MASK 0x1 ++#define BITS_HEADER_DONE_OFFSET 31 ++#define BITS_HEADER_DONE_MASK 0x1 ++#define IQ_ADDR 0x0358 ++#define EQ_ADDR 0x0360 ++#define EQFRM_LEN 0x0364 ++#define ADDRQ_STAT 0x036C ++#define TX_CNT_INUSE_MASK GENMASK(5, 0) ++#define BIT_TX_READY BIT(24) ++#define BIT_RX_READY BIT(25) ++#define RX_COE_CTRL 0x0380 ++#define BIT_COE_IPV6_UDP_ZERO_DROP BIT(13) ++#define BIT_COE_PAYLOAD_DROP BIT(14) ++#define BIT_COE_IPHDR_DROP BIT(15) ++#define COE_ERR_DROP (BIT_COE_IPHDR_DROP | \ ++ BIT_COE_PAYLOAD_DROP | \ ++ BIT_COE_IPV6_UDP_ZERO_DROP) ++#define TSO_DBG_EN 0x03A4 ++#define BITS_TSO_DBG_EN BIT(31) ++#define TSO_DBG_STATE 0x03A8 ++#define TSO_DBG_ADDR 0x03AC ++#define TSO_DBG_TX_INFO 0x03B0 ++#define TSO_DBG_TX_ERR 0x03B4 ++/* global control register list */ ++#define GLB_HOSTMAC_L32 0x0000 ++#define GLB_HOSTMAC_H16 0x0004 ++#define GLB_SOFT_RESET 0x0008 ++#define SOFT_RESET_ALL BIT(0) ++#define GLB_FWCTRL 0x0010 ++#define FWCTRL_VLAN_ENABLE BIT(0) ++#define FWCTRL_FW2CPU_ENA BIT(5) ++#define FWCTRL_FWALL2CPU BIT(7) ++#define GLB_MACTCTRL 0x0014 ++#define MACTCTRL_UNI2CPU BIT(1) ++#define MACTCTRL_MULTI2CPU BIT(3) ++#define MACTCTRL_BROAD2CPU BIT(5) ++#define MACTCTRL_MACT_ENA BIT(7) ++#define GLB_IRQ_STAT 0x0030 ++#define GLB_IRQ_ENA 0x0034 ++#define IRQ_ENA_PORT0_MASK GENMASK(7, 0) ++#define IRQ_ENA_PORT0 BIT(18) ++#define IRQ_ENA_ALL BIT(19) ++#define GLB_IRQ_RAW 0x0038 ++#define IRQ_INT_RX_RDY BIT(0) ++#define IRQ_INT_TX_PER_PACKET BIT(1) ++#define IRQ_INT_TX_FIFO_EMPTY BIT(6) ++#define IRQ_INT_MULTI_RXRDY BIT(7) ++#define INT_TX_ERR BIT(8) ++#define DEF_INT_MASK (IRQ_INT_MULTI_RXRDY | \ ++ IRQ_INT_TX_PER_PACKET | \ ++ IRQ_INT_TX_FIFO_EMPTY) ++#define GLB_MAC_L32_BASE 0x0100 ++#define GLB_MAC_H16_BASE 0x0104 ++#define MACFLT_HI16_MASK GENMASK(15, 0) ++#define BIT_MACFLT_ENA BIT(17) ++#define BIT_MACFLT_FW2CPU BIT(21) ++#define glb_mac_h16(reg) (GLB_MAC_H16_BASE + ((reg) * 0x8)) ++#define glb_mac_l32(reg) (GLB_MAC_L32_BASE + ((reg) * 0x8)) ++#define MAX_MAC_FILTER_NUM 8 ++#define MAX_UNICAST_ADDRESSES 2 ++#define MAX_MULTICAST_ADDRESSES (MAX_MAC_FILTER_NUM - MAX_UNICAST_ADDRESSES) ++/* software tx and rx queue number, should be power of 2 */ ++#define TXQ_NUM 64 ++#define RXQ_NUM 128 ++#define FEMAC_POLL_WEIGHT 64 ++#define HW_CAP_TSO BIT(0) ++#define HW_CAP_RXCSUM BIT(1) ++#define has_tso_cap(hw_cap) ((hw_cap) & HW_CAP_TSO) ++#define has_rxcsum_cap(hw_cap) ((hw_cap) & HW_CAP_RXCSUM) ++#define RXBUF_ADDR_ALIGN_SIZE 64UL ++/* UDP header len is 2 word */ ++#define UDP_HDR_LEN 2 ++/* IPv6 header len is 10 word */ ++#define IPV6_HDR_LEN 10 ++#define WORD_TO_BYTE 4 ++ ++#define BIT_OFFSET_NFRAGS_NUM 11 ++#define BIT_OFFSET_PROT_HEADER_LEN 16 ++#define BIT_OFFSET_IP_HEADER_LEN 20 ++#define BIT_FLAG_SG BIT(26) ++#define BIT_FLAG_TXCSUM BIT(27) ++#define BIT_FLAG_UDP BIT(28) ++#define BIT_FLAG_IPV6 BIT(29) ++#define BIT_FLAG_VLAN BIT(30) ++#define BIT_FLAG_TSO BIT(31) ++ ++#define PHY_RESET_DELAYS_PROPERTY "goke,phy-reset-delays-us" ++ ++/* ++ * The threshold for activing tx flow ctrl. ++ * When the left amount of receive queue descriptors is below this threshold, ++ * hardware will send pause frame immediately. ++ * We advise this value is set between 1 and 10. ++ * Too bigger is not a good choice. ++ * This value must be smaller than tx flow ctrl deactive threshold. ++ */ ++#define TX_FLOW_CTRL_ACTIVE_THRESHOLD 3 ++/* ++ * The threshold for deactiving tx flow ctrl. ++ * When the left amount of receive queue descriptors is ++ * above or equal with this threshold, ++ * hardware will exit flow control state. ++ * We advise this value is set between 1 and 10. ++ * Too bigger is not a good choice. ++ * This value must be larger than tx flow ctrl active threshold. ++ */ ++#define TX_FLOW_CTRL_DEACTIVE_THRESHOLD 5 ++#define FC_ACTIVE_MIN 1 ++#define FC_ACTIVE_DEFAULT 3 ++#define FC_ACTIVE_MAX 31 ++#define FC_DEACTIVE_MIN 1 ++#define FC_DEACTIVE_DEFAULT 5 ++#define FC_DEACTIVE_MAX 31 ++ ++#ifdef CONFIG_FEPHY_OPT ++/* FEPHY register list */ ++ ++#define SYS_REG_ADDR 0x12028000 ++#define FEPHY_TRIM_CACHE 0x3022 ++#define FEPHY_TRIM_VALUE 0x20a1 ++#define LOW_TEM_VALUE 117 ++#define HIGH_TEM_VALUE 915 ++#define LINK_STATUS 0x4 ++#define IS_LINK 0X4 ++#define SPEED_STATUS 0x18 ++#define SPEED_100M 0x8 ++#define LINK_AN_SR 0x11 ++#define MISC_CTRL45 0x00B4 ++#define MISC_CTRL47 0x00BC ++#define MISC_CTRL48 0x00C0 ++#define TSENSOR_RESULT0 0x3ff ++#define TSENSOR_RESULT1 0x3ff0000 ++#define TSENSOR_RESULT2 0x3ff ++#define TSENSOR_RESULT3 0x3ff0000 ++#define TSENSOR_EN 0xc3200000 ++#define HIGH_TEMP 100 ++#define NORMAL_TEMP1 90 ++#define NORMAL_TEMP2 20 ++#define LOW_TEMP 10 ++#define TSENSOR_LIMIT 0xfffff ++#define regval_to_temp(val) ((val - 117) * 165 / 798 - 40) ++#define FEPHY_OPT_TIMER (30 * HZ) ++#endif ++ ++enum phy_reset_delays { ++ PRE_DELAY, ++ PULSE, ++ POST_DELAY, ++ DELAYS_NUM, ++}; ++ ++struct femac_queue { ++ struct sk_buff **skb; ++ dma_addr_t *dma_phys; ++ unsigned int num; ++ unsigned int head; ++ unsigned int tail; ++}; ++ ++struct femac_tx_desc_ring { ++ struct tx_desc *desc; ++ dma_addr_t dma_phys; ++}; ++ ++#define FEMAC_RX_REFILL_IN_IRQ ++ ++struct femac_priv { ++ void __iomem *port_base; ++ void __iomem *glb_base; ++ struct clk *clk; ++ struct reset_control *mac_rst; ++ struct reset_control *phy_rst; ++ u32 phy_reset_delays[DELAYS_NUM]; ++ u32 link_status; ++ ++#ifdef CONFIG_FEPHY_OPT ++ struct delayed_work watchdog_queue; ++#endif ++ struct device *dev; ++ struct net_device *ndev; ++ ++ u32 hw_cap; ++ struct femac_queue txq; ++ struct femac_queue rxq; ++#ifdef FEMAC_RX_REFILL_IN_IRQ ++ struct sk_buff_head rx_head; ++ spinlock_t rxlock; ++#endif ++ struct femac_tx_desc_ring tx_ring; ++ u32 tx_fifo_used_cnt; ++ struct napi_struct napi; ++ ++ /* 802.3x flow control */ ++ bool tx_pause_en; ++ u32 tx_pause_active_thresh; ++ u32 tx_pause_deactive_thresh; ++}; ++ ++struct frags_info { ++ /* Word(2*i+2) */ ++ u32 addr; ++ /* Word(2*i+3) */ ++ u32 size : 16; ++ u32 reserved : 16; ++}; ++ ++struct tx_desc { ++ /* Word0 */ ++ u32 total_len : 17; ++ u32 reserv : 15; ++ /* Word1 */ ++ u32 ipv6_id; ++ /* Word2 */ ++ u32 linear_addr; ++ /* Word3 */ ++ u32 linear_len : 16; ++ u32 reserv3 : 16; ++ /* MAX_SKB_FRAGS is 30 */ ++ struct frags_info frags[30]; ++}; ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_fix.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_fix.c.patch new file mode 100644 index 00000000..b0e4f098 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_fix.c.patch @@ -0,0 +1,86 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_fix.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_fix.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,83 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include "phy_fix.h" ++ ++static const u32 phy_v2_fix_param[] = { ++#include "phy_v2.h" ++}; ++ ++static const u32 phy_v1_fix_param[] = { ++#include "phy_v1.h" ++}; ++ ++static int phy_expanded_write_bulk(struct phy_device *phy_dev, ++ const u32 reg_and_val[], int count) ++{ ++ int i, v; ++ u32 reg_addr; ++ u16 val; ++ ++ v = phy_read(phy_dev, MII_BMCR); ++ v = (u32)v | BMCR_PDOWN; ++ phy_write(phy_dev, MII_BMCR, v); ++ ++ for (i = 0; i < count; i += 2) { /* Process 2 data at a time. */ ++ reg_addr = reg_and_val[i]; ++ val = (u16)reg_and_val[i + 1]; ++ phy_write(phy_dev, MII_EXPMA, reg_addr); ++ phy_write(phy_dev, MII_EXPMD, val); ++ } ++ ++ v = phy_read(phy_dev, MII_BMCR); ++ v = (u32)v & (~BMCR_PDOWN); ++ phy_write(phy_dev, MII_BMCR, v); ++ ++ return 0; ++} ++ ++static int goke_fephy_v272_fix(struct phy_device *phy_dev) ++{ ++ int count; ++ ++ count = ARRAY_SIZE(phy_v2_fix_param); ++ if (count % 2) /* must be an even number, mod 2 */ ++ pr_warn("internal FEPHY fix register count is not right.\n"); ++ phy_expanded_write_bulk(phy_dev, phy_v2_fix_param, count); ++ ++ return 0; ++} ++ ++static int goke_fephy_v115_fix(struct phy_device *phy_dev) ++{ ++ int count; ++ ++ count = ARRAY_SIZE(phy_v1_fix_param); ++ if (count % 2) /* must be an even number, mod 2 */ ++ pr_warn("internal FEPHY fix register count is not right.\n"); ++ phy_expanded_write_bulk(phy_dev, phy_v1_fix_param, count); ++ ++ return 0; ++} ++ ++void phy_register_fixups(void) ++{ ++ phy_register_fixup_for_uid(GOKE_PHY_ID_V272, ++ GOKE_PHY_MASK, ++ goke_fephy_v272_fix); ++ ++ phy_register_fixup_for_uid(GOKE_PHY_ID_V115, ++ GOKE_PHY_MASK, ++ goke_fephy_v115_fix); ++} ++ ++void phy_unregister_fixups(void) ++{ ++ phy_unregister_fixup_for_uid(GOKE_PHY_ID_V272, ++ GOKE_PHY_MASK); ++ ++ phy_unregister_fixup_for_uid(GOKE_PHY_ID_V115, ++ GOKE_PHY_MASK); ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_fix.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_fix.h.patch new file mode 100644 index 00000000..24c58a4a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_fix.h.patch @@ -0,0 +1,21 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_fix.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_fix.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __ETH_PHY_FIX_H__ ++#define __ETH_PHY_FIX_H__ ++ ++#define GOKE_PHY_ID_V272 0x20669901 ++#define GOKE_PHY_ID_V115 0x20669903 ++#define GOKE_PHY_MASK 0xffffffff ++ ++#define MII_EXPMD 0x1d ++#define MII_EXPMA 0x1e ++ ++void phy_register_fixups(void); ++void phy_unregister_fixups(void); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_v1.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_v1.h.patch new file mode 100644 index 00000000..e979ca58 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_v1.h.patch @@ -0,0 +1,192 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_v1.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_v1.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,188 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __ETH_PHY_S28V115_2C02_H__ ++#define __ETH_PHY__S28V115_2C02_H__ ++ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, ++ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, ++ 0x3402, 0x2C, 0x3403, 0x02, 0x3404, 0xFD, ++ 0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0xF6, ++ 0x3408, 0x36, 0x3409, 0x18, 0x340A, 0x26, ++ 0x340B, 0x05, 0x340C, 0xC6, 0x340D, 0x01, ++ 0x340E, 0xF7, 0x340F, 0x36, 0x3410, 0x18, ++ 0x3411, 0xCC, 0x3412, 0x35, 0x3413, 0x9F, ++ 0x3414, 0x1A, 0x3415, 0xB3, 0x3416, 0x00, ++ 0x3417, 0xD2, 0x3418, 0x27, 0x3419, 0x09, ++ 0x341A, 0xFD, 0x341B, 0x00, 0x341C, 0xD2, ++ 0x341D, 0x7F, 0x341E, 0x01, 0x341F, 0xBF, ++ 0x3420, 0x7F, 0x3421, 0x01, 0x3422, 0xB1, ++ 0x3423, 0x39, 0x3424, 0x3C, 0x3425, 0x3C, ++ 0x3426, 0x30, 0x3427, 0xF6, 0x3428, 0x30, ++ 0x3429, 0x55, 0x342A, 0xC0, 0x342B, 0x07, ++ 0x342C, 0x18, 0x342D, 0xFE, 0x342E, 0x30, ++ 0x342F, 0x4C, 0x3430, 0x18, 0x3431, 0x3A, ++ 0x3432, 0x18, 0x3433, 0xE6, 0x3434, 0x00, ++ 0x3435, 0x5C, 0x3436, 0xE7, 0x3437, 0x01, ++ 0x3438, 0xC1, 0x3439, 0x07, 0x343A, 0x23, ++ 0x343B, 0x04, 0x343C, 0xC6, 0x343D, 0x07, ++ 0x343E, 0xE7, 0x343F, 0x01, 0x3440, 0x58, ++ 0x3441, 0x58, 0x3442, 0x58, 0x3443, 0x58, ++ 0x3444, 0x58, 0x3445, 0xE7, 0x3446, 0x00, ++ 0x3447, 0xF6, 0x3448, 0x20, 0x3449, 0x04, ++ 0x344A, 0xC4, 0x344B, 0x1F, 0x344C, 0xEA, ++ 0x344D, 0x00, 0x344E, 0xF7, 0x344F, 0x20, ++ 0x3450, 0x04, 0x3451, 0x38, 0x3452, 0x38, ++ 0x3453, 0x39, 0x3454, 0x3C, 0x3455, 0x37, ++ 0x3456, 0x36, 0x3457, 0x30, 0x3458, 0x1A, ++ 0x3459, 0xEE, 0x345A, 0x00, 0x345B, 0x18, ++ 0x345C, 0xE6, 0x345D, 0x00, 0x345E, 0x26, ++ 0x345F, 0x1C, 0x3460, 0xF6, 0x3461, 0x00, ++ 0x3462, 0x5C, 0x3463, 0xC5, 0x3464, 0x04, ++ 0x3465, 0x27, 0x3466, 0x06, 0x3467, 0xCC, ++ 0x3468, 0x36, 0x3469, 0x12, 0x346A, 0xBD, ++ 0x346B, 0xF0, 0x346C, 0xA5, 0x346D, 0xF6, ++ 0x346E, 0x00, 0x346F, 0x47, 0x3470, 0xC4, ++ 0x3471, 0xF3, 0x3472, 0xF7, 0x3473, 0x00, ++ 0x3474, 0x47, 0x3475, 0xC6, 0x3476, 0x01, ++ 0x3477, 0x1A, 0x3478, 0xEE, 0x3479, 0x00, ++ 0x347A, 0x20, 0x347B, 0x10, 0x347C, 0x5A, ++ 0x347D, 0x26, 0x347E, 0x14, 0x347F, 0xF6, ++ 0x3480, 0x00, 0x3481, 0x46, 0x3482, 0x4F, ++ 0x3483, 0xC4, 0x3484, 0x0C, 0x3485, 0x83, ++ 0x3486, 0x00, 0x3487, 0x08, 0x3488, 0x26, ++ 0x3489, 0x05, 0x348A, 0xC6, 0x348B, 0x02, ++ 0x348C, 0x18, 0x348D, 0xE7, 0x348E, 0x00, ++ 0x348F, 0x5F, 0x3490, 0x38, 0x3491, 0x38, ++ 0x3492, 0x39, 0x3493, 0xF6, 0x3494, 0x00, ++ 0x3495, 0x5C, 0x3496, 0xC5, 0x3497, 0x04, ++ 0x3498, 0x27, 0x3499, 0x06, 0x349A, 0xCC, ++ 0x349B, 0x36, 0x349C, 0x08, 0x349D, 0xBD, ++ 0x349E, 0xF0, 0x349F, 0xA5, 0x34A0, 0xF6, ++ 0x34A1, 0x00, 0x34A2, 0x47, 0x34A3, 0xC4, ++ 0x34A4, 0xF3, 0x34A5, 0xCA, 0x34A6, 0x08, ++ 0x34A7, 0xF7, 0x34A8, 0x00, 0x34A9, 0x47, ++ 0x34AA, 0x18, 0x34AB, 0xFE, 0x34AC, 0x00, ++ 0x34AD, 0xB6, 0x34AE, 0x18, 0x34AF, 0xAD, ++ 0x34B0, 0x00, 0x34B1, 0xBD, 0x34B2, 0x34, ++ 0x34B3, 0x24, 0x34B4, 0xF6, 0x34B5, 0x1E, ++ 0x34B6, 0x05, 0x34B7, 0xC5, 0x34B8, 0x02, ++ 0x34B9, 0x27, 0x34BA, 0x0A, 0x34BB, 0xF6, ++ 0x34BC, 0x1E, 0x34BD, 0x07, 0x34BE, 0xC5, ++ 0x34BF, 0x02, 0x34C0, 0x27, 0x34C1, 0x03, ++ 0x34C2, 0xBD, 0x34C3, 0xC0, 0x34C4, 0x33, ++ 0x34C5, 0xF6, 0x34C6, 0x31, 0x34C7, 0x1F, ++ 0x34C8, 0x37, 0x34C9, 0xC6, 0x34CA, 0x52, ++ 0x34CB, 0xBD, 0x34CC, 0xDC, 0x34CD, 0x53, ++ 0x34CE, 0x31, 0x34CF, 0xF6, 0x34D0, 0x00, ++ 0x34D1, 0x41, 0x34D2, 0xC5, 0x34D3, 0x10, ++ 0x34D4, 0x26, 0x34D5, 0x04, 0x34D6, 0x13, ++ 0x34D7, 0x23, 0x34D8, 0x40, 0x34D9, 0x0D, ++ 0x34DA, 0xBD, 0x34DB, 0x93, 0x34DC, 0xCE, ++ 0x34DD, 0x1A, 0x34DE, 0xEE, 0x34DF, 0x00, ++ 0x34E0, 0x18, 0x34E1, 0x6F, 0x34E2, 0x00, ++ 0x34E3, 0xC6, 0x34E4, 0x04, 0x34E5, 0x20, ++ 0x34E6, 0xA9, 0x34E7, 0x1A, 0x34E8, 0xEE, ++ 0x34E9, 0x00, 0x34EA, 0x18, 0x34EB, 0x6F, ++ 0x34EC, 0x00, 0x34ED, 0xC6, 0x34EE, 0x01, ++ 0x34EF, 0x20, 0x34F0, 0x9F, 0x34F1, 0x3C, ++ 0x34F2, 0x37, 0x34F3, 0x36, 0x34F4, 0x30, ++ 0x34F5, 0x1A, 0x34F6, 0xEE, 0x34F7, 0x00, ++ 0x34F8, 0x18, 0x34F9, 0xE6, 0x34FA, 0x00, ++ 0x34FB, 0x26, 0x34FC, 0x49, 0x34FD, 0xF6, ++ 0x34FE, 0x00, 0x34FF, 0x5C, 0x3500, 0xC5, ++ 0x3501, 0x04, 0x3502, 0x27, 0x3503, 0x06, ++ 0x3504, 0xCC, 0x3505, 0x35, 0x3506, 0xFC, ++ 0x3507, 0xBD, 0x3508, 0xF0, 0x3509, 0xA5, ++ 0x350A, 0xC6, 0x350B, 0x52, 0x350C, 0xBD, ++ 0x350D, 0xDC, 0x350E, 0xF3, 0x350F, 0x5D, ++ 0x3510, 0x27, 0x3511, 0x03, 0x3512, 0xBD, ++ 0x3513, 0xC0, 0x3514, 0x22, 0x3515, 0xF6, ++ 0x3516, 0x00, 0x3517, 0x46, 0x3518, 0xC5, ++ 0x3519, 0x0C, 0x351A, 0x26, 0x351B, 0x0A, ++ 0x351C, 0x1A, 0x351D, 0xEE, 0x351E, 0x00, ++ 0x351F, 0x18, 0x3520, 0x6F, 0x3521, 0x00, ++ 0x3522, 0xC6, 0x3523, 0x07, 0x3524, 0x20, ++ 0x3525, 0x1D, 0x3526, 0xFC, 0x3527, 0x30, ++ 0x3528, 0x0C, 0x3529, 0xBD, 0x352A, 0x93, ++ 0x352B, 0x19, 0x352C, 0xBD, 0x352D, 0x9F, ++ 0x352E, 0x0B, 0x352F, 0xC6, 0x3530, 0x02, ++ 0x3531, 0x37, 0x3532, 0xC6, 0x3533, 0x51, ++ 0x3534, 0xBD, 0x3535, 0xDC, 0x3536, 0x53, ++ 0x3537, 0x31, 0x3538, 0x7F, 0x3539, 0x02, ++ 0x353A, 0x07, 0x353B, 0xC6, 0x353C, 0x02, ++ 0x353D, 0x1A, 0x353E, 0xEE, 0x353F, 0x00, ++ 0x3540, 0x18, 0x3541, 0xE7, 0x3542, 0x00, ++ 0x3543, 0x38, 0x3544, 0x38, 0x3545, 0x39, ++ 0x3546, 0xC6, 0x3547, 0x52, 0x3548, 0xBD, ++ 0x3549, 0xDC, 0x354A, 0xF3, 0x354B, 0x5D, ++ 0x354C, 0x27, 0x354D, 0x03, 0x354E, 0xBD, ++ 0x354F, 0xC0, 0x3550, 0x22, 0x3551, 0xF6, ++ 0x3552, 0x00, 0x3553, 0x46, 0x3554, 0xC5, ++ 0x3555, 0x0C, 0x3556, 0x26, 0x3557, 0x0A, ++ 0x3558, 0x1A, 0x3559, 0xEE, 0x355A, 0x00, ++ 0x355B, 0x18, 0x355C, 0x6F, 0x355D, 0x00, ++ 0x355E, 0xC6, 0x355F, 0x07, 0x3560, 0x20, ++ 0x3561, 0xE1, 0x3562, 0xC6, 0x3563, 0x51, ++ 0x3564, 0xBD, 0x3565, 0xDC, 0x3566, 0xF3, ++ 0x3567, 0x5D, 0x3568, 0x26, 0x3569, 0x04, ++ 0x356A, 0xC6, 0x356B, 0x02, 0x356C, 0x20, ++ 0x356D, 0xD5, 0x356E, 0xF6, 0x356F, 0x00, ++ 0x3570, 0x41, 0x3571, 0xC5, 0x3572, 0x10, ++ 0x3573, 0x26, 0x3574, 0x20, 0x3575, 0xF6, ++ 0x3576, 0x02, 0x3577, 0x07, 0x3578, 0xC1, ++ 0x3579, 0x02, 0x357A, 0x24, 0x357B, 0x19, ++ 0x357C, 0x18, 0x357D, 0xFE, 0x357E, 0x02, ++ 0x357F, 0x08, 0x3580, 0x18, 0x3581, 0xAD, ++ 0x3582, 0x00, 0x3583, 0xF6, 0x3584, 0x02, ++ 0x3585, 0x06, 0x3586, 0x27, 0x3587, 0x0D, ++ 0x3588, 0xC6, 0x3589, 0x02, 0x358A, 0x37, ++ 0x358B, 0xC6, 0x358C, 0x51, 0x358D, 0xBD, ++ 0x358E, 0xDC, 0x358F, 0x53, 0x3590, 0x31, ++ 0x3591, 0xC6, 0x3592, 0x02, 0x3593, 0x20, ++ 0x3594, 0xAE, 0x3595, 0x1A, 0x3596, 0xEE, ++ 0x3597, 0x00, 0x3598, 0x18, 0x3599, 0x6F, ++ 0x359A, 0x00, 0x359B, 0xC6, 0x359C, 0x03, ++ 0x359D, 0x20, 0x359E, 0xA4, 0x359F, 0xF6, ++ 0x35A0, 0x01, 0x35A1, 0xBF, 0x35A2, 0xC1, ++ 0x35A3, 0x08, 0x35A4, 0x24, 0x35A5, 0x55, ++ 0x35A6, 0xBD, 0x35A7, 0xF6, 0x35A8, 0xD3, ++ 0x35A9, 0x35, 0x35AA, 0xBA, 0x35AB, 0x35, ++ 0x35AC, 0xC2, 0x35AD, 0x35, 0x35AE, 0xCA, ++ 0x35AF, 0x35, 0x35B0, 0xD2, 0x35B1, 0x35, ++ 0x35B2, 0xDA, 0x35B3, 0x35, 0x35B4, 0xE2, ++ 0x35B5, 0x35, 0x35B6, 0xEA, 0x35B7, 0x35, ++ 0x35B8, 0xF2, 0x35B9, 0x39, 0x35BA, 0xCC, ++ 0x35BB, 0x01, 0x35BC, 0xB1, 0x35BD, 0xBD, ++ 0x35BE, 0x34, 0x35BF, 0x54, 0x35C0, 0x20, ++ 0x35C1, 0x36, 0x35C2, 0xCC, 0x35C3, 0x01, ++ 0x35C4, 0xB1, 0x35C5, 0xBD, 0x35C6, 0xC1, ++ 0x35C7, 0x52, 0x35C8, 0x20, 0x35C9, 0x2E, ++ 0x35CA, 0xCC, 0x35CB, 0x01, 0x35CC, 0xB1, ++ 0x35CD, 0xBD, 0x35CE, 0x34, 0x35CF, 0xF1, ++ 0x35D0, 0x20, 0x35D1, 0x26, 0x35D2, 0xCC, ++ 0x35D3, 0x01, 0x35D4, 0xB1, 0x35D5, 0xBD, ++ 0x35D6, 0xC3, 0x35D7, 0x9A, 0x35D8, 0x20, ++ 0x35D9, 0x1E, 0x35DA, 0xCC, 0x35DB, 0x01, ++ 0x35DC, 0xB1, 0x35DD, 0xBD, 0x35DE, 0xC4, ++ 0x35DF, 0x39, 0x35E0, 0x20, 0x35E1, 0x16, ++ 0x35E2, 0xCC, 0x35E3, 0x01, 0x35E4, 0xB1, ++ 0x35E5, 0xBD, 0x35E6, 0xC5, 0x35E7, 0x0B, ++ 0x35E8, 0x20, 0x35E9, 0x0E, 0x35EA, 0xCC, ++ 0x35EB, 0x01, 0x35EC, 0xB1, 0x35ED, 0xBD, ++ 0x35EE, 0xC6, 0x35EF, 0x3A, 0x35F0, 0x20, ++ 0x35F1, 0x06, 0x35F2, 0xCC, 0x35F3, 0x01, ++ 0x35F4, 0xB1, 0x35F5, 0xBD, 0x35F6, 0xC7, ++ 0x35F7, 0xC2, 0x35F8, 0xF7, 0x35F9, 0x01, ++ 0x35FA, 0xBF, 0x35FB, 0x39, 0x35FC, 0x43, ++ 0x35FD, 0x3A, 0x35FE, 0x41, 0x35FF, 0x44, ++ 0x3600, 0x54, 0x3601, 0x5F, 0x3602, 0x41, ++ 0x3603, 0x54, 0x3604, 0x4E, 0x3605, 0x0A, ++ 0x3606, 0x0D, 0x3607, 0x00, 0x3608, 0x43, ++ 0x3609, 0x3A, 0x360A, 0x45, 0x360B, 0x6E, ++ 0x360C, 0x5F, 0x360D, 0x53, 0x360E, 0x74, ++ 0x360F, 0x0A, 0x3610, 0x0D, 0x3611, 0x00, ++ 0x3612, 0x43, 0x3613, 0x3A, 0x3614, 0x49, ++ 0x3615, 0x0A, 0x3616, 0x0D, 0x3617, 0x00, ++ 0x3618, 0x00, 0x3400, 0x01, 0x33f8, 0x01 ++#endif +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_v2.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_v2.h.patch new file mode 100644 index 00000000..a6344899 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-phy_v2.h.patch @@ -0,0 +1,45 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_v2.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_v2.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __ETH_PHY_V272_2723_H__ ++#define __ETH_PHY_V272_2723_H__ ++ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, ++ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, ++ 0x3402, 0x27, 0x3403, 0x23, 0x3404, 0xFD, ++ 0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0x20, ++ 0x3408, 0x00, 0x3409, 0x3C, 0x340A, 0x3C, ++ 0x340B, 0x30, 0x340C, 0xF6, 0x340D, 0x00, ++ 0x340E, 0x4A, 0x340F, 0xC4, 0x3410, 0x7F, ++ 0x3411, 0xE7, 0x3412, 0x01, 0x3413, 0xF6, ++ 0x3414, 0x01, 0x3415, 0xBE, 0x3416, 0xC1, ++ 0x3417, 0x02, 0x3418, 0x27, 0x3419, 0x0E, ++ 0x341A, 0xE6, 0x341B, 0x01, 0x341C, 0xC1, ++ 0x341D, 0x14, 0x341E, 0x27, 0x341F, 0x08, ++ 0x3420, 0xC1, 0x3421, 0x18, 0x3422, 0x25, ++ 0x3423, 0x09, 0x3424, 0xC1, 0x3425, 0x1B, ++ 0x3426, 0x22, 0x3427, 0x05, 0x3428, 0xC6, ++ 0x3429, 0x5C, 0x342A, 0xF7, 0x342B, 0x20, ++ 0x342C, 0xA1, 0x342D, 0xF6, 0x342E, 0x01, ++ 0x342F, 0xBF, 0x3430, 0xC1, 0x3431, 0x01, ++ 0x3432, 0x26, 0x3433, 0x29, 0x3434, 0xF6, ++ 0x3435, 0x30, 0x3436, 0x55, 0x3437, 0xC0, ++ 0x3438, 0x05, 0x3439, 0xE7, 0x343A, 0x01, ++ 0x343B, 0xC1, 0x343C, 0x13, 0x343D, 0x23, ++ 0x343E, 0x04, 0x343F, 0xC6, 0x3440, 0x13, ++ 0x3441, 0xE7, 0x3442, 0x01, 0x3443, 0x18, ++ 0x3444, 0xFE, 0x3445, 0x30, 0x3446, 0x4C, ++ 0x3447, 0x18, 0x3448, 0x3A, 0x3449, 0x18, ++ 0x344A, 0xE6, 0x344B, 0x00, 0x344C, 0x58, ++ 0x344D, 0x58, 0x344E, 0x58, 0x344F, 0x58, ++ 0x3450, 0x58, 0x3451, 0xE7, 0x3452, 0x00, ++ 0x3453, 0xF6, 0x3454, 0x20, 0x3455, 0x04, ++ 0x3456, 0xC4, 0x3457, 0x1F, 0x3458, 0xEA, ++ 0x3459, 0x00, 0x345A, 0xF7, 0x345B, 0x20, ++ 0x345C, 0x04, 0x345D, 0x38, 0x345E, 0x38, ++ 0x345F, 0x39, 0x3400, 0x01, 0x33f8, 0x01 ++#endif +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-util.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-util.c.patch new file mode 100644 index 00000000..db2ab67d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-util.c.patch @@ -0,0 +1,296 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/util.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/util.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,292 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++ ++#include "util.h" ++ ++static void femac_do_udp_checksum(struct sk_buff *skb) ++{ ++ int offset; ++ __wsum csum; ++ __sum16 udp_csum; ++ ++ offset = skb_checksum_start_offset(skb); ++ WARN_ON(offset >= skb_headlen(skb)); ++ csum = skb_checksum(skb, offset, skb->len - offset, 0); ++ ++ offset += skb->csum_offset; ++ WARN_ON(offset + sizeof(__sum16) > skb_headlen(skb)); ++ ++ udp_csum = csum_fold(csum); ++ if (udp_csum == 0) ++ udp_csum = CSUM_MANGLED_0; ++ ++ *(__sum16 *)(skb->data + offset) = udp_csum; ++ ++ skb->ip_summed = CHECKSUM_NONE; ++} ++ ++static __be16 femac_get_l3_proto(struct sk_buff *skb) ++{ ++ __be16 l3_proto; ++ ++ l3_proto = skb->protocol; ++ if (skb->protocol == htons(ETH_P_8021Q)) ++ l3_proto = vlan_get_protocol(skb); ++ ++ return l3_proto; ++} ++ ++static inline bool femac_skb_is_ipv6(struct sk_buff *skb) ++{ ++ return (femac_get_l3_proto(skb) == htons(ETH_P_IPV6)); ++} ++ ++static int femac_check_hw_capability_for_ipv6(struct sk_buff *skb) ++{ ++ unsigned int l4_proto; ++ ++ l4_proto = ipv6_hdr(skb)->nexthdr; ++ if ((l4_proto != IPPROTO_TCP) && (l4_proto != IPPROTO_UDP)) { ++ /* ++ * when IPv6 next header is not tcp or udp, ++ * it means that IPv6 next header is extension header. ++ * Hardware can't deal with this case, ++ * so do checksumming by software or do GSO by software. ++ */ ++ if (skb_is_gso(skb)) { ++ return -ENOTSUPP; ++ } ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL && ++ skb_checksum_help(skb)) { ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++int femac_check_hw_capability(struct sk_buff *skb) ++{ ++ /* ++ * if tcp_mtu_probe() use (2 * tp->mss_cache) as probe_size, ++ * the linear data length will be larger than 2048, ++ * the MAC can't handle it, so let the software do it. ++ */ ++ if (skb_is_gso(skb) && (skb_headlen(skb) > 2048)) { /* max is 2048 */ ++ return -ENOTSUPP; ++ } ++ ++ if (femac_skb_is_ipv6(skb)) { ++ return femac_check_hw_capability_for_ipv6(skb); ++ } ++ ++ return 0; ++} ++ ++static unsigned int femac_get_pkt_info_gso(struct sk_buff *skb, ++ bool txcsum, unsigned int max_mss, unsigned int l4_proto) ++{ ++ u32 pkt_info = 0; ++ bool do_txcsum = txcsum; ++ ++ /* ++ * Although netcard support UFO feature, it can't deal with ++ * UDP header checksum. ++ * So the driver will do UDP header checksum and netcard will just ++ * fragment the packet. ++ */ ++ if (do_txcsum && skb_is_gso(skb) && (l4_proto == IPPROTO_UDP)) { ++ femac_do_udp_checksum(skb); ++ do_txcsum = false; ++ } ++ ++ if (do_txcsum) ++ pkt_info |= BIT_FLAG_TXCSUM; ++ ++ if (skb_is_gso(skb)) { ++ pkt_info |= (BIT_FLAG_SG | BIT_FLAG_TSO); ++ } else if (skb_shinfo(skb)->nr_frags) { ++ pkt_info |= BIT_FLAG_SG; ++ } ++ ++ pkt_info |= (skb_shinfo(skb)->nr_frags << BIT_OFFSET_NFRAGS_NUM); ++ pkt_info |= (skb_is_gso(skb) ? ((skb_shinfo(skb)->gso_size > max_mss) ? max_mss : skb_shinfo(skb)->gso_size) : ++ (skb->len + ETH_FCS_LEN)); ++ return pkt_info; ++} ++ ++u32 femac_get_pkt_info(struct sk_buff *skb) ++{ ++ __be16 l3_proto; ++ unsigned int l4_proto = IPPROTO_MAX; ++ bool do_txcsum = false; ++ int max_data_len = skb->len - ETH_HLEN; ++ unsigned int max_mss = ETH_DATA_LEN; ++ u32 pkt_info = 0; ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) ++ do_txcsum = true; ++ ++ l3_proto = skb->protocol; ++ if (skb->protocol == htons(ETH_P_8021Q)) { ++ l3_proto = vlan_get_protocol(skb); ++ max_data_len -= VLAN_HLEN; ++ pkt_info |= BIT_FLAG_VLAN; ++ } ++ ++ if (l3_proto == htons(ETH_P_IP)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((max_data_len >= GSO_MAX_SIZE) && ++ (ntohs(iph->tot_len) <= (iph->ihl << 2))) /* trans 2 bytes */ ++ iph->tot_len = htons(GSO_MAX_SIZE - 1); ++ ++ max_mss -= iph->ihl * WORD_TO_BYTE; ++ pkt_info |= (iph->ihl << BIT_OFFSET_IP_HEADER_LEN); ++ l4_proto = iph->protocol; ++ } else if (l3_proto == htons(ETH_P_IPV6)) { ++ max_mss -= IPV6_HDR_LEN * WORD_TO_BYTE; ++ pkt_info |= BIT_FLAG_IPV6; ++ pkt_info |= (IPV6_HDR_LEN << BIT_OFFSET_IP_HEADER_LEN); ++ l4_proto = ipv6_hdr(skb)->nexthdr; ++ } else { ++ do_txcsum = false; ++ } ++ ++ if (l4_proto == IPPROTO_TCP) { ++ max_mss -= tcp_hdr(skb)->doff * WORD_TO_BYTE; ++ pkt_info |= (tcp_hdr(skb)->doff << BIT_OFFSET_PROT_HEADER_LEN); ++ } else if (l4_proto == IPPROTO_UDP) { ++ if (l3_proto == htons(ETH_P_IPV6)) ++ max_mss -= sizeof(struct frag_hdr); ++ pkt_info |= (BIT_FLAG_UDP | ++ (UDP_HDR_LEN << BIT_OFFSET_PROT_HEADER_LEN)); ++ } else { ++ do_txcsum = false; ++ } ++ ++ pkt_info |= femac_get_pkt_info_gso(skb, do_txcsum, max_mss, l4_proto); ++ ++ return pkt_info; ++} ++ ++void femac_sleep_us(u32 time_us) ++{ ++ u32 time_ms; ++ ++ if (!time_us) { ++ return; ++ } ++ ++ time_ms = DIV_ROUND_UP(time_us, 1000); /* add 1000us, round up */ ++ if (time_ms < 20) { /* less than 20 ms */ ++ usleep_range(time_us, time_us + 500); /* add maximum 500us */ ++ } else { ++ msleep(time_ms); ++ } ++} ++ ++void femac_set_flow_ctrl(const struct femac_priv *priv) ++{ ++ unsigned int pause_en; ++ unsigned int tx_flow_ctrl; ++ ++ tx_flow_ctrl = readl(priv->port_base + FC_LEVEL); ++ tx_flow_ctrl &= ~FC_DEACTIVE_THR_MASK; ++ tx_flow_ctrl |= priv->tx_pause_deactive_thresh; ++ tx_flow_ctrl &= ~FC_ACTIVE_THR_MASK; ++ tx_flow_ctrl |= priv->tx_pause_active_thresh << BITS_FC_ACTIVE_THR_OFFSET; ++ ++ pause_en = readl(priv->port_base + MAC_SET); ++ ++ if (priv->tx_pause_en) { ++ tx_flow_ctrl |= BIT_FC_EN; ++ pause_en |= BIT_PAUSE_EN; ++ } else { ++ tx_flow_ctrl &= ~BIT_FC_EN; ++ pause_en &= ~BIT_PAUSE_EN; ++ } ++ ++ writel(tx_flow_ctrl, priv->port_base + FC_LEVEL); ++ ++ writel(pause_en, priv->port_base + MAC_SET); ++} ++ ++void femac_get_pauseparam(struct net_device *dev, ++ struct ethtool_pauseparam *pause) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ ++ pause->autoneg = dev->phydev->autoneg; ++ pause->rx_pause = 1; ++ if (priv->tx_pause_en) ++ pause->tx_pause = 1; ++} ++ ++int femac_set_pauseparam(struct net_device *dev, ++ struct ethtool_pauseparam *pause) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ struct phy_device *phy = dev->phydev; ++ int ret = 0; ++ ++ if (pause->rx_pause == 0) { ++ return -EINVAL; ++ } ++ ++ if (pause->tx_pause != priv->tx_pause_en) { ++ priv->tx_pause_en = pause->tx_pause; ++ femac_set_flow_ctrl(priv); ++ } ++ ++ if (phy->autoneg) { ++ if (netif_running(dev)) { ++ struct ethtool_cmd cmd; ++ /* auto-negotiation automatically restarted */ ++ cmd.cmd = ETHTOOL_NWAY_RST; ++ cmd.supported = phy->supported; ++ cmd.advertising = phy->advertising; ++ cmd.autoneg = phy->autoneg; ++ cmd.speed = phy->speed; ++ cmd.duplex = phy->duplex; ++ cmd.phy_address = phy->mdio.addr; ++ ret = phy_ethtool_sset(phy, &cmd); ++ } ++ } ++ ++ return ret; ++} ++ ++void femac_enable_rxcsum_drop(const struct femac_priv *priv, ++ bool drop) ++{ ++ unsigned int val; ++ ++ val = readl(priv->port_base + RX_COE_CTRL); ++ val &= ~COE_ERR_DROP; ++ if (drop) ++ val |= (BIT_COE_IPHDR_DROP | BIT_COE_IPV6_UDP_ZERO_DROP); ++ writel(val, priv->port_base + RX_COE_CTRL); ++} ++ ++int femac_set_features(struct net_device *dev, netdev_features_t features) ++{ ++ struct femac_priv *priv = netdev_priv(dev); ++ netdev_features_t changed = dev->features ^ features; ++ ++ if (changed & NETIF_F_RXCSUM) { ++ if (features & NETIF_F_RXCSUM) { ++ femac_enable_rxcsum_drop(priv, true); ++ } else { ++ femac_enable_rxcsum_drop(priv, false); ++ } ++ } ++ ++ return 0; ++} +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-util.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-util.h.patch new file mode 100644 index 00000000..be29d192 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-ethernet-goke-femac-util.h.patch @@ -0,0 +1,26 @@ +--- linux-4.9.37/drivers/net/ethernet/goke/femac/util.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/ethernet/goke/femac/util.h 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __ETH_UTIL_H__ ++#define __ETH_UTIL_H__ ++ ++#include "femac.h" ++ ++int femac_check_hw_capability(struct sk_buff *skb); ++u32 femac_get_pkt_info(struct sk_buff *skb); ++void femac_sleep_us(u32 time_us); ++void femac_set_flow_ctrl(const struct femac_priv *priv); ++void femac_get_pauseparam(struct net_device *dev, ++ struct ethtool_pauseparam *pause); ++int femac_set_pauseparam(struct net_device *dev, ++ struct ethtool_pauseparam *pause); ++void femac_enable_rxcsum_drop(const struct femac_priv *priv, ++ bool drop); ++int femac_set_features(struct net_device *dev, netdev_features_t features); ++ ++#endif +\ В конце файла нет новой строки diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-Kconfig.patch new file mode 100644 index 00000000..8f42a3de --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-Kconfig.patch @@ -0,0 +1,16 @@ +--- linux-4.9.37/drivers/net/phy/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/net/phy/Kconfig 2021-06-07 13:01:33.000000000 +0300 +@@ -89,6 +89,13 @@ + config MDIO_CAVIUM + tristate + ++config MDIO_GOKE_FEMAC ++ tristate "Goke femac MDIO buses" ++ depends on HAS_IOMEM && OF_MDIO ++ help ++ This module provides a driver for the MDIO busses found in the ++ Goke SoC that have an Fast Ethernet. ++ + config MDIO_GPIO + tristate "GPIO lib-based bitbanged MDIO buses" + depends on MDIO_BITBANG && GPIOLIB diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-Makefile.patch new file mode 100644 index 00000000..682f96aa --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/net/phy/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/net/phy/Makefile 2021-06-07 13:01:33.000000000 +0300 +@@ -13,6 +13,7 @@ + obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o + obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o + obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium.o ++obj-$(CONFIG_MDIO_GOKE_FEMAC) += mdio-goke-femac.o + obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o + obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o + obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-mdio-goke-femac.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-mdio-goke-femac.c.patch new file mode 100644 index 00000000..d588a0cb --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-mdio-goke-femac.c.patch @@ -0,0 +1,453 @@ +--- linux-4.9.37/drivers/net/phy/mdio-goke-femac.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/net/phy/mdio-goke-femac.c 2021-06-07 13:01:33.000000000 +0300 +@@ -0,0 +1,450 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MDIO_RWCTRL 0x00 ++#define MDIO_RO_DATA 0x04 ++#define MDIO_WRITE BIT(13) ++#define MDIO_RW_FINISH BIT(15) ++#define BIT_PHY_ADDR_OFFSET 8 ++#define BIT_WR_DATA_OFFSET 16 ++ ++#define BIT_MASK_FEPHY_ADDR GENMASK(4, 0) ++#define BIT_FEPHY_SEL BIT(5) ++ ++#if defined(CONFIG_ARCH_CJ104V100) ++#define BIT_OFFSET_LD_SET 0 ++#define BIT_OFFSET_LDO_SET 5 ++#define BIT_OFFSET_R_TUNING 8 ++#else ++#define BIT_OFFSET_LD_SET 25 ++#define BIT_OFFSET_LDO_SET 22 ++#define BIT_OFFSET_R_TUNING 16 ++#endif ++#define MII_EXPMD 0x1d ++#define MII_EXPMA 0x1e ++ ++#define REG_LD_AM 0x3050 ++#define BIT_MASK_LD_SET GENMASK(4, 0) ++#define REG_LDO_AM 0x3051 ++#define BIT_MASK_LDO_SET GENMASK(2, 0) ++#define REG_R_TUNING 0x3052 ++#define BIT_MASK_R_TUNING GENMASK(5, 0) ++#define REG_WR_DONE 0x3053 ++#define BIT_CFG_DONE BIT(0) ++#define BIT_CFG_ACK BIT(1) ++#define REG_DEF_ATE 0x3057 ++#define BIT_AUTOTRIM_DONE BIT(0) ++ ++#define PHY_RESET_DELAYS_PROPERTY "goke,phy-reset-delays-us" ++ ++enum phy_reset_delays { ++ PRE_DELAY, ++ PULSE, ++ POST_DELAY, ++ DELAYS_NUM, ++}; ++ ++struct femac_mdio_data { ++ struct clk *clk; ++ struct clk *fephy_clk; ++ struct reset_control *phy_rst; ++ struct reset_control *fephy_rst; ++ u32 phy_reset_delays[DELAYS_NUM]; ++ void __iomem *membase; ++ void __iomem *fephy_iobase; ++ void __iomem *fephy_trim_iobase; ++ struct mii_bus *bus; ++ u32 phy_addr; ++}; ++ ++static int femac_mdio_wait_ready(struct femac_mdio_data *data) ++{ ++ u32 val; ++ ++ return readl_poll_timeout_atomic(data->membase + MDIO_RWCTRL, ++ val, val & MDIO_RW_FINISH, 20, 10000); ++} ++ ++static int femac_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ++{ ++ struct femac_mdio_data *data = bus->priv; ++ int ret; ++ ++ ret = femac_mdio_wait_ready(data); ++ if (ret) ++ return ret; ++ ++ writel(((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum), ++ data->membase + MDIO_RWCTRL); ++ ++ ret = femac_mdio_wait_ready(data); ++ if (ret) ++ return ret; ++ ++ return readl(data->membase + MDIO_RO_DATA) & 0xFFFF; ++} ++ ++static int femac_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ++ u16 value) ++{ ++ struct femac_mdio_data *data = bus->priv; ++ int ret; ++ ++ ret = femac_mdio_wait_ready(data); ++ if (ret) ++ return ret; ++ ++ writel(MDIO_WRITE | (value << BIT_WR_DATA_OFFSET) | ++ ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum), ++ data->membase + MDIO_RWCTRL); ++ ++ return femac_mdio_wait_ready(data); ++} ++ ++static void femac_sleep_us(u32 time_us) ++{ ++ u32 time_ms; ++ ++ if (!time_us) ++ return; ++ ++ time_ms = DIV_ROUND_UP(time_us, 1000); ++ if (time_ms < 20) ++ usleep_range(time_us, time_us + 500); ++ else ++ msleep(time_ms); ++} ++ ++static void femac_phy_reset(const struct femac_mdio_data *data) ++{ ++ /* To make sure PHY hardware reset success, ++ * we must keep PHY in deassert state first and ++ * then complete the hardware reset operation ++ */ ++ reset_control_deassert(data->phy_rst); ++ femac_sleep_us(data->phy_reset_delays[PRE_DELAY]); ++ ++ reset_control_assert(data->phy_rst); ++ /* delay some time to ensure reset ok, ++ * this depends on PHY hardware feature ++ */ ++ femac_sleep_us(data->phy_reset_delays[PULSE]); ++ reset_control_deassert(data->phy_rst); ++ /* delay some time to ensure later MDIO access */ ++ femac_sleep_us(data->phy_reset_delays[POST_DELAY]); ++} ++ ++static void femac_get_phy_addr(struct femac_mdio_data *data, ++ struct device_node *np) ++{ ++ struct device_node *child = NULL; ++ int addr; ++ ++ child = of_get_next_available_child(np, NULL); ++ if (!child) { ++ pr_err("%s: No valid PHY device node!\n", __func__); ++ return; ++ } ++ ++ addr = of_mdio_parse_addr(&data->bus->dev, child); ++ if (addr < 0) { ++ pr_err("%s: get PHY address failed!\n", __func__); ++ return; ++ } ++ ++ data->phy_addr = addr; ++} ++ ++static inline bool femac_use_fephy(struct femac_mdio_data *data) ++{ ++ /*return false;*/ ++ return (data->fephy_iobase ? ++ !(readl(data->fephy_iobase) & BIT_FEPHY_SEL) : false); ++} ++ ++static void femac_fephy_reset(struct femac_mdio_data *data) ++{ ++ u32 val; ++ ++ /* disable MDCK clock to make sure FEPHY reset success */ ++ clk_disable_unprepare(data->clk); ++ ++ val = readl(data->fephy_iobase); ++ val &= ~BIT_MASK_FEPHY_ADDR; ++ val |= data->phy_addr; ++ writel(val, data->fephy_iobase); ++ ++ clk_prepare_enable(data->fephy_clk); ++ udelay(10); ++ ++ reset_control_assert(data->fephy_rst); ++ udelay(10); ++ reset_control_deassert(data->fephy_rst); ++ /* delay at least 15ms for MDIO operation */ ++ msleep(20); ++ ++ clk_prepare_enable(data->clk); ++ /* delay 5ms after enable MDCK to make sure FEPHY trim safe */ ++ mdelay(5); ++} ++ ++static inline int fephy_expanded_read(struct mii_bus *bus, int phy_addr, ++ u32 reg_addr) ++{ ++ int ret; ++ ++ femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); ++ ret = femac_mdio_read(bus, phy_addr, MII_EXPMD); ++ ++ return ret; ++} ++ ++static inline int fephy_expanded_write(struct mii_bus *bus, int phy_addr, ++ u32 reg_addr, u16 val) ++{ ++ int ret; ++ ++ femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); ++ ret = femac_mdio_write(bus, phy_addr, MII_EXPMD, val); ++ ++ return ret; ++} ++ ++void femac_fephy_use_default_trim(struct femac_mdio_data *data) ++{ ++ unsigned short val; ++ int timeout = 3; ++ ++ pr_info("No OTP data, internal PHY use default ATE parameters!\n"); ++ ++ do { ++ msleep(250); ++ val = fephy_expanded_read(data->bus, data->phy_addr, ++ REG_DEF_ATE); ++ val &= BIT_AUTOTRIM_DONE; ++ } while (!val && --timeout); ++ ++ if (!timeout) ++ pr_err("femac PHY wait autotrim done timeout!\n"); ++ ++ mdelay(5); ++} ++ ++static void femac_fephy_trim(struct femac_mdio_data *data) ++{ ++ struct mii_bus *bus = data->bus; ++ u32 phy_addr = data->phy_addr; ++ int timeout = 3000; ++ u32 val; ++ u8 ld_set; ++ u8 ldo_set; ++ u8 r_tuning; ++ ++ val = readl(data->fephy_iobase); ++ ld_set = (val >> BIT_OFFSET_LD_SET) & BIT_MASK_LD_SET; ++ ldo_set = (val >> BIT_OFFSET_LDO_SET) & BIT_MASK_LDO_SET; ++ r_tuning = (val >> BIT_OFFSET_R_TUNING) & BIT_MASK_R_TUNING; ++ ++ if (!ld_set && !ldo_set && !r_tuning) { ++ femac_fephy_use_default_trim(data); ++ return; ++ } ++ ++ val = fephy_expanded_read(bus, phy_addr, REG_LD_AM); ++ val = (val & ~BIT_MASK_LD_SET) | (ld_set & BIT_MASK_LD_SET); ++ fephy_expanded_write(bus, phy_addr, REG_LD_AM, val); ++ ++ val = fephy_expanded_read(bus, phy_addr, REG_LDO_AM); ++ val = (val & ~BIT_MASK_LDO_SET) | (ldo_set & BIT_MASK_LDO_SET); ++ fephy_expanded_write(bus, phy_addr, REG_LDO_AM, val); ++ ++ val = fephy_expanded_read(bus, phy_addr, REG_R_TUNING); ++ val = (val & ~BIT_MASK_R_TUNING) | (r_tuning & BIT_MASK_R_TUNING); ++ fephy_expanded_write(bus, phy_addr, REG_R_TUNING, val); ++ ++ val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE); ++ if (val & BIT_CFG_ACK) ++ pr_err("femac PHY 0x3053 bit CFG_ACK value: 1\n"); ++ val = val | BIT_CFG_DONE; ++ fephy_expanded_write(bus, phy_addr, REG_WR_DONE, val); ++ ++ do { ++ usleep_range(100, 150); ++ val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE); ++ val &= BIT_CFG_ACK; ++ } while (!val && --timeout); ++ if (!timeout) ++ pr_err("femac PHY 0x3053 wait bit CFG_ACK timeout!\n"); ++ ++ mdelay(5); ++ ++ pr_info("FEPHY:addr=%d, la_am=0x%x, ldo_am=0x%x, r_tuning=0x%x\n", ++ phy_addr, ++ fephy_expanded_read(bus, phy_addr, REG_LD_AM), ++ fephy_expanded_read(bus, phy_addr, REG_LDO_AM), ++ fephy_expanded_read(bus, phy_addr, REG_R_TUNING)); ++} ++ ++static void femac_fephy_reset_and_trim(struct femac_mdio_data *data) ++{ ++ femac_fephy_reset(data); ++ femac_fephy_trim(data); ++} ++ ++static void femac_fephy_set_phy_addr(struct femac_mdio_data *data) ++{ ++ u32 val; ++ ++ if (!data->fephy_iobase) ++ return; ++ ++ val = readl(data->fephy_iobase); ++ val &= ~BIT_MASK_FEPHY_ADDR; ++ val |= (data->phy_addr + 1); ++ writel(val, data->fephy_iobase); ++} ++ ++static int femac_mdio_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct mii_bus *bus; ++ struct femac_mdio_data *data; ++ struct resource *res; ++ int ret; ++ ++ bus = mdiobus_alloc_size(sizeof(*data)); ++ if (!bus) ++ return -ENOMEM; ++ ++ bus->name = "femac_mii_bus"; ++ bus->read = &femac_mdio_read; ++ bus->write = &femac_mdio_write; ++ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); ++ bus->parent = &pdev->dev; ++ ++ data = bus->priv; ++ data->bus = bus; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ data->membase = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(data->membase)) { ++ ret = PTR_ERR(data->membase); ++ goto err_out_free_mdiobus; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (res) { ++ data->fephy_iobase = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(data->fephy_iobase)) { ++ ret = PTR_ERR(data->fephy_iobase); ++ goto err_out_free_mdiobus; ++ } ++ } else { ++ data->fephy_iobase = NULL; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ if (res) { ++ data->fephy_trim_iobase = devm_ioremap_resource(&pdev->dev, ++ res); ++ if (IS_ERR(data->fephy_trim_iobase)) { ++ ret = PTR_ERR(data->fephy_trim_iobase); ++ goto err_out_free_mdiobus; ++ } ++ } else { ++ data->fephy_trim_iobase = NULL; ++ } ++ ++ data->clk = devm_clk_get(&pdev->dev, "mdio"); ++ if (IS_ERR(data->clk)) { ++ ret = PTR_ERR(data->clk); ++ goto err_out_free_mdiobus; ++ } ++ ++ data->fephy_clk = devm_clk_get(&pdev->dev, "phy"); ++ if (IS_ERR(data->fephy_clk)) ++ data->fephy_clk = NULL; ++ ++ ret = clk_prepare_enable(data->clk); ++ if (ret) ++ goto err_out_free_mdiobus; ++ ++ data->phy_rst = devm_reset_control_get(&pdev->dev, "external-phy"); ++ if (IS_ERR(data->phy_rst)) { ++ data->phy_rst = NULL; ++ } else { ++ ret = of_property_read_u32_array(np, ++ PHY_RESET_DELAYS_PROPERTY, ++ data->phy_reset_delays, ++ DELAYS_NUM); ++ if (ret) ++ goto err_out_disable_clk; ++ femac_phy_reset(data); ++ } ++ ++ data->fephy_rst = devm_reset_control_get(&pdev->dev, "internal-phy"); ++ if (IS_ERR(data->fephy_rst)) ++ data->fephy_rst = NULL; ++ ++ femac_get_phy_addr(data, np); ++ if (femac_use_fephy(data)) ++ femac_fephy_reset_and_trim(data); ++ else ++ femac_fephy_set_phy_addr(data); ++ ++ ret = of_mdiobus_register(bus, np); ++ if (ret) ++ goto err_out_disable_clk; ++ ++ platform_set_drvdata(pdev, bus); ++ ++ return 0; ++ ++err_out_disable_clk: ++ clk_disable_unprepare(data->fephy_clk); ++ clk_disable_unprepare(data->clk); ++err_out_free_mdiobus: ++ mdiobus_free(bus); ++ return ret; ++} ++ ++static int femac_mdio_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *bus = platform_get_drvdata(pdev); ++ struct femac_mdio_data *data = bus->priv; ++ ++ mdiobus_unregister(bus); ++ clk_disable_unprepare(data->clk); ++ mdiobus_free(bus); ++ ++ return 0; ++} ++ ++static const struct of_device_id femac_mdio_dt_ids[] = { ++ { .compatible = "goke,femac-mdio" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, femac_mdio_dt_ids); ++ ++static struct platform_driver femac_mdio_driver = { ++ .probe = femac_mdio_probe, ++ .remove = femac_mdio_remove, ++ .driver = { ++ .name = "femac-mdio", ++ .of_match_table = femac_mdio_dt_ids, ++ }, ++}; ++ ++module_platform_driver(femac_mdio_driver); ++ ++MODULE_DESCRIPTION("Goke Fast Ethernet MAC MDIO interface driver"); ++MODULE_LICENSE("GPL v2"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-phy_device.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-phy_device.c.patch new file mode 100644 index 00000000..84f20872 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-phy-phy_device.c.patch @@ -0,0 +1,56 @@ +--- linux-4.9.37/drivers/net/phy/phy_device.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/net/phy/phy_device.c 2021-06-07 13:01:33.000000000 +0300 +@@ -234,6 +234,53 @@ + } + EXPORT_SYMBOL(phy_register_fixup_for_id); + ++/** ++ * phy_unregister_fixup - remove a phy_fixup from the list ++ * @bus_id: A string matches fixup->bus_id (or PHY_ANY_ID) in phy_fixup_list ++ * @phy_uid: A phy id matches fixup->phy_id (or PHY_ANY_UID) in phy_fixup_list ++ * @phy_uid_mask: Applied to phy_uid and fixup->phy_uid before comparison ++ */ ++int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask) ++{ ++ struct list_head *pos, *n; ++ struct phy_fixup *fixup; ++ int ret; ++ ++ ret = -ENODEV; ++ ++ mutex_lock(&phy_fixup_lock); ++ list_for_each_safe(pos, n, &phy_fixup_list) { ++ fixup = list_entry(pos, struct phy_fixup, list); ++ ++ if ((!strcmp(fixup->bus_id, bus_id)) && ++ ((fixup->phy_uid & phy_uid_mask) == ++ (phy_uid & phy_uid_mask))) { ++ list_del(&fixup->list); ++ kfree(fixup); ++ ret = 0; ++ break; ++ } ++ } ++ mutex_unlock(&phy_fixup_lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(phy_unregister_fixup); ++ ++/* Unregisters a fixup of any PHY with the UID in phy_uid */ ++int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask) ++{ ++ return phy_unregister_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask); ++} ++EXPORT_SYMBOL(phy_unregister_fixup_for_uid); ++ ++/* Unregisters a fixup of the PHY with id string bus_id */ ++int phy_unregister_fixup_for_id(const char *bus_id) ++{ ++ return phy_unregister_fixup(bus_id, PHY_ANY_UID, 0xffffffff); ++} ++EXPORT_SYMBOL(phy_unregister_fixup_for_id); ++ + /* Returns 1 if fixup matches phydev in bus_id and phy_uid. + * Fixups can be set to match any in one or more fields. + */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-usb-cdc_ether.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-usb-cdc_ether.c.patch new file mode 100644 index 00000000..592a2581 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-net-usb-cdc_ether.c.patch @@ -0,0 +1,55 @@ +--- linux-4.9.37/drivers/net/usb/cdc_ether.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/net/usb/cdc_ether.c 2021-06-07 13:01:33.000000000 +0300 +@@ -310,6 +310,26 @@ + return -ENODEV; + } + ++ return 0; ++ ++bad_desc: ++ dev_info(&dev->udev->dev, "bad CDC descriptors\n"); ++ return -ENODEV; ++} ++EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind); ++ ++ ++/* like usbnet_generic_cdc_bind() but handles filter initialization ++ * correctly ++ */ ++int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf) ++{ ++ int rv; ++ ++ rv = usbnet_generic_cdc_bind(dev, intf); ++ if (rv < 0) ++ goto bail_out; ++ + /* Some devices don't initialise properly. In particular + * the packet filter is not reset. There are devices that + * don't do reset all the way. So the packet filter should +@@ -317,13 +337,10 @@ + */ + usbnet_cdc_update_filter(dev); + +- return 0; +- +-bad_desc: +- dev_info(&dev->udev->dev, "bad CDC descriptors\n"); +- return -ENODEV; ++bail_out: ++ return rv; + } +-EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind); ++EXPORT_SYMBOL_GPL(usbnet_ether_cdc_bind); + + void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf) + { +@@ -417,7 +434,7 @@ + BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) + < sizeof(struct cdc_state))); + +- status = usbnet_generic_cdc_bind(dev, intf); ++ status = usbnet_ether_cdc_bind(dev, intf); + if (status < 0) + return status; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-Kconfig.patch new file mode 100644 index 00000000..50f62179 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-Kconfig.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/phy/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/phy/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -481,6 +481,7 @@ + If unsure, say N. + + source "drivers/phy/tegra/Kconfig" ++source "drivers/phy/goke/Kconfig" + + config PHY_NS2_PCIE + tristate "Broadcom Northstar2 PCIe PHY driver" diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-Makefile.patch new file mode 100644 index 00000000..4b7367f5 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-Makefile.patch @@ -0,0 +1,8 @@ +--- linux-4.9.37/drivers/phy/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/phy/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -59,4 +59,5 @@ + obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o + obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o + obj-$(CONFIG_ARCH_TEGRA) += tegra/ ++obj-$(CONFIG_ARCH_GOKE) += goke/ + obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-Kconfig.patch new file mode 100644 index 00000000..51340f15 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-Kconfig.patch @@ -0,0 +1,29 @@ +--- linux-4.9.37/drivers/phy/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/phy/goke/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,26 @@ ++config PHY_GOKE_USBP2 ++ tristate "GOKE USBP2 PHY Driver" ++ select GENERIC_PHY ++ default n ++ help ++ Support for PHY on goke Socs. This Phy supports ++ USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one ++ USB host port to accept one USB device. Support init the phy ++ and adjust phy Eye Diagram. ++ ++menuconfig USB_MODE_OPTION ++ bool "goke USB related configuration" ++ ++if USB_MODE_OPTION ++ ++config USB_DRD0_IN_HOST ++ bool "USB DRD0 Mode Select HOST" ++ help ++ Select whether the USB drd0 is working in host mode. ++ ++config USB_DRD0_IN_DEVICE ++ bool "USB DRD0 Mode Select DEVICE" ++ help ++ Select whether the USB drd0 is working in device mode. ++ ++endif # USB_MODE_OPTION diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-Makefile.patch new file mode 100644 index 00000000..ac561eb0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-Makefile.patch @@ -0,0 +1,4 @@ +--- linux-4.9.37/drivers/phy/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/phy/goke/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1 @@ ++obj-$(CONFIG_PHY_GOKE_USBP2) += phy-goke-usbp2.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-phy-goke-usb.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-phy-goke-usb.h.patch new file mode 100644 index 00000000..d4ce319d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-phy-goke-usb.h.patch @@ -0,0 +1,61 @@ +--- linux-4.9.37/drivers/phy/goke/phy-goke-usb.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/phy/goke/phy-goke-usb.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef USB2_INCLUDE_PHY_H ++#define USB2_INCLUDE_PHY_H ++ ++extern void bsp_usb_phy_on(struct phy *phy); ++extern void bsp_usb_phy_off(struct phy *phy); ++extern void bsp_usb3_phy_on(struct phy *phy); ++extern void bsp_usb3_phy_off(struct phy *phy); ++ ++ ++struct bsp_priv { ++ void __iomem *sys_ctrl; ++ void __iomem *peri_ctrl; ++ void __iomem *combphy_base; ++ void __iomem *misc_ctrl; ++ unsigned int phyid; ++ void __iomem *ctrl_base; ++ void __iomem *switch_base; ++}; ++ ++typedef enum mode { ++ PCIE_X2 = 0, ++ PCIE_X1, ++ USB3 ++} combphy_mode; ++ ++#define U_LEVEL1 10 ++#define U_LEVEL2 20 ++#define U_LEVEL3 30 ++#define U_LEVEL4 50 ++#define U_LEVEL5 100 ++#define U_LEVEL6 200 ++#define U_LEVEL7 300 ++#define U_LEVEL8 500 ++ ++#define M_LEVEL1 2 ++#define M_LEVEL2 5 ++#define M_LEVEL3 10 ++#define M_LEVEL4 20 ++#define M_LEVEL5 50 ++#define M_LEVEL6 100 ++#define M_LEVEL7 200 ++ ++#define __1K__ 0x400 ++#define __2K__ 0x800 ++#define __4K__ 0x1000 ++#define __8K__ 0x2000 ++#define __64K__ 0x10000 ++ ++#define CRG_REGBASE_NODE_IDX 0 ++#define MISC_REGBASE_NODE_IDX 1 ++#define CTRL_REGBASE_NODE_IDX 2 ++#define PHY_REGBASE_NODE_IDX 3 ++ ++#endif /* USB2_INCLUDE_PHY_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-phy-goke-usbp2.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-phy-goke-usbp2.c.patch new file mode 100644 index 00000000..18379f2c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-phy-goke-phy-goke-usbp2.c.patch @@ -0,0 +1,761 @@ +--- linux-4.9.37/drivers/phy/goke/phy-goke-usbp2.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/phy/goke/phy-goke-usbp2.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,758 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "phy-goke-usb.h" ++ ++#define USBP2_PHY_TRIM_OFFSET 0x0008 ++#define USBP2_PHY_TRIM_MASK 0x1f00 ++#define USBP2_PHY_TRIM_VAL(a) (((a) << 8) & USBP2_PHY_TRIM_MASK) ++ ++#define USBP2_PHY_SVB_OFFSET 0x0000 ++#define USBP2_PHY_SVB_MASK 0x0f000000 ++#define USBP2_PHY_SVB_VAL(a) (((a) << 24) & USBP2_PHY_SVB_MASK) ++ ++struct bsp_usbp2_priv { ++ void __iomem *crg_base; ++ void __iomem *phy_base; ++ void __iomem *pin_base; ++ struct phy *phy; ++ struct device *dev; ++ struct clk **clks; ++ int num_clocks; ++ u32 phy_pll_offset; ++ u32 phy_pll_mask; ++ u32 phy_pll_val; ++ u32 crg_offset; ++ u32 crg_defal_mask; ++ u32 crg_defal_val; ++ u32 vbus_offset; ++ u32 vbus_val; ++ int vbus_flag; ++ u32 pwren_offset; ++ u32 pwren_val; ++ int pwren_flag; ++ u32 ana_cfg_0_eye_val; ++ u32 ana_cfg_0_offset; ++ int ana_cfg_0_flag; ++ u32 ana_cfg_2_eye_val; ++ u32 ana_cfg_2_offset; ++ int ana_cfg_2_flag; ++ u32 ana_cfg_4_eye_val; ++ u32 ana_cfg_4_offset; ++ int ana_cfg_4_flag; ++ struct reset_control *usb_phy_tpor_rst; ++ struct reset_control *usb_phy_por_rst; ++ u32 trim_otp_addr; ++ u32 trim_otp_mask; ++ u32 trim_otp_bit_offset; ++ u32 trim_otp_min; ++ u32 trim_otp_max; ++ int trim_flag; ++ u32 svb_otp_addr; ++ u32 svb_otp_predev5_min; ++ u32 svb_otp_predev5_max; ++ u32 svb_phy_predev5_val; ++ int svb_predev5_flag; ++ u32 svb_otp_predev4_min; ++ u32 svb_otp_predev4_max; ++ u32 svb_phy_predev4_val; ++ int svb_predev4_flag; ++ u32 svb_otp_predev3_min; ++ u32 svb_otp_predev3_max; ++ u32 svb_phy_predev3_val; ++ int svb_predev3_flag; ++ u32 svb_otp_predev2_min; ++ u32 svb_otp_predev2_max; ++ u32 svb_phy_predev2_val; ++ int svb_predev2_flag; ++ int svb_flag; ++}; ++ ++void bsp_usbp2_def_all_exist(struct bsp_usbp2_priv *priv) ++{ ++ if (priv == NULL) ++ return; ++ ++ /* All parameters exist by default */ ++ priv->vbus_flag = 1; ++ ++ priv->pwren_flag = 1; ++ ++ priv->ana_cfg_0_flag = 1; ++ ++ priv->ana_cfg_2_flag = 1; ++ ++ priv->ana_cfg_4_flag = 1; ++ ++ priv->trim_flag = 1; ++ ++ priv->svb_predev5_flag = 1; ++ ++ priv->svb_predev4_flag = 1; ++ ++ priv->svb_predev3_flag = 1; ++ ++ priv->svb_predev2_flag = 1; ++ ++ priv->svb_flag = 1; ++} ++ ++void bsp_usbp2_get_eye_para(struct device *dev, struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return; ++ ++ /* ++ * Get phy eye parameters,if you want to change them,please open ++ * dtsi file and modify parameters at phy node. ++ */ ++ ret = of_property_read_u32(dev->of_node, "ana_cfg_0_eye_val", ++ &(priv->ana_cfg_0_eye_val)); ++ if (ret) ++ priv->ana_cfg_0_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "ana_cfg_0_offset", ++ &(priv->ana_cfg_0_offset)); ++ if (ret) ++ priv->ana_cfg_0_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "ana_cfg_2_eye_val", ++ &(priv->ana_cfg_2_eye_val)); ++ if (ret) ++ priv->ana_cfg_2_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "ana_cfg_2_offset", ++ &(priv->ana_cfg_2_offset)); ++ if (ret) ++ priv->ana_cfg_2_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "ana_cfg_4_eye_val", ++ &(priv->ana_cfg_4_eye_val)); ++ if (ret) ++ priv->ana_cfg_4_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "ana_cfg_4_offset", ++ &(priv->ana_cfg_4_offset)); ++ if (ret) ++ priv->ana_cfg_4_flag = 0; ++} ++ ++void bsp_usbp2_phy_eye_config(struct bsp_usbp2_priv *priv) ++{ ++ if (priv == NULL) ++ return; ++ ++ if (priv->ana_cfg_0_flag) ++ writel(priv->ana_cfg_0_eye_val, priv->phy_base + priv->ana_cfg_0_offset); ++ ++ if (priv->ana_cfg_2_flag) ++ writel(priv->ana_cfg_2_eye_val, priv->phy_base + priv->ana_cfg_2_offset); ++ ++ if (priv->ana_cfg_4_flag) ++ writel(priv->ana_cfg_4_eye_val, priv->phy_base + priv->ana_cfg_4_offset); ++} ++ ++void bsp_usbp2_get_trim_para(struct device *dev, struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return; ++ ++ /* get phy trim parameters */ ++ ret = of_property_read_u32(dev->of_node, "trim_otp_addr", ++ &(priv->trim_otp_addr)); ++ if (ret) ++ priv->trim_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "trim_otp_mask", ++ &(priv->trim_otp_mask)); ++ if (ret) ++ priv->trim_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "trim_otp_bit_offset", ++ &(priv->trim_otp_bit_offset)); ++ if (ret) ++ priv->trim_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "trim_otp_min", &(priv->trim_otp_min)); ++ if (ret) ++ priv->trim_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "trim_otp_max", &(priv->trim_otp_max)); ++ if (ret) ++ priv->trim_flag = 0; ++} ++ ++void bsp_usbp2_phy_trim_config(struct bsp_usbp2_priv *priv) ++{ ++ unsigned int trim_otp_val; ++ unsigned int reg; ++ void __iomem *phy_trim = NULL; ++ ++ if (priv == NULL) ++ return; ++ ++ if (priv->trim_flag) { ++ phy_trim = ioremap_nocache(priv->trim_otp_addr, __1K__); ++ if (phy_trim == NULL) ++ return; ++ ++ reg = readl(phy_trim); ++ trim_otp_val = (reg & priv->trim_otp_mask); ++ if ((trim_otp_val >= priv->trim_otp_min) && ++ (trim_otp_val <= priv->trim_otp_max)) { ++ /* set trim value to phy */ ++ reg = readl(priv->phy_base + USBP2_PHY_TRIM_OFFSET); ++ reg &= ~USBP2_PHY_TRIM_MASK; ++ reg |= USBP2_PHY_TRIM_VAL(trim_otp_val >> priv->trim_otp_bit_offset); ++ writel(reg, priv->phy_base + USBP2_PHY_TRIM_OFFSET); ++ } ++ iounmap(phy_trim); ++ } ++} ++ ++void bsp_usbp2_get_svb_para_1(struct device *dev, struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return; ++ ++ /* get phy svb parmteters */ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_addr", &(priv->svb_otp_addr)); ++ if (ret) ++ priv->svb_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_min", ++ &(priv->svb_otp_predev5_min)); ++ if (ret) ++ priv->svb_predev5_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_max", ++ &(priv->svb_otp_predev5_max)); ++ if (ret) ++ priv->svb_predev5_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_phy_predev5_val", ++ &(priv->svb_phy_predev5_val)); ++ if (ret) ++ priv->svb_predev5_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_min", ++ &(priv->svb_otp_predev4_min)); ++ if (ret) ++ priv->svb_predev4_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_max", ++ &(priv->svb_otp_predev4_max)); ++ if (ret) ++ priv->svb_predev4_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_phy_predev4_val", ++ &(priv->svb_phy_predev4_val)); ++ if (ret) ++ priv->svb_predev4_flag = 0; ++} ++ ++void bsp_usbp2_get_svb_para_2(struct device *dev, struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_min", ++ &(priv->svb_otp_predev3_min)); ++ if (ret) ++ priv->svb_predev3_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_max", ++ &(priv->svb_otp_predev3_max)); ++ if (ret) ++ priv->svb_predev3_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_phy_predev3_val", ++ &(priv->svb_phy_predev3_val)); ++ if (ret) ++ priv->svb_predev3_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_min", ++ &(priv->svb_otp_predev2_min)); ++ if (ret) ++ priv->svb_predev2_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_max", ++ &(priv->svb_otp_predev2_max)); ++ if (ret) ++ priv->svb_predev2_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "svb_phy_predev2_val", ++ &(priv->svb_phy_predev2_val)); ++ if (ret) ++ priv->svb_predev2_flag = 0; ++} ++ ++void bsp_usbp2_phy_svb_config(struct bsp_usbp2_priv *priv) ++{ ++ unsigned int reg; ++ unsigned int ret; ++ void __iomem *phy_svb = NULL; ++ ++ if (priv == NULL) ++ return; ++ ++ if (priv->svb_flag) { ++ phy_svb = ioremap_nocache(priv->svb_otp_addr, __1K__); ++ if (phy_svb == NULL) ++ return; ++ ++ ret = readl(phy_svb); ++ reg = readl(priv->phy_base + USBP2_PHY_SVB_OFFSET); ++ reg &= ~USBP2_PHY_SVB_MASK; ++ if ((ret >= priv->svb_otp_predev5_min) && ++ (ret < priv->svb_otp_predev5_max) && (priv->svb_predev5_flag)) ++ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev5_val); ++ else if ((ret >= priv->svb_otp_predev4_min) && ++ (ret < priv->svb_otp_predev4_max) && (priv->svb_predev4_flag)) ++ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev4_val); ++ else if ((ret >= priv->svb_otp_predev3_min) && ++ (ret <= priv->svb_otp_predev3_max) && (priv->svb_predev3_flag)) ++ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev3_val); ++ else if ((ret > priv->svb_otp_predev2_min) && ++ (ret <= priv->svb_otp_predev2_max) && (priv->svb_predev2_flag)) ++ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev2_val); ++ else ++ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev4_val); ++ ++ writel(reg, priv->phy_base + USBP2_PHY_SVB_OFFSET); ++ iounmap(phy_svb); ++ } ++} ++ ++static void bsp_usb_vbus_and_pwren_config(struct device *dev, struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return; ++ ++ /* Some chips do not have VBUS encapsulation and need to be configured */ ++ ret = of_property_read_u32(dev->of_node, "vbus_offset", &(priv->vbus_offset)); ++ if (ret) ++ priv->vbus_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "vbus_val", &(priv->vbus_val)); ++ if (ret) ++ priv->vbus_flag = 0; ++ ++ /* Some chips do not have PWREN encapsulation and need to be configured */ ++ ret = of_property_read_u32(dev->of_node, "pwren_offset", &(priv->pwren_offset)); ++ if (ret) ++ priv->pwren_flag = 0; ++ ++ ret = of_property_read_u32(dev->of_node, "pwren_val", &(priv->pwren_val)); ++ if (ret) ++ priv->pwren_flag = 0; ++ ++ if (priv->vbus_flag) ++ writel(priv->vbus_val, priv->pin_base + priv->vbus_offset); ++ ++ udelay(U_LEVEL2); ++ ++ if (priv->pwren_flag) ++ writel(priv->pwren_val, priv->pin_base + priv->pwren_offset); ++ ++ udelay(U_LEVEL2); ++} ++ ++static int bsp_usbp2_get_pll_clk(struct device *dev, ++ struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return -EINVAL; ++ ++ /* Get phy pll clk config parameters from the phy node of the dtsi file */ ++ ret = of_property_read_u32(dev->of_node, "phy_pll_offset", ++ &(priv->phy_pll_offset)); ++ if (ret) { ++ dev_err(dev, "get phy_pll_offset failed: %d\n", ret); ++ return ret; ++ } ++ ++ ret = of_property_read_u32(dev->of_node, "phy_pll_mask", &(priv->phy_pll_mask)); ++ if (ret) { ++ dev_err(dev, "get phy_pll_mask failed: %d\n", ret); ++ return ret; ++ } ++ ++ ret = of_property_read_u32(dev->of_node, "phy_pll_val", &(priv->phy_pll_val)); ++ if (ret) { ++ dev_err(dev, "get phy_pll_val failed: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int bsp_usbp2_set_crg_val(struct device *dev, ++ struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ unsigned int reg; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return -EINVAL; ++ ++ /* Get CRG default value from the phy node of the dtsi file */ ++ ret = of_property_read_u32(dev->of_node, "crg_offset", &(priv->crg_offset)); ++ if (ret) { ++ dev_err(dev, "get crg_offset failed: %d\n", ret); ++ return ret; ++ } ++ ++ ret = of_property_read_u32(dev->of_node, "crg_defal_mask", ++ &(priv->crg_defal_mask)); ++ if (ret) { ++ dev_err(dev, "get crg_defal_mask failed: %d\n", ret); ++ return ret; ++ } ++ ++ ret = of_property_read_u32(dev->of_node, "crg_defal_val", ++ &(priv->crg_defal_val)); ++ if (ret) { ++ dev_err(dev, "get crg_defal_val failed: %d\n", ret); ++ return ret; ++ } ++ ++ /* write phy crg default value */ ++ reg = readl(priv->crg_base + priv->crg_offset); ++ reg &= ~priv->crg_defal_mask; ++ reg |= priv->crg_defal_val; ++ writel(reg, priv->crg_base + priv->crg_offset); ++ ++ return 0; ++} ++ ++static int bsp_usbp2_phy_get_para(struct device *dev, ++ struct bsp_usbp2_priv *priv) ++{ ++ unsigned int ret; ++ ++ if ((dev == NULL) || (priv == NULL)) ++ return -EINVAL; ++ ++ bsp_usbp2_def_all_exist(priv); ++ ++ ret = bsp_usbp2_get_pll_clk(dev, priv); ++ if (ret) { ++ dev_err(dev, "get pll clk failed: %d\n", ret); ++ return ret; ++ } ++ ++ bsp_usbp2_get_trim_para(dev, priv); ++ bsp_usbp2_get_eye_para(dev, priv); ++ bsp_usbp2_get_svb_para_1(dev, priv); ++ bsp_usbp2_get_svb_para_2(dev, priv); ++ ++ return 0; ++} ++ ++static int bsp_usbp2_phy_get_clks(struct bsp_usbp2_priv *priv, int count) ++{ ++ struct device *dev = priv->dev; ++ struct device_node *np = dev->of_node; ++ int i; ++ ++ priv->num_clocks = count; ++ ++ if (!count) ++ return 0; ++ ++ priv->clks = ++ devm_kcalloc(dev, priv->num_clocks, sizeof(struct clk *), GFP_KERNEL); ++ if (priv->clks == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < priv->num_clocks; i++) { ++ struct clk *clk; ++ ++ clk = of_clk_get(np, i); ++ if (IS_ERR(clk)) { ++ while (--i >= 0) ++ clk_put(priv->clks[i]); ++ ++ devm_kfree(dev, priv->clks); ++ priv->clks = NULL; ++ return PTR_ERR(clk); ++ } ++ ++ priv->clks[i] = clk; ++ } ++ return 0; ++} ++ ++static int bsp_usbp2_clk_rst_config(struct platform_device *pdev, ++ struct bsp_usbp2_priv *priv) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = pdev->dev.of_node; ++ unsigned int ret; ++ ++ ret = bsp_usbp2_phy_get_clks(priv, of_clk_get_parent_count(np)); ++ if (ret) { ++ dev_err(dev, "get phy clk failed\n"); ++ return ret; ++ } ++ ++ priv->usb_phy_tpor_rst = devm_reset_control_get(dev, "phy_tpor_reset"); ++ if (IS_ERR_OR_NULL(priv->usb_phy_tpor_rst)) { ++ dev_err(dev, "get phy_tpor_reset failed: %d\n", ret); ++ return PTR_ERR(priv->usb_phy_tpor_rst); ++ } ++ ++ priv->usb_phy_por_rst = devm_reset_control_get(dev, "phy_por_reset"); ++ if (IS_ERR_OR_NULL(priv->usb_phy_por_rst)) { ++ dev_err(dev, "get phy_por_reset failed: %d\n", ret); ++ return PTR_ERR(priv->usb_phy_por_rst);; ++ } ++ ++ return 0; ++} ++ ++static int bsp_usbp2_iomap(struct device_node *np, ++ struct bsp_usbp2_priv *priv) ++{ ++ if ((np == NULL) || (priv == NULL)) ++ return -EINVAL; ++ ++ priv->phy_base = of_iomap(np, 0); ++ if (IS_ERR(priv->phy_base)) ++ return -ENOMEM; ++ ++ priv->crg_base = of_iomap(np, 1); ++ if (IS_ERR(priv->crg_base)) { ++ iounmap(priv->phy_base); ++ return -ENOMEM; ++ } ++ ++ priv->pin_base = of_iomap(np, 2); ++ if (IS_ERR(priv->pin_base)) { ++ iounmap(priv->phy_base); ++ iounmap(priv->crg_base); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static int bsp_usbp2_phy_init(struct phy *phy) ++{ ++ struct bsp_usbp2_priv *priv = phy_get_drvdata(phy); ++ int i, ret; ++ unsigned int reg; ++ ++ for (i = 0; i < priv->num_clocks; i++) { ++ ret = clk_prepare_enable(priv->clks[i]); ++ if (ret < 0) { ++ while (--i >= 0) { ++ clk_disable_unprepare(priv->clks[i]); ++ clk_put(priv->clks[i]); ++ } ++ } ++ } ++ ++ udelay(U_LEVEL5); ++ ++ /* undo por reset */ ++ ret = reset_control_deassert(priv->usb_phy_por_rst); ++ if (ret) ++ return ret; ++ ++ /* pll out clk */ ++ reg = readl(priv->phy_base + priv->phy_pll_offset); ++ reg &= ~priv->phy_pll_mask; ++ reg |= priv->phy_pll_val; ++ writel(reg, priv->phy_base + priv->phy_pll_offset); ++ ++ mdelay(M_LEVEL1); ++ ++ /* undo tpor reset */ ++ ret = reset_control_deassert(priv->usb_phy_tpor_rst); ++ if (ret) ++ return ret; ++ ++ udelay(U_LEVEL6); ++ ++ bsp_usbp2_phy_eye_config(priv); ++ ++ bsp_usbp2_phy_trim_config(priv); ++ ++ bsp_usbp2_phy_svb_config(priv); ++ return 0; ++} ++ ++static int bsp_usbp2_phy_exit(struct phy *phy) ++{ ++ struct bsp_usbp2_priv *priv = phy_get_drvdata(phy); ++ int i, ret; ++ ++ for (i = 0; i < priv->num_clocks; i++) ++ clk_disable_unprepare(priv->clks[i]); ++ ++ ret = reset_control_assert(priv->usb_phy_por_rst); ++ if (ret) ++ return ret; ++ ++ ret = reset_control_assert(priv->usb_phy_tpor_rst); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static const struct phy_ops bsp_usbp2_phy_ops = { ++ .init = bsp_usbp2_phy_init, ++ .exit = bsp_usbp2_phy_exit, ++ .owner = THIS_MODULE, ++}; ++ ++static int bsp_usbp2_phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct phy *phy = NULL; ++ struct bsp_usbp2_priv *priv = NULL; ++ struct device_node *np = pdev->dev.of_node; ++ struct phy_provider *phy_provider = NULL; ++ unsigned int ret; ++ ++ phy = devm_phy_create(dev, dev->of_node, &bsp_usbp2_phy_ops); ++ if (IS_ERR(phy)) ++ return PTR_ERR(phy); ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (priv == NULL) ++ return -ENOMEM; ++ ++ ret = bsp_usbp2_iomap(np, priv); ++ if (ret) { ++ devm_kfree(dev, priv); ++ priv = NULL; ++ ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, priv); ++ priv->dev = dev; ++ ++ ret = bsp_usbp2_clk_rst_config(pdev, priv); ++ if (ret) ++ goto xvp_unmap; ++ ++ ret = bsp_usbp2_phy_get_para(dev, priv); ++ if (ret) ++ goto xvp_unmap; ++ ++ bsp_usb_vbus_and_pwren_config(dev, priv); ++ ++ ret = bsp_usbp2_set_crg_val(dev, priv); ++ if (ret) ++ goto xvp_unmap; ++ ++ platform_set_drvdata(pdev, priv); ++ phy_set_drvdata(phy, priv); ++ ++ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); ++ if (IS_ERR(phy_provider)) { ++ ret = PTR_ERR(phy_provider); ++ goto xvp_unmap; ++ } ++ ++ return 0; ++xvp_unmap: ++ iounmap(priv->phy_base); ++ iounmap(priv->crg_base); ++ iounmap(priv->pin_base); ++ ++ devm_kfree(dev, priv); ++ priv = NULL; ++ ++ return ret; ++} ++ ++static int bsp_usbp2_phy_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct bsp_usbp2_priv *priv = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < priv->num_clocks; i++) ++ clk_put(priv->clks[i]); ++ ++ iounmap(priv->phy_base); ++ iounmap(priv->crg_base); ++ iounmap(priv->pin_base); ++ ++ devm_kfree(dev, priv); ++ priv = NULL; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static int bsp_usbp2_phy_suspend(struct device *dev) ++{ ++ struct phy *phy = dev_get_drvdata(dev); ++ ++ if (bsp_usbp2_phy_exit(phy)) ++ return -1; ++ ++ return 0; ++} ++ ++static int bsp_usbp2_phy_resume(struct device *dev) ++{ ++ struct phy *phy = dev_get_drvdata(dev); ++ ++ if (bsp_usbp2_phy_init(phy)) ++ return -1; ++ ++ return 0; ++} ++#endif /* CONFIG_PM_SLEEP */ ++ ++static SIMPLE_DEV_PM_OPS(bsp_usb_pm_ops, bsp_usbp2_phy_suspend, ++ bsp_usbp2_phy_resume); ++ ++static const struct of_device_id bsp_usbp2_phy_of_match[] = { ++ { .compatible = "goke,usbp2-phy" }, ++ {}, ++}; ++ ++static struct platform_driver bsp_usbp2_phy_driver = { ++ .probe = bsp_usbp2_phy_probe, ++ .remove = bsp_usbp2_phy_remove, ++ .driver = { ++ .name = "goke-usbp2-phy", ++ .pm = &bsp_usb_pm_ops, ++ .of_match_table = bsp_usbp2_phy_of_match, ++ } ++}; ++module_platform_driver(bsp_usbp2_phy_driver); ++MODULE_DESCRIPTION("GOKE USB PHY driver"); ++MODULE_ALIAS("platform:usbp2-phy"); ++MODULE_LICENSE("GPL v2"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-Kconfig.patch new file mode 100644 index 00000000..fb039cc4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-Kconfig.patch @@ -0,0 +1,15 @@ +--- linux-4.9.37/drivers/power/reset/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/power/reset/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -67,6 +67,12 @@ + Say Y here if you have a Broadcom STB board and you wish + to have restart support. + ++config POWER_RESET_GOKE ++ bool "Goke power-off driver" ++ depends on ARCH_GOKE ++ help ++ Reboot support for Goke boards. ++ + config POWER_RESET_GPIO + bool "GPIO power-off driver" + depends on OF_GPIO diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-Makefile.patch new file mode 100644 index 00000000..30065ca0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/power/reset/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/power/reset/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -5,6 +5,7 @@ + obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o + obj-$(CONFIG_POWER_RESET_BRCMKONA) += brcm-kona-reset.o + obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o ++obj-$(CONFIG_POWER_RESET_GOKE) += goke-reboot.o + obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o + obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o + obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-goke-reboot.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-goke-reboot.c.patch new file mode 100644 index 00000000..27127b33 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-power-reset-goke-reboot.c.patch @@ -0,0 +1,76 @@ +--- linux-4.9.37/drivers/power/reset/goke-reboot.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/power/reset/goke-reboot.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,73 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++static void __iomem *base; ++static u32 reboot_offset; ++ ++static int bsp_restart_handler(struct notifier_block *this, ++ unsigned long mode, void *cmd) ++{ ++ writel_relaxed(0xdeadbeef, base + reboot_offset); ++ ++ while (1) ++ cpu_do_idle(); ++ ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block bsp_restart_nb = { ++ .notifier_call = bsp_restart_handler, ++ .priority = 128, ++}; ++ ++static int bsp_reboot_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ int err; ++ ++ base = of_iomap(np, 0); ++ if (!base) { ++ WARN(1, "failed to map base address"); ++ return -ENODEV; ++ } ++ ++ if (of_property_read_u32(np, "reboot-offset", &reboot_offset) < 0) { ++ pr_err("failed to find reboot-offset property\n"); ++ iounmap(base); ++ return -EINVAL; ++ } ++ ++ err = register_restart_handler(&bsp_restart_nb); ++ if (err) { ++ dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n", ++ err); ++ iounmap(base); ++ } ++ ++ return err; ++} ++ ++static const struct of_device_id bsp_reboot_of_match[] = { ++ { .compatible = "goke,sysctrl" }, ++ {} ++}; ++ ++static struct platform_driver bsp_reboot_driver = { ++ .probe = bsp_reboot_probe, ++ .driver = { ++ .name = "goke-reboot", ++ .of_match_table = bsp_reboot_of_match, ++ }, ++}; ++module_platform_driver(bsp_reboot_driver); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-Kconfig.patch new file mode 100644 index 00000000..2e6fdb04 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-Kconfig.patch @@ -0,0 +1,17 @@ +--- linux-4.9.37/drivers/pwm/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/pwm/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -175,6 +175,14 @@ + To compile this driver as a module, choose M here: the module + will be called pwm-fsl-ftm. + ++config PWM_GOKE ++ tristate "Goke PWM support" ++ help ++ Generic PWM framework driver for Goke SoCs. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called pwm-goke. ++ + config PWM_IMG + tristate "Imagination Technologies PWM driver" + depends on HAS_IOMEM diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-Makefile.patch new file mode 100644 index 00000000..f9a259e8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/pwm/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/pwm/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -15,6 +15,7 @@ + obj-$(CONFIG_PWM_CROS_EC) += pwm-cros-ec.o + obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o + obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o ++obj-$(CONFIG_PWM_GOKE) += pwm-goke.o + obj-$(CONFIG_PWM_IMG) += pwm-img.o + obj-$(CONFIG_PWM_IMX) += pwm-imx.o + obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-pwm-goke.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-pwm-goke.c.patch new file mode 100644 index 00000000..45fb4bc0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-pwm-pwm-goke.c.patch @@ -0,0 +1,263 @@ +--- linux-4.9.37/drivers/pwm/pwm-goke.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/pwm/pwm-goke.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,260 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PWM_CFG0_ADDR(x) (((x)*0x20) + 0x0) ++#define PWM_CFG1_ADDR(x) (((x)*0x20) + 0x4) ++#define PWM_CFG2_ADDR(x) (((x)*0x20) + 0x8) ++#define PWM_CTRL_ADDR(x) (((x)*0x20) + 0xC) ++ ++#define PWM_ENABLE_SHIFT 0 ++#define PWM_ENABLE_MASK BIT(0) ++ ++#define PWM_POLARITY_SHIFT 1 ++#define PWM_POLARITY_MASK BIT(1) ++ ++#define PWM_KEEP_SHIFT 2 ++#define PWM_KEEP_MASK BIT(2) ++ ++#define PWM_PERIOD_MASK GENMASK(31, 0) ++#define PWM_DUTY_MASK GENMASK(31, 0) ++ ++struct goke_pwm_chip { ++ struct pwm_chip chip; ++ struct clk *clk; ++ void __iomem *base; ++ struct reset_control *rstc; ++}; ++ ++struct goke_pwm_soc { ++ u32 num_pwms; ++}; ++ ++static const struct goke_pwm_soc pwm_soc[1] = { ++ { .num_pwms = 2 }, ++}; ++ ++static inline struct goke_pwm_chip *to_goke_pwm_chip(struct pwm_chip *chip) ++{ ++ return container_of(chip, struct goke_pwm_chip, chip); ++} ++ ++static void goke_pwm_set_bits(void __iomem *base, u32 offset, ++ u32 mask, u32 data) ++{ ++ void __iomem *address = base + offset; ++ u32 value; ++ ++ value = readl(address); ++ value &= ~mask; ++ value |= (data & mask); ++ writel(value, address); ++} ++ ++static void goke_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); ++ ++ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), ++ PWM_ENABLE_MASK, 0x1); ++} ++ ++static void goke_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); ++ ++ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), ++ PWM_ENABLE_MASK, 0x0); ++} ++ ++static void goke_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ++ int duty_cycle_ns, int period_ns) ++{ ++ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); ++ u32 duty; ++ u64 period, freq; ++ ++ freq = div_u64(clk_get_rate(bsp_pwm_chip->clk), 1000000); ++ ++ period = div_u64(freq * period_ns, 1000); ++ duty = div_u64(period * duty_cycle_ns, period_ns); ++ ++ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CFG0_ADDR(pwm->hwpwm), ++ PWM_PERIOD_MASK, period); ++ ++ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CFG1_ADDR(pwm->hwpwm), ++ PWM_DUTY_MASK, duty); ++} ++ ++static void goke_pwm_set_polarity(struct pwm_chip *chip, ++ struct pwm_device *pwm, ++ enum pwm_polarity polarity) ++{ ++ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); ++ ++ if (polarity == PWM_POLARITY_INVERSED) ++ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), ++ PWM_POLARITY_MASK, (0x1 << PWM_POLARITY_SHIFT)); ++ else ++ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), ++ PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT)); ++} ++ ++static void goke_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, ++ struct pwm_state *state) { ++ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); ++ void __iomem *base; ++ u32 freq; ++ u64 value; ++ ++ freq = div_u64(clk_get_rate(bsp_pwm_chip->clk), 1000000); ++ base = bsp_pwm_chip->base; ++ ++ value = readl(base + PWM_CFG0_ADDR(pwm->hwpwm)); ++ state->period = div_u64(value * 1000, freq); ++ ++ value = readl(base + PWM_CFG1_ADDR(pwm->hwpwm)); ++ state->duty_cycle = div_u64(value * 1000, freq); ++ ++ value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm)); ++ state->enabled = (PWM_ENABLE_MASK & value); ++} ++ ++static int goke_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ++ struct pwm_state *state) ++{ ++ if (state->polarity != pwm->state.polarity) { ++ goke_pwm_set_polarity(chip, pwm, state->polarity); ++ } ++ ++ if (state->period != pwm->state.period || ++ state->duty_cycle != pwm->state.duty_cycle) { ++ goke_pwm_config(chip, pwm, state->duty_cycle, state->period); ++ } ++ ++ if (state->enabled != pwm->state.enabled) { ++ if (state->enabled) { ++ goke_pwm_enable(chip, pwm); ++ } ++ else { ++ goke_pwm_disable(chip, pwm); ++ } ++ } ++ ++ return 0; ++} ++ ++static struct pwm_ops goke_pwm_ops = { ++ .get_state = goke_pwm_get_state, ++ .apply = goke_pwm_apply, ++ ++ .owner = THIS_MODULE, ++}; ++ ++static int goke_pwm_probe(struct platform_device *pdev) ++{ ++ const struct goke_pwm_soc *soc = ++ of_device_get_match_data(&pdev->dev); ++ struct goke_pwm_chip *pwm_chip; ++ struct resource *res; ++ int ret; ++ int i; ++ ++ pwm_chip = devm_kzalloc(&pdev->dev, sizeof(*pwm_chip), GFP_KERNEL); ++ if (pwm_chip == NULL) { ++ return -ENOMEM; ++ } ++ ++ pwm_chip->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(pwm_chip->clk)) { ++ dev_err(&pdev->dev, "getting clock failed with %ld\n", ++ PTR_ERR(pwm_chip->clk)); ++ return PTR_ERR(pwm_chip->clk); ++ } ++ ++ pwm_chip->chip.ops = &goke_pwm_ops; ++ pwm_chip->chip.dev = &pdev->dev; ++ pwm_chip->chip.base = -1; ++ pwm_chip->chip.npwm = soc->num_pwms; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ pwm_chip->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(pwm_chip->base)) { ++ return PTR_ERR(pwm_chip->base); ++ } ++ ++ ret = clk_prepare_enable(pwm_chip->clk); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ pwm_chip->rstc = devm_reset_control_get(&pdev->dev, NULL); ++ if (IS_ERR(pwm_chip->rstc)) { ++ clk_disable_unprepare(pwm_chip->clk); ++ return PTR_ERR(pwm_chip->rstc); ++ } ++ ++ reset_control_assert(pwm_chip->rstc); ++ msleep(30); ++ reset_control_deassert(pwm_chip->rstc); ++ ++ ret = pwmchip_add(&pwm_chip->chip); ++ if (ret < 0) { ++ clk_disable_unprepare(pwm_chip->clk); ++ return ret; ++ } ++ ++ for (i = 0; i < pwm_chip->chip.npwm; i++) { ++ goke_pwm_set_bits(pwm_chip->base, PWM_CTRL_ADDR(i), ++ PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT)); ++ } ++ ++ platform_set_drvdata(pdev, pwm_chip); ++ ++ return 0; ++} ++ ++static int goke_pwm_remove(struct platform_device *pdev) ++{ ++ struct goke_pwm_chip *pwm_chip; ++ ++ pwm_chip = platform_get_drvdata(pdev); ++ ++ reset_control_assert(pwm_chip->rstc); ++ msleep(30); ++ reset_control_deassert(pwm_chip->rstc); ++ ++ clk_disable_unprepare(pwm_chip->clk); ++ ++ return pwmchip_remove(&pwm_chip->chip); ++} ++ ++static const struct of_device_id goke_pwm_of_match[] = { ++ { .compatible = "goke,goke-pwm" }, ++ { .compatible = "goke,pwm", .data = &pwm_soc[0] }, {} ++}; ++MODULE_DEVICE_TABLE(of, goke_pwm_of_match); ++ ++static struct platform_driver goke_pwm_driver = { ++ .driver = { ++ .name = "goke-pwm", ++ .of_match_table = goke_pwm_of_match, ++ }, ++ .probe = goke_pwm_probe, ++ .remove = goke_pwm_remove, ++}; ++module_platform_driver(goke_pwm_driver); ++ ++MODULE_AUTHOR("Goke"); ++MODULE_DESCRIPTION("Goke SoCs PWM driver"); ++MODULE_LICENSE("GPL"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-Kconfig.patch new file mode 100644 index 00000000..d1f6ee52 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-Kconfig.patch @@ -0,0 +1,26 @@ +--- linux-4.9.37/drivers/rtc/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/rtc/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -3,7 +3,7 @@ + # + + config RTC_LIB +- bool ++ bool "Real Time Clock LIB" + + config RTC_MC146818_LIB + bool +@@ -824,6 +824,14 @@ + # requires defining CMOS_READ/CMOS_WRITE, and a + # global rtc_lock ... it's not yet just another platform_device. + ++config RTC_DRV_GOKE ++ tristate "Goke RTC support" ++ help ++ Generic RTC framework driver for Goke SoCs. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called rtc. ++ + config RTC_DRV_CMOS + tristate "PC-style 'CMOS'" + depends on X86 || ARM || M32R || PPC || MIPS || SPARC64 || MN10300 diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-Makefile.patch new file mode 100644 index 00000000..eba1b215 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/rtc/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/rtc/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -68,6 +68,7 @@ + obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o + obj-$(CONFIG_RTC_DRV_GEMINI) += rtc-gemini.o + obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o ++obj-$(CONFIG_RTC_DRV_GOKE) += rtc-goke.o + obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o + obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o + obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-rtc-goke.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-rtc-goke.c.patch new file mode 100644 index 00000000..e2d786e1 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-rtc-rtc-goke.c.patch @@ -0,0 +1,589 @@ +--- linux-4.9.37/drivers/rtc/rtc-goke.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/rtc/rtc-goke.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,586 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++union u_spi_rw { ++ struct { ++ unsigned int spi_wdata : 8; /* [7:0] */ ++ unsigned int spi_rdata : 8; /* [15:8] */ ++ unsigned int spi_addr : 7; /* [22:16] */ ++ unsigned int spi_rw : 1; /* [23] */ ++ unsigned int spi_start : 1; /* [24] */ ++ unsigned int reserved : 6; /* [30:25] */ ++ unsigned int spi_busy : 1; /* [31] */ ++ } bits; ++ unsigned int u32; ++}; ++ ++#define SPI_CLK_DIV (0x000) ++#define SPI_RW (0x004) ++ ++#define SPI_WRITE (0) ++#define SPI_READ (1) ++ ++/* RTC REG */ ++#define RTC_10MS_COUN 0x00 ++#define RTC_S_COUNT 0x01 ++#define RTC_M_COUNT 0x02 ++#define RTC_H_COUNT 0x03 ++#define RTC_D_COUNT_L 0x04 ++#define RTC_D_COUNT_H 0x05 ++ ++#define RTC_MR_10MS 0x06 ++#define RTC_MR_S 0x07 ++#define RTC_MR_M 0x08 ++#define RTC_MR_H 0x09 ++#define RTC_MR_D_L 0x0A ++#define RTC_MR_D_H 0x0B ++ ++#define RTC_LR_10MS 0x0C ++#define RTC_LR_S 0x0D ++#define RTC_LR_M 0x0E ++#define RTC_LR_H 0x0F ++#define RTC_LR_D_L 0x10 ++#define RTC_LR_D_H 0x11 ++ ++#define RTC_LORD 0x12 ++ ++#define RTC_IMSC 0x13 ++#define RTC_INT_CLR 0x14 ++#define RTC_INT 0x15 ++#define RTC_INT_RAW 0x16 ++ ++#define RTC_CLK 0x17 ++#define RTC_POR_N 0x18 ++#define RTC_SAR_CTRL 0x1A ++#define RTC_CLK_CFG 0x1B ++ ++#define RTC_FREQ_H 0x51 ++#define RTC_FREQ_L 0x52 ++ ++#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) || \ ++ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) ++ ++#define RTC_REG_LOCK1 0x64 ++#define RTC_REG_LOCK2 0x65 ++#define RTC_REG_LOCK3 0x66 ++#define RTC_REG_LOCK4 0x67 ++#endif ++ ++ ++#define FREQ_H_DEFAULT 0x8 ++#define FREQ_L_DEFAULT 0x1B ++ ++#define LV_CTL_DEFAULT 0x20 ++#define CLK_DIV_DEFAULT 0x4 ++#define INT_RST_DEFAULT 0x0 ++#define INT_MSK_DEFAULT 0x4 ++ ++#define AIE_INT_MASK BIT(0) ++#define LV_INT_MASK BIT(1) ++#define REG_LOAD_STAT BIT(0) ++#define REG_LOCK_STAT BIT(1) ++#define REG_LOCK_BYPASS BIT(2) ++ ++#define RTC_RW_RETRY_CNT 5 ++#define SPI_RW_RETRY_CNT 500 ++#define RTC_SLEEP_TIME_MS 20 ++ ++#define DATE_TO_SEC(d, h, m, s) (s + m*60 + h*60*60 + d*24*60*60) ++#define SEC_TO_DAY(s) (s/(60*60*24)) ++ ++struct goke_rtc { ++ struct rtc_device *rtc_dev; ++ void __iomem *regs; ++ int rtc_irq; ++}; ++ ++static int goke_spi_write(void *spi_reg, unsigned char reg, ++ unsigned char val) ++{ ++ union u_spi_rw w_data, r_data; ++ int cnt = SPI_RW_RETRY_CNT; ++ ++ r_data.u32 = 0; ++ w_data.u32 = 0; ++ ++ w_data.bits.spi_wdata = val; ++ w_data.bits.spi_addr = reg; ++ w_data.bits.spi_rw = SPI_WRITE; ++ w_data.bits.spi_start = 0x1; ++ ++ writel(w_data.u32, (spi_reg+SPI_RW)); ++ ++ do ++ r_data.u32 = readl(spi_reg+SPI_RW); ++ while (r_data.bits.spi_busy && (--cnt)); ++ ++ if (r_data.bits.spi_busy) ++ return -EIO; ++ ++ return 0; ++} ++ ++ ++static int goke_spi_rtc_write(void *spi_reg, unsigned char reg, ++ unsigned char val) ++{ ++ return goke_spi_write(spi_reg, reg, val); ++} ++ ++static int goke_spi_read(void *spi_reg, unsigned char reg, ++ unsigned char *val) ++{ ++ union u_spi_rw w_data, r_data; ++ int cnt = SPI_RW_RETRY_CNT; ++ ++ r_data.u32 = 0; ++ w_data.u32 = 0; ++ w_data.bits.spi_addr = reg; ++ w_data.bits.spi_rw = SPI_READ; ++ w_data.bits.spi_start = 0x1; ++ ++ writel(w_data.u32, (spi_reg+SPI_RW)); ++ ++ do ++ r_data.u32 = readl(spi_reg+SPI_RW); ++ while (r_data.bits.spi_busy && (--cnt)); ++ ++ if (r_data.bits.spi_busy) ++ return -EIO; ++ ++ *val = r_data.bits.spi_rdata; ++ ++ return 0; ++} ++ ++static int goke_spi_rtc_read(void *spi_reg, unsigned char reg, ++ unsigned char *val) ++{ ++ return goke_spi_read(spi_reg, reg, val); ++} ++ ++static int goke_rtc_read_time(struct device *dev, struct rtc_time *time) ++{ ++ struct goke_rtc *rtc = dev_get_drvdata(dev); ++ unsigned char dayl = 0, dayh = 0; ++ unsigned char second = 0, minute = 0, hour = 0; ++ unsigned long seconds = 0; ++ unsigned int day = 0; ++ unsigned char raw_value = 0; ++ int cnt = RTC_RW_RETRY_CNT; ++ unsigned int ret = 0; ++ ++ ret = (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_INT_RAW, &raw_value); ++ if (ret) { ++ dev_err(dev, "IO err.\n"); ++ return ret; ++ } ++ ++ if (raw_value & LV_INT_MASK) { ++ //dev_err(dev, "low voltage detected, date/time is not reliable.\n"); ++ (unsigned int)goke_spi_write(rtc->regs, RTC_INT_CLR, 1); ++ //return -EINVAL; ++ } ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); ++ if (raw_value & REG_LOCK_BYPASS) ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LORD, ++ (~(REG_LOCK_BYPASS)) & raw_value); ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); ++ /* lock the time */ ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LORD, ++ (REG_LOCK_STAT) | raw_value); ++ /* wait rtc load flag */ ++ do { ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); ++ msleep(RTC_SLEEP_TIME_MS); ++ } while ((ret || (raw_value & REG_LOCK_STAT)) && (--cnt)); ++ ++ if (!ret && (raw_value & REG_LOCK_STAT)) ++ return -EBUSY; ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_S_COUNT, &second); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_M_COUNT, &minute); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_H_COUNT, &hour); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_D_COUNT_L, &dayl); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_D_COUNT_H, &dayh); ++ ++ if (ret) { ++ dev_err(dev, "IO err.\n"); ++ return ret; ++ } ++ ++ day = (dayl | (dayh << 8)); ++ seconds = DATE_TO_SEC(day, hour, minute, second); ++ ++ rtc_time_to_tm(seconds, time); ++ ++ return rtc_valid_tm(time); ++} ++ ++static int goke_rtc_set_time(struct device *dev, struct rtc_time *time) ++{ ++ struct goke_rtc *rtc = dev_get_drvdata(dev); ++ unsigned int ret = 0; ++ unsigned int days; ++ unsigned long seconds = 0; ++ unsigned int cnt = RTC_RW_RETRY_CNT; ++ unsigned char raw_value = 0; ++ ++ ret = rtc_tm_to_time(time, &seconds); ++ if (ret) ++ return ret; ++ days = SEC_TO_DAY(seconds); ++ ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_10MS, 0); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_S, time->tm_sec); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_M, time->tm_min); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_H, time->tm_hour); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_D_L, (days & 0xFF)); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_D_H, (days >> 8)); ++ ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LORD, ++ (raw_value | REG_LOAD_STAT)); ++ /* wait rtc load flag */ ++ do { ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); ++ msleep(RTC_SLEEP_TIME_MS); ++ } while ((ret || (raw_value & REG_LOAD_STAT)) && (--cnt)); ++ ++ if (!ret && (raw_value & REG_LOAD_STAT)) ++ return -EBUSY; ++ ++ if (ret) ++ dev_err(dev, "IO err.\n"); ++ ++ return ret; ++} ++ ++static int goke_rtc_read_alarm(struct device *dev, ++ struct rtc_wkalrm *alrm) ++{ ++ struct goke_rtc *rtc = dev_get_drvdata(dev); ++ unsigned char dayl = 0, dayh = 0; ++ unsigned char second = 0, minute = 0, hour = 0; ++ unsigned long seconds = 0; ++ unsigned int day = 0; ++ unsigned char int_state = 0; ++ unsigned int ret = 0; ++ ++ memset(alrm, 0, sizeof(struct rtc_wkalrm)); ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_S, &second); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_M, &minute); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_H, &hour); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_D_L, &dayl); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_D_H, &dayh); ++ ++ day = (unsigned int)(dayl | (dayh << 8)); ++ seconds = DATE_TO_SEC(day, hour, minute, second); ++ ++ rtc_time_to_tm(seconds, &alrm->time); ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_IMSC, &int_state); ++ if (ret) { ++ dev_err(dev, "IO err.\n"); ++ return ret; ++ } ++ ++ alrm->enabled = !!(int_state & AIE_INT_MASK); ++ alrm->pending = alrm->enabled; ++ ++ return 0; ++} ++ ++static int goke_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ++{ ++ struct goke_rtc *rtc = dev_get_drvdata(dev); ++ unsigned int days; ++ unsigned long seconds = 0; ++ unsigned char val = 0; ++ unsigned int ret = 0; ++ ++ rtc_tm_to_time(&alrm->time, &seconds); ++ ++ days = SEC_TO_DAY(seconds); ++ ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_10MS, 0); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_S, alrm->time.tm_sec); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_M, alrm->time.tm_min); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_H, alrm->time.tm_hour); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_D_L, (days & 0xFF)); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_D_H, (days >> 8)); ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_IMSC, &val); ++ if (alrm->enabled) ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, ++ val | AIE_INT_MASK); ++ else ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, ++ val & ~AIE_INT_MASK); ++ ++ if (ret) { ++ dev_err(dev, "IO err.\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int goke_rtc_alarm_irq_enable(struct device *dev, ++ unsigned int enabled) ++{ ++ struct goke_rtc *rtc = dev_get_drvdata(dev); ++ unsigned char val = 0; ++ unsigned int ret = 0; ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_IMSC, &val); ++ if (enabled) ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, ++ val | AIE_INT_MASK); ++ else ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, ++ val & ~AIE_INT_MASK); ++ ++ if (ret) { ++ dev_err(dev, "IO err.\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++ ++/* ++ * interrupt function ++ * do nothing. left for future ++ */ ++static irqreturn_t goke_rtc_alm_interrupt(int irq, void *data) ++{ ++ struct goke_rtc *rtc = (struct goke_rtc *)data; ++ unsigned char val = 0; ++ unsigned int ret = 0; ++ ++ ret |= (unsigned int)goke_spi_read(rtc->regs, RTC_INT, &val); ++ ret |= (unsigned int)goke_spi_write(rtc->regs, RTC_INT_CLR, AIE_INT_MASK); ++ ++ if (ret) { ++ dev_err(&rtc->rtc_dev->dev, "IO err.\n"); ++ return ret; ++ } ++ ++ if (val & AIE_INT_MASK) ++ rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); ++ ++ return IRQ_HANDLED; ++} ++ ++#define FREQ_MAX_VAL 3277000 ++#define FREQ_MIN_VAL 3276000 ++ ++static int goke_rtc_ioctl(struct device *dev, ++ unsigned int cmd, unsigned long arg) ++{ ++ struct goke_rtc *rtc = dev_get_drvdata(dev); ++ unsigned int ret = 0; ++ ++ switch (cmd) { ++ case RTC_PLL_SET: { ++ char freq_l, freq_h; ++ struct rtc_pll_info pll_info; ++ ++ if (copy_from_user(&pll_info, (struct rtc_pll_info *)(uintptr_t)arg, ++ sizeof(struct rtc_pll_info))) ++ return -EFAULT; ++ ++ /* freq = 32700 + (freq /3052)*100 */ ++ if (pll_info.pll_value > FREQ_MAX_VAL ++ || pll_info.pll_value < FREQ_MIN_VAL) ++ return -EINVAL; ++ ++ pll_info.pll_value = (pll_info.pll_value - 3270000) ++ * 3052 / 10000; ++ ++ freq_l = (char)((unsigned int)pll_info.pll_value & 0xff); ++ freq_h = (char)(((unsigned int)pll_info.pll_value >> 8) & 0xf); ++ ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_FREQ_H, freq_h); ++ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_FREQ_L, freq_l); ++ ++ if (ret) { ++ dev_err(dev, "IO err.\n"); ++ return ret; ++ } ++ ++ return 0; ++ } ++ case RTC_PLL_GET: { ++ char freq_l, freq_h; ++ struct rtc_pll_info pll_info; ++ ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_FREQ_H, &freq_h); ++ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_FREQ_L, &freq_l); ++ ++ if (ret) { ++ dev_err(dev, "IO err.\n"); ++ return ret; ++ } ++ ++ pll_info.pll_value = (((unsigned char)freq_h & 0xf) << 8) + freq_l; ++ pll_info.pll_value = 3270000 ++ + (pll_info.pll_value * 10000) / 3052; ++ ++ pll_info.pll_max = FREQ_MAX_VAL; ++ pll_info.pll_min = FREQ_MIN_VAL; ++ ++ if (copy_to_user((void __user *)(uintptr_t)arg, ++ &pll_info, sizeof(struct rtc_pll_info))) ++ return -EFAULT; ++ ++ return 0; ++ } ++ default: ++ return -ENOIOCTLCMD; ++ } ++} ++ ++static const struct rtc_class_ops goke_rtc_ops = { ++ .read_time = goke_rtc_read_time, ++ .set_time = goke_rtc_set_time, ++ .read_alarm = goke_rtc_read_alarm, ++ .set_alarm = goke_rtc_set_alarm, ++ .alarm_irq_enable = goke_rtc_alarm_irq_enable, ++ .ioctl = goke_rtc_ioctl, ++}; ++ ++static int goke_rtc_init(struct goke_rtc *rtc) ++{ ++ void *spi_reg = rtc->regs; ++ unsigned int ret = 0; ++ unsigned char val = 0; ++ /* ++ * clk div value = (apb_clk/spi_clk)/2-1, ++ * apb clk = 100MHz, spi_clk = 10MHz,so value= 0x4 ++ */ ++ writel(CLK_DIV_DEFAULT, (spi_reg+SPI_CLK_DIV)); ++ ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_IMSC, INT_MSK_DEFAULT); ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_SAR_CTRL, LV_CTL_DEFAULT); ++ ++#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) || \ ++ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) ++ /* default driver capability */ ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK4, 0x5A); ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK3, 0x5A); ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK2, 0xAB); ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK1, 0xCD); ++#endif ++ ++ /*driver capability */ ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_CLK_CFG, 0x01); ++ ++ /* default FREQ COEF */ ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_FREQ_H, FREQ_H_DEFAULT); ++ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_FREQ_L, FREQ_L_DEFAULT); ++ ++ ret |= (unsigned int)goke_spi_rtc_read(spi_reg, RTC_INT_RAW, &val); ++ if (ret) { ++ dev_err(&rtc->rtc_dev->dev, "IO err.\n"); ++ return ret; ++ } ++ ++ if (val & LV_INT_MASK) { ++ /* dev_err(&rtc->rtc_dev->dev, ++ "low voltage detected, date/time is not reliable.\n"); */ ++ goke_spi_write(rtc->regs, RTC_INT_CLR, 1); ++ } ++ ++ return ret; ++} ++ ++static int goke_rtc_probe(struct platform_device *pdev) ++{ ++ struct resource *mem = NULL; ++ struct goke_rtc *rtc; ++ int ret; ++ ++ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); ++ if (!rtc) ++ return -ENOMEM; ++ ++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ rtc->regs = devm_ioremap_resource(&pdev->dev, mem); ++ if (IS_ERR((const void *)rtc->regs)) { ++ dev_err(&pdev->dev, "could not map I/O memory\n"); ++ return PTR_ERR((const void *)rtc->regs); ++ } ++ ++ rtc->rtc_irq = platform_get_irq(pdev, 0); ++ ret = devm_request_irq(&pdev->dev, rtc->rtc_irq, ++ goke_rtc_alm_interrupt, 0, pdev->name, rtc); ++ if (ret) { ++ dev_err(&pdev->dev, "could not request irq %d\n", rtc->rtc_irq); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, rtc); ++ rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, ++ &goke_rtc_ops, THIS_MODULE); ++ if (IS_ERR(rtc->rtc_dev)) { ++ dev_err(&pdev->dev, "could not register rtc device\n"); ++ return PTR_ERR(rtc->rtc_dev); ++ } ++ ++ if (goke_rtc_init(rtc)) { ++ dev_err(&pdev->dev, "goke_rtc_init failed.\n"); ++ return -EIO; ++ } ++ ++ dev_info(&pdev->dev, "RTC driver for goke enabled\n"); ++ ++ return 0; ++} ++ ++static int goke_rtc_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++static const struct of_device_id goke_rtc_match[] = { ++ { .compatible = "goke,rtc" }, ++ {}, ++}; ++ ++static struct platform_driver goke_rtc_driver = { ++ .probe = goke_rtc_probe, ++ .remove = goke_rtc_remove, ++ .driver = { ++ .name = "goke_rtc", ++ .of_match_table = goke_rtc_match, ++ }, ++}; ++ ++module_platform_driver(goke_rtc_driver); ++ ++ ++MODULE_AUTHOR("Goke"); ++MODULE_DESCRIPTION("Goke RTC driver"); ++MODULE_LICENSE("GPL v2"); ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-scsi-scsi_lib.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-scsi-scsi_lib.c.patch new file mode 100644 index 00000000..1a80b15b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-scsi-scsi_lib.c.patch @@ -0,0 +1,38 @@ +--- linux-4.9.37/drivers/scsi/scsi_lib.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/scsi/scsi_lib.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1420,7 +1420,7 @@ + if (scsi_host_in_recovery(shost)) + return 0; + +- busy = atomic_inc_return(&shost->host_busy) - 1; ++ busy = atomic_read(&shost->host_busy); + if (atomic_read(&shost->host_blocked) > 0) { + if (busy) + goto starved; +@@ -1429,7 +1429,7 @@ + * unblock after host_blocked iterates to zero + */ + if (atomic_dec_return(&shost->host_blocked) > 0) +- goto out_dec; ++ goto out; + + SCSI_LOG_MLQUEUE(3, + shost_printk(KERN_INFO, shost, +@@ -1449,6 +1449,7 @@ + spin_unlock_irq(shost->host_lock); + } + ++ atomic_inc(&shost->host_busy); + return 1; + + starved: +@@ -1456,8 +1457,7 @@ + if (list_empty(&sdev->starved_entry)) + list_add_tail(&sdev->starved_entry, &shost->starved_list); + spin_unlock_irq(shost->host_lock); +-out_dec: +- atomic_dec(&shost->host_busy); ++out: + return 0; + } + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-spi-spi-pl022.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-spi-spi-pl022.c.patch new file mode 100644 index 00000000..46c1fcda --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-spi-spi-pl022.c.patch @@ -0,0 +1,381 @@ +--- linux-4.9.37/drivers/spi/spi-pl022.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/spi/spi-pl022.c 2021-06-07 13:01:34.000000000 +0300 +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + /* + * This macro is used to define some register default values. +@@ -136,6 +137,18 @@ + /* This one is only in the PL023 variant */ + #define SSP_CR1_MASK_FBCLKDEL_ST (0x7UL << 13) + ++#ifdef CONFIG_ARCH_GOKE ++/* ++ * The Goke version of this block adds some bits ++ * in SSP_CR1 ++ */ ++#define SSP_CR1_MASK_BIGEND_GOKE (0x1UL << 4) ++#define SSP_CR1_MASK_ALTASENS_GOKE (0x1UL << 6) ++ ++#define SSP_TX_FIFO_CR(r) (r + 0x28) ++#define SSP_RX_FIFO_CR(r) (r + 0x2C) ++#endif ++ + /* + * SSP Status Register - SSP_SR + */ +@@ -296,6 +309,10 @@ + + #define SPI_POLLING_TIMEOUT 1000 + ++#ifdef CONFIG_ARCH_GOKE ++#define PL022_IDS_INDEX_GOKE 4 ++#endif ++ + /* + * The type of reading going on on this chip + */ +@@ -337,6 +354,15 @@ + bool internal_cs_ctrl; + }; + ++#ifdef CONFIG_ARCH_GOKE ++struct cs_data { ++ struct resource res; ++ void __iomem *virt_addr; ++ unsigned int cs_sb; ++ unsigned int cs_mask_bit; ++}; ++#endif ++ + /** + * struct pl022 - This is the private SSP driver data structure + * @adev: AMBA device model hookup +@@ -346,6 +372,13 @@ + * @clk: outgoing clock "SPICLK" for the SPI bus + * @master: SPI framework hookup + * @master_info: controller-specific data from machine setup ++ * @kworker: thread struct for message pump ++ * @kworker_task: pointer to task for message pump kworker thread ++ * @pump_messages: work struct for scheduling work to the message pump ++ * @queue_lock: spinlock to syncronise access to message queue ++ * @queue: message queue ++ * @busy: message pump is busy ++ * @running: message pump is running + * @pump_transfers: Tasklet used in Interrupt Transfer mode + * @cur_msg: Pointer to current spi_message being processed + * @cur_transfer: Pointer to current spi_transfer +@@ -403,6 +436,9 @@ + #endif + int cur_cs; + int *chipselects; ++#ifdef CONFIG_ARCH_GOKE ++ struct cs_data *cs_data; ++#endif + }; + + /** +@@ -459,13 +495,41 @@ + static void internal_cs_control(struct pl022 *pl022, u32 command) + { + u32 tmp; +- ++#ifdef CONFIG_ARCH_GOKE ++ struct amba_device *adev = pl022->adev; ++ struct amba_driver *adrv = container_of(adev->dev.driver, ++ struct amba_driver, drv); ++ ++ if (pl022->vendor->extended_cr && (adev->periphid == ++ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) { ++ if (pl022->cs_data) { ++ tmp = readl(pl022->cs_data->virt_addr); ++ tmp &= ~(pl022->cs_data->cs_mask_bit); ++ tmp |= ((u32)pl022->cur_cs) << pl022->cs_data->cs_sb; ++ writel(tmp, pl022->cs_data->virt_addr); ++ } ++ ++ if (command == SSP_CHIP_SELECT) ++ /* Enable SSP */ ++ writew((readw(SSP_CR1(pl022->virtbase)) | ++ SSP_CR1_MASK_SSE), ++ SSP_CR1(pl022->virtbase)); ++ else ++ /* disable SSP */ ++ writew((readw(SSP_CR1(pl022->virtbase)) & ++ (~SSP_CR1_MASK_SSE)), ++ SSP_CR1(pl022->virtbase)); ++ } else { ++#endif + tmp = readw(SSP_CSR(pl022->virtbase)); + if (command == SSP_CHIP_SELECT) +- tmp &= ~BIT(pl022->cur_cs); ++ tmp &= ~BIT((u32)pl022->cur_cs); + else +- tmp |= BIT(pl022->cur_cs); ++ tmp |= BIT((u32)pl022->cur_cs); + writew(tmp, SSP_CSR(pl022->virtbase)); ++#ifdef CONFIG_ARCH_GOKE ++ } ++#endif + } + + static void pl022_cs_control(struct pl022 *pl022, u32 command) +@@ -566,8 +630,16 @@ + static void restore_state(struct pl022 *pl022) + { + struct chip_data *chip = pl022->cur_chip; ++#ifdef CONFIG_ARCH_GOKE ++ struct amba_device *adev = pl022->adev; ++ struct amba_driver *adrv = container_of(adev->dev.driver, ++ struct amba_driver, drv); + ++ if (pl022->vendor->extended_cr && (adev->periphid != ++ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) ++#else + if (pl022->vendor->extended_cr) ++#endif + writel(chip->cr0, SSP_CR0(pl022->virtbase)); + else + writew(chip->cr0, SSP_CR0(pl022->virtbase)); +@@ -640,6 +712,15 @@ + GEN_MASK_BITS(SSP_FEEDBACK_CLK_DELAY_NONE, SSP_CR1_MASK_FBCLKDEL_ST, 13) \ + ) + ++#ifdef CONFIG_ARCH_GOKE ++/* Goke versions extend this register to use all 16 bits */ ++#define DEFAULT_SSP_REG_CR1_GOKE ( \ ++ DEFAULT_SSP_REG_CR1 | \ ++ GEN_MASK_BITS(SSP_RX_MSB, SSP_CR1_MASK_BIGEND_GOKE, 4) | \ ++ GEN_MASK_BITS(0x0, SSP_CR1_MASK_ALTASENS_GOKE, 6) \ ++) ++#endif ++ + #define DEFAULT_SSP_REG_CPSR ( \ + GEN_MASK_BITS(SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \ + ) +@@ -659,8 +740,22 @@ + writel(DEFAULT_SSP_REG_CR0_ST_PL023, SSP_CR0(pl022->virtbase)); + writew(DEFAULT_SSP_REG_CR1_ST_PL023, SSP_CR1(pl022->virtbase)); + } else if (pl022->vendor->extended_cr) { ++#ifdef CONFIG_ARCH_GOKE ++ struct amba_device *adev = pl022->adev; ++ struct amba_driver *adrv = container_of(adev->dev.driver, ++ struct amba_driver, drv); ++ ++ if (adev->periphid == adrv->id_table[PL022_IDS_INDEX_GOKE].id) { ++ writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); ++ writew(DEFAULT_SSP_REG_CR1_GOKE, ++ SSP_CR1(pl022->virtbase)); ++ } else { ++#endif + writel(DEFAULT_SSP_REG_CR0_ST, SSP_CR0(pl022->virtbase)); + writew(DEFAULT_SSP_REG_CR1_ST, SSP_CR1(pl022->virtbase)); ++#ifdef CONFIG_ARCH_GOKE ++ } ++#endif + } else { + writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); + writew(DEFAULT_SSP_REG_CR1, SSP_CR1(pl022->virtbase)); +@@ -1803,7 +1898,7 @@ + .com_mode = POLLING_TRANSFER, + .iface = SSP_INTERFACE_MOTOROLA_SPI, + .hierarchy = SSP_SLAVE, +- .slave_tx_disable = DO_NOT_DRIVE_TX, ++ .slave_tx_disable = DRIVE_TX, + .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, + .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, + .ctrl_len = SSP_BITS_8, +@@ -1835,6 +1930,13 @@ + unsigned int bits = spi->bits_per_word; + u32 tmp; + struct device_node *np = spi->dev.of_node; ++#ifdef CONFIG_ARCH_GOKE ++ struct amba_device *adev = pl022->adev; ++ struct amba_driver *adrv = container_of(adev->dev.driver, ++ struct amba_driver, drv); ++ writel(0, SSP_TX_FIFO_CR(pl022->virtbase)); ++ writel(0, SSP_RX_FIFO_CR(pl022->virtbase)); ++#endif + + if (!spi->max_speed_hz) + return -EINVAL; +@@ -1856,8 +1958,10 @@ + if (chip_info == NULL) { + if (np) { + chip_info_dt = pl022_default_chip_info; +- +- chip_info_dt.hierarchy = SSP_MASTER; ++ if(pl022->master->slave) ++ chip_info_dt.hierarchy = SSP_SLAVE; ++ else ++ chip_info_dt.hierarchy = SSP_MASTER; + of_property_read_u32(np, "pl022,interface", + &chip_info_dt.iface); + of_property_read_u32(np, "pl022,com-mode", +@@ -1977,7 +2081,12 @@ + chip->cpsr = clk_freq.cpsdvsr; + + /* Special setup for the ST micro extended control registers */ ++#ifdef CONFIG_ARCH_GOKE ++ if (pl022->vendor->extended_cr && (adev->periphid != ++ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) { ++#else + if (pl022->vendor->extended_cr) { ++#endif + u32 etx; + + if (pl022->vendor->pl023) { +@@ -2011,6 +2120,22 @@ + SSP_CR1_MASK_RXIFLSEL_ST, 7); + SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, + SSP_CR1_MASK_TXIFLSEL_ST, 10); ++#ifdef CONFIG_ARCH_GOKE ++ } else if (pl022->vendor->extended_cr && (adev->periphid == ++ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) { ++ SSP_WRITE_BITS(chip->cr0, bits - 1, ++ SSP_CR0_MASK_DSS, 0); ++ SSP_WRITE_BITS(chip->cr0, chip_info->iface, ++ SSP_CR0_MASK_FRF, 4); ++ ++ if (spi->mode & SPI_LSB_FIRST) ++ tmp = !!SPI_LSB_FIRST; ++ else ++ tmp = !SPI_LSB_FIRST; ++ ++ SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_BIGEND_GOKE, 4); ++ SSP_WRITE_BITS(chip->cr1, 0x0, SSP_CR1_MASK_ALTASENS_GOKE, 6); ++#endif + } else { + SSP_WRITE_BITS(chip->cr0, bits - 1, + SSP_CR0_MASK_DSS, 0); +@@ -2099,11 +2224,14 @@ + static int pl022_probe(struct amba_device *adev, const struct amba_id *id) + { + struct device *dev = &adev->dev; ++ struct amba_driver *adrv = container_of(adev->dev.driver, ++ struct amba_driver, drv); + struct pl022_ssp_controller *platform_info = + dev_get_platdata(&adev->dev); + struct spi_master *master; + struct pl022 *pl022 = NULL; /*Data for this driver */ + struct device_node *np = adev->dev.of_node; ++ unsigned int slave_mode; + int status = 0, i, num_cs; + + dev_info(&adev->dev, +@@ -2156,12 +2284,62 @@ + master->rt = platform_info->rt; + master->dev.of_node = dev->of_node; + ++ if (of_property_read_u32(np, "pl022,slave_mode", ++ &slave_mode) == 0) { ++ if (slave_mode == 1){ ++ master->slave = true; ++ } else if (slave_mode == 0) { ++ master->slave = false; ++ } else { ++ dev_err(&adev->dev, "spi Master/Slave mode err!!!\n"); ++ goto err_no_gpio; ++ } ++ ++ } ++ + if (platform_info->num_chipselect && platform_info->chipselects) { + for (i = 0; i < num_cs; i++) + pl022->chipselects[i] = platform_info->chipselects[i]; + } else if (pl022->vendor->internal_cs_ctrl) { + for (i = 0; i < num_cs; i++) + pl022->chipselects[i] = i; ++ ++#ifdef CONFIG_ARCH_GOKE ++ if ((adev->periphid == adrv->id_table[PL022_IDS_INDEX_GOKE].id) ++ && pl022->vendor->extended_cr ++ && (num_cs > 1)) { ++ pl022->cs_data = devm_kzalloc(dev, ++ sizeof(struct cs_data), ++ GFP_KERNEL); ++ if (!pl022->cs_data) { ++ status = -ENOMEM; ++ goto err_no_mem; ++ } ++ ++ if (of_address_to_resource(np, 1, ++ &pl022->cs_data->res)) { ++ status = -EPROBE_DEFER; ++ goto err_no_gpio; ++ } ++ ++ if (of_property_read_u32(np, "spi_cs_sb", ++ &pl022->cs_data->cs_sb)) { ++ status = -EPROBE_DEFER; ++ goto err_no_gpio; ++ } ++ ++ if (of_property_read_u32(np, "spi_cs_mask_bit", ++ &pl022->cs_data->cs_mask_bit)) { ++ status = -EPROBE_DEFER; ++ goto err_no_gpio; ++ } ++ ++ pl022->cs_data->virt_addr = devm_ioremap(dev, ++ pl022->cs_data->res.start, ++ resource_size(&adev->res)); ++ } else ++ pl022->cs_data = NULL; ++#endif + } else if (IS_ENABLED(CONFIG_OF)) { + for (i = 0; i < num_cs; i++) { + int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); +@@ -2288,6 +2466,11 @@ + err_no_ioremap: + amba_release_regions(adev); + err_no_ioregion: ++#ifdef CONFIG_ARCH_GOKE ++ if (pl022->cs_data) ++ release_mem_region(pl022->cs_data->res.start, ++ resource_size(&pl022->cs_data->res)); ++#endif + err_no_gpio: + err_no_mem: + spi_master_put(master); +@@ -2314,6 +2497,11 @@ + + clk_disable_unprepare(pl022->clk); + amba_release_regions(adev); ++#ifdef CONFIG_ARCH_GOKE ++ if (pl022->cs_data) ++ release_mem_region(pl022->cs_data->res.start, ++ resource_size(&pl022->cs_data->res)); ++#endif + tasklet_disable(&pl022->pump_transfers); + return 0; + } +@@ -2390,13 +2578,13 @@ + }; + + static struct vendor_data vendor_arm = { +- .fifodepth = 8, ++ .fifodepth = 256, + .max_bpw = 16, + .unidir = false, +- .extended_cr = false, ++ .extended_cr = true, + .pl023 = false, + .loopback = true, +- .internal_cs_ctrl = false, ++ .internal_cs_ctrl = true, + }; + + static struct vendor_data vendor_st = { +@@ -2433,7 +2621,7 @@ + { + /* + * ARM PL022 variant, this has a 16bit wide +- * and 8 locations deep TX/RX FIFO ++ * and 256 locations deep TX/RX FIFO + */ + .id = 0x00041022, + .mask = 0x000fffff, diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-spi-spi.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-spi-spi.c.patch new file mode 100644 index 00000000..28bfb9bf --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-spi-spi.c.patch @@ -0,0 +1,128 @@ +--- linux-4.9.37/drivers/spi/spi.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/spi/spi.c 2021-06-07 13:01:34.000000000 +0300 +@@ -323,11 +323,125 @@ + return 0; + } + ++#ifdef CONFIG_PM_SLEEP ++static int spi_legacy_suspend(struct device *dev, pm_message_t message) ++{ ++ int value = 0; ++ struct spi_driver *drv = to_spi_driver(dev->driver); ++ ++ /* suspend will stop irqs and dma; no more i/o */ ++ if (drv) { ++ if (drv->suspend) ++ value = drv->suspend(to_spi_device(dev), message); ++ else ++ dev_dbg(dev, "... can't suspend\n"); ++ } ++ return value; ++} ++ ++static int spi_legacy_resume(struct device *dev) ++{ ++ int value = 0; ++ struct spi_driver *drv = to_spi_driver(dev->driver); ++ ++ /* resume may restart the i/o queue */ ++ if (drv) { ++ if (drv->resume) ++ value = drv->resume(to_spi_device(dev)); ++ else ++ dev_dbg(dev, "... can't resume\n"); ++ } ++ return value; ++} ++ ++static int spi_pm_suspend(struct device *dev) ++{ ++ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ ++ if (pm) ++ return pm_generic_suspend(dev); ++ else ++ return spi_legacy_suspend(dev, PMSG_SUSPEND); ++} ++ ++static int spi_pm_resume(struct device *dev) ++{ ++ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ ++ if (pm) ++ return pm_generic_resume(dev); ++ else ++ return spi_legacy_resume(dev); ++} ++ ++static int spi_pm_freeze(struct device *dev) ++{ ++ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ ++ if (pm) ++ return pm_generic_freeze(dev); ++ else ++ return spi_legacy_suspend(dev, PMSG_FREEZE); ++} ++ ++static int spi_pm_thaw(struct device *dev) ++{ ++ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ ++ if (pm) ++ return pm_generic_thaw(dev); ++ else ++ return spi_legacy_resume(dev); ++} ++ ++static int spi_pm_poweroff(struct device *dev) ++{ ++ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ ++ if (pm) ++ return pm_generic_poweroff(dev); ++ else ++ return spi_legacy_suspend(dev, PMSG_HIBERNATE); ++} ++ ++static int spi_pm_restore(struct device *dev) ++{ ++ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; ++ ++ if (pm) ++ return pm_generic_restore(dev); ++ else ++ return spi_legacy_resume(dev); ++} ++#else ++#define spi_pm_suspend NULL ++#define spi_pm_resume NULL ++#define spi_pm_freeze NULL ++#define spi_pm_thaw NULL ++#define spi_pm_poweroff NULL ++#define spi_pm_restore NULL ++#endif ++ ++static const struct dev_pm_ops spi_pm = { ++ .suspend = spi_pm_suspend, ++ .resume = spi_pm_resume, ++ .freeze = spi_pm_freeze, ++ .thaw = spi_pm_thaw, ++ .poweroff = spi_pm_poweroff, ++ .restore = spi_pm_restore, ++ SET_RUNTIME_PM_OPS( ++ pm_generic_runtime_suspend, ++ pm_generic_runtime_resume, ++ NULL ++ ) ++}; ++ + struct bus_type spi_bus_type = { + .name = "spi", + .dev_groups = spi_dev_groups, + .match = spi_match_device, + .uevent = spi_uevent, ++ .pm = &spi_pm, + }; + EXPORT_SYMBOL_GPL(spi_bus_type); + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-tty-serial-amba-pl011.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-tty-serial-amba-pl011.c.patch new file mode 100644 index 00000000..bb9c8b08 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-tty-serial-amba-pl011.c.patch @@ -0,0 +1,47 @@ +--- linux-4.9.37/drivers/tty/serial/amba-pl011.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/tty/serial/amba-pl011.c 2021-06-07 13:01:34.000000000 +0300 +@@ -109,12 +109,20 @@ + + static unsigned int get_fifosize_arm(struct amba_device *dev) + { ++#ifdef CONFIG_ARCH_GOKE ++ return 64; ++#else + return amba_rev(dev) < 3 ? 16 : 32; ++#endif + } + + static struct vendor_data vendor_arm = { + .reg_offset = pl011_std_offsets, ++#ifdef CONFIG_ARCH_GOKE ++ .ifls = UART011_IFLS_RX1_8|UART011_IFLS_TX1_8, ++#else + .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, ++#endif + .fr_busy = UART01x_FR_BUSY, + .fr_dsr = UART01x_FR_DSR, + .fr_cts = UART01x_FR_CTS, +@@ -405,7 +413,11 @@ + pl011_reg_to_offset(uap, REG_DR), + .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, + .direction = DMA_MEM_TO_DEV, ++#ifdef CONFIG_ARCH_GOKE ++ .dst_maxburst = 7, ++#else + .dst_maxburst = uap->fifosize >> 1, ++#endif + .device_fc = false, + }; + struct dma_chan *chan; +@@ -461,7 +473,11 @@ + pl011_reg_to_offset(uap, REG_DR), + .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, + .direction = DMA_DEV_TO_MEM, ++#ifdef CONFIG_ARCH_GOKE ++ .src_maxburst = 7, ++#else + .src_maxburst = uap->fifosize >> 2, ++#endif + .device_fc = false, + }; + struct dma_slave_caps caps; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-tty-vt-selection.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-tty-vt-selection.c.patch new file mode 100644 index 00000000..28ea27db --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-tty-vt-selection.c.patch @@ -0,0 +1,100 @@ +--- linux-4.9.37/drivers/tty/vt/selection.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/tty/vt/selection.c 2021-06-07 13:01:34.000000000 +0300 +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -40,6 +41,7 @@ + static int sel_end; + static int sel_buffer_lth; + static char *sel_buffer; ++static DEFINE_MUTEX(sel_lock); + + /* clear_selection, highlight and highlight_pointer can be called + from interrupt (via scrollback/front) */ +@@ -163,7 +165,7 @@ + char *bp, *obp; + int i, ps, pe, multiplier; + u16 c; +- int mode; ++ int mode, ret = 0; + + poke_blanked_console(); + +@@ -203,6 +205,7 @@ + pe = tmp; + } + ++ mutex_lock(&sel_lock); + if (sel_cons != vc_cons[fg_console].d) { + clear_selection(); + sel_cons = vc_cons[fg_console].d; +@@ -248,9 +251,10 @@ + break; + case TIOCL_SELPOINTER: + highlight_pointer(pe); +- return 0; ++ goto unlock; + default: +- return -EINVAL; ++ ret = -EINVAL; ++ goto unlock; + } + + /* remove the pointer */ +@@ -272,7 +276,7 @@ + else if (new_sel_start == sel_start) + { + if (new_sel_end == sel_end) /* no action required */ +- return 0; ++ goto unlock; + else if (new_sel_end > sel_end) /* extend to right */ + highlight(sel_end + 2, new_sel_end); + else /* contract from right */ +@@ -299,7 +303,8 @@ + if (!bp) { + printk(KERN_WARNING "selection: kmalloc() failed\n"); + clear_selection(); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto unlock; + } + kfree(sel_buffer); + sel_buffer = bp; +@@ -324,7 +329,9 @@ + } + } + sel_buffer_lth = bp - sel_buffer; +- return 0; ++unlock: ++ mutex_unlock(&sel_lock); ++ return ret; + } + + /* Insert the contents of the selection buffer into the +@@ -352,10 +359,13 @@ + tty_buffer_lock_exclusive(&vc->port); + + add_wait_queue(&vc->paste_wait, &wait); ++ mutex_lock(&sel_lock); + while (sel_buffer && sel_buffer_lth > pasted) { + set_current_state(TASK_INTERRUPTIBLE); + if (tty_throttled(tty)) { ++ mutex_unlock(&sel_lock); + schedule(); ++ mutex_lock(&sel_lock); + continue; + } + __set_current_state(TASK_RUNNING); +@@ -364,6 +374,7 @@ + count); + pasted += count; + } ++ mutex_unlock(&sel_lock); + remove_wait_queue(&vc->paste_wait, &wait); + __set_current_state(TASK_RUNNING); + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-Makefile.patch new file mode 100644 index 00000000..783aca1e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-Makefile.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/drivers/usb/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -7,7 +7,7 @@ + obj-$(CONFIG_USB) += core/ + obj-$(CONFIG_USB_SUPPORT) += phy/ + +-obj-$(CONFIG_USB_DWC3) += dwc3/ ++obj-$(CONFIG_ARCH_GOKE) += dwc3/ + obj-$(CONFIG_USB_DWC2) += dwc2/ + obj-$(CONFIG_USB_ISP1760) += isp1760/ + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-devices.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-devices.c.patch new file mode 100644 index 00000000..6642b00d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-devices.c.patch @@ -0,0 +1,19 @@ +--- linux-4.9.37/drivers/usb/core/devices.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/core/devices.c 2021-06-07 13:01:34.000000000 +0300 +@@ -182,14 +182,8 @@ + + dir = usb_endpoint_dir_in(desc) ? 'I' : 'O'; + +- if (speed == USB_SPEED_HIGH) { +- switch (usb_endpoint_maxp(desc) & (0x03 << 11)) { +- case 1 << 11: +- bandwidth = 2; break; +- case 2 << 11: +- bandwidth = 3; break; +- } +- } ++ if (speed == USB_SPEED_HIGH) ++ bandwidth = usb_endpoint_maxp_mult(desc); + + /* this isn't checking for illegal values */ + switch (usb_endpoint_type(desc)) { diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-hub.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-hub.c.patch new file mode 100644 index 00000000..04878229 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-hub.c.patch @@ -0,0 +1,13 @@ +--- linux-4.9.37/drivers/usb/core/hub.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/core/hub.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1345,6 +1345,10 @@ + ret = -ENODEV; + goto fail; + } else if (hub->descriptor->bNbrPorts == 0) { ++ if (!hdev->parent) { ++ dev_info(hub_dev, "hub can't support USB3.0\n"); ++ return -ENODEV; ++ } + message = "hub doesn't have any ports!"; + ret = -ENODEV; + goto fail; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-urb.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-urb.c.patch new file mode 100644 index 00000000..6cbce28e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-core-urb.c.patch @@ -0,0 +1,16 @@ +--- linux-4.9.37/drivers/usb/core/urb.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/core/urb.c 2021-06-07 13:01:34.000000000 +0300 +@@ -407,11 +407,8 @@ + } + + /* "high bandwidth" mode, 1-3 packets/uframe? */ +- if (dev->speed == USB_SPEED_HIGH) { +- int mult = 1 + ((max >> 11) & 0x03); +- max &= 0x07ff; +- max *= mult; +- } ++ if (dev->speed == USB_SPEED_HIGH) ++ max *= usb_endpoint_maxp_mult(&ep->desc); + + if (urb->number_of_packets <= 0) + return -EINVAL; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-Makefile.patch new file mode 100644 index 00000000..1dd0b194 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-Makefile.patch @@ -0,0 +1,17 @@ +--- linux-4.9.37/drivers/usb/dwc3/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -1,9 +1,12 @@ + # define_trace.h needs to know how to find our header + CFLAGS_trace.o := -I$(src) + +-obj-$(CONFIG_USB_DWC3) += dwc3.o ++obj-$(CONFIG_USB_DWC3) += dwc3.o dwc3-goke.o + +-dwc3-y := core.o debug.o trace.o ++dwc3-y := core.o proc.o ++ifneq ($(CONFIG_TRACING),) ++dwc3-y += trace.o ++endif + + ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),) + dwc3-y += host.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-core.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-core.c.patch new file mode 100644 index 00000000..0ee9c5b0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-core.c.patch @@ -0,0 +1,138 @@ +--- linux-4.9.37/drivers/usb/dwc3/core.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/core.c 2021-06-07 13:01:34.000000000 +0300 +@@ -44,11 +44,27 @@ + #include "core.h" + #include "gadget.h" + #include "io.h" ++#include "dwc3-goke.h" + + #include "debug.h" + + #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ + ++ ++/* ++ * Default to the number of outstanding pipelined transfer ++ * requests is 0x3[11:8], modify the field change to 0x7. ++ */ ++static void dwc3_outstanding_pipe_choose(struct dwc3 *dwc) ++{ ++ u32 reg; ++ ++ reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1); ++ reg &= ~DWC3_PIPE_TRANS_LIMIT_MASK; ++ reg |= DWC3_PIPE_TRANS_LIMIT; ++ dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg); ++} ++ + /** + * dwc3_get_dr_mode - Validates and sets dr_mode + * @dwc: pointer to our context structure +@@ -305,13 +321,7 @@ + struct dwc3_event_buffer *evt; + + evt = dwc->ev_buf; +- dwc3_trace(trace_dwc3_core, +- "Event buf %p dma %08llx length %d\n", +- evt->buf, (unsigned long long) evt->dma, +- evt->length); +- + evt->lpos = 0; +- + dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), + lower_32_bits(evt->dma)); + dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), +@@ -428,9 +438,6 @@ + + dwc->num_in_eps = DWC3_NUM_IN_EPS(parms); + dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps; +- +- dwc3_trace(trace_dwc3_core, "found %d IN and %d OUT endpoints", +- dwc->num_in_eps, dwc->num_out_eps); + } + + static void dwc3_cache_hwparams(struct dwc3 *dwc) +@@ -683,13 +690,13 @@ + reg |= DWC3_GCTL_GBLHIBERNATIONEN; + break; + default: +- dwc3_trace(trace_dwc3_core, "No power optimization available\n"); ++ /* nothing */ ++ break; + } + + /* check if current dwc3 is on simulation board */ + if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { +- dwc3_trace(trace_dwc3_core, +- "running on FPGA platform\n"); ++ dev_info(dwc->dev, "Running with FPGA optmizations\n"); + dwc->is_fpga = true; + } + +@@ -982,7 +989,8 @@ + */ + hird_threshold = 12; + +- dwc->maximum_speed = usb_get_maximum_speed(dev); ++ dwc->maximum_speed = usb_get_max_speed(dev); ++ + dwc->dr_mode = usb_get_dr_mode(dev); + dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); + +@@ -996,6 +1004,8 @@ + &hird_threshold); + dwc->usb3_lpm_capable = device_property_read_bool(dev, + "snps,usb3_lpm_capable"); ++ dwc->usb2_lpm_disable = device_property_read_bool(dev, ++ "snps,usb2-lpm-disable"); + + dwc->disable_scramble_quirk = device_property_read_bool(dev, + "snps,disable_scramble_quirk"); +@@ -1026,6 +1036,16 @@ + dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev, + "snps,dis-del-phy-power-chg-quirk"); + ++ dwc->dis_initiate_u1 = device_property_read_bool(dev, ++ "snps,dis_initiate_u1"); ++ dwc->dis_initiate_u2 = device_property_read_bool(dev, ++ "snps,dis_initiate_u2"); ++ ++ dwc->eps_new_init = device_property_read_bool(dev, ++ "snps,eps_new_init"); ++ device_property_read_u32(dev, "eps_directions", ++ &dwc->eps_directions); ++ + dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, + "snps,tx_de_emphasis_quirk"); + device_property_read_u8(dev, "snps,tx_de_emphasis", +@@ -1044,6 +1064,10 @@ + platform_set_drvdata(pdev, dwc); + dwc3_cache_hwparams(dwc); + ++ device_property_read_u32_array(dev, "eps_map", ++ dwc->dwceps_map_to_usbeps, ++ DWC3_NUM_EPS(&dwc->hwparams)); ++ + ret = dwc3_core_get_phy(dwc); + if (ret) + goto err0; +@@ -1087,6 +1111,8 @@ + goto err4; + } + ++ dwc3_outstanding_pipe_choose(dwc); ++ + /* Check the maximum_speed parameter */ + switch (dwc->maximum_speed) { + case USB_SPEED_LOW: +@@ -1177,6 +1203,10 @@ + dwc3_free_event_buffers(dwc); + dwc3_free_scratch_buffers(dwc); + ++ bsp_dwc3_exited(); ++ ++ dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); ++ + return 0; + } + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-core.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-core.h.patch new file mode 100644 index 00000000..dacc13cc --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-core.h.patch @@ -0,0 +1,131 @@ +--- linux-4.9.37/drivers/usb/dwc3/core.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/core.h 2021-06-07 13:01:34.000000000 +0300 +@@ -35,6 +35,8 @@ + #include + + #define DWC3_MSG_MAX 500 ++#define DWC3_PIPE_TRANS_LIMIT_MASK (0xf << 8) ++#define DWC3_PIPE_TRANS_LIMIT (0x7 << 8) + + /* Global constants */ + #define DWC3_ZLP_BUF_SIZE 1024 /* size of a superspeed bulk */ +@@ -386,6 +388,9 @@ + + #define DWC3_DSTS_RXFIFOEMPTY (1 << 17) + ++#define DWC3_EVENT_PRAM_MAX_SOFFN 0x3fff ++#define DWC3_EVENT_PRAM_SOFFN_MASK 0x3fff ++ + #define DWC3_DSTS_SOFFN_MASK (0x3fff << 3) + #define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3) + +@@ -488,7 +493,7 @@ + #define DWC3_EP_DIRECTION_TX true + #define DWC3_EP_DIRECTION_RX false + +-#define DWC3_TRB_NUM 256 ++#define DWC3_TRB_NUM 4096 + + /** + * struct dwc3_ep - device side endpoint representation +@@ -535,7 +540,8 @@ + #define DWC3_EP_WEDGE (1 << 2) + #define DWC3_EP_BUSY (1 << 4) + #define DWC3_EP_PENDING_REQUEST (1 << 5) +-#define DWC3_EP_MISSED_ISOC (1 << 6) ++#define DWC3_EP_MISSED_ISOC (1 << 6) ++#define DWC3_EP_UPDATE (1 << 7) + + /* This last one is specific to EP0 */ + #define DWC3_EP0_DIR_IN (1 << 31) +@@ -549,14 +555,15 @@ + * By using u8 types we ensure that our % operator when incrementing + * enqueue and dequeue get optimized away by the compiler. + */ +- u8 trb_enqueue; +- u8 trb_dequeue; ++ u32 trb_enqueue; ++ u32 trb_dequeue; + + u8 number; + u8 type; + u8 resource_index; + u32 allocated_requests; + u32 queued_requests; ++ u32 frame_number; + u32 interval; + + char name[20]; +@@ -806,6 +813,7 @@ + * @start_config_issued: true when StartConfig command has been issued + * @three_stage_setup: set if we perform a three phase setup + * @usb3_lpm_capable: set if hadrware supports Link Power Management ++ * @usb2_lpm_disable: set to disable usb2 lpm + * @disable_scramble_quirk: set if we enable the disable scramble quirk + * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk + * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk +@@ -854,6 +862,7 @@ + struct dwc3_event_buffer *ev_buf; + struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM]; + ++ u32 dwceps_map_to_usbeps[DWC3_ENDPOINTS_NUM]; + struct usb_gadget gadget; + struct usb_gadget_driver *gadget_driver; + +@@ -929,6 +938,12 @@ + + u8 num_out_eps; + u8 num_in_eps; ++/* ++ * NOTICE: eps_directions bitmap[0~31] 0: out ep, 1: in ep ++ * and used with total ep numbers(num_out_eps + num_in_eps) ++ */ ++#define DWC3_EPS_DEFAULT_DIRECTIONS 0xaaaaaaaa ++ u32 eps_directions; + + void *mem; + +@@ -941,6 +956,13 @@ + u8 lpm_nyet_threshold; + u8 hird_threshold; + ++ struct proc_dir_entry* parent_entry; ++ struct proc_dir_entry* csts_entry; ++ u8 udc_connect_status; ++ #define UDC_DISCONNECTED 0 ++ #define UDC_CONNECT_HOST 1 ++ #define UDC_CONNECT_CHARGER 2 ++ + const char *hsphy_interface; + + unsigned connected:1; +@@ -956,6 +978,7 @@ + unsigned setup_packet_pending:1; + unsigned three_stage_setup:1; + unsigned usb3_lpm_capable:1; ++ unsigned usb2_lpm_disable:1; + + unsigned disable_scramble_quirk:1; + unsigned u2exit_lfps_quirk:1; +@@ -972,6 +995,11 @@ + unsigned dis_u2_freeclk_exists_quirk:1; + unsigned dis_del_phy_power_chg_quirk:1; + ++ unsigned dis_initiate_u1:1; ++ unsigned dis_initiate_u2:1; ++ ++ unsigned eps_new_init:1; ++ + unsigned tx_de_emphasis_quirk:1; + unsigned tx_de_emphasis:2; + }; +@@ -1175,6 +1203,9 @@ + { return 0; } + #endif + ++int dwc3_proc_init(struct dwc3 *dwc); ++int dwc3_proc_shutdown(struct dwc3 *dwc); ++ + /* power management interface */ + #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) + int dwc3_gadget_suspend(struct dwc3 *dwc); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-debug.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-debug.h.patch new file mode 100644 index 00000000..19a97d70 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-debug.h.patch @@ -0,0 +1,468 @@ +--- linux-4.9.37/drivers/usb/dwc3/debug.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/debug.h 2021-06-07 13:01:34.000000000 +0300 +@@ -125,55 +125,344 @@ + } + + /** ++ * dwc3_trb_type_string - returns TRB type as a string ++ * @type: the type of the TRB ++ */ ++static inline const char *dwc3_trb_type_string(unsigned int type) ++{ ++ switch (type) { ++ case DWC3_TRBCTL_NORMAL: ++ return "normal"; ++ case DWC3_TRBCTL_CONTROL_SETUP: ++ return "setup"; ++ case DWC3_TRBCTL_CONTROL_STATUS2: ++ return "status2"; ++ case DWC3_TRBCTL_CONTROL_STATUS3: ++ return "status3"; ++ case DWC3_TRBCTL_CONTROL_DATA: ++ return "data"; ++ case DWC3_TRBCTL_ISOCHRONOUS_FIRST: ++ return "isoc-first"; ++ case DWC3_TRBCTL_ISOCHRONOUS: ++ return "isoc"; ++ case DWC3_TRBCTL_LINK_TRB: ++ return "link"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) ++{ ++ switch (state) { ++ case EP0_UNCONNECTED: ++ return "Unconnected"; ++ case EP0_SETUP_PHASE: ++ return "Setup Phase"; ++ case EP0_DATA_PHASE: ++ return "Data Phase"; ++ case EP0_STATUS_PHASE: ++ return "Status Phase"; ++ default: ++ return "UNKNOWN"; ++ } ++} ++ ++/** + * dwc3_gadget_event_string - returns event name + * @event: the event code + */ +-static inline const char * +-dwc3_gadget_event_string(const struct dwc3_event_devt *event) ++static inline const char *dwc3_gadget_event_string(char *str, size_t size, ++ const struct dwc3_event_devt *event) + { +- static char str[256]; + enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; + + switch (event->type) { + case DWC3_DEVICE_EVENT_DISCONNECT: +- sprintf(str, "Disconnect: [%s]", ++ snprintf(str, size, "Disconnect: [%s]", + dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_RESET: +- sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state)); ++ snprintf(str, size, "Reset [%s]", ++ dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_CONNECT_DONE: +- sprintf(str, "Connection Done [%s]", ++ snprintf(str, size, "Connection Done [%s]", + dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: +- sprintf(str, "Link Change [%s]", ++ snprintf(str, size, "Link Change [%s]", + dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_WAKEUP: +- sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state)); ++ snprintf(str, size, "WakeUp [%s]", ++ dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_EOPF: +- sprintf(str, "End-Of-Frame [%s]", ++ snprintf(str, size, "End-Of-Frame [%s]", + dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_SOF: +- sprintf(str, "Start-Of-Frame [%s]", ++ snprintf(str, size, "Start-Of-Frame [%s]", + dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_ERRATIC_ERROR: +- sprintf(str, "Erratic Error [%s]", ++ snprintf(str, size, "Erratic Error [%s]", + dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_CMD_CMPL: +- sprintf(str, "Command Complete [%s]", ++ snprintf(str, size, "Command Complete [%s]", + dwc3_gadget_link_string(state)); + break; + case DWC3_DEVICE_EVENT_OVERFLOW: +- sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state)); ++ snprintf(str, size, "Overflow [%s]", ++ dwc3_gadget_link_string(state)); + break; + default: +- sprintf(str, "UNKNOWN"); ++ snprintf(str, size, "UNKNOWN"); ++ } ++ ++ return str; ++} ++ ++static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str, ++ size_t size) ++{ ++ switch (t & USB_RECIP_MASK) { ++ case USB_RECIP_DEVICE: ++ snprintf(str, size, "Get Device Status(Length = %d)", l); ++ break; ++ case USB_RECIP_INTERFACE: ++ snprintf(str, size, "Get Interface Status(Intf = %d, Length = %d)", ++ i, l); ++ break; ++ case USB_RECIP_ENDPOINT: ++ snprintf(str, size, "Get Endpoint Status(ep%d%s)", ++ i & ~USB_DIR_IN, ++ i & USB_DIR_IN ? "in" : "out"); ++ break; ++ } ++} ++ ++static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, ++ __u16 i, char *str, size_t size) ++{ ++ switch (t & USB_RECIP_MASK) { ++ case USB_RECIP_DEVICE: ++ snprintf(str, size, "%s Device Feature(%s%s)", ++ b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", ++ ({char *s; ++ switch (v) { ++ case USB_DEVICE_SELF_POWERED: ++ s = "Self Powered"; ++ break; ++ case USB_DEVICE_REMOTE_WAKEUP: ++ s = "Remote Wakeup"; ++ break; ++ case USB_DEVICE_TEST_MODE: ++ s = "Test Mode"; ++ break; ++ default: ++ s = "UNKNOWN"; ++ } s; }), ++ v == USB_DEVICE_TEST_MODE ? ++ ({ char *s; ++ switch (i) { ++ case TEST_J: ++ s = ": TEST_J"; ++ break; ++ case TEST_K: ++ s = ": TEST_K"; ++ break; ++ case TEST_SE0_NAK: ++ s = ": TEST_SE0_NAK"; ++ break; ++ case TEST_PACKET: ++ s = ": TEST_PACKET"; ++ break; ++ case TEST_FORCE_EN: ++ s = ": TEST_FORCE_EN"; ++ break; ++ default: ++ s = ": UNKNOWN"; ++ } s; }) : ""); ++ break; ++ case USB_RECIP_INTERFACE: ++ snprintf(str, size, "%s Interface Feature(%s)", ++ b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", ++ v == USB_INTRF_FUNC_SUSPEND ? ++ "Function Suspend" : "UNKNOWN"); ++ break; ++ case USB_RECIP_ENDPOINT: ++ snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)", ++ b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", ++ v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN", ++ i & ~USB_DIR_IN, ++ i & USB_DIR_IN ? "in" : "out"); ++ break; ++ } ++} ++ ++static inline void dwc3_decode_set_address(__u16 v, char *str, size_t size) ++{ ++ snprintf(str, size, "Set Address(Addr = %02x)", v); ++} ++ ++static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v, ++ __u16 i, __u16 l, char *str, size_t size) ++{ ++ snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)", ++ b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set", ++ ({ char *s; ++ switch (v >> 8) { ++ case USB_DT_DEVICE: ++ s = "Device"; ++ break; ++ case USB_DT_CONFIG: ++ s = "Configuration"; ++ break; ++ case USB_DT_STRING: ++ s = "String"; ++ break; ++ case USB_DT_INTERFACE: ++ s = "Interface"; ++ break; ++ case USB_DT_ENDPOINT: ++ s = "Endpoint"; ++ break; ++ case USB_DT_DEVICE_QUALIFIER: ++ s = "Device Qualifier"; ++ break; ++ case USB_DT_OTHER_SPEED_CONFIG: ++ s = "Other Speed Config"; ++ break; ++ case USB_DT_INTERFACE_POWER: ++ s = "Interface Power"; ++ break; ++ case USB_DT_OTG: ++ s = "OTG"; ++ break; ++ case USB_DT_DEBUG: ++ s = "Debug"; ++ break; ++ case USB_DT_INTERFACE_ASSOCIATION: ++ s = "Interface Association"; ++ break; ++ case USB_DT_BOS: ++ s = "BOS"; ++ break; ++ case USB_DT_DEVICE_CAPABILITY: ++ s = "Device Capability"; ++ break; ++ case USB_DT_PIPE_USAGE: ++ s = "Pipe Usage"; ++ break; ++ case USB_DT_SS_ENDPOINT_COMP: ++ s = "SS Endpoint Companion"; ++ break; ++ case USB_DT_SSP_ISOC_ENDPOINT_COMP: ++ s = "SSP Isochronous Endpoint Companion"; ++ break; ++ default: ++ s = "UNKNOWN"; ++ break; ++ } s; }), v & 0xff, l); ++} ++ ++ ++static inline void dwc3_decode_get_configuration(__u16 l, char *str, ++ size_t size) ++{ ++ snprintf(str, size, "Get Configuration(Length = %d)", l); ++} ++ ++static inline void dwc3_decode_set_configuration(__u8 v, char *str, size_t size) ++{ ++ snprintf(str, size, "Set Configuration(Config = %d)", v); ++} ++ ++static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str, ++ size_t size) ++{ ++ snprintf(str, size, "Get Interface(Intf = %d, Length = %d)", i, l); ++} ++ ++static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str, size_t size) ++{ ++ snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v); ++} ++ ++static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str, ++ size_t size) ++{ ++ snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)", i, l); ++} ++ ++static inline void dwc3_decode_set_sel(__u16 l, char *str, size_t size) ++{ ++ snprintf(str, size, "Set SEL(Length = %d)", l); ++} ++ ++static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str, size_t size) ++{ ++ snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", v); ++} ++ ++/** ++ * dwc3_decode_ctrl - returns a string represetion of ctrl request ++ */ ++static inline const char *dwc3_decode_ctrl(char *str, size_t size, ++ __u8 bRequestType, __u8 bRequest, __u16 wValue, __u16 wIndex, ++ __u16 wLength) ++{ ++ switch (bRequest) { ++ case USB_REQ_GET_STATUS: ++ dwc3_decode_get_status(bRequestType, wIndex, wLength, str, ++ size); ++ break; ++ case USB_REQ_CLEAR_FEATURE: ++ case USB_REQ_SET_FEATURE: ++ dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue, ++ wIndex, str, size); ++ break; ++ case USB_REQ_SET_ADDRESS: ++ dwc3_decode_set_address(wValue, str, size); ++ break; ++ case USB_REQ_GET_DESCRIPTOR: ++ case USB_REQ_SET_DESCRIPTOR: ++ dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue, ++ wIndex, wLength, str, size); ++ break; ++ case USB_REQ_GET_CONFIGURATION: ++ dwc3_decode_get_configuration(wLength, str, size); ++ break; ++ case USB_REQ_SET_CONFIGURATION: ++ dwc3_decode_set_configuration(wValue, str, size); ++ break; ++ case USB_REQ_GET_INTERFACE: ++ dwc3_decode_get_intf(wIndex, wLength, str, size); ++ break; ++ case USB_REQ_SET_INTERFACE: ++ dwc3_decode_set_intf(wValue, wIndex, str, size); ++ break; ++ case USB_REQ_SYNCH_FRAME: ++ dwc3_decode_synch_frame(wIndex, wLength, str, size); ++ break; ++ case USB_REQ_SET_SEL: ++ dwc3_decode_set_sel(wLength, str, size); ++ break; ++ case USB_REQ_SET_ISOCH_DELAY: ++ dwc3_decode_set_isoch_delay(wValue, str, size); ++ break; ++ default: ++ snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x", ++ bRequestType, bRequest, ++ cpu_to_le16(wValue) & 0xff, ++ cpu_to_le16(wValue) >> 8, ++ cpu_to_le16(wIndex) & 0xff, ++ cpu_to_le16(wIndex) >> 8, ++ cpu_to_le16(wLength) & 0xff, ++ cpu_to_le16(wLength) >> 8); + } + + return str; +@@ -183,30 +472,52 @@ + * dwc3_ep_event_string - returns event name + * @event: then event code + */ +-static inline const char * +-dwc3_ep_event_string(const struct dwc3_event_depevt *event) ++static inline const char *dwc3_ep_event_string(char *str, size_t size, ++ const struct dwc3_event_depevt *event, u32 ep0state) + { + u8 epnum = event->endpoint_number; +- static char str[256]; ++ size_t len; + int status; + int ret; + +- ret = sprintf(str, "ep%d%s: ", epnum >> 1, ++ ret = snprintf(str, size, "ep%d%s: ", epnum >> 1, + (epnum & 1) ? "in" : "out"); + if (ret < 0) + return "UNKNOWN"; + ++ status = event->status; ++ + switch (event->endpoint_event) { + case DWC3_DEPEVT_XFERCOMPLETE: +- strcat(str, "Transfer Complete"); ++ len = strlen(str); ++ snprintf(str + len, size - len, "Transfer Complete (%c%c%c)", ++ status & DEPEVT_STATUS_SHORT ? 'S' : 's', ++ status & DEPEVT_STATUS_IOC ? 'I' : 'i', ++ status & DEPEVT_STATUS_LST ? 'L' : 'l'); ++ ++ len = strlen(str); ++ ++ if (epnum <= 1) ++ snprintf(str + len, size - len, " [%s]", ++ dwc3_ep0_state_string(ep0state)); + break; + case DWC3_DEPEVT_XFERINPROGRESS: +- strcat(str, "Transfer In-Progress"); ++ len = strlen(str); ++ ++ snprintf(str + len, size - len, "Transfer In Progress [%d] (%c%c%c)", ++ event->parameters, ++ status & DEPEVT_STATUS_SHORT ? 'S' : 's', ++ status & DEPEVT_STATUS_IOC ? 'I' : 'i', ++ status & DEPEVT_STATUS_LST ? 'M' : 'm'); + break; + case DWC3_DEPEVT_XFERNOTREADY: +- strcat(str, "Transfer Not Ready"); +- status = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; +- strcat(str, status ? " (Active)" : " (Not Active)"); ++ len = strlen(str); ++ ++ snprintf(str + len, size - len, "Transfer Not Ready [%d]%s", ++ event->parameters, ++ status & DEPEVT_STATUS_TRANSFER_ACTIVE ? ++ " (Active)" : " (Not Active)"); ++ + break; + case DWC3_DEPEVT_RXTXFIFOEVT: + strcat(str, "FIFO"); +@@ -216,7 +527,7 @@ + + switch (status) { + case DEPEVT_STREAMEVT_FOUND: +- sprintf(str + ret, " Stream %d Found", ++ snprintf(str + ret, size - ret, " Stream %d Found", + event->parameters); + break; + case DEPEVT_STREAMEVT_NOTFOUND: +@@ -230,7 +541,7 @@ + strcat(str, "Endpoint Command Complete"); + break; + default: +- sprintf(str, "UNKNOWN"); ++ snprintf(str, size, "UNKNOWN"); + } + + return str; +@@ -270,14 +581,15 @@ + } + } + +-static inline const char *dwc3_decode_event(u32 event) ++static inline const char *dwc3_decode_event(char *str, size_t size, u32 event, ++ u32 ep0state) + { + const union dwc3_event evt = (union dwc3_event) event; + + if (evt.type.is_devspec) +- return dwc3_gadget_event_string(&evt.devt); ++ return dwc3_gadget_event_string(str, size, &evt.devt); + else +- return dwc3_ep_event_string(&evt.depevt); ++ return dwc3_ep_event_string(str, size, &evt.depevt, ep0state); + } + + static inline const char *dwc3_ep_cmd_status_string(int status) +@@ -310,7 +622,6 @@ + } + } + +-void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...); + + #ifdef CONFIG_DEBUG_FS + extern void dwc3_debugfs_init(struct dwc3 *); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-debugfs.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-debugfs.c.patch new file mode 100644 index 00000000..b21de3a7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-debugfs.c.patch @@ -0,0 +1,46 @@ +--- linux-4.9.37/drivers/usb/dwc3/debugfs.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/debugfs.c 2021-06-07 13:01:34.000000000 +0300 +@@ -689,30 +689,6 @@ + return 0; + } + +-static inline const char *dwc3_trb_type_string(struct dwc3_trb *trb) +-{ +- switch (DWC3_TRBCTL_TYPE(trb->ctrl)) { +- case DWC3_TRBCTL_NORMAL: +- return "normal"; +- case DWC3_TRBCTL_CONTROL_SETUP: +- return "control-setup"; +- case DWC3_TRBCTL_CONTROL_STATUS2: +- return "control-status2"; +- case DWC3_TRBCTL_CONTROL_STATUS3: +- return "control-status3"; +- case DWC3_TRBCTL_CONTROL_DATA: +- return "control-data"; +- case DWC3_TRBCTL_ISOCHRONOUS_FIRST: +- return "isoc-first"; +- case DWC3_TRBCTL_ISOCHRONOUS: +- return "isoc"; +- case DWC3_TRBCTL_LINK_TRB: +- return "link"; +- default: +- return "UNKNOWN"; +- } +-} +- + static int dwc3_ep_trb_ring_show(struct seq_file *s, void *unused) + { + struct dwc3_ep *dep = s->private; +@@ -733,10 +709,11 @@ + + for (i = 0; i < DWC3_TRB_NUM; i++) { + struct dwc3_trb *trb = &dep->trb_pool[i]; ++ unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl); + + seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d\n", + trb->bph, trb->bpl, trb->size, +- dwc3_trb_type_string(trb), ++ dwc3_trb_type_string(type), + !!(trb->ctrl & DWC3_TRB_CTRL_IOC), + !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI), + !!(trb->ctrl & DWC3_TRB_CTRL_CSP), diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-dwc3-goke.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-dwc3-goke.c.patch new file mode 100644 index 00000000..5ae4b5e8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-dwc3-goke.c.patch @@ -0,0 +1,362 @@ +--- linux-4.9.37/drivers/usb/dwc3/dwc3-goke.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/dwc3-goke.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,359 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dwc3-goke.h" ++ ++#define USB3_CTRL 0x190 ++#define REG_SYS_STAT 0x8c ++#define PCIE_USB3_MODE_MASK (0x3 << 12) ++#define USB3_PCLK_OCC_SEL (0x1 << 30) ++ ++#define PERI_USB3_GTXTHRCFG 0x2310000 ++ ++#define REG_GUSB3PIPECTL0 0xc2c0 ++#define GTXTHRCFG 0xc108 ++ ++#define PCS_SSP_SOFT_RESET (0x1 << 31) ++#define SUSPEND_USB3_SS_PHY (0x1 << 17) ++ ++#define GUSB2PHYCFG_OFFSET 0xc200 ++#define GCTL_OFFSET 0xc110 ++#define GUCTL_OFFSET 0xc12C ++#define GFLADJ_OFFSET 0xc630 ++ ++#define U2_FREECLK_EXISTS (0x1 << 30) ++#define SOFITPSYNC (0x1 << 10) ++#define REFCLKPER_MASK 0xffc00000 ++#define REFCLKPER_VAL 0x29 ++#define set_refclkper(a) (((a) << 22) & REFCLKPER_MASK) ++ ++#define PLS1 (0x1 << 31) ++#define DECR_MASK 0x7f000000 ++#define DECR_VAL 0xa ++#define set_decr(a) (((a) << 24) & DECR_MASK) ++ ++#define LPM_SEL (0x1 << 23) ++#define FLADJ_MASK 0x003fff00 ++#define FLADJ_VAL 0x7f0 ++#define set_fladj(a) (((a) << 8) & FLADJ_MASK) ++ ++#define DOUBLE_PCIE_MODE 0x0 ++#define P0_PCIE_ADD_P1_USB3 (0x1 << 12) ++#define DOUBLE_USB3 (0x2 << 12) ++ ++#define PCIE_X1_MODE (0x0 << 12) ++#define USB3_MODE (0x1 << 12) ++ ++static struct bsp_priv *usb_priv = NULL; ++ ++ ++ ++int usb_get_max_speed(struct device *dev) ++{ ++ unsigned int ret; ++ struct device_node *np = dev->of_node; ++ ++ if (np == NULL) ++ return -EINVAL; ++ ++ usb_priv = kzalloc(sizeof(*usb_priv), GFP_KERNEL); ++ if (usb_priv == NULL) ++ return -ENOMEM; ++ ++ usb_priv->peri_crg = of_iomap(np, DEV_NODE_FLAG1); ++ if (IS_ERR(usb_priv->peri_crg)) { ++ kfree(usb_priv); ++ usb_priv = NULL; ++ return -ENOMEM; ++ } ++ ++ usb_priv->sys_ctrl = of_iomap(np, DEV_NODE_FLAG2); ++ if (IS_ERR(usb_priv->sys_ctrl)) { ++ iounmap(usb_priv->peri_crg); ++ ++ kfree(usb_priv); ++ usb_priv = NULL; ++ return -ENOMEM; ++ } ++ ++ ret = usb_get_maximum_speed(dev); ++ ++ iounmap(usb_priv->sys_ctrl); ++ iounmap(usb_priv->peri_crg); ++ ++ return ret; ++} ++EXPORT_SYMBOL(usb_get_max_speed); ++ ++void bsp_dwc3_exited(void) ++{ ++ kfree(usb_priv); ++ usb_priv = NULL; ++} ++EXPORT_SYMBOL(bsp_dwc3_exited); ++ ++static int set_ctrl_crg_val(struct device_node *np, struct dwc3_host *host) ++{ ++ unsigned int ret; ++ unsigned int reg; ++ ++ if ((np == NULL) || (host == NULL)) ++ return -EINVAL; ++ ++ /* get usb ctrl crg para */ ++ ret = of_property_read_u32(np, "crg_offset", &host->crg_offset); ++ if (ret) ++ return ret; ++ ++ ret = of_property_read_u32(np, "crg_ctrl_def_mask", &host->crg_ctrl_def_mask); ++ if (ret) ++ return ret; ++ ++ ret = of_property_read_u32(np, "crg_ctrl_def_val", &host->crg_ctrl_def_val); ++ if (ret) ++ return ret; ++ ++ /* write usb ctrl crg default value */ ++ reg = readl(host->crg_base + host->crg_offset); ++ reg &= ~host->crg_ctrl_def_mask; ++ reg |= host->crg_ctrl_def_val; ++ writel(reg, host->crg_base + host->crg_offset); ++ ++ return 0; ++} ++ ++static int dwc3_bsp_clk_init(struct dwc3_host *host, int count) ++{ ++ struct device *dev = host->dev; ++ struct device_node *np = dev->of_node; ++ int i, ret; ++ ++ if (!count) ++ return -EINVAL; ++ ++ if (np == NULL) ++ return -EINVAL; ++ ++ host->num_clocks = count; ++ ++ host->clks = devm_kcalloc(dev, host->num_clocks, sizeof(struct clk *), GFP_KERNEL); ++ if (host->clks == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < host->num_clocks; i++) { ++ struct clk *clk; ++ ++ clk = of_clk_get(np, i); ++ if (IS_ERR(clk)) { ++ while (--i >= 0) ++ clk_put(host->clks[i]); ++ ++ ret = PTR_ERR(clk); ++ goto clk_free; ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret < 0) { ++ while (--i >= 0) { ++ clk_disable_unprepare(host->clks[i]); ++ clk_put(host->clks[i]); ++ } ++ clk_put(clk); ++ ++ goto clk_free; ++ } ++ ++ host->clks[i] = clk; ++ } ++ ++ return 0; ++clk_free: ++ devm_kfree(dev, host->clks); ++ host->clks = NULL; ++ ++ return ret; ++} ++ ++static void control_free_clk_config(struct dwc3_host *host) ++{ ++ unsigned int reg; ++ ++ if (host == NULL) ++ return; ++ ++ reg = readl(host->ctrl_base + GUSB2PHYCFG_OFFSET); ++ reg &= ~U2_FREECLK_EXISTS; ++ writel(reg, host->ctrl_base + GUSB2PHYCFG_OFFSET); ++ ++ reg = readl(host->ctrl_base + GCTL_OFFSET); ++ reg &= ~SOFITPSYNC; ++ writel(reg, host->ctrl_base + GCTL_OFFSET); ++ ++ reg = readl(host->ctrl_base + GUCTL_OFFSET); ++ reg &= ~REFCLKPER_MASK; ++ reg |= set_refclkper(REFCLKPER_VAL); ++ writel(reg, host->ctrl_base + GUCTL_OFFSET); ++ ++ reg = readl(host->ctrl_base + GFLADJ_OFFSET); ++ reg &= ~PLS1; ++ writel(reg, host->ctrl_base + GFLADJ_OFFSET); ++ ++ reg = readl(host->ctrl_base + GFLADJ_OFFSET); ++ reg &= ~DECR_MASK; ++ reg |= set_decr(DECR_VAL); ++ writel(reg, host->ctrl_base + GFLADJ_OFFSET); ++ ++ reg = readl(host->ctrl_base + GFLADJ_OFFSET); ++ reg |= LPM_SEL; ++ writel(reg, host->ctrl_base + GFLADJ_OFFSET); ++ ++ reg = readl(host->ctrl_base + GFLADJ_OFFSET); ++ reg &= ~FLADJ_MASK; ++ reg |= set_fladj(FLADJ_VAL); ++ writel(reg, host->ctrl_base + GFLADJ_OFFSET); ++} ++ ++static int dwc3_bsp_iomap(struct device_node *np, struct dwc3_host *host) ++{ ++ if ((np == NULL) || (host == NULL)) ++ return -EINVAL; ++ ++ host->ctrl_base = of_iomap(np, DEV_NODE_FLAG0); ++ if (IS_ERR(host->ctrl_base)) ++ return -ENOMEM; ++ ++ host->crg_base = of_iomap(np, DEV_NODE_FLAG1); ++ if (IS_ERR(host->crg_base)) { ++ iounmap(host->ctrl_base); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static int dwc3_bsp_probe(struct platform_device *pdev) ++{ ++ struct dwc3_host *host = NULL; ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ int ret, i; ++ ++ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); ++ if (host == NULL) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, host); ++ host->dev = dev; ++ ++ ret = dwc3_bsp_iomap(np, host); ++ if (ret) { ++ devm_kfree(dev, host); ++ host = NULL; ++ ++ return -ENOMEM; ++ } ++ ++ host->port_rst = devm_reset_control_get(dev, "vcc_reset"); ++ if (IS_ERR_OR_NULL(host->port_rst)) { ++ ret = PTR_ERR(host->port_rst); ++ goto dwc3_unmap; ++ } ++ ++ ret = set_ctrl_crg_val(np, host); ++ if (ret) ++ goto dwc3_unmap; ++ ++ reset_control_assert(host->port_rst); ++ ++ ret = dwc3_bsp_clk_init(host, of_clk_get_parent_count(np)); ++ if (ret) ++ goto dwc3_unmap; ++ ++ reset_control_deassert(host->port_rst); ++ ++ control_free_clk_config(host); ++ ++ udelay(U_LEVEL2); ++ ++ ret = of_platform_populate(np, NULL, NULL, dev); ++ if (ret) { ++ for (i = 0; i < host->num_clocks; i++) { ++ clk_disable_unprepare(host->clks[i]); ++ clk_put(host->clks[i]); ++ } ++ goto dwc3_unmap; ++ } ++ ++ return 0; ++dwc3_unmap: ++ iounmap(host->ctrl_base); ++ iounmap(host->crg_base); ++ ++ devm_kfree(dev, host); ++ host = NULL; ++ ++ return ret; ++} ++ ++static int dwc3_bsp_remove(struct platform_device *pdev) ++{ ++ struct dwc3_host *host = platform_get_drvdata(pdev); ++ struct device *dev = &pdev->dev; ++ int i; ++ ++ for (i = 0; i < host->num_clocks; i++) { ++ clk_disable_unprepare(host->clks[i]); ++ clk_put(host->clks[i]); ++ } ++ ++ reset_control_assert(host->port_rst); ++ ++ of_platform_depopulate(dev); ++ ++ iounmap(host->ctrl_base); ++ iounmap(host->crg_base); ++ ++ devm_kfree(dev, host); ++ host = NULL; ++ ++ return 0; ++} ++ ++static const struct of_device_id bsp_dwc3_match[] = { ++ { .compatible = "goke,dwusb2" }, ++ { .compatible = "goke,dwusb3" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bsp_dwc3_match); ++ ++static struct platform_driver dwc3_bsp_driver = { ++ .probe = dwc3_bsp_probe, ++ .remove = dwc3_bsp_remove, ++ .driver = { ++ .name = "goke-dwc3", ++ .of_match_table = bsp_dwc3_match, ++ }, ++}; ++module_platform_driver(dwc3_bsp_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("DesignWare USB3 of Goke"); ++MODULE_AUTHOR("Goke Technologies Co., Ltd..>"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-dwc3-goke.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-dwc3-goke.h.patch new file mode 100644 index 00000000..e965533e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-dwc3-goke.h.patch @@ -0,0 +1,39 @@ +--- linux-4.9.37/drivers/usb/dwc3/dwc3-goke.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/dwc3-goke.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef USB_INCLUDE_DWC3_GOKE_H ++#define USB_INCLUDE_DWC3_GOKE_H ++ ++struct bsp_priv { ++ void __iomem *peri_crg; ++ void __iomem *sys_ctrl; ++ void __iomem *misc_ctrl; ++ unsigned int speed_id; ++}; ++ ++struct dwc3_host { ++ struct device *dev; ++ struct clk **clks; ++ int num_clocks; ++ void __iomem *ctrl_base; ++ void __iomem *crg_base; ++ struct reset_control *port_rst; ++ u32 crg_offset; ++ u32 crg_ctrl_def_mask; ++ u32 crg_ctrl_def_val; ++}; ++ ++extern int usb_get_max_speed(struct device *dev); ++extern void bsp_dwc3_exited(void); ++ ++#define DEV_NODE_FLAG0 0 ++#define DEV_NODE_FLAG1 1 ++#define DEV_NODE_FLAG2 2 ++ ++#define U_LEVEL2 200 ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-ep0.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-ep0.c.patch new file mode 100644 index 00000000..69778f86 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-ep0.c.patch @@ -0,0 +1,601 @@ +--- linux-4.9.37/drivers/usb/dwc3/ep0.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/ep0.c 2021-06-07 13:01:34.000000000 +0300 +@@ -39,22 +39,6 @@ + static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, + struct dwc3_ep *dep, struct dwc3_request *req); + +-static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) +-{ +- switch (state) { +- case EP0_UNCONNECTED: +- return "Unconnected"; +- case EP0_SETUP_PHASE: +- return "Setup Phase"; +- case EP0_DATA_PHASE: +- return "Data Phase"; +- case EP0_STATUS_PHASE: +- return "Status Phase"; +- default: +- return "UNKNOWN"; +- } +-} +- + static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum, + dma_addr_t buf_dma, u32 len, u32 type, bool chain) + { +@@ -92,21 +76,16 @@ + int ret; + + dep = dwc->eps[epnum]; +- if (dep->flags & DWC3_EP_BUSY) { +- dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name); ++ if (dep->flags & DWC3_EP_BUSY) + return 0; +- } + + memset(¶ms, 0, sizeof(params)); + params.param0 = upper_32_bits(dwc->ep0_trb_addr); + params.param1 = lower_32_bits(dwc->ep0_trb_addr); + + ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); +- if (ret < 0) { +- dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed", +- dep->name); ++ if (ret < 0) + return ret; +- } + + dep->flags |= DWC3_EP_BUSY; + dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep); +@@ -166,9 +145,6 @@ + + if (dwc->ep0state == EP0_STATUS_PHASE) + __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); +- else +- dwc3_trace(trace_dwc3_ep0, +- "too early for delayed status"); + + return 0; + } +@@ -232,9 +208,8 @@ + + spin_lock_irqsave(&dwc->lock, flags); + if (!dep->endpoint.desc) { +- dwc3_trace(trace_dwc3_ep0, +- "trying to queue request %p to disabled %s", +- request, dep->name); ++ dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", ++ dep->name); + ret = -ESHUTDOWN; + goto out; + } +@@ -245,11 +220,6 @@ + goto out; + } + +- dwc3_trace(trace_dwc3_ep0, +- "queueing request %p to %s length %d state '%s'", +- request, dep->name, request->length, +- dwc3_ep0_state_string(dwc->ep0state)); +- + ret = __dwc3_gadget_ep0_queue(dep, req); + + out: +@@ -317,6 +287,24 @@ + WARN_ON(ret < 0); + } + ++static u32 dwc3_usbep_to_dwc3ep(struct dwc3 *dwc, u32 num) ++{ ++ u32 res = 0; ++ int i = 0; ++ ++ if (!dwc) ++ return 0; ++ ++ for (i = 0; i < dwc->num_in_eps + dwc->num_out_eps; i++) { ++ if (dwc->dwceps_map_to_usbeps[i] == num) { ++ res = i; ++ break; ++ } ++ } ++ ++ return res; ++} ++ + static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) + { + struct dwc3_ep *dep; +@@ -327,6 +315,9 @@ + if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) + epnum |= 1; + ++ if (dwc->eps_new_init) ++ epnum = dwc3_usbep_to_dwc3ep(dwc, epnum); ++ + dep = dwc->eps[epnum]; + if (dep->flags & DWC3_EP_ENABLED) + return dep; +@@ -399,126 +390,203 @@ + return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); + } + +-static int dwc3_ep0_handle_feature(struct dwc3 *dwc, ++static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state, ++ int set) ++{ ++ u32 reg; ++ ++ if (state != USB_STATE_CONFIGURED) ++ return -EINVAL; ++ if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && ++ (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) ++ return -EINVAL; ++ ++ if (dwc->dis_initiate_u1) ++ return -EINVAL; ++ ++ reg = dwc3_readl(dwc->regs, DWC3_DCTL); ++ if (set) ++ reg |= DWC3_DCTL_INITU1ENA; ++ else ++ reg &= ~DWC3_DCTL_INITU1ENA; ++ dwc3_writel(dwc->regs, DWC3_DCTL, reg); ++ ++ return 0; ++} ++ ++static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state, ++ int set) ++{ ++ u32 reg; ++ ++ ++ if (state != USB_STATE_CONFIGURED) ++ return -EINVAL; ++ if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && ++ (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) ++ return -EINVAL; ++ ++ if (dwc->dis_initiate_u2) ++ return -EINVAL; ++ ++ reg = dwc3_readl(dwc->regs, DWC3_DCTL); ++ if (set) ++ reg |= DWC3_DCTL_INITU2ENA; ++ else ++ reg &= ~DWC3_DCTL_INITU2ENA; ++ dwc3_writel(dwc->regs, DWC3_DCTL, reg); ++ ++ return 0; ++} ++ ++static int dwc3_ep0_handle_test(struct dwc3 *dwc, enum usb_device_state state, ++ u32 wIndex, int set) ++{ ++ if ((wIndex & 0xff) != 0) ++ return -EINVAL; ++ if (!set) ++ return -EINVAL; ++ ++ switch (wIndex >> 8) { ++ case TEST_J: ++ case TEST_K: ++ case TEST_SE0_NAK: ++ case TEST_PACKET: ++ case TEST_FORCE_EN: ++ dwc->test_mode_nr = wIndex >> 8; ++ dwc->test_mode = true; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int dwc3_ep0_handle_device(struct dwc3 *dwc, + struct usb_ctrlrequest *ctrl, int set) + { +- struct dwc3_ep *dep; +- u32 recip; ++ enum usb_device_state state; + u32 wValue; + u32 wIndex; +- u32 reg; +- int ret; +- enum usb_device_state state; ++ int ret = 0; + + wValue = le16_to_cpu(ctrl->wValue); + wIndex = le16_to_cpu(ctrl->wIndex); +- recip = ctrl->bRequestType & USB_RECIP_MASK; + state = dwc->gadget.state; + +- switch (recip) { +- case USB_RECIP_DEVICE: ++ switch (wValue) { ++ case USB_DEVICE_REMOTE_WAKEUP: ++ break; ++ /* ++ * 9.4.1 says only only for SS, in AddressState only for ++ * default control pipe ++ */ ++ case USB_DEVICE_U1_ENABLE: ++ ret = dwc3_ep0_handle_u1(dwc, state, set); ++ break; ++ case USB_DEVICE_U2_ENABLE: ++ ret = dwc3_ep0_handle_u2(dwc, state, set); ++ break; ++ case USB_DEVICE_LTM_ENABLE: ++ ret = -EINVAL; ++ break; ++ case USB_DEVICE_TEST_MODE: ++ ret = dwc3_ep0_handle_test(dwc, state, wIndex, set); ++ break; ++ default: ++ ret = -EINVAL; ++ } + +- switch (wValue) { +- case USB_DEVICE_REMOTE_WAKEUP: +- break; +- /* +- * 9.4.1 says only only for SS, in AddressState only for +- * default control pipe +- */ +- case USB_DEVICE_U1_ENABLE: +- if (state != USB_STATE_CONFIGURED) +- return -EINVAL; +- if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && +- (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) +- return -EINVAL; ++ return ret; ++} + +- reg = dwc3_readl(dwc->regs, DWC3_DCTL); +- if (set) +- reg |= DWC3_DCTL_INITU1ENA; +- else +- reg &= ~DWC3_DCTL_INITU1ENA; +- dwc3_writel(dwc->regs, DWC3_DCTL, reg); +- break; ++static int dwc3_ep0_handle_intf(struct dwc3 *dwc, ++ struct usb_ctrlrequest *ctrl, int set) ++{ ++ enum usb_device_state state; ++ u32 wValue; ++ u32 wIndex; ++ int ret = 0; + +- case USB_DEVICE_U2_ENABLE: +- if (state != USB_STATE_CONFIGURED) +- return -EINVAL; +- if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && +- (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) +- return -EINVAL; ++ wValue = le16_to_cpu(ctrl->wValue); ++ wIndex = le16_to_cpu(ctrl->wIndex); ++ state = dwc->gadget.state; + +- reg = dwc3_readl(dwc->regs, DWC3_DCTL); +- if (set) +- reg |= DWC3_DCTL_INITU2ENA; +- else +- reg &= ~DWC3_DCTL_INITU2ENA; +- dwc3_writel(dwc->regs, DWC3_DCTL, reg); +- break; ++ switch (wValue) { ++ case USB_INTRF_FUNC_SUSPEND: ++ if (wIndex & USB_INTRF_FUNC_SUSPEND_LP) ++ /* XXX enable Low power suspend */ ++ ; ++ if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) ++ /* XXX enable remote wakeup */ ++ ; ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static int dwc3_ep0_handle_endpoint(struct dwc3 *dwc, ++ struct usb_ctrlrequest *ctrl, int set) ++{ ++ struct dwc3_ep *dep; ++ enum usb_device_state state; ++ u32 wValue; ++ u32 wIndex; ++ int ret; + +- case USB_DEVICE_LTM_ENABLE: ++ wValue = le16_to_cpu(ctrl->wValue); ++ wIndex = le16_to_cpu(ctrl->wIndex); ++ state = dwc->gadget.state; ++ ++ switch (wValue) { ++ case USB_ENDPOINT_HALT: ++ dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); ++ if (!dep) + return -EINVAL; + +- case USB_DEVICE_TEST_MODE: +- if ((wIndex & 0xff) != 0) +- return -EINVAL; +- if (!set) +- return -EINVAL; +- +- switch (wIndex >> 8) { +- case TEST_J: +- case TEST_K: +- case TEST_SE0_NAK: +- case TEST_PACKET: +- case TEST_FORCE_EN: +- dwc->test_mode_nr = wIndex >> 8; +- dwc->test_mode = true; +- break; +- default: +- return -EINVAL; +- } ++ if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) + break; +- default: ++ ++ ret = __dwc3_gadget_ep_set_halt(dep, set, true); ++ if (ret) + return -EINVAL; +- } + break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int dwc3_ep0_handle_feature(struct dwc3 *dwc, ++ struct usb_ctrlrequest *ctrl, int set) ++{ ++ u32 recip; ++ int ret; ++ enum usb_device_state state; ++ ++ recip = ctrl->bRequestType & USB_RECIP_MASK; ++ state = dwc->gadget.state; + ++ switch (recip) { ++ case USB_RECIP_DEVICE: ++ ret = dwc3_ep0_handle_device(dwc, ctrl, set); ++ break; + case USB_RECIP_INTERFACE: +- switch (wValue) { +- case USB_INTRF_FUNC_SUSPEND: +- if (wIndex & USB_INTRF_FUNC_SUSPEND_LP) +- /* XXX enable Low power suspend */ +- ; +- if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) +- /* XXX enable remote wakeup */ +- ; +- break; +- default: +- return -EINVAL; +- } ++ ret = dwc3_ep0_handle_intf(dwc, ctrl, set); + break; +- + case USB_RECIP_ENDPOINT: +- switch (wValue) { +- case USB_ENDPOINT_HALT: +- dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); +- if (!dep) +- return -EINVAL; +- if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) +- break; +- ret = __dwc3_gadget_ep_set_halt(dep, set, true); +- if (ret) +- return -EINVAL; +- break; +- default: +- return -EINVAL; +- } ++ ret = dwc3_ep0_handle_endpoint(dwc, ctrl, set); + break; +- + default: +- return -EINVAL; ++ ret = -EINVAL; + } + +- return 0; ++ return ret; + } + + static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) +@@ -529,13 +597,12 @@ + + addr = le16_to_cpu(ctrl->wValue); + if (addr > 127) { +- dwc3_trace(trace_dwc3_ep0, "invalid device address %d", addr); ++ dev_err(dwc->dev, "invalid device address %d\n", addr); + return -EINVAL; + } + + if (state == USB_STATE_CONFIGURED) { +- dwc3_trace(trace_dwc3_ep0, +- "trying to set address when configured"); ++ dev_err(dwc->dev, "can't SetAddress() from Configured State\n"); + return -EINVAL; + } + +@@ -595,7 +662,15 @@ + * nothing is pending from application. + */ + reg = dwc3_readl(dwc->regs, DWC3_DCTL); +- reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); ++ if (dwc->dis_initiate_u1) ++ reg &= (~DWC3_DCTL_ACCEPTU1ENA); ++ else ++ reg |= DWC3_DCTL_ACCEPTU1ENA; ++ ++ if (dwc->dis_initiate_u2) ++ reg &= (~DWC3_DCTL_ACCEPTU2ENA); ++ else ++ reg |= DWC3_DCTL_ACCEPTU2ENA; + dwc3_writel(dwc->regs, DWC3_DCTL, reg); + } + break; +@@ -720,35 +795,27 @@ + + switch (ctrl->bRequest) { + case USB_REQ_GET_STATUS: +- dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS"); + ret = dwc3_ep0_handle_status(dwc, ctrl); + break; + case USB_REQ_CLEAR_FEATURE: +- dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE"); + ret = dwc3_ep0_handle_feature(dwc, ctrl, 0); + break; + case USB_REQ_SET_FEATURE: +- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE"); + ret = dwc3_ep0_handle_feature(dwc, ctrl, 1); + break; + case USB_REQ_SET_ADDRESS: +- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS"); + ret = dwc3_ep0_set_address(dwc, ctrl); + break; + case USB_REQ_SET_CONFIGURATION: +- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION"); + ret = dwc3_ep0_set_config(dwc, ctrl); + break; + case USB_REQ_SET_SEL: +- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL"); + ret = dwc3_ep0_set_sel(dwc, ctrl); + break; + case USB_REQ_SET_ISOCH_DELAY: +- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY"); + ret = dwc3_ep0_set_isoch_delay(dwc, ctrl); + break; + default: +- dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver"); + ret = dwc3_ep0_delegate_req(dwc, ctrl); + break; + } +@@ -824,9 +891,6 @@ + status = DWC3_TRB_SIZE_TRBSTS(trb->size); + if (status == DWC3_TRBSTS_SETUP_PENDING) { + dwc->setup_packet_pending = true; +- +- dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); +- + if (r) + dwc3_gadget_giveback(ep0, r, -ECONNRESET); + +@@ -916,7 +980,7 @@ + + ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr); + if (ret < 0) { +- dwc3_trace(trace_dwc3_ep0, "Invalid Test #%d", ++ dev_err(dwc->dev, "invalid test #%d\n", + dwc->test_mode_nr); + dwc3_ep0_stall_and_restart(dwc); + return; +@@ -924,10 +988,8 @@ + } + + status = DWC3_TRB_SIZE_TRBSTS(trb->size); +- if (status == DWC3_TRBSTS_SETUP_PENDING) { ++ if (status == DWC3_TRBSTS_SETUP_PENDING) + dwc->setup_packet_pending = true; +- dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); +- } + + dwc->ep0state = EP0_SETUP_PHASE; + dwc3_ep0_out_start(dwc); +@@ -944,17 +1006,14 @@ + + switch (dwc->ep0state) { + case EP0_SETUP_PHASE: +- dwc3_trace(trace_dwc3_ep0, "Setup Phase"); + dwc3_ep0_inspect_setup(dwc, event); + break; + + case EP0_DATA_PHASE: +- dwc3_trace(trace_dwc3_ep0, "Data Phase"); + dwc3_ep0_complete_data(dwc, event); + break; + + case EP0_STATUS_PHASE: +- dwc3_trace(trace_dwc3_ep0, "Status Phase"); + dwc3_ep0_complete_status(dwc, event); + break; + default: +@@ -981,10 +1040,8 @@ + + ret = usb_gadget_map_request(&dwc->gadget, &req->request, + dep->number); +- if (ret) { +- dwc3_trace(trace_dwc3_ep0, "failed to map request"); ++ if (ret) + return; +- } + + maxpacket = dep->endpoint.maxpacket; + +@@ -1010,10 +1067,8 @@ + } else { + ret = usb_gadget_map_request(&dwc->gadget, &req->request, + dep->number); +- if (ret) { +- dwc3_trace(trace_dwc3_ep0, "failed to map request"); ++ if (ret) + return; +- } + + dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma, + req->request.length, DWC3_TRBCTL_CONTROL_DATA, +@@ -1073,8 +1128,6 @@ + { + switch (event->status) { + case DEPEVT_STATUS_CONTROL_DATA: +- dwc3_trace(trace_dwc3_ep0, "Control Data"); +- + /* + * We already have a DATA transfer in the controller's cache, + * if we receive a XferNotReady(DATA) we will ignore it, unless +@@ -1087,8 +1140,7 @@ + if (dwc->ep0_expect_in != event->endpoint_number) { + struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; + +- dwc3_trace(trace_dwc3_ep0, +- "Wrong direction for Data phase"); ++ dev_err(dwc->dev, "unexpected direction for Data Phase\n"); + dwc3_ep0_end_control_data(dwc, dep); + dwc3_ep0_stall_and_restart(dwc); + return; +@@ -1100,13 +1152,10 @@ + if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) + return; + +- dwc3_trace(trace_dwc3_ep0, "Control Status"); +- + dwc->ep0state = EP0_STATUS_PHASE; + + if (dwc->delayed_status) { + WARN_ON_ONCE(event->endpoint_number != 1); +- dwc3_trace(trace_dwc3_ep0, "Delayed Status"); + return; + } + +@@ -1117,10 +1166,6 @@ + void dwc3_ep0_interrupt(struct dwc3 *dwc, + const struct dwc3_event_depevt *event) + { +- dwc3_trace(trace_dwc3_ep0, "%s: state '%s'", +- dwc3_ep_event_string(event), +- dwc3_ep0_state_string(dwc->ep0state)); +- + switch (event->endpoint_event) { + case DWC3_DEPEVT_XFERCOMPLETE: + dwc3_ep0_xfer_complete(dwc, event); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-gadget.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-gadget.c.patch new file mode 100644 index 00000000..70f15733 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-gadget.c.patch @@ -0,0 +1,976 @@ +--- linux-4.9.37/drivers/usb/dwc3/gadget.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/gadget.c 2021-06-07 13:01:34.000000000 +0300 +@@ -35,6 +35,15 @@ + #include "gadget.h" + #include "io.h" + ++static void dwc3_gadget_sync_connected_status(struct dwc3 *dwc); ++static int __dwc3_gadget_get_frame(struct dwc3 *dwc); ++static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep, ++ const struct dwc3_event_depevt *event); ++static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep); ++ ++#define DWC3_ALIGN_FRAME(d) (((d)->frame_number + (d)->interval) \ ++ & ~((d)->interval - 1)) ++ + /** + * dwc3_gadget_set_test_mode - Enables USB2 Test Modes + * @dwc: pointer to our context structure +@@ -139,9 +148,6 @@ + udelay(5); + } + +- dwc3_trace(trace_dwc3_gadget, +- "link state change request timed out"); +- + return -ETIMEDOUT; + } + +@@ -153,7 +159,7 @@ + * if it is point to the link TRB, wrap around to the beginning. The + * link TRB is always at the last TRB entry. + */ +-static void dwc3_ep_inc_trb(u8 *index) ++static void dwc3_ep_inc_trb(u32 *index) + { + (*index)++; + if (*index == (DWC3_TRB_NUM - 1)) +@@ -247,7 +253,7 @@ + struct dwc3_gadget_ep_cmd_params *params) + { + struct dwc3 *dwc = dep->dwc; +- u32 timeout = 500; ++ u32 timeout = 5000; + u32 reg; + + int cmd_status = 0; +@@ -563,8 +569,6 @@ + u32 reg; + int ret; + +- dwc3_trace(trace_dwc3_gadget, "Enabling %s", dep->name); +- + if (!(dep->flags & DWC3_EP_ENABLED)) { + ret = dwc3_gadget_start_config(dwc, dep); + if (ret) +@@ -590,7 +594,7 @@ + dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); + + if (usb_endpoint_xfer_control(desc)) +- return 0; ++ goto out; + + /* Initialize the TRB ring */ + dep->trb_dequeue = 0; +@@ -608,15 +612,19 @@ + trb_link->ctrl |= DWC3_TRB_CTRL_HWO; + } + ++ ++out: ++ trace_dwc3_gadget_ep_enable(dep); ++ + return 0; + } + +-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force); ++static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force); + static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) + { + struct dwc3_request *req; + +- dwc3_stop_active_transfer(dwc, dep->number, true); ++ dwc3_stop_active_transfer(dep, true); + + /* - giveback all requests to gadget driver */ + while (!list_empty(&dep->started_list)) { +@@ -645,7 +653,7 @@ + struct dwc3 *dwc = dep->dwc; + u32 reg; + +- dwc3_trace(trace_dwc3_gadget, "Disabling %s", dep->name); ++ trace_dwc3_gadget_ep_disable(dep); + + dwc3_remove_requests(dwc, dep); + +@@ -787,10 +795,7 @@ + struct dwc3 *dwc = dep->dwc; + struct usb_gadget *gadget = &dwc->gadget; + enum usb_device_speed speed = gadget->speed; +- +- dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s", +- dep->name, req, (unsigned long long) dma, +- length, chain ? " chain" : ""); ++ unsigned int chain_skip = 0; + + trb = &dep->trb_pool[dep->trb_enqueue]; + +@@ -816,12 +821,55 @@ + case USB_ENDPOINT_XFER_ISOC: + if (!node) { + trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; +- ++ /* ++ * USB Specification 2.0 Section 5.9.2 states that: "If ++ * there is only a single transaction in the microframe, ++ * only a DATA0 data packet PID is used. If there are ++ * two transactions per microframe, DATA1 is used for ++ * the first transaction data packet and DATA0 is used ++ * for the second transaction data packet. If there are ++ * three transactions per microframe, DATA2 is used for ++ * the first transaction data packet, DATA1 is used for ++ * the second, and DATA0 is used for the third." ++ * ++ * IOW, we should satisfy the following cases: ++ * ++ * 1) length <= maxpacket ++ * - DATA0 ++ * ++ * 2) maxpacket < length <= (2 * maxpacket) ++ * - DATA1, DATA0 ++ * ++ * 3) (2 * maxpacket) < length <= (3 * maxpacket) ++ * - DATA2, DATA1, DATA0 ++ */ + if (speed == USB_SPEED_HIGH) { + struct usb_ep *ep = &dep->endpoint; +- trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1); ++ //unsigned int mult = ep->mult - 1; ++ unsigned int mult = 2; //backport commit ec5bb87e4e2a1d3a35563a7bcfac9febf67aba9d ++ unsigned int maxp = usb_endpoint_maxp(ep->desc); ++ ++ if (length <= (2 * maxp)) ++ mult--; ++ ++ if (length <= maxp) ++ mult--; ++ ++ trb->size |= DWC3_TRB_SIZE_PCM1(mult); ++ ++ /* ++ * If there are three transactions per mframe, ++ * and each transcation length = 1024B, no any ++ * chain trb needed, so skip it. ++ */ ++ if (length == (3 * maxp)) ++ chain_skip = 1; + } ++ ++ if (speed == USB_SPEED_SUPER) ++ chain_skip = 1; + } else { ++ chain_skip = 1; + trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; + } + +@@ -848,7 +896,7 @@ + (dwc3_calc_trbs_left(dep) == 0)) + trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI; + +- if (chain) ++ if ((!chain_skip) && chain) + trb->ctrl |= DWC3_TRB_CTRL_CHN; + + if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable) +@@ -868,9 +916,9 @@ + * index is 0, we will wrap backwards, skip the link TRB, and return + * the one just before that. + */ +-static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) ++static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u32 index) + { +- u8 tmp = index; ++ u32 tmp = index; + + if (!tmp) + tmp = DWC3_TRB_NUM - 1; +@@ -881,7 +929,7 @@ + static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) + { + struct dwc3_trb *tmp; +- u8 trbs_left; ++ u32 trbs_left; + + /* + * If enqueue & dequeue are equal than it is either full or empty. +@@ -910,11 +958,13 @@ + static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, + struct dwc3_request *req) + { ++ struct dwc3 *dwc = dep->dwc; ++ struct usb_gadget *gadget = &dwc->gadget; ++ enum usb_device_speed speed = gadget->speed; + struct scatterlist *sg = req->sg; + struct scatterlist *s; +- unsigned int length; ++ unsigned int length, i; + dma_addr_t dma; +- int i; + + for_each_sg(sg, s, req->num_pending_sgs, i) { + unsigned chain = true; +@@ -925,8 +975,11 @@ + if (sg_is_last(s)) + chain = false; + +- dwc3_prepare_one_trb(dep, req, dma, length, +- chain, i); ++ if ((speed == USB_SPEED_HIGH) && ++ usb_endpoint_xfer_isoc(dep->endpoint.desc)) ++ dwc3_prepare_one_trb(dep, req, dma, length, chain, 0); ++ else ++ dwc3_prepare_one_trb(dep, req, dma, length, chain, i); + + if (!dwc3_calc_trbs_left(dep)) + break; +@@ -994,11 +1047,22 @@ + + memset(¶ms, 0, sizeof(params)); + +- if (starting) { ++ if (starting && !(dep->flags&DWC3_EP_UPDATE)) { + params.param0 = upper_32_bits(req->trb_dma); + params.param1 = lower_32_bits(req->trb_dma); +- cmd = DWC3_DEPCMD_STARTTRANSFER | +- DWC3_DEPCMD_PARAM(cmd_param); ++ ++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { ++ while (__dwc3_gadget_target_frame_elapsed(dep)) ++ dep->frame_number = DWC3_ALIGN_FRAME(dep); ++ ++ dep->frame_number = DWC3_ALIGN_FRAME(dep); ++ cmd_param = dep->frame_number; ++ } ++ ++ cmd = DWC3_DEPCMD_STARTTRANSFER | DWC3_DEPCMD_PARAM(cmd_param); ++ ++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) ++ dep->flags |= DWC3_EP_UPDATE; + } else { + cmd = DWC3_DEPCMD_UPDATETRANSFER | + DWC3_DEPCMD_PARAM(dep->resource_index); +@@ -1027,34 +1091,36 @@ + return 0; + } + +-static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, +- struct dwc3_ep *dep, u32 cur_uf) +-{ +- u32 uf; ++static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep) { ++ u16 cframe = __dwc3_gadget_get_frame(dep->dwc); ++ u16 eframe = dep->frame_number & DWC3_EVENT_PRAM_SOFFN_MASK; ++ ++ if (eframe == cframe) ++ return true; ++ ++ return (((eframe - cframe) & DWC3_EVENT_PRAM_SOFFN_MASK) ++ > DWC3_EVENT_PRAM_MAX_SOFFN / 2); ++} + ++static void __dwc3_gadget_start_isoc(struct dwc3_ep *dep) ++{ + if (list_empty(&dep->pending_list)) { +- dwc3_trace(trace_dwc3_gadget, +- "ISOC ep %s run out for requests", +- dep->name); + dep->flags |= DWC3_EP_PENDING_REQUEST; + return; + } + +- /* 4 micro frames in the future */ +- uf = cur_uf + dep->interval * 4; ++ while (__dwc3_gadget_target_frame_elapsed(dep)) ++ dep->frame_number = DWC3_ALIGN_FRAME(dep); + +- __dwc3_gadget_kick_transfer(dep, uf); ++ dep->frame_number = DWC3_ALIGN_FRAME(dep); ++ __dwc3_gadget_kick_transfer(dep, dep->frame_number); + } + +-static void dwc3_gadget_start_isoc(struct dwc3 *dwc, +- struct dwc3_ep *dep, const struct dwc3_event_depevt *event) ++static void dwc3_gadget_start_isoc(struct dwc3_ep *dep, ++ const struct dwc3_event_depevt *event) + { +- u32 cur_uf, mask; +- +- mask = ~(dep->interval - 1); +- cur_uf = event->parameters & mask; +- +- __dwc3_gadget_start_isoc(dwc, dep, cur_uf); ++ dwc3_gadget_endpoint_frame_from_event(dep, event); ++ __dwc3_gadget_start_isoc(dep); + } + + static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) +@@ -1063,16 +1129,15 @@ + int ret; + + if (!dep->endpoint.desc) { +- dwc3_trace(trace_dwc3_gadget, +- "trying to queue request %p to disabled %s", +- &req->request, dep->endpoint.name); ++ dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", ++ dep->name); + return -ESHUTDOWN; + } + + if (WARN(req->dep != dep, "request %pK belongs to '%s'\n", + &req->request, req->dep->name)) { +- dwc3_trace(trace_dwc3_gadget, "request %pK belongs to '%s'", +- &req->request, req->dep->name); ++ dev_err(dwc->dev, "%s: request %p belongs to '%s'\n", ++ dep->name, &req->request, req->dep->name); + return -EINVAL; + } + +@@ -1106,7 +1171,7 @@ + if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { + if ((dep->flags & DWC3_EP_PENDING_REQUEST) && + list_empty(&dep->started_list)) { +- dwc3_stop_active_transfer(dwc, dep->number, true); ++ dwc3_stop_active_transfer(dep, true); + dep->flags = DWC3_EP_ENABLED; + } + return 0; +@@ -1116,10 +1181,6 @@ + return 0; + + ret = __dwc3_gadget_kick_transfer(dep, 0); +- if (ret && ret != -EBUSY) +- dwc3_trace(trace_dwc3_gadget, +- "%s: failed to kick transfers", +- dep->name); + if (ret == -EBUSY) + ret = 0; + +@@ -1138,7 +1199,6 @@ + struct usb_request *request; + struct usb_ep *ep = &dep->endpoint; + +- dwc3_trace(trace_dwc3_gadget, "queueing ZLP"); + request = dwc3_gadget_ep_alloc_request(ep, GFP_ATOMIC); + if (!request) + return -ENOMEM; +@@ -1197,6 +1257,10 @@ + + spin_lock_irqsave(&dwc->lock, flags); + ++ ++ if (list_empty(&dep->pending_list) && list_empty(&dep->started_list) ) ++ goto out0 ; ++ + list_for_each_entry(r, &dep->pending_list, list) { + if (r == req) + break; +@@ -1209,7 +1273,7 @@ + } + if (r == req) { + /* wait until it is processed */ +- dwc3_stop_active_transfer(dwc, dep->number, true); ++ dwc3_stop_active_transfer(dep, true); + goto out1; + } + dev_err(dwc->dev, "request %pK was not queued to %s\n", +@@ -1247,9 +1311,6 @@ + unsigned transfer_in_flight; + unsigned started; + +- if (dep->flags & DWC3_EP_STALL) +- return 0; +- + if (dep->number > 1) + trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue); + else +@@ -1260,9 +1321,6 @@ + + if (!protocol && ((dep->direction && transfer_in_flight) || + (!dep->direction && started))) { +- dwc3_trace(trace_dwc3_gadget, +- "%s: pending request, cannot halt", +- dep->name); + return -EAGAIN; + } + +@@ -1274,8 +1332,6 @@ + else + dep->flags |= DWC3_EP_STALL; + } else { +- if (!(dep->flags & DWC3_EP_STALL)) +- return 0; + + ret = dwc3_send_clear_stall_ep_cmd(dep); + if (ret) +@@ -1355,15 +1411,21 @@ + + /* -------------------------------------------------------------------------- */ + +-static int dwc3_gadget_get_frame(struct usb_gadget *g) ++static int __dwc3_gadget_get_frame(struct dwc3 *dwc) + { +- struct dwc3 *dwc = gadget_to_dwc(g); + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_DSTS); + return DWC3_DSTS_SOFFN(reg); + } + ++static int dwc3_gadget_get_frame(struct usb_gadget *g) ++{ ++ struct dwc3 *dwc = gadget_to_dwc(g); ++ ++ return __dwc3_gadget_get_frame(dwc); ++} ++ + static int __dwc3_gadget_wakeup(struct dwc3 *dwc) + { + int retries; +@@ -1384,10 +1446,8 @@ + + speed = reg & DWC3_DSTS_CONNECTSPD; + if ((speed == DWC3_DSTS_SUPERSPEED) || +- (speed == DWC3_DSTS_SUPERSPEED_PLUS)) { +- dwc3_trace(trace_dwc3_gadget, "no wakeup on SuperSpeed"); ++ (speed == DWC3_DSTS_SUPERSPEED_PLUS)) + return 0; +- } + + link_state = DWC3_DSTS_USBLNKST(reg); + +@@ -1396,9 +1456,6 @@ + case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ + break; + default: +- dwc3_trace(trace_dwc3_gadget, +- "can't wakeup from '%s'", +- dwc3_gadget_link_string(link_state)); + return -EINVAL; + } + +@@ -1503,11 +1560,6 @@ + if (!timeout) + return -ETIMEDOUT; + +- dwc3_trace(trace_dwc3_gadget, "gadget %s data soft-%s", +- dwc->gadget_driver +- ? dwc->gadget_driver->function : "no-function", +- is_on ? "connect" : "disconnect"); +- + return 0; + } + +@@ -1677,6 +1729,7 @@ + + /* begin to receive SETUP packets */ + dwc->ep0state = EP0_SETUP_PHASE; ++ dwc->link_state = DWC3_LINK_STATE_SS_DIS; + dwc3_ep0_out_start(dwc); + + dwc3_gadget_enable_irq(dwc); +@@ -1767,6 +1820,81 @@ + .udc_stop = dwc3_gadget_stop, + }; + ++static int dwc3_gadget_init_hw_all_endpoints(struct dwc3 *dwc) ++{ ++ struct dwc3_ep *dep; ++ struct dwc3_hwparams *parms = &dwc->hwparams; ++ u32 direction = dwc->eps_directions; ++ u8 num_eps = DWC3_NUM_EPS(parms); ++ u8 num_in_eps = 0; ++ u8 num_out_eps = 0; ++ u8 epnum = 0; ++ u8 i; ++ ++ if (!direction) ++ direction = DWC3_EPS_DEFAULT_DIRECTIONS; ++ ++ for (i = 0; i < num_eps; i++) { ++ if (direction & 0x1) ++ epnum = (num_in_eps++ << 1) + 1; ++ else ++ epnum = (num_out_eps++ << 1); ++ ++ dep = kzalloc(sizeof(*dep), GFP_KERNEL); ++ if (!dep) ++ return -ENOMEM; ++ ++ dep->dwc = dwc; ++ dep->number = epnum; ++ dep->direction = !!(direction & 0x1); ++ dep->regs = dwc->regs + DWC3_DEP_BASE(i); ++ dwc->eps[i] = dep; ++ ++ snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, ++ (epnum & 1) ? "in" : "out"); ++ ++ dep->endpoint.name = dep->name; ++ spin_lock_init(&dep->lock); ++ ++ if (epnum == 0 || epnum == 1) { ++ usb_ep_set_maxpacket_limit(&dep->endpoint, 512); ++ dep->endpoint.maxburst = 1; ++ dep->endpoint.ops = &dwc3_gadget_ep0_ops; ++ if (!epnum) ++ dwc->gadget.ep0 = &dep->endpoint; ++ } else { ++ int ret; ++ ++ usb_ep_set_maxpacket_limit(&dep->endpoint, 1024); ++ dep->endpoint.max_streams = 15; ++ dep->endpoint.ops = &dwc3_gadget_ep_ops; ++ list_add_tail(&dep->endpoint.ep_list, ++ &dwc->gadget.ep_list); ++ ++ ret = dwc3_alloc_trb_pool(dep); ++ if (ret) ++ return ret; ++ } ++ ++ if (epnum == 0 || epnum == 1) { ++ dep->endpoint.caps.type_control = true; ++ } else { ++ dep->endpoint.caps.type_iso = true; ++ dep->endpoint.caps.type_bulk = true; ++ dep->endpoint.caps.type_int = true; ++ } ++ ++ dep->endpoint.caps.dir_in = !!(direction & 0x1); ++ dep->endpoint.caps.dir_out = !(direction & 0x1); ++ direction = (direction >> 1); ++ ++ INIT_LIST_HEAD(&dep->pending_list); ++ INIT_LIST_HEAD(&dep->started_list); ++ } ++ ++ return 0; ++} ++ + /* -------------------------------------------------------------------------- */ + + static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, +@@ -1794,8 +1922,6 @@ + dep->endpoint.name = dep->name; + spin_lock_init(&dep->lock); + +- dwc3_trace(trace_dwc3_gadget, "initializing %s", dep->name); +- + if (epnum == 0 || epnum == 1) { + usb_ep_set_maxpacket_limit(&dep->endpoint, 512); + dep->endpoint.maxburst = 1; +@@ -1840,17 +1966,24 @@ + + INIT_LIST_HEAD(&dwc->gadget.ep_list); + ++ if (dwc->eps_new_init) { ++ ret = dwc3_gadget_init_hw_all_endpoints(dwc); ++ if (ret < 0) { ++ dev_err(dwc->dev, "failed to initialize OUT endpoints\n"); ++ return ret; ++ } ++ return 0; ++ } ++ + ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0); + if (ret < 0) { +- dwc3_trace(trace_dwc3_gadget, +- "failed to allocate OUT endpoints"); ++ dev_err(dwc->dev, "failed to initialize OUT endpoints\n"); + return ret; + } + + ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1); + if (ret < 0) { +- dwc3_trace(trace_dwc3_gadget, +- "failed to allocate IN endpoints"); ++ dev_err(dwc->dev, "failed to initialize IN endpoints\n"); + return ret; + } + +@@ -1886,14 +2019,12 @@ + + /* -------------------------------------------------------------------------- */ + +-static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, +- struct dwc3_request *req, struct dwc3_trb *trb, +- const struct dwc3_event_depevt *event, int status, +- int chain) ++static int __dwc3_cleanup_done_trbs(struct dwc3_ep *dep, struct dwc3_request *req, ++ struct dwc3_trb *trb, const struct dwc3_event_depevt *event, ++ int status, int chain) + { + unsigned int count; + unsigned int s_pkt = 0; +- unsigned int trb_status; + + dwc3_ep_inc_deq(dep); + +@@ -1922,37 +2053,6 @@ + req->request.actual += count; + + if (dep->direction) { +- if (count) { +- trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); +- if (trb_status == DWC3_TRBSTS_MISSED_ISOC) { +- dwc3_trace(trace_dwc3_gadget, +- "%s: incomplete IN transfer", +- dep->name); +- /* +- * If missed isoc occurred and there is +- * no request queued then issue END +- * TRANSFER, so that core generates +- * next xfernotready and we will issue +- * a fresh START TRANSFER. +- * If there are still queued request +- * then wait, do not issue either END +- * or UPDATE TRANSFER, just attach next +- * request in pending_list during +- * giveback.If any future queued request +- * is successfully transferred then we +- * will issue UPDATE TRANSFER for all +- * request in the pending_list. +- */ +- dep->flags |= DWC3_EP_MISSED_ISOC; +- } else { +- dev_err(dwc->dev, "incomplete IN transfer %s\n", +- dep->name); +- status = -ECONNRESET; +- } +- } else { +- dep->flags &= ~DWC3_EP_MISSED_ISOC; +- } +- } else { + if (count && (event->status & DEPEVT_STATUS_SHORT)) + s_pkt = 1; + } +@@ -1967,7 +2067,7 @@ + return 0; + } + +-static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, ++static int dwc3_cleanup_done_reqs(struct dwc3_ep *dep, + const struct dwc3_event_depevt *event, int status) + { + struct dwc3_request *req, *n; +@@ -1994,14 +2094,14 @@ + req->sg = sg_next(s); + req->num_pending_sgs--; + +- ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, ++ ret = __dwc3_cleanup_done_trbs(dep, req, trb, + event, status, chain); + if (ret) + break; + } + } else { + trb = &dep->trb_pool[dep->trb_dequeue]; +- ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, ++ ret = __dwc3_cleanup_done_trbs(dep, req, trb, + event, status, chain); + } + +@@ -2045,9 +2145,9 @@ + * flag, so that END TRANSFER is issued when an + * entry is added into request list. + */ +- dep->flags = DWC3_EP_PENDING_REQUEST; ++ dep->flags |= DWC3_EP_PENDING_REQUEST; + } else { +- dwc3_stop_active_transfer(dwc, dep->number, true); ++ dwc3_stop_active_transfer(dep, true); + dep->flags = DWC3_EP_ENABLED; + } + return 1; +@@ -2059,19 +2159,28 @@ + return 1; + } + +-static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, +- struct dwc3_ep *dep, const struct dwc3_event_depevt *event) ++static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep, ++ const struct dwc3_event_depevt *event) ++{ ++ dep->frame_number = event->parameters; ++} ++ ++static void dwc3_endpoint_transfer_complete(struct dwc3_ep *dep, ++ const struct dwc3_event_depevt *event) + { ++ struct dwc3 *dwc = dep->dwc; + unsigned status = 0; + int clean_busy; + u32 is_xfer_complete; + ++ dwc3_gadget_endpoint_frame_from_event(dep, event); ++ + is_xfer_complete = (event->endpoint_event == DWC3_DEPEVT_XFERCOMPLETE); + + if (event->status & DEPEVT_STATUS_BUSERR) + status = -ECONNRESET; + +- clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status); ++ clean_busy = dwc3_cleanup_done_reqs(dep, event, status); + if (clean_busy && (!dep->endpoint.desc || is_xfer_complete || + usb_endpoint_xfer_isoc(dep->endpoint.desc))) + dep->flags &= ~DWC3_EP_BUSY; +@@ -2109,12 +2218,16 @@ + if (!dep->endpoint.desc) + return; + +- if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { ++ if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) || (dep->flags&DWC3_EP_ENABLED)) { + int ret; +- +- ret = __dwc3_gadget_kick_transfer(dep, 0); +- if (!ret || ret == -EBUSY) +- return; ++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && ++ (!(dep->flags & (DWC3_EP_BUSY | DWC3_EP_UPDATE)))) { ++ __dwc3_gadget_start_isoc(dep); ++ } else { ++ ret = __dwc3_gadget_kick_transfer(dep, 0); ++ if (!ret || ret == -EBUSY) ++ return; ++ } + } + } + +@@ -2139,37 +2252,24 @@ + dep->resource_index = 0; + + if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { +- dwc3_trace(trace_dwc3_gadget, +- "%s is an Isochronous endpoint", +- dep->name); ++ dev_err(dwc->dev, "XferComplete for Isochronous endpoint\n"); + return; + } + +- dwc3_endpoint_transfer_complete(dwc, dep, event); ++ dwc3_endpoint_transfer_complete(dep, event); + break; + case DWC3_DEPEVT_XFERINPROGRESS: +- dwc3_endpoint_transfer_complete(dwc, dep, event); ++ dwc3_endpoint_transfer_complete(dep, event); + break; + case DWC3_DEPEVT_XFERNOTREADY: + if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { +- dwc3_gadget_start_isoc(dwc, dep, event); ++ dwc3_gadget_start_isoc(dep, event); + } else { +- int active; + int ret; + +- active = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; +- +- dwc3_trace(trace_dwc3_gadget, "%s: reason %s", +- dep->name, active ? "Transfer Active" +- : "Transfer Not Active"); +- + ret = __dwc3_gadget_kick_transfer(dep, 0); + if (!ret || ret == -EBUSY) + return; +- +- dwc3_trace(trace_dwc3_gadget, +- "%s: failed to kick transfers", +- dep->name); + } + + break; +@@ -2179,26 +2279,9 @@ + dep->name); + return; + } +- +- switch (event->status) { +- case DEPEVT_STREAMEVT_FOUND: +- dwc3_trace(trace_dwc3_gadget, +- "Stream %d found and started", +- event->parameters); +- +- break; +- case DEPEVT_STREAMEVT_NOTFOUND: +- /* FALLTHROUGH */ +- default: +- dwc3_trace(trace_dwc3_gadget, +- "unable to find suitable stream"); +- } + break; + case DWC3_DEPEVT_RXTXFIFOEVT: +- dwc3_trace(trace_dwc3_gadget, "%s FIFO Overrun", dep->name); +- break; + case DWC3_DEPEVT_EPCMDCMPLT: +- dwc3_trace(trace_dwc3_gadget, "Endpoint Command Complete"); + break; + } + } +@@ -2242,15 +2325,13 @@ + } + } + +-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force) ++static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force) + { +- struct dwc3_ep *dep; ++ struct dwc3 *dwc = dep->dwc; + struct dwc3_gadget_ep_cmd_params params; + u32 cmd; + int ret; + +- dep = dwc->eps[epnum]; +- + if (!dep->resource_index) + return; + +@@ -2596,8 +2677,6 @@ + (pwropt != DWC3_GHWPARAMS1_EN_PWROPT_HIB)) { + if ((dwc->link_state == DWC3_LINK_STATE_U3) && + (next == DWC3_LINK_STATE_RESUME)) { +- dwc3_trace(trace_dwc3_gadget, +- "ignoring transition U3 -> Resume"); + return; + } + } +@@ -2731,11 +2810,7 @@ + break; + case DWC3_DEVICE_EVENT_EOPF: + /* It changed to be suspend event for version 2.30a and above */ +- if (dwc->revision < DWC3_REVISION_230A) { +- dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame"); +- } else { +- dwc3_trace(trace_dwc3_gadget, "U3/L1-L2 Suspend Event"); +- ++ if (dwc->revision >= DWC3_REVISION_230A) { + /* + * Ignore suspend event until the gadget enters into + * USB_STATE_CONFIGURED state. +@@ -2746,26 +2821,21 @@ + } + break; + case DWC3_DEVICE_EVENT_SOF: +- dwc3_trace(trace_dwc3_gadget, "Start of Periodic Frame"); +- break; + case DWC3_DEVICE_EVENT_ERRATIC_ERROR: +- dwc3_trace(trace_dwc3_gadget, "Erratic Error"); +- break; + case DWC3_DEVICE_EVENT_CMD_CMPL: +- dwc3_trace(trace_dwc3_gadget, "Command Complete"); +- break; + case DWC3_DEVICE_EVENT_OVERFLOW: +- dwc3_trace(trace_dwc3_gadget, "Overflow"); + break; ++ + default: + dev_WARN(dwc->dev, "UNKNOWN IRQ %d\n", event->type); + } ++ dwc3_gadget_sync_connected_status(dwc); + } + + static void dwc3_process_event_entry(struct dwc3 *dwc, + const union dwc3_event *event) + { +- trace_dwc3_event(event->raw); ++ trace_dwc3_event(event->raw, dwc); + + /* Endpoint IRQ, handle it and return early */ + if (event->type.is_devspec == 0) { +@@ -2984,8 +3054,7 @@ + * composite.c that we are USB 2.0 + LPM ECN. + */ + if (dwc->revision < DWC3_REVISION_220A) +- dwc3_trace(trace_dwc3_gadget, +- "Changing max_speed on rev %08x", ++ dev_info(dwc->dev, "changing max_speed on rev %08x\n", + dwc->revision); + + dwc->gadget.max_speed = dwc->maximum_speed; +@@ -3005,6 +3074,8 @@ + if (ret) + goto err5; + ++ dwc3_proc_init(dwc); ++ + ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); + if (ret) { + dev_err(dwc->dev, "failed to register udc\n"); +@@ -3042,6 +3113,8 @@ + { + usb_del_gadget_udc(&dwc->gadget); + ++ dwc3_proc_shutdown(dwc); ++ + dwc3_gadget_free_endpoints(dwc); + + dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE, +@@ -3106,3 +3179,70 @@ + enable_irq(dwc->irq_gadget); + } + } ++ ++/* ++ * dwc3_gadget_sync_connected_status() function just for ++ * user space get udc connected status. and this function ++ * just report three status: Disconnected, Connected host, ++ * Connected charger. ++ * ++ * After some tests, report connected udc connected status by ++ * DSTS register, [21:18]USB Link Status and [2:0] Connect Speed. ++ * ++ * How to identify whitch status is the UDC connected? ++ * 1. Host connected: ++ * Host would reset udc, so dwc3 core get reset event interrupt, ++ * dwc3_gadget_reset_interrupt() set dwc->connected = true, ++ * so check connected host by dwc->connected == true ++ * ++ * 2. Disconnected: ++ * When vbus detect 5V lose, dwc3 core generated a disconnect event intr. ++ * dwc3_gadget_disconnect_interrupt() set dwc->connected = false. ++ * so check disconnected by dwc->connected == false ++ * ++ * 3. Charger connected: (Fixedme) ++ * As dwc3 core size, DP keep pullup register when connected to charger. ++ * no any port reset action created, so dwc3 would entry FullSpeed mode. ++ * so chect connected charger by FullSpeed && dwc->connectd == false ++ * ++ */ ++static void dwc3_gadget_sync_connected_status(struct dwc3 *dwc) ++{ ++ u32 reg; ++ u8 speed; ++ u8 state; ++ static int prev = UDC_DISCONNECTED; ++ ++ reg = dwc3_readl(dwc->regs, DWC3_DSTS); ++ speed = reg & DWC3_DSTS_CONNECTSPD; ++ state = DWC3_DSTS_USBLNKST(reg); ++ ++ /* ++ * step1 check is connected host? ++ */ ++ if (dwc->connected == true) { ++ if (prev != UDC_CONNECT_HOST) ++ dwc->udc_connect_status = UDC_CONNECT_HOST; ++ goto out; ++ } ++ ++ /* ++ * step2 disconectd status && fullspeed mode, ++ * as connected charger. ++ */ ++ if ((speed == DWC3_DSTS_FULLSPEED) && (state != DWC3_LINK_STATE_SS_DIS)) { ++ if (prev != UDC_CONNECT_CHARGER) ++ dwc->udc_connect_status = UDC_CONNECT_CHARGER; ++ goto out; ++ } ++ ++ /* ++ * step3 not host and charger connected, so just ++ * disconnectd. ++ */ ++ if (prev != UDC_DISCONNECTED) ++ dwc->udc_connect_status = UDC_DISCONNECTED; ++ ++out: ++ prev = dwc->udc_connect_status; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-host.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-host.c.patch new file mode 100644 index 00000000..5aab5060 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-host.c.patch @@ -0,0 +1,21 @@ +--- linux-4.9.37/drivers/usb/dwc3/host.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/host.c 2021-06-07 13:01:34.000000000 +0300 +@@ -21,7 +21,7 @@ + + int dwc3_host_init(struct dwc3 *dwc) + { +- struct property_entry props[3]; ++ struct property_entry props[4]; + struct platform_device *xhci; + int ret, irq; + struct resource *res; +@@ -93,6 +93,9 @@ + if (dwc->usb3_lpm_capable) + props[prop_idx++].name = "usb3-lpm-capable"; + ++ if (dwc->usb2_lpm_disable) ++ props[prop_idx++].name = "usb2-lpm-disable"; ++ + /** + * WORKAROUND: dwc3 revisions <=3.00a have a limitation + * where Port Disable command doesn't work. diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-io.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-io.h.patch new file mode 100644 index 00000000..09dbbcfc --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-io.h.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/drivers/usb/dwc3/io.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/io.h 2021-06-07 13:01:34.000000000 +0300 +@@ -40,8 +40,7 @@ + * documentation, so we revert it back to the proper addresses, the + * same way they are described on SNPS documentation + */ +- dwc3_trace(trace_dwc3_readl, "addr %p value %08x", +- base - DWC3_GLOBALS_REGS_START + offset, value); ++ trace_dwc3_readl(base - DWC3_GLOBALS_REGS_START, offset, value); + + return value; + } +@@ -60,8 +59,7 @@ + * documentation, so we revert it back to the proper addresses, the + * same way they are described on SNPS documentation + */ +- dwc3_trace(trace_dwc3_writel, "addr %p value %08x", +- base - DWC3_GLOBALS_REGS_START + offset, value); ++ trace_dwc3_writel(base - DWC3_GLOBALS_REGS_START, offset, value); + } + + #endif /* __DRIVERS_USB_DWC3_IO_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-proc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-proc.c.patch new file mode 100644 index 00000000..a221b416 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-proc.c.patch @@ -0,0 +1,123 @@ +--- linux-4.9.37/drivers/usb/dwc3/proc.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/proc.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,120 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "core.h" ++ ++#define DWC3_PROC_ROOT "dwc3" ++#define DWC3_PROC_CONNECTED_STATUS "csts" ++ ++static struct proc_dir_entry *proc_dwc3_dir = NULL; ++static int proc_dwc3_dir_cnt = 0; ++ ++static void dwc3_stats_seq_printout(struct seq_file *s) ++{ ++ struct dwc3 *dwc = s->private; ++ ++ switch (dwc->udc_connect_status) { ++ case UDC_CONNECT_HOST: ++ seq_puts(s, "cnt2host\n"); ++ break; ++ case UDC_CONNECT_CHARGER: ++ seq_puts(s, "cnt2charger\n"); ++ break; ++ default: ++ seq_puts(s, "disconnected\n"); ++ break; ++ } ++} ++ ++/* define parameters where showed in proc file */ ++static int dwc3_stats_seq_show(struct seq_file *s, void *v) ++{ ++ if (s == NULL) ++ return -EINVAL; ++ ++ dwc3_stats_seq_printout(s); ++ return 0; ++} ++ ++/* proc file open */ ++static int dwc3_stats_proc_open(struct inode *inode, struct file *file) ++{ ++ if ((inode == NULL) || (file == NULL)) ++ return -EINVAL; ++ ++ return single_open(file, dwc3_stats_seq_show, PDE_DATA(inode)); ++}; ++ ++/* proc file operation */ ++static const struct file_operations dwc3_stats_proc_ops = { ++ .owner = THIS_MODULE, ++ .open = dwc3_stats_proc_open, ++ .read = seq_read, ++ .release = single_release, ++}; ++ ++int dwc3_proc_init(struct dwc3 *dwc) ++{ ++ struct proc_dir_entry *proc_entry = NULL; ++ ++ if (dwc == NULL) ++ return -EINVAL; ++ ++ if (proc_dwc3_dir == NULL) { ++ proc_entry = proc_mkdir(DWC3_PROC_ROOT, NULL); ++ if (proc_entry == NULL) { ++ pr_err("%s: failed to create proc file %s\n", ++ __func__, DWC3_PROC_ROOT); ++ return 1; ++ } ++ proc_dwc3_dir = proc_entry; ++ } ++ proc_dwc3_dir_cnt++; ++ ++ proc_entry = proc_mkdir(to_platform_device(dwc->dev)->name, proc_dwc3_dir); ++ if (proc_entry == NULL) { ++ pr_err("%s: failed to create proc file %s\n", ++ __func__, to_platform_device(dwc->dev)->name); ++ return -1; ++ } ++ dwc->parent_entry = proc_entry; ++ ++ proc_entry = proc_create_data(DWC3_PROC_CONNECTED_STATUS, ++ 0, dwc->parent_entry, &dwc3_stats_proc_ops, dwc); ++ if (proc_entry == NULL) { ++ pr_err("%s: failed to create proc file %s\n", ++ __func__, DWC3_PROC_CONNECTED_STATUS); ++ return -1; ++ } ++ dwc->csts_entry = proc_entry; ++ ++ /* ++ * add here if more proc information need. ++ */ ++ return 0; ++} ++ ++int dwc3_proc_shutdown(struct dwc3 *dwc) ++{ ++ if (proc_dwc3_dir != NULL) { ++ remove_proc_entry(DWC3_PROC_CONNECTED_STATUS, dwc->parent_entry); ++ remove_proc_entry(to_platform_device(dwc->dev)->name, proc_dwc3_dir); ++ } ++ ++ if (proc_dwc3_dir_cnt) ++ proc_dwc3_dir_cnt--; ++ ++ if (proc_dwc3_dir_cnt == 0) { ++ remove_proc_entry(DWC3_PROC_ROOT, NULL); ++ proc_dwc3_dir = NULL; ++ } ++ ++ return 0; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-trace.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-trace.h.patch new file mode 100644 index 00000000..8934a527 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-dwc3-trace.h.patch @@ -0,0 +1,315 @@ +--- linux-4.9.37/drivers/usb/dwc3/trace.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/dwc3/trace.h 2021-06-07 13:01:34.000000000 +0300 +@@ -27,57 +27,53 @@ + #include "core.h" + #include "debug.h" + +-DECLARE_EVENT_CLASS(dwc3_log_msg, +- TP_PROTO(struct va_format *vaf), +- TP_ARGS(vaf), +- TP_STRUCT__entry(__dynamic_array(char, msg, DWC3_MSG_MAX)), ++DECLARE_EVENT_CLASS(dwc3_log_io, ++ TP_PROTO(void *base, u32 offset, u32 value), ++ TP_ARGS(base, offset, value), ++ TP_STRUCT__entry( ++ __field(void *, base) ++ __field(u32, offset) ++ __field(u32, value) ++ ), + TP_fast_assign( +- vsnprintf(__get_str(msg), DWC3_MSG_MAX, vaf->fmt, *vaf->va); ++ __entry->base = base; ++ __entry->offset = offset; ++ __entry->value = value; + ), +- TP_printk("%s", __get_str(msg)) +-); +- +-DEFINE_EVENT(dwc3_log_msg, dwc3_readl, +- TP_PROTO(struct va_format *vaf), +- TP_ARGS(vaf) +-); +- +-DEFINE_EVENT(dwc3_log_msg, dwc3_writel, +- TP_PROTO(struct va_format *vaf), +- TP_ARGS(vaf) +-); +- +-DEFINE_EVENT(dwc3_log_msg, dwc3_gadget, +- TP_PROTO(struct va_format *vaf), +- TP_ARGS(vaf) ++ TP_printk("addr %p value %08x", __entry->base + __entry->offset, ++ __entry->value) + ); + +-DEFINE_EVENT(dwc3_log_msg, dwc3_core, +- TP_PROTO(struct va_format *vaf), +- TP_ARGS(vaf) ++DEFINE_EVENT(dwc3_log_io, dwc3_readl, ++ TP_PROTO(void *base, u32 offset, u32 value), ++ TP_ARGS(base, offset, value) + ); + +-DEFINE_EVENT(dwc3_log_msg, dwc3_ep0, +- TP_PROTO(struct va_format *vaf), +- TP_ARGS(vaf) ++DEFINE_EVENT(dwc3_log_io, dwc3_writel, ++ TP_PROTO(void *base, u32 offset, u32 value), ++ TP_ARGS(base, offset, value) + ); + + DECLARE_EVENT_CLASS(dwc3_log_event, +- TP_PROTO(u32 event), +- TP_ARGS(event), ++ TP_PROTO(u32 event, struct dwc3 *dwc), ++ TP_ARGS(event, dwc), + TP_STRUCT__entry( + __field(u32, event) ++ __field(u32, ep0state) ++ __dynamic_array(char, str, DWC3_MSG_MAX) + ), + TP_fast_assign( + __entry->event = event; ++ __entry->ep0state = dwc->ep0state; + ), + TP_printk("event (%08x): %s", __entry->event, +- dwc3_decode_event(__entry->event)) ++ dwc3_decode_event(__get_str(str), DWC3_MSG_MAX, ++ __entry->event, __entry->ep0state)) + ); + + DEFINE_EVENT(dwc3_log_event, dwc3_event, +- TP_PROTO(u32 event), +- TP_ARGS(event) ++ TP_PROTO(u32 event, struct dwc3 *dwc), ++ TP_ARGS(event, dwc) + ); + + DECLARE_EVENT_CLASS(dwc3_log_ctrl, +@@ -89,6 +85,7 @@ + __field(__u16, wValue) + __field(__u16, wIndex) + __field(__u16, wLength) ++ __dynamic_array(char, str, DWC3_MSG_MAX) + ), + TP_fast_assign( + __entry->bRequestType = ctrl->bRequestType; +@@ -97,10 +94,10 @@ + __entry->wIndex = le16_to_cpu(ctrl->wIndex); + __entry->wLength = le16_to_cpu(ctrl->wLength); + ), +- TP_printk("bRequestType %02x bRequest %02x wValue %04x wIndex %04x wLength %d", +- __entry->bRequestType, __entry->bRequest, +- __entry->wValue, __entry->wIndex, +- __entry->wLength ++ TP_printk("%s", dwc3_decode_ctrl(__get_str(str), DWC3_MSG_MAX, ++ __entry->bRequestType, ++ __entry->bRequest, __entry->wValue, ++ __entry->wIndex, __entry->wLength) + ) + ); + +@@ -113,7 +110,7 @@ + TP_PROTO(struct dwc3_request *req), + TP_ARGS(req), + TP_STRUCT__entry( +- __dynamic_array(char, name, DWC3_MSG_MAX) ++ __string(name, req->dep->name) + __field(struct dwc3_request *, req) + __field(unsigned, actual) + __field(unsigned, length) +@@ -123,7 +120,7 @@ + __field(int, no_interrupt) + ), + TP_fast_assign( +- snprintf(__get_str(name), DWC3_MSG_MAX, "%s", req->dep->name); ++ __assign_str(name, req->dep->name); + __entry->req = req; + __entry->actual = req->request.actual; + __entry->length = req->request.length; +@@ -179,7 +176,7 @@ + __entry->param = param; + __entry->status = status; + ), +- TP_printk("cmd '%s' [%d] param %08x --> status: %s", ++ TP_printk("cmd '%s' [%x] param %08x --> status: %s", + dwc3_gadget_generic_cmd_string(__entry->cmd), + __entry->cmd, __entry->param, + dwc3_gadget_generic_cmd_status_string(__entry->status) +@@ -196,7 +193,7 @@ + struct dwc3_gadget_ep_cmd_params *params, int cmd_status), + TP_ARGS(dep, cmd, params, cmd_status), + TP_STRUCT__entry( +- __dynamic_array(char, name, DWC3_MSG_MAX) ++ __string(name, dep->name) + __field(unsigned int, cmd) + __field(u32, param0) + __field(u32, param1) +@@ -204,14 +201,14 @@ + __field(int, cmd_status) + ), + TP_fast_assign( +- snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); ++ __assign_str(name, dep->name); + __entry->cmd = cmd; + __entry->param0 = params->param0; + __entry->param1 = params->param1; + __entry->param2 = params->param2; + __entry->cmd_status = cmd_status; + ), +- TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x --> status: %s", ++ TP_printk("%s: cmd '%s' [%x] params %08x %08x %08x --> status: %s", + __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), + __entry->cmd, __entry->param0, + __entry->param1, __entry->param2, +@@ -229,7 +226,7 @@ + TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb), + TP_ARGS(dep, trb), + TP_STRUCT__entry( +- __dynamic_array(char, name, DWC3_MSG_MAX) ++ __string(name, dep->name) + __field(struct dwc3_trb *, trb) + __field(u32, allocated) + __field(u32, queued) +@@ -237,9 +234,10 @@ + __field(u32, bph) + __field(u32, size) + __field(u32, ctrl) ++ __field(u32, type) + ), + TP_fast_assign( +- snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); ++ __assign_str(name, dep->name); + __entry->trb = trb; + __entry->allocated = dep->allocated_requests; + __entry->queued = dep->queued_requests; +@@ -247,47 +245,40 @@ + __entry->bph = trb->bph; + __entry->size = trb->size; + __entry->ctrl = trb->ctrl; ++ __entry->type = usb_endpoint_type(dep->endpoint.desc); + ), +- TP_printk("%s: %d/%d trb %p buf %08x%08x size %d ctrl %08x (%c%c%c%c:%c%c:%s)", ++ TP_printk("%s: %d/%d trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", + __get_str(name), __entry->queued, __entry->allocated, + __entry->trb, __entry->bph, __entry->bpl, +- __entry->size, __entry->ctrl, ++ ({char *s; ++ int pcm = ((__entry->size >> 24) & 3) + 1; ++ switch (__entry->type) { ++ case USB_ENDPOINT_XFER_INT: ++ case USB_ENDPOINT_XFER_ISOC: ++ switch (pcm) { ++ case 1: ++ s = "1x "; ++ break; ++ case 2: ++ s = "2x "; ++ break; ++ case 3: ++ default: ++ s = "3x "; ++ break; ++ } ++ break; ++ default: ++ s = ""; ++ } s; }), ++ DWC3_TRB_SIZE_LENGTH(__entry->size), __entry->ctrl, + __entry->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h', + __entry->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l', + __entry->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c', + __entry->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's', + __entry->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's', + __entry->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c', +- ({char *s; +- switch (__entry->ctrl & 0x3f0) { +- case DWC3_TRBCTL_NORMAL: +- s = "normal"; +- break; +- case DWC3_TRBCTL_CONTROL_SETUP: +- s = "setup"; +- break; +- case DWC3_TRBCTL_CONTROL_STATUS2: +- s = "status2"; +- break; +- case DWC3_TRBCTL_CONTROL_STATUS3: +- s = "status3"; +- break; +- case DWC3_TRBCTL_CONTROL_DATA: +- s = "data"; +- break; +- case DWC3_TRBCTL_ISOCHRONOUS_FIRST: +- s = "isoc-first"; +- break; +- case DWC3_TRBCTL_ISOCHRONOUS: +- s = "isoc"; +- break; +- case DWC3_TRBCTL_LINK_TRB: +- s = "link"; +- break; +- default: +- s = "UNKNOWN"; +- break; +- } s; }) ++ dwc3_trb_type_string(DWC3_TRBCTL_TYPE(__entry->ctrl)) + ) + ); + +@@ -301,6 +292,56 @@ + TP_ARGS(dep, trb) + ); + ++DECLARE_EVENT_CLASS(dwc3_log_ep, ++ TP_PROTO(struct dwc3_ep *dep), ++ TP_ARGS(dep), ++ TP_STRUCT__entry( ++ __string(name, dep->name) ++ __field(unsigned, maxpacket) ++ __field(unsigned, maxpacket_limit) ++ __field(unsigned, max_streams) ++ __field(unsigned, maxburst) ++ __field(unsigned, flags) ++ __field(unsigned, direction) ++ __field(u8, trb_enqueue) ++ __field(u8, trb_dequeue) ++ ), ++ TP_fast_assign( ++ __assign_str(name, dep->name); ++ __entry->maxpacket = dep->endpoint.maxpacket; ++ __entry->maxpacket_limit = dep->endpoint.maxpacket_limit; ++ __entry->max_streams = dep->endpoint.max_streams; ++ __entry->maxburst = dep->endpoint.maxburst; ++ __entry->flags = dep->flags; ++ __entry->direction = dep->direction; ++ __entry->trb_enqueue = dep->trb_enqueue; ++ __entry->trb_dequeue = dep->trb_dequeue; ++ ), ++ TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c%c:%c", ++ __get_str(name), __entry->maxpacket, ++ __entry->maxpacket_limit, __entry->max_streams, ++ __entry->maxburst, __entry->trb_enqueue, ++ __entry->trb_dequeue, ++ __entry->flags & DWC3_EP_ENABLED ? 'E' : 'e', ++ __entry->flags & DWC3_EP_STALL ? 'S' : 's', ++ __entry->flags & DWC3_EP_WEDGE ? 'W' : 'w', ++ __entry->flags & DWC3_EP_BUSY ? 'B' : 'b', ++ __entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p', ++ __entry->flags & DWC3_EP_MISSED_ISOC ? 'M' : 'm', ++ __entry->direction ? '<' : '>' ++ ) ++); ++ ++DEFINE_EVENT(dwc3_log_ep, dwc3_gadget_ep_enable, ++ TP_PROTO(struct dwc3_ep *dep), ++ TP_ARGS(dep) ++); ++ ++DEFINE_EVENT(dwc3_log_ep, dwc3_gadget_ep_disable, ++ TP_PROTO(struct dwc3_ep *dep), ++ TP_ARGS(dep) ++); ++ + #endif /* __DWC3_TRACE_H */ + + /* this part has to be here */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-Kconfig.patch new file mode 100644 index 00000000..9e03b0f3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-Kconfig.patch @@ -0,0 +1,20 @@ +--- linux-4.9.37/drivers/usb/gadget/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -158,6 +158,9 @@ + config USB_U_ETHER + tristate + ++config USB_U_AUDIO ++ tristate ++ + config USB_F_SERIAL + tristate + +@@ -381,6 +384,7 @@ + depends on SND + select USB_LIBCOMPOSITE + select SND_PCM ++ select USB_U_AUDIO + select USB_F_UAC2 + help + This Audio function is compatible with USB Audio Class diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-composite.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-composite.c.patch new file mode 100644 index 00000000..16222312 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-composite.c.patch @@ -0,0 +1,36 @@ +--- linux-4.9.37/drivers/usb/gadget/composite.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/composite.c 2021-06-07 13:01:34.000000000 +0300 +@@ -205,7 +205,7 @@ + + if (g->speed == USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) || + usb_endpoint_xfer_int(_ep->desc))) +- _ep->mult = ((usb_endpoint_maxp(_ep->desc) & 0x1800) >> 11) + 1; ++ _ep->mult = usb_endpoint_maxp_mult(_ep->desc); + + if (!want_comp_desc) + return 0; +@@ -315,6 +315,9 @@ + list_del(&f->list); + if (f->unbind) + f->unbind(c, f); ++ ++ if (f->bind_deactivated) ++ usb_function_activate(f); + } + EXPORT_SYMBOL_GPL(usb_remove_function); + +@@ -956,12 +959,8 @@ + + f = list_first_entry(&config->functions, + struct usb_function, list); +- list_del(&f->list); +- if (f->unbind) { +- DBG(cdev, "unbind function '%s'/%p\n", f->name, f); +- f->unbind(config, f); +- /* may free memory for "f" */ +- } ++ ++ usb_remove_function(config, f); + } + list_del(&config->list); + if (config->unbind) { diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-configfs.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-configfs.c.patch new file mode 100644 index 00000000..7bf7aca6 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-configfs.c.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/drivers/usb/gadget/configfs.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/configfs.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1209,6 +1209,9 @@ + + list_for_each_entry_safe(f, tmp, &c->functions, list) { + ++ if (f->disable) ++ f->disable(f); ++ + list_move_tail(&f->list, &cfg->func_list); + if (f->unbind) { + dev_dbg(&gi->cdev.gadget->dev, +@@ -1216,6 +1219,9 @@ + f->name, f); + f->unbind(c, f); + } ++ ++ if (f->bind_deactivated) ++ usb_function_activate(f); + } + c->next_interface_id = 0; + memset(c->interface, 0, sizeof(c->interface)); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-epautoconf.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-epautoconf.c.patch new file mode 100644 index 00000000..3bcb3255 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-epautoconf.c.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/drivers/usb/gadget/epautoconf.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/epautoconf.c 2021-06-07 13:01:34.000000000 +0300 +@@ -82,9 +82,16 @@ + } + + /* Second, look at endpoints until an unclaimed one looks usable */ +- list_for_each_entry (ep, &gadget->ep_list, ep_list) { +- if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) +- goto found_ep; ++ if (type == USB_ENDPOINT_XFER_INT) { ++ list_for_each_entry_reverse(ep, &gadget->ep_list, ep_list) { ++ if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) ++ goto found_ep; ++ } ++ } else { ++ list_for_each_entry(ep, &gadget->ep_list, ep_list) { ++ if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) ++ goto found_ep; ++ } + } + + /* Fail */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-Makefile.patch new file mode 100644 index 00000000..6eec3b0f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-Makefile.patch @@ -0,0 +1,15 @@ +--- linux-4.9.37/drivers/usb/gadget/function/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -32,8 +32,11 @@ + obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o + usb_f_fs-y := f_fs.o + obj-$(CONFIG_USB_F_FS) += usb_f_fs.o +-usb_f_uac1-y := f_uac1.o u_uac1.o ++obj-$(CONFIG_USB_U_AUDIO) += u_audio.o ++usb_f_uac1-y := f_uac1.o + obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o ++usb_f_uac1_legacy-y := f_uac1_legacy.o u_uac1_legacy.o ++obj-$(CONFIG_USB_F_UAC1_LEGACY) += usb_f_uac1_legacy.o + usb_f_uac2-y := f_uac2.o + obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o + usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_hid.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_hid.c.patch new file mode 100644 index 00000000..bab5db8a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_hid.c.patch @@ -0,0 +1,199 @@ +--- linux-4.9.37/drivers/usb/gadget/function/f_hid.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/f_hid.c 2021-06-07 13:01:34.000000000 +0300 +@@ -284,6 +284,7 @@ + size_t count, loff_t *offp) + { + struct f_hidg *hidg = file->private_data; ++ struct usb_request *req; + unsigned long flags; + ssize_t status = -ENOMEM; + +@@ -293,7 +294,7 @@ + spin_lock_irqsave(&hidg->write_spinlock, flags); + + #define WRITE_COND (!hidg->write_pending) +- ++try_again: + /* write queue */ + while (!WRITE_COND) { + spin_unlock_irqrestore(&hidg->write_spinlock, flags); +@@ -308,6 +309,7 @@ + } + + hidg->write_pending = 1; ++ req = hidg->req; + count = min_t(unsigned, count, hidg->report_length); + + spin_unlock_irqrestore(&hidg->write_spinlock, flags); +@@ -320,24 +322,38 @@ + goto release_write_pending; + } + +- hidg->req->status = 0; +- hidg->req->zero = 0; +- hidg->req->length = count; +- hidg->req->complete = f_hidg_req_complete; +- hidg->req->context = hidg; ++ spin_lock_irqsave(&hidg->write_spinlock, flags); ++ ++ /* we our function has been disabled by host */ ++ if (!hidg->req) { ++ free_ep_req(hidg->in_ep, hidg->req); ++ /* ++ * TODO ++ * Should we fail with error here? ++ */ ++ goto try_again; ++ } ++ ++ req->status = 0; ++ req->zero = 0; ++ req->length = count; ++ req->complete = f_hidg_req_complete; ++ req->context = hidg; + + status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC); + if (status < 0) { + ERROR(hidg->func.config->cdev, + "usb_ep_queue error on int endpoint %zd\n", status); +- goto release_write_pending; ++ goto release_write_pending_unlocked; + } else { + status = count; + } ++ spin_unlock_irqrestore(&hidg->write_spinlock, flags); + + return status; + release_write_pending: + spin_lock_irqsave(&hidg->write_spinlock, flags); ++release_write_pending_unlocked: + hidg->write_pending = 0; + spin_unlock_irqrestore(&hidg->write_spinlock, flags); + +@@ -541,12 +557,23 @@ + kfree(list); + } + spin_unlock_irqrestore(&hidg->read_spinlock, flags); ++ ++ spin_lock_irqsave(&hidg->write_spinlock, flags); ++ if (!hidg->write_pending) { ++ free_ep_req(hidg->in_ep, hidg->req); ++ hidg->write_pending = 1; ++ } ++ ++ hidg->req = NULL; ++ spin_unlock_irqrestore(&hidg->write_spinlock, flags); + } + + static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) + { + struct usb_composite_dev *cdev = f->config->cdev; + struct f_hidg *hidg = func_to_hidg(f); ++ struct usb_request *req_in = NULL; ++ unsigned long flags; + int i, status = 0; + + VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt); +@@ -567,6 +594,12 @@ + goto fail; + } + hidg->in_ep->driver_data = hidg; ++ ++ req_in = hidg_alloc_ep_req(hidg->in_ep, hidg->report_length); ++ if (!req_in) { ++ status = -ENOMEM; ++ goto disable_ep_in; ++ } + } + + +@@ -578,12 +611,12 @@ + hidg->out_ep); + if (status) { + ERROR(cdev, "config_ep_by_speed FAILED!\n"); +- goto fail; ++ goto free_req_in; + } + status = usb_ep_enable(hidg->out_ep); + if (status < 0) { +- ERROR(cdev, "Enable IN endpoint FAILED!\n"); +- goto fail; ++ ERROR(cdev, "Enable OUT endpoint FAILED!\n"); ++ goto free_req_in; + } + hidg->out_ep->driver_data = hidg; + +@@ -599,17 +632,37 @@ + req->context = hidg; + status = usb_ep_queue(hidg->out_ep, req, + GFP_ATOMIC); +- if (status) ++ if (status) { + ERROR(cdev, "%s queue req --> %d\n", + hidg->out_ep->name, status); ++ free_ep_req(hidg->out_ep, req); ++ } + } else { +- usb_ep_disable(hidg->out_ep); + status = -ENOMEM; +- goto fail; ++ goto disable_out_ep; + } + } + } + ++ if (hidg->in_ep != NULL) { ++ spin_lock_irqsave(&hidg->write_spinlock, flags); ++ hidg->req = req_in; ++ hidg->write_pending = 0; ++ spin_unlock_irqrestore(&hidg->write_spinlock, flags); ++ ++ wake_up(&hidg->write_queue); ++ } ++ return 0; ++disable_out_ep: ++ usb_ep_disable(hidg->out_ep); ++free_req_in: ++ if (req_in) ++ free_ep_req(hidg->in_ep, req_in); ++ ++disable_ep_in: ++ if (hidg->in_ep) ++ usb_ep_disable(hidg->in_ep); ++ + fail: + return status; + } +@@ -658,12 +711,6 @@ + goto fail; + hidg->out_ep = ep; + +- /* preallocate request and buffer */ +- status = -ENOMEM; +- hidg->req = alloc_ep_req(hidg->in_ep, hidg->report_length); +- if (!hidg->req) +- goto fail; +- + /* set descriptor dynamic values */ + hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; + hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; +@@ -690,6 +737,8 @@ + goto fail; + + spin_lock_init(&hidg->write_spinlock); ++ hidg->write_pending = 1; ++ hidg->req = NULL; + spin_lock_init(&hidg->read_spinlock); + init_waitqueue_head(&hidg->write_queue); + init_waitqueue_head(&hidg->read_queue); +@@ -954,10 +1003,6 @@ + device_destroy(hidg_class, MKDEV(major, hidg->minor)); + cdev_del(&hidg->cdev); + +- /* disable/free request and end point */ +- usb_ep_disable(hidg->in_ep); +- free_ep_req(hidg->in_ep, hidg->req); +- + usb_free_all_descriptors(f); + } + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_mass_storage.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_mass_storage.c.patch new file mode 100644 index 00000000..0781e81c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_mass_storage.c.patch @@ -0,0 +1,45 @@ +--- linux-4.9.37/drivers/usb/gadget/function/f_mass_storage.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/f_mass_storage.c 2021-06-07 13:01:34.000000000 +0300 +@@ -301,6 +301,7 @@ + unsigned int bad_lun_okay:1; + unsigned int running:1; + unsigned int sysfs:1; ++ unsigned int actived:1; + + int thread_wakeup_needed; + struct completion thread_notifier; +@@ -1371,7 +1372,7 @@ + + up_read(&common->filesem); + down_write(&common->filesem); +- fsg_lun_close(curlun); ++ common->actived = 0; + up_write(&common->filesem); + down_read(&common->filesem); + +@@ -1815,7 +1816,7 @@ + + /* If the medium isn't mounted and the command needs to access + * it, return an error. */ +- if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { ++ if (curlun && !common->actived && needs_medium) { + curlun->sense_data = SS_MEDIUM_NOT_PRESENT; + return -EINVAL; + } +@@ -2280,6 +2281,7 @@ + } + + common->running = 0; ++ common->actived = 0; + if (!new_fsg || rc) + return rc; + +@@ -2323,7 +2325,7 @@ + bh->inreq->complete = bulk_in_complete; + bh->outreq->complete = bulk_out_complete; + } +- ++ common->actived = 1; + common->running = 1; + for (i = 0; i < ARRAY_SIZE(common->luns); ++i) + if (common->luns[i]) diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac1.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac1.c.patch new file mode 100644 index 00000000..51fb2613 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac1.c.patch @@ -0,0 +1,1214 @@ +--- linux-4.9.37/drivers/usb/gadget/function/f_uac1.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/f_uac1.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1,24 +1,34 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* +- * f_audio.c -- USB Audio class function driver +- * +- * Copyright (C) 2008 Bryan Wu +- * Copyright (C) 2008 Analog Devices, Inc ++ * f_uac1.c -- USB Audio Class 1.0 Function (using u_audio API) + * +- * Enter bugs at http://blackfin.uclinux.org/ ++ * Copyright (C) 2016 Ruslan Bilovol + * +- * Licensed under the GPL-2 or later. ++ * This driver doesn't expect any real Audio codec to be present ++ * on the device - the audio streams are simply sinked to and ++ * sourced from a virtual ALSA sound card created. ++ * ++ * This file is based on f_uac1.c which is ++ * Copyright (C) 2008 Bryan Wu ++ * Copyright (C) 2008 Analog Devices, Inc + */ + +-#include +-#include ++#include + #include +-#include +-#include + ++#include "u_audio.h" + #include "u_uac1.h" + +-static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); +-static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); ++struct f_uac1 { ++ struct g_audio g_audio; ++ u8 ac_intf, as_in_intf, as_out_intf; ++ u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */ ++}; ++ ++static inline struct f_uac1 *func_to_uac1(struct usb_function *f) ++{ ++ return container_of(f, struct f_uac1, g_audio.func); ++} + + /* + * DESCRIPTORS ... most are static, but strings and full +@@ -26,12 +36,27 @@ + */ + + /* +- * We have two interfaces- AudioControl and AudioStreaming +- * TODO: only supcard playback currently ++ * We have three interfaces - one AudioControl and two AudioStreaming ++ * ++ * The driver implements a simple UAC_1 topology. ++ * USB-OUT -> IT_1 -> OT_2 -> ALSA_Capture ++ * ALSA_Playback -> IT_3 -> OT_4 -> USB-IN + */ +-#define F_AUDIO_AC_INTERFACE 0 +-#define F_AUDIO_AS_INTERFACE 1 +-#define F_AUDIO_NUM_INTERFACES 1 ++#define F_AUDIO_AC_INTERFACE 0 ++#define F_AUDIO_AS_OUT_INTERFACE 1 ++#define F_AUDIO_AS_IN_INTERFACE 2 ++/* Number of streaming interfaces */ ++#define F_AUDIO_NUM_INTERFACES 2 ++ ++static struct usb_interface_assoc_descriptor uac_iad = { ++ .bLength = sizeof(uac_iad), ++ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, ++ .bFirstInterface = 0, ++ .bInterfaceCount = 3, ++ .bFunctionClass = USB_CLASS_AUDIO, ++ .bFunctionSubClass = 0, ++ .bFunctionProtocol = UAC_VERSION_1, ++}; + + /* B.3.1 Standard AC Interface Descriptor */ + static struct usb_interface_descriptor ac_interface_desc = { +@@ -46,89 +71,91 @@ + * The number of AudioStreaming and MIDIStreaming interfaces + * in the Audio Interface Collection + */ +-DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); ++DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); + + #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) +-/* 1 input terminal, 1 output terminal and 1 feature unit */ +-#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ +- + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) ++/* 2 input terminals and 2 output terminals */ ++#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \ ++ + 2*UAC_DT_INPUT_TERMINAL_SIZE + 2*UAC_DT_OUTPUT_TERMINAL_SIZE) + /* B.3.2 Class-Specific AC Interface Descriptor */ +-static struct uac1_ac_header_descriptor_1 ac_header_desc = { ++static struct uac1_ac_header_descriptor_2 ac_header_desc = { + .bLength = UAC_DT_AC_HEADER_LENGTH, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_HEADER, +- .bcdADC = __constant_cpu_to_le16(0x0100), +- .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), ++ .bcdADC = cpu_to_le16(0x0100), ++ .wTotalLength = cpu_to_le16(UAC_DT_TOTAL_LENGTH), + .bInCollection = F_AUDIO_NUM_INTERFACES, + .baInterfaceNr = { +- /* Interface number of the first AudioStream interface */ ++ /* Interface number of the AudioStream interfaces */ + [0] = 1, ++ [1] = 2, + } + }; + +-#define INPUT_TERMINAL_ID 1 +-static struct uac_input_terminal_descriptor input_terminal_desc = { ++#define USB_OUT_IT_ID 1 ++static struct uac_input_terminal_descriptor usb_out_it_desc = { + .bLength = UAC_DT_INPUT_TERMINAL_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_INPUT_TERMINAL, +- .bTerminalID = INPUT_TERMINAL_ID, +- .wTerminalType = UAC_TERMINAL_STREAMING, ++ .bTerminalID = USB_OUT_IT_ID, ++ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), + .bAssocTerminal = 0, +- .wChannelConfig = 0x3, ++ .wChannelConfig = cpu_to_le16(0x3), + }; + +-DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); +- +-#define FEATURE_UNIT_ID 2 +-static struct uac_feature_unit_descriptor_0 feature_unit_desc = { +- .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), ++#define IO_OUT_OT_ID 2 ++static struct uac1_output_terminal_descriptor io_out_ot_desc = { ++ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, +- .bDescriptorSubtype = UAC_FEATURE_UNIT, +- .bUnitID = FEATURE_UNIT_ID, +- .bSourceID = INPUT_TERMINAL_ID, +- .bControlSize = 2, +- .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), +-}; +- +-static struct usb_audio_control mute_control = { +- .list = LIST_HEAD_INIT(mute_control.list), +- .name = "Mute Control", +- .type = UAC_FU_MUTE, +- /* Todo: add real Mute control code */ +- .set = generic_set_cmd, +- .get = generic_get_cmd, +-}; +- +-static struct usb_audio_control volume_control = { +- .list = LIST_HEAD_INIT(volume_control.list), +- .name = "Volume Control", +- .type = UAC_FU_VOLUME, +- /* Todo: add real Volume control code */ +- .set = generic_set_cmd, +- .get = generic_get_cmd, +-}; +- +-static struct usb_audio_control_selector feature_unit = { +- .list = LIST_HEAD_INIT(feature_unit.list), +- .id = FEATURE_UNIT_ID, +- .name = "Mute & Volume Control", +- .type = UAC_FEATURE_UNIT, +- .desc = (struct usb_descriptor_header *)&feature_unit_desc, ++ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, ++ .bTerminalID = IO_OUT_OT_ID, ++ .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER), ++ .bAssocTerminal = 0, ++ .bSourceID = USB_OUT_IT_ID, + }; + +-#define OUTPUT_TERMINAL_ID 3 +-static struct uac1_output_terminal_descriptor output_terminal_desc = { +- .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, ++#define IO_IN_IT_ID 3 ++static struct uac_input_terminal_descriptor io_in_it_desc = { ++ .bLength = UAC_DT_INPUT_TERMINAL_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, +- .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, +- .bTerminalID = OUTPUT_TERMINAL_ID, +- .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER, +- .bAssocTerminal = FEATURE_UNIT_ID, +- .bSourceID = FEATURE_UNIT_ID, ++ .bDescriptorSubtype = UAC_INPUT_TERMINAL, ++ .bTerminalID = IO_IN_IT_ID, ++ .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE), ++ .bAssocTerminal = 0, ++ .wChannelConfig = cpu_to_le16(0x3), ++}; ++ ++#define USB_IN_OT_ID 4 ++static struct uac1_output_terminal_descriptor usb_in_ot_desc = { ++ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, ++ .bTerminalID = USB_IN_OT_ID, ++ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), ++ .bAssocTerminal = 0, ++ .bSourceID = IO_IN_IT_ID, + }; + + /* B.4.1 Standard AS Interface Descriptor */ +-static struct usb_interface_descriptor as_interface_alt_0_desc = { ++static struct usb_interface_descriptor as_out_interface_alt_0_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bAlternateSetting = 0, ++ .bNumEndpoints = 0, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, ++}; ++ ++static struct usb_interface_descriptor as_out_interface_alt_1_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bAlternateSetting = 1, ++ .bNumEndpoints = 1, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, ++}; ++ ++static struct usb_interface_descriptor as_in_interface_alt_0_desc = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bAlternateSetting = 0, +@@ -137,7 +164,7 @@ + .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, + }; + +-static struct usb_interface_descriptor as_interface_alt_1_desc = { ++static struct usb_interface_descriptor as_in_interface_alt_1_desc = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bAlternateSetting = 1, +@@ -147,18 +174,27 @@ + }; + + /* B.4.2 Class-Specific AS Interface Descriptor */ +-static struct uac1_as_header_descriptor as_header_desc = { ++static struct uac1_as_header_descriptor as_out_header_desc = { ++ .bLength = UAC_DT_AS_HEADER_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_AS_GENERAL, ++ .bTerminalLink = USB_OUT_IT_ID, ++ .bDelay = 1, ++ .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), ++}; ++ ++static struct uac1_as_header_descriptor as_in_header_desc = { + .bLength = UAC_DT_AS_HEADER_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_AS_GENERAL, +- .bTerminalLink = INPUT_TERMINAL_ID, ++ .bTerminalLink = USB_IN_OT_ID, + .bDelay = 1, +- .wFormatTag = UAC_FORMAT_TYPE_I_PCM, ++ .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), + }; + + DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); + +-static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { ++static struct uac_format_type_i_discrete_descriptor_1 as_out_type_i_desc = { + .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = UAC_FORMAT_TYPE, +@@ -184,48 +220,138 @@ + .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, + .bDescriptorType = USB_DT_CS_ENDPOINT, + .bDescriptorSubtype = UAC_EP_GENERAL, +- .bmAttributes = 1, ++ .bmAttributes = 1, + .bLockDelayUnits = 1, +- .wLockDelay = __constant_cpu_to_le16(1), ++ .wLockDelay = cpu_to_le16(1), ++}; ++ ++static struct uac_format_type_i_discrete_descriptor_1 as_in_type_i_desc = { ++ .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_FORMAT_TYPE, ++ .bFormatType = UAC_FORMAT_TYPE_I, ++ .bSubframeSize = 2, ++ .bBitResolution = 16, ++ .bSamFreqType = 1, ++}; ++ ++/* Standard ISO OUT Endpoint Descriptor */ ++static struct usb_endpoint_descriptor as_in_ep_desc = { ++ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_IN, ++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC ++ | USB_ENDPOINT_XFER_ISOC, ++ .wMaxPacketSize = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), ++ .bInterval = 4, ++}; ++ ++/* Class-specific AS ISO OUT Endpoint Descriptor */ ++static struct uac_iso_endpoint_descriptor as_iso_in_desc = { ++ .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, ++ .bDescriptorType = USB_DT_CS_ENDPOINT, ++ .bDescriptorSubtype = UAC_EP_GENERAL, ++ .bmAttributes = 1, ++ .bLockDelayUnits = 0, ++ .wLockDelay = 0, ++}; ++ ++static struct usb_ss_ep_comp_descriptor as_ss_ep_comp = { ++ .bLength = sizeof(as_ss_ep_comp), ++ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, ++ .bMaxBurst = 0, ++ .bmAttributes = 0, ++ .wBytesPerInterval = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), + }; + + static struct usb_descriptor_header *f_audio_desc[] = { ++ (struct usb_descriptor_header *)&uac_iad, ++ (struct usb_descriptor_header *)&ac_interface_desc, ++ (struct usb_descriptor_header *)&ac_header_desc, ++ ++ (struct usb_descriptor_header *)&usb_out_it_desc, ++ (struct usb_descriptor_header *)&io_out_ot_desc, ++ (struct usb_descriptor_header *)&io_in_it_desc, ++ (struct usb_descriptor_header *)&usb_in_ot_desc, ++ ++ (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, ++ (struct usb_descriptor_header *)&as_out_interface_alt_1_desc, ++ (struct usb_descriptor_header *)&as_out_header_desc, ++ ++ (struct usb_descriptor_header *)&as_out_type_i_desc, ++ ++ (struct usb_descriptor_header *)&as_out_ep_desc, ++ (struct usb_descriptor_header *)&as_iso_out_desc, ++ ++ (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, ++ (struct usb_descriptor_header *)&as_in_interface_alt_1_desc, ++ (struct usb_descriptor_header *)&as_in_header_desc, ++ ++ (struct usb_descriptor_header *)&as_in_type_i_desc, ++ ++ (struct usb_descriptor_header *)&as_in_ep_desc, ++ (struct usb_descriptor_header *)&as_iso_in_desc, ++ NULL, ++}; ++ ++static struct usb_descriptor_header *f_audio_ss_desc[] = { ++ (struct usb_descriptor_header *)&uac_iad, + (struct usb_descriptor_header *)&ac_interface_desc, + (struct usb_descriptor_header *)&ac_header_desc, + +- (struct usb_descriptor_header *)&input_terminal_desc, +- (struct usb_descriptor_header *)&output_terminal_desc, +- (struct usb_descriptor_header *)&feature_unit_desc, +- +- (struct usb_descriptor_header *)&as_interface_alt_0_desc, +- (struct usb_descriptor_header *)&as_interface_alt_1_desc, +- (struct usb_descriptor_header *)&as_header_desc, ++ (struct usb_descriptor_header *)&usb_out_it_desc, ++ (struct usb_descriptor_header *)&io_out_ot_desc, ++ (struct usb_descriptor_header *)&io_in_it_desc, ++ (struct usb_descriptor_header *)&usb_in_ot_desc, ++ ++ (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, ++ (struct usb_descriptor_header *)&as_out_interface_alt_1_desc, ++ (struct usb_descriptor_header *)&as_out_header_desc, + +- (struct usb_descriptor_header *)&as_type_i_desc, ++ (struct usb_descriptor_header *)&as_out_type_i_desc, + + (struct usb_descriptor_header *)&as_out_ep_desc, ++ (struct usb_descriptor_header *)&as_ss_ep_comp, + (struct usb_descriptor_header *)&as_iso_out_desc, ++ ++ (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, ++ (struct usb_descriptor_header *)&as_in_interface_alt_1_desc, ++ (struct usb_descriptor_header *)&as_in_header_desc, ++ ++ (struct usb_descriptor_header *)&as_in_type_i_desc, ++ ++ (struct usb_descriptor_header *)&as_in_ep_desc, ++ (struct usb_descriptor_header *)&as_ss_ep_comp, ++ (struct usb_descriptor_header *)&as_iso_in_desc, + NULL, + }; + + enum { + STR_AC_IF, +- STR_INPUT_TERMINAL, +- STR_INPUT_TERMINAL_CH_NAMES, +- STR_FEAT_DESC_0, +- STR_OUTPUT_TERMINAL, +- STR_AS_IF_ALT0, +- STR_AS_IF_ALT1, ++ STR_USB_OUT_IT, ++ STR_USB_OUT_IT_CH_NAMES, ++ STR_IO_OUT_OT, ++ STR_IO_IN_IT, ++ STR_IO_IN_IT_CH_NAMES, ++ STR_USB_IN_OT, ++ STR_AS_OUT_IF_ALT0, ++ STR_AS_OUT_IF_ALT1, ++ STR_AS_IN_IF_ALT0, ++ STR_AS_IN_IF_ALT1, + }; + + static struct usb_string strings_uac1[] = { + [STR_AC_IF].s = "AC Interface", +- [STR_INPUT_TERMINAL].s = "Input terminal", +- [STR_INPUT_TERMINAL_CH_NAMES].s = "Channels", +- [STR_FEAT_DESC_0].s = "Volume control & mute", +- [STR_OUTPUT_TERMINAL].s = "Output terminal", +- [STR_AS_IF_ALT0].s = "AS Interface", +- [STR_AS_IF_ALT1].s = "AS Interface", ++ [STR_USB_OUT_IT].s = "Playback Input terminal", ++ [STR_USB_OUT_IT_CH_NAMES].s = "Playback Channels", ++ [STR_IO_OUT_OT].s = "Playback Output terminal", ++ [STR_IO_IN_IT].s = "Capture Input terminal", ++ [STR_IO_IN_IT_CH_NAMES].s = "Capture Channels", ++ [STR_USB_IN_OT].s = "Capture Output terminal", ++ [STR_AS_OUT_IF_ALT0].s = "Playback Inactive", ++ [STR_AS_OUT_IF_ALT1].s = "Playback Active", ++ [STR_AS_IN_IF_ALT0].s = "Capture Inactive", ++ [STR_AS_IN_IF_ALT1].s = "Capture Active", + { }, + }; + +@@ -243,216 +369,6 @@ + * This function is an ALSA sound card following USB Audio Class Spec 1.0. + */ + +-/*-------------------------------------------------------------------------*/ +-struct f_audio_buf { +- u8 *buf; +- int actual; +- struct list_head list; +-}; +- +-static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) +-{ +- struct f_audio_buf *copy_buf; +- +- copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); +- if (!copy_buf) +- return ERR_PTR(-ENOMEM); +- +- copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); +- if (!copy_buf->buf) { +- kfree(copy_buf); +- return ERR_PTR(-ENOMEM); +- } +- +- return copy_buf; +-} +- +-static void f_audio_buffer_free(struct f_audio_buf *audio_buf) +-{ +- kfree(audio_buf->buf); +- kfree(audio_buf); +-} +-/*-------------------------------------------------------------------------*/ +- +-struct f_audio { +- struct gaudio card; +- +- /* endpoints handle full and/or high speeds */ +- struct usb_ep *out_ep; +- +- spinlock_t lock; +- struct f_audio_buf *copy_buf; +- struct work_struct playback_work; +- struct list_head play_queue; +- +- /* Control Set command */ +- struct list_head cs; +- u8 set_cmd; +- struct usb_audio_control *set_con; +-}; +- +-static inline struct f_audio *func_to_audio(struct usb_function *f) +-{ +- return container_of(f, struct f_audio, card.func); +-} +- +-/*-------------------------------------------------------------------------*/ +- +-static void f_audio_playback_work(struct work_struct *data) +-{ +- struct f_audio *audio = container_of(data, struct f_audio, +- playback_work); +- struct f_audio_buf *play_buf; +- +- spin_lock_irq(&audio->lock); +- if (list_empty(&audio->play_queue)) { +- spin_unlock_irq(&audio->lock); +- return; +- } +- play_buf = list_first_entry(&audio->play_queue, +- struct f_audio_buf, list); +- list_del(&play_buf->list); +- spin_unlock_irq(&audio->lock); +- +- u_audio_playback(&audio->card, play_buf->buf, play_buf->actual); +- f_audio_buffer_free(play_buf); +-} +- +-static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) +-{ +- struct f_audio *audio = req->context; +- struct usb_composite_dev *cdev = audio->card.func.config->cdev; +- struct f_audio_buf *copy_buf = audio->copy_buf; +- struct f_uac1_opts *opts; +- int audio_buf_size; +- int err; +- +- opts = container_of(audio->card.func.fi, struct f_uac1_opts, +- func_inst); +- audio_buf_size = opts->audio_buf_size; +- +- if (!copy_buf) +- return -EINVAL; +- +- /* Copy buffer is full, add it to the play_queue */ +- if (audio_buf_size - copy_buf->actual < req->actual) { +- list_add_tail(©_buf->list, &audio->play_queue); +- schedule_work(&audio->playback_work); +- copy_buf = f_audio_buffer_alloc(audio_buf_size); +- if (IS_ERR(copy_buf)) +- return -ENOMEM; +- } +- +- memcpy(copy_buf->buf + copy_buf->actual, req->buf, req->actual); +- copy_buf->actual += req->actual; +- audio->copy_buf = copy_buf; +- +- err = usb_ep_queue(ep, req, GFP_ATOMIC); +- if (err) +- ERROR(cdev, "%s queue req: %d\n", ep->name, err); +- +- return 0; +- +-} +- +-static void f_audio_complete(struct usb_ep *ep, struct usb_request *req) +-{ +- struct f_audio *audio = req->context; +- int status = req->status; +- u32 data = 0; +- struct usb_ep *out_ep = audio->out_ep; +- +- switch (status) { +- +- case 0: /* normal completion? */ +- if (ep == out_ep) +- f_audio_out_ep_complete(ep, req); +- else if (audio->set_con) { +- memcpy(&data, req->buf, req->length); +- audio->set_con->set(audio->set_con, audio->set_cmd, +- le16_to_cpu(data)); +- audio->set_con = NULL; +- } +- break; +- default: +- break; +- } +-} +- +-static int audio_set_intf_req(struct usb_function *f, +- const struct usb_ctrlrequest *ctrl) +-{ +- struct f_audio *audio = func_to_audio(f); +- struct usb_composite_dev *cdev = f->config->cdev; +- struct usb_request *req = cdev->req; +- u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); +- u16 len = le16_to_cpu(ctrl->wLength); +- u16 w_value = le16_to_cpu(ctrl->wValue); +- u8 con_sel = (w_value >> 8) & 0xFF; +- u8 cmd = (ctrl->bRequest & 0x0F); +- struct usb_audio_control_selector *cs; +- struct usb_audio_control *con; +- +- DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", +- ctrl->bRequest, w_value, len, id); +- +- list_for_each_entry(cs, &audio->cs, list) { +- if (cs->id == id) { +- list_for_each_entry(con, &cs->control, list) { +- if (con->type == con_sel) { +- audio->set_con = con; +- break; +- } +- } +- break; +- } +- } +- +- audio->set_cmd = cmd; +- req->context = audio; +- req->complete = f_audio_complete; +- +- return len; +-} +- +-static int audio_get_intf_req(struct usb_function *f, +- const struct usb_ctrlrequest *ctrl) +-{ +- struct f_audio *audio = func_to_audio(f); +- struct usb_composite_dev *cdev = f->config->cdev; +- struct usb_request *req = cdev->req; +- int value = -EOPNOTSUPP; +- u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); +- u16 len = le16_to_cpu(ctrl->wLength); +- u16 w_value = le16_to_cpu(ctrl->wValue); +- u8 con_sel = (w_value >> 8) & 0xFF; +- u8 cmd = (ctrl->bRequest & 0x0F); +- struct usb_audio_control_selector *cs; +- struct usb_audio_control *con; +- +- DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", +- ctrl->bRequest, w_value, len, id); +- +- list_for_each_entry(cs, &audio->cs, list) { +- if (cs->id == id) { +- list_for_each_entry(con, &cs->control, list) { +- if (con->type == con_sel && con->get) { +- value = con->get(con, cmd); +- break; +- } +- } +- break; +- } +- } +- +- req->context = audio; +- req->complete = f_audio_complete; +- len = min_t(size_t, sizeof(value), len); +- memcpy(req->buf, &value, len); +- +- return len; +-} +- + static int audio_set_endpoint_req(struct usb_function *f, + const struct usb_ctrlrequest *ctrl) + { +@@ -531,14 +447,6 @@ + * activation uses set_alt(). + */ + switch (ctrl->bRequestType) { +- case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: +- value = audio_set_intf_req(f, ctrl); +- break; +- +- case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: +- value = audio_get_intf_req(f, ctrl); +- break; +- + case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: + value = audio_set_endpoint_req(f, ctrl); + break; +@@ -571,143 +479,162 @@ + + static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) + { +- struct f_audio *audio = func_to_audio(f); + struct usb_composite_dev *cdev = f->config->cdev; +- struct usb_ep *out_ep = audio->out_ep; +- struct usb_request *req; +- struct f_uac1_opts *opts; +- int req_buf_size, req_count, audio_buf_size; +- int i = 0, err = 0; +- +- DBG(cdev, "intf %d, alt %d\n", intf, alt); ++ struct usb_gadget *gadget = cdev->gadget; ++ struct device *dev = &gadget->dev; ++ struct f_uac1 *uac1 = func_to_uac1(f); ++ int ret = 0; ++ ++ /* No i/f has more than 2 alt settings */ ++ if (alt > 1) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return -EINVAL; ++ } + +- opts = container_of(f->fi, struct f_uac1_opts, func_inst); +- req_buf_size = opts->req_buf_size; +- req_count = opts->req_count; +- audio_buf_size = opts->audio_buf_size; +- +- if (intf == 1) { +- if (alt == 1) { +- err = config_ep_by_speed(cdev->gadget, f, out_ep); +- if (err) +- return err; +- +- usb_ep_enable(out_ep); +- audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); +- if (IS_ERR(audio->copy_buf)) +- return -ENOMEM; +- +- /* +- * allocate a bunch of read buffers +- * and queue them all at once. +- */ +- for (i = 0; i < req_count && err == 0; i++) { +- req = usb_ep_alloc_request(out_ep, GFP_ATOMIC); +- if (req) { +- req->buf = kzalloc(req_buf_size, +- GFP_ATOMIC); +- if (req->buf) { +- req->length = req_buf_size; +- req->context = audio; +- req->complete = +- f_audio_complete; +- err = usb_ep_queue(out_ep, +- req, GFP_ATOMIC); +- if (err) +- ERROR(cdev, +- "%s queue req: %d\n", +- out_ep->name, err); +- } else +- err = -ENOMEM; +- } else +- err = -ENOMEM; +- } +- +- } else { +- struct f_audio_buf *copy_buf = audio->copy_buf; +- if (copy_buf) { +- list_add_tail(©_buf->list, +- &audio->play_queue); +- schedule_work(&audio->playback_work); +- } ++ if (intf == uac1->ac_intf) { ++ /* Control I/f has only 1 AltSetting - 0 */ ++ if (alt) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return -EINVAL; + } ++ return 0; ++ } ++ ++ if (intf == uac1->as_out_intf) { ++ uac1->as_out_alt = alt; ++ ++ if (alt) ++ ret = u_audio_start_capture(&uac1->g_audio); ++ else ++ u_audio_stop_capture(&uac1->g_audio); ++ } else if (intf == uac1->as_in_intf) { ++ uac1->as_in_alt = alt; ++ ++ if (alt) ++ ret = u_audio_start_playback(&uac1->g_audio); ++ else ++ u_audio_stop_playback(&uac1->g_audio); ++ } else { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return -EINVAL; + } + +- return err; ++ return ret; + } + +-static void f_audio_disable(struct usb_function *f) ++static int f_audio_get_alt(struct usb_function *f, unsigned intf) + { +- return; ++ struct usb_composite_dev *cdev = f->config->cdev; ++ struct usb_gadget *gadget = cdev->gadget; ++ struct device *dev = &gadget->dev; ++ struct f_uac1 *uac1 = func_to_uac1(f); ++ ++ if (intf == uac1->ac_intf) ++ return uac1->ac_alt; ++ else if (intf == uac1->as_out_intf) ++ return uac1->as_out_alt; ++ else if (intf == uac1->as_in_intf) ++ return uac1->as_in_alt; ++ else ++ dev_err(dev, "%s:%d Invalid Interface %d!\n", ++ __func__, __LINE__, intf); ++ ++ return -EINVAL; + } + +-/*-------------------------------------------------------------------------*/ + +-static void f_audio_build_desc(struct f_audio *audio) ++static void f_audio_disable(struct usb_function *f) + { +- struct gaudio *card = &audio->card; +- u8 *sam_freq; +- int rate; +- +- /* Set channel numbers */ +- input_terminal_desc.bNrChannels = u_audio_get_playback_channels(card); +- as_type_i_desc.bNrChannels = u_audio_get_playback_channels(card); ++ struct f_uac1 *uac1 = func_to_uac1(f); + +- /* Set sample rates */ +- rate = u_audio_get_playback_rate(card); +- sam_freq = as_type_i_desc.tSamFreq[0]; +- memcpy(sam_freq, &rate, 3); ++ uac1->as_out_alt = 0; ++ uac1->as_in_alt = 0; + +- /* Todo: Set Sample bits and other parameters */ +- +- return; ++ u_audio_stop_capture(&uac1->g_audio); + } + ++/*-------------------------------------------------------------------------*/ ++ + /* audio function driver setup/binding */ +-static int +-f_audio_bind(struct usb_configuration *c, struct usb_function *f) ++static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) + { +- struct usb_composite_dev *cdev = c->cdev; +- struct f_audio *audio = func_to_audio(f); +- struct usb_string *us; +- int status; +- struct usb_ep *ep = NULL; +- struct f_uac1_opts *audio_opts; ++ struct usb_composite_dev *cdev = c->cdev; ++ struct usb_gadget *gadget = cdev->gadget; ++ struct f_uac1 *uac1 = func_to_uac1(f); ++ struct g_audio *audio = func_to_g_audio(f); ++ struct f_uac1_opts *audio_opts; ++ struct usb_ep *ep = NULL; ++ struct usb_string *us; ++ u8 *sam_freq; ++ int rate; ++ int status; + + audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); +- audio->card.gadget = c->cdev->gadget; +- /* set up ASLA audio devices */ +- if (!audio_opts->bound) { +- status = gaudio_setup(&audio->card); +- if (status < 0) +- return status; +- audio_opts->bound = true; +- } ++ + us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); + if (IS_ERR(us)) + return PTR_ERR(us); ++ uac_iad.iFunction = us[STR_AC_IF].id; + ac_interface_desc.iInterface = us[STR_AC_IF].id; +- input_terminal_desc.iTerminal = us[STR_INPUT_TERMINAL].id; +- input_terminal_desc.iChannelNames = us[STR_INPUT_TERMINAL_CH_NAMES].id; +- feature_unit_desc.iFeature = us[STR_FEAT_DESC_0].id; +- output_terminal_desc.iTerminal = us[STR_OUTPUT_TERMINAL].id; +- as_interface_alt_0_desc.iInterface = us[STR_AS_IF_ALT0].id; +- as_interface_alt_1_desc.iInterface = us[STR_AS_IF_ALT1].id; ++ usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id; ++ usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id; ++ io_out_ot_desc.iTerminal = us[STR_IO_OUT_OT].id; ++ as_out_interface_alt_0_desc.iInterface = us[STR_AS_OUT_IF_ALT0].id; ++ as_out_interface_alt_1_desc.iInterface = us[STR_AS_OUT_IF_ALT1].id; ++ io_in_it_desc.iTerminal = us[STR_IO_IN_IT].id; ++ io_in_it_desc.iChannelNames = us[STR_IO_IN_IT_CH_NAMES].id; ++ usb_in_ot_desc.iTerminal = us[STR_USB_IN_OT].id; ++ as_in_interface_alt_0_desc.iInterface = us[STR_AS_IN_IF_ALT0].id; ++ as_in_interface_alt_1_desc.iInterface = us[STR_AS_IN_IF_ALT1].id; + ++ /* Set channel numbers */ ++ usb_out_it_desc.bNrChannels = num_channels(audio_opts->c_chmask); ++ usb_out_it_desc.wChannelConfig = cpu_to_le16(audio_opts->c_chmask); ++ as_out_type_i_desc.bNrChannels = num_channels(audio_opts->c_chmask); ++ as_out_type_i_desc.bSubframeSize = audio_opts->c_ssize; ++ as_out_type_i_desc.bBitResolution = audio_opts->c_ssize * 8; ++ io_in_it_desc.bNrChannels = num_channels(audio_opts->p_chmask); ++ io_in_it_desc.wChannelConfig = cpu_to_le16(audio_opts->p_chmask); ++ as_in_type_i_desc.bNrChannels = num_channels(audio_opts->p_chmask); ++ as_in_type_i_desc.bSubframeSize = audio_opts->p_ssize; ++ as_in_type_i_desc.bBitResolution = audio_opts->p_ssize * 8; + +- f_audio_build_desc(audio); ++ /* Set sample rates */ ++ rate = audio_opts->c_srate; ++ sam_freq = as_out_type_i_desc.tSamFreq[0]; ++ memcpy(sam_freq, &rate, 3); ++ rate = audio_opts->p_srate; ++ sam_freq = as_in_type_i_desc.tSamFreq[0]; ++ memcpy(sam_freq, &rate, 3); + + /* allocate instance-specific interface IDs, and patch descriptors */ + status = usb_interface_id(c, f); + if (status < 0) + goto fail; ++ uac_iad.bFirstInterface = status; + ac_interface_desc.bInterfaceNumber = status; ++ uac1->ac_intf = status; ++ uac1->ac_alt = 0; ++ ++ status = usb_interface_id(c, f); ++ if (status < 0) ++ goto fail; ++ as_out_interface_alt_0_desc.bInterfaceNumber = status; ++ as_out_interface_alt_1_desc.bInterfaceNumber = status; ++ ac_header_desc.baInterfaceNr[0] = status; ++ uac1->as_out_intf = status; ++ uac1->as_out_alt = 0; + + status = usb_interface_id(c, f); + if (status < 0) + goto fail; +- as_interface_alt_0_desc.bInterfaceNumber = status; +- as_interface_alt_1_desc.bInterfaceNumber = status; ++ as_in_interface_alt_0_desc.bInterfaceNumber = status; ++ as_in_interface_alt_1_desc.bInterfaceNumber = status; ++ ac_header_desc.baInterfaceNr[1] = status; ++ uac1->as_in_intf = status; ++ uac1->as_in_alt = 0; ++ ++ audio->gadget = gadget; + + status = -ENODEV; + +@@ -718,51 +645,41 @@ + audio->out_ep = ep; + audio->out_ep->desc = &as_out_ep_desc; + +- status = -ENOMEM; ++ ep = usb_ep_autoconfig(cdev->gadget, &as_in_ep_desc); ++ if (!ep) ++ goto fail; ++ audio->in_ep = ep; ++ audio->in_ep->desc = &as_in_ep_desc; + + /* copy descriptors, and track endpoint copies */ +- status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, +- NULL); ++ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, ++ f_audio_ss_desc, NULL); + if (status) + goto fail; +- return 0; +- +-fail: +- gaudio_cleanup(&audio->card); +- return status; +-} + +-/*-------------------------------------------------------------------------*/ ++ audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize); ++ audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); ++ audio->params.c_chmask = audio_opts->c_chmask; ++ audio->params.c_srate = audio_opts->c_srate; ++ audio->params.c_ssize = audio_opts->c_ssize; ++ audio->params.p_chmask = audio_opts->p_chmask; ++ audio->params.p_srate = audio_opts->p_srate; ++ audio->params.p_ssize = audio_opts->p_ssize; ++ audio->params.req_number = audio_opts->req_number; + +-static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) +-{ +- con->data[cmd] = value; ++ status = g_audio_setup(audio, "UAC1_PCM", "UAC1_Gadget"); ++ if (status) ++ goto err_card_register; + + return 0; +-} + +-static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) +-{ +- return con->data[cmd]; ++err_card_register: ++ usb_free_all_descriptors(f); ++fail: ++ return status; + } + +-/* Todo: add more control selecotor dynamically */ +-static int control_selector_init(struct f_audio *audio) +-{ +- INIT_LIST_HEAD(&audio->cs); +- list_add(&feature_unit.list, &audio->cs); +- +- INIT_LIST_HEAD(&feature_unit.control); +- list_add(&mute_control.list, &feature_unit.control); +- list_add(&volume_control.list, &feature_unit.control); +- +- volume_control.data[UAC__CUR] = 0xffc0; +- volume_control.data[UAC__MIN] = 0xe3a0; +- volume_control.data[UAC__MAX] = 0xfff0; +- volume_control.data[UAC__RES] = 0x0030; +- +- return 0; +-} ++/*-------------------------------------------------------------------------*/ + + static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item) + { +@@ -781,9 +698,10 @@ + .release = f_uac1_attr_release, + }; + +-#define UAC1_INT_ATTRIBUTE(name) \ +-static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ +- char *page) \ ++#define UAC1_ATTRIBUTE(name) \ ++static ssize_t f_uac1_opts_##name##_show( \ ++ struct config_item *item, \ ++ char *page) \ + { \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ + int result; \ +@@ -795,7 +713,8 @@ + return result; \ + } \ + \ +-static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ ++static ssize_t f_uac1_opts_##name##_store( \ ++ struct config_item *item, \ + const char *page, size_t len) \ + { \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ +@@ -822,64 +741,22 @@ + \ + CONFIGFS_ATTR(f_uac1_opts_, name) + +-UAC1_INT_ATTRIBUTE(req_buf_size); +-UAC1_INT_ATTRIBUTE(req_count); +-UAC1_INT_ATTRIBUTE(audio_buf_size); +- +-#define UAC1_STR_ATTRIBUTE(name) \ +-static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ +- char *page) \ +-{ \ +- struct f_uac1_opts *opts = to_f_uac1_opts(item); \ +- int result; \ +- \ +- mutex_lock(&opts->lock); \ +- result = sprintf(page, "%s\n", opts->name); \ +- mutex_unlock(&opts->lock); \ +- \ +- return result; \ +-} \ +- \ +-static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ +- const char *page, size_t len) \ +-{ \ +- struct f_uac1_opts *opts = to_f_uac1_opts(item); \ +- int ret = -EBUSY; \ +- char *tmp; \ +- \ +- mutex_lock(&opts->lock); \ +- if (opts->refcnt) \ +- goto end; \ +- \ +- tmp = kstrndup(page, len, GFP_KERNEL); \ +- if (tmp) { \ +- ret = -ENOMEM; \ +- goto end; \ +- } \ +- if (opts->name##_alloc) \ +- kfree(opts->name); \ +- opts->name##_alloc = true; \ +- opts->name = tmp; \ +- ret = len; \ +- \ +-end: \ +- mutex_unlock(&opts->lock); \ +- return ret; \ +-} \ +- \ +-CONFIGFS_ATTR(f_uac1_opts_, name) +- +-UAC1_STR_ATTRIBUTE(fn_play); +-UAC1_STR_ATTRIBUTE(fn_cap); +-UAC1_STR_ATTRIBUTE(fn_cntl); ++UAC1_ATTRIBUTE(c_chmask); ++UAC1_ATTRIBUTE(c_srate); ++UAC1_ATTRIBUTE(c_ssize); ++UAC1_ATTRIBUTE(p_chmask); ++UAC1_ATTRIBUTE(p_srate); ++UAC1_ATTRIBUTE(p_ssize); ++UAC1_ATTRIBUTE(req_number); + + static struct configfs_attribute *f_uac1_attrs[] = { +- &f_uac1_opts_attr_req_buf_size, +- &f_uac1_opts_attr_req_count, +- &f_uac1_opts_attr_audio_buf_size, +- &f_uac1_opts_attr_fn_play, +- &f_uac1_opts_attr_fn_cap, +- &f_uac1_opts_attr_fn_cntl, ++ &f_uac1_opts_attr_c_chmask, ++ &f_uac1_opts_attr_c_srate, ++ &f_uac1_opts_attr_c_ssize, ++ &f_uac1_opts_attr_p_chmask, ++ &f_uac1_opts_attr_p_srate, ++ &f_uac1_opts_attr_p_ssize, ++ &f_uac1_opts_attr_req_number, + NULL, + }; + +@@ -894,12 +771,6 @@ + struct f_uac1_opts *opts; + + opts = container_of(f, struct f_uac1_opts, func_inst); +- if (opts->fn_play_alloc) +- kfree(opts->fn_play); +- if (opts->fn_cap_alloc) +- kfree(opts->fn_cap); +- if (opts->fn_cntl_alloc) +- kfree(opts->fn_cntl); + kfree(opts); + } + +@@ -917,21 +788,22 @@ + config_group_init_type_name(&opts->func_inst.group, "", + &f_uac1_func_type); + +- opts->req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE; +- opts->req_count = UAC1_REQ_COUNT; +- opts->audio_buf_size = UAC1_AUDIO_BUF_SIZE; +- opts->fn_play = FILE_PCM_PLAYBACK; +- opts->fn_cap = FILE_PCM_CAPTURE; +- opts->fn_cntl = FILE_CONTROL; ++ opts->c_chmask = UAC1_DEF_CCHMASK; ++ opts->c_srate = UAC1_DEF_CSRATE; ++ opts->c_ssize = UAC1_DEF_CSSIZE; ++ opts->p_chmask = UAC1_DEF_PCHMASK; ++ opts->p_srate = UAC1_DEF_PSRATE; ++ opts->p_ssize = UAC1_DEF_PSSIZE; ++ opts->req_number = UAC1_DEF_REQ_NUM; + return &opts->func_inst; + } + + static void f_audio_free(struct usb_function *f) + { +- struct f_audio *audio = func_to_audio(f); ++ struct g_audio *audio; + struct f_uac1_opts *opts; + +- gaudio_cleanup(&audio->card); ++ audio = func_to_g_audio(f); + opts = container_of(f->fi, struct f_uac1_opts, func_inst); + kfree(audio); + mutex_lock(&opts->lock); +@@ -941,42 +813,41 @@ + + static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) + { ++ struct g_audio *audio = func_to_g_audio(f); ++ ++ g_audio_cleanup(audio); + usb_free_all_descriptors(f); ++ ++ audio->gadget = NULL; + } + + static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) + { +- struct f_audio *audio; ++ struct f_uac1 *uac1; + struct f_uac1_opts *opts; + + /* allocate and initialize one new instance */ +- audio = kzalloc(sizeof(*audio), GFP_KERNEL); +- if (!audio) ++ uac1 = kzalloc(sizeof(*uac1), GFP_KERNEL); ++ if (!uac1) + return ERR_PTR(-ENOMEM); + +- audio->card.func.name = "g_audio"; +- + opts = container_of(fi, struct f_uac1_opts, func_inst); + mutex_lock(&opts->lock); + ++opts->refcnt; + mutex_unlock(&opts->lock); +- INIT_LIST_HEAD(&audio->play_queue); +- spin_lock_init(&audio->lock); +- +- audio->card.func.bind = f_audio_bind; +- audio->card.func.unbind = f_audio_unbind; +- audio->card.func.set_alt = f_audio_set_alt; +- audio->card.func.setup = f_audio_setup; +- audio->card.func.disable = f_audio_disable; +- audio->card.func.free_func = f_audio_free; +- +- control_selector_init(audio); + +- INIT_WORK(&audio->playback_work, f_audio_playback_work); ++ uac1->g_audio.func.name = "uac1_func"; ++ uac1->g_audio.func.bind = f_audio_bind; ++ uac1->g_audio.func.unbind = f_audio_unbind; ++ uac1->g_audio.func.set_alt = f_audio_set_alt; ++ uac1->g_audio.func.get_alt = f_audio_get_alt; ++ uac1->g_audio.func.setup = f_audio_setup; ++ uac1->g_audio.func.disable = f_audio_disable; ++ uac1->g_audio.func.free_func = f_audio_free; + +- return &audio->card.func; ++ return &uac1->g_audio.func; + } + + DECLARE_USB_FUNCTION_INIT(uac1, f_audio_alloc_inst, f_audio_alloc); + MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Bryan Wu"); ++MODULE_AUTHOR("Ruslan Bilovol"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac1_legacy.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac1_legacy.c.patch new file mode 100644 index 00000000..631ef046 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac1_legacy.c.patch @@ -0,0 +1,1023 @@ +--- linux-4.9.37/drivers/usb/gadget/function/f_uac1_legacy.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/f_uac1_legacy.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,1020 @@ ++/* ++ * f_audio.c -- USB Audio class function driver ++ * ++ * Copyright (C) 2008 Bryan Wu ++ * Copyright (C) 2008 Analog Devices, Inc ++ * ++ * Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * Licensed under the GPL-2 or later. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include "u_uac1_legacy.h" ++ ++static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); ++static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); ++ ++/* ++ * DESCRIPTORS ... most are static, but strings and full ++ * configuration descriptors are built on demand. ++ */ ++ ++/* ++ * We have two interfaces- AudioControl and AudioStreaming ++ * TODO: only supcard playback currently ++ */ ++#define F_AUDIO_AC_INTERFACE 0 ++#define F_AUDIO_AS_INTERFACE 1 ++#define F_AUDIO_NUM_INTERFACES 1 ++ ++/* B.3.1 Standard AC Interface Descriptor */ ++static struct usb_interface_descriptor ac_interface_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bNumEndpoints = 0, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, ++}; ++ ++/* ++ * The number of AudioStreaming and MIDIStreaming interfaces ++ * in the Audio Interface Collection ++ */ ++DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); ++ ++#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) ++/* 1 input terminal, 1 output terminal and 1 feature unit */ ++#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ ++ + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) ++/* B.3.2 Class-Specific AC Interface Descriptor */ ++static struct uac1_ac_header_descriptor_1 ac_header_desc = { ++ .bLength = UAC_DT_AC_HEADER_LENGTH, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_HEADER, ++ .bcdADC = __constant_cpu_to_le16(0x0100), ++ .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), ++ .bInCollection = F_AUDIO_NUM_INTERFACES, ++ .baInterfaceNr = { ++ /* Interface number of the first AudioStream interface */ ++ [0] = 1, ++ } ++}; ++ ++#define INPUT_TERMINAL_ID 1 ++static struct uac_input_terminal_descriptor input_terminal_desc = { ++ .bLength = UAC_DT_INPUT_TERMINAL_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_INPUT_TERMINAL, ++ .bTerminalID = INPUT_TERMINAL_ID, ++ .wTerminalType = UAC_TERMINAL_STREAMING, ++ .bAssocTerminal = 0, ++ .wChannelConfig = 0x3, ++}; ++ ++DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); ++ ++#define FEATURE_UNIT_ID 2 ++static struct uac_feature_unit_descriptor_0 feature_unit_desc = { ++ .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_FEATURE_UNIT, ++ .bUnitID = FEATURE_UNIT_ID, ++ .bSourceID = INPUT_TERMINAL_ID, ++ .bControlSize = 2, ++ .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), ++}; ++ ++static struct usb_audio_control mute_control = { ++ .list = LIST_HEAD_INIT(mute_control.list), ++ .name = "Mute Control", ++ .type = UAC_FU_MUTE, ++ /* Todo: add real Mute control code */ ++ .set = generic_set_cmd, ++ .get = generic_get_cmd, ++}; ++ ++static struct usb_audio_control volume_control = { ++ .list = LIST_HEAD_INIT(volume_control.list), ++ .name = "Volume Control", ++ .type = UAC_FU_VOLUME, ++ /* Todo: add real Volume control code */ ++ .set = generic_set_cmd, ++ .get = generic_get_cmd, ++}; ++ ++static struct usb_audio_control_selector feature_unit = { ++ .list = LIST_HEAD_INIT(feature_unit.list), ++ .id = FEATURE_UNIT_ID, ++ .name = "Mute & Volume Control", ++ .type = UAC_FEATURE_UNIT, ++ .desc = (struct usb_descriptor_header *)&feature_unit_desc, ++}; ++ ++#define OUTPUT_TERMINAL_ID 3 ++static struct uac1_output_terminal_descriptor output_terminal_desc = { ++ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, ++ .bTerminalID = OUTPUT_TERMINAL_ID, ++ .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER, ++ .bAssocTerminal = FEATURE_UNIT_ID, ++ .bSourceID = FEATURE_UNIT_ID, ++}; ++ ++/* B.4.1 Standard AS Interface Descriptor */ ++static struct usb_interface_descriptor as_interface_alt_0_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bAlternateSetting = 0, ++ .bNumEndpoints = 0, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, ++}; ++ ++static struct usb_interface_descriptor as_interface_alt_1_desc = { ++ .bLength = USB_DT_INTERFACE_SIZE, ++ .bDescriptorType = USB_DT_INTERFACE, ++ .bAlternateSetting = 1, ++ .bNumEndpoints = 1, ++ .bInterfaceClass = USB_CLASS_AUDIO, ++ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, ++}; ++ ++/* B.4.2 Class-Specific AS Interface Descriptor */ ++static struct uac1_as_header_descriptor as_header_desc = { ++ .bLength = UAC_DT_AS_HEADER_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_AS_GENERAL, ++ .bTerminalLink = INPUT_TERMINAL_ID, ++ .bDelay = 1, ++ .wFormatTag = UAC_FORMAT_TYPE_I_PCM, ++}; ++ ++DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); ++ ++static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { ++ .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubtype = UAC_FORMAT_TYPE, ++ .bFormatType = UAC_FORMAT_TYPE_I, ++ .bSubframeSize = 2, ++ .bBitResolution = 16, ++ .bSamFreqType = 1, ++}; ++ ++/* Standard ISO OUT Endpoint Descriptor */ ++static struct usb_endpoint_descriptor as_out_ep_desc = { ++ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, ++ .bDescriptorType = USB_DT_ENDPOINT, ++ .bEndpointAddress = USB_DIR_OUT, ++ .bmAttributes = USB_ENDPOINT_SYNC_ADAPTIVE ++ | USB_ENDPOINT_XFER_ISOC, ++ .wMaxPacketSize = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), ++ .bInterval = 4, ++}; ++ ++/* Class-specific AS ISO OUT Endpoint Descriptor */ ++static struct uac_iso_endpoint_descriptor as_iso_out_desc = { ++ .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, ++ .bDescriptorType = USB_DT_CS_ENDPOINT, ++ .bDescriptorSubtype = UAC_EP_GENERAL, ++ .bmAttributes = 1, ++ .bLockDelayUnits = 1, ++ .wLockDelay = __constant_cpu_to_le16(1), ++}; ++ ++static struct usb_descriptor_header *f_audio_desc[] = { ++ (struct usb_descriptor_header *)&ac_interface_desc, ++ (struct usb_descriptor_header *)&ac_header_desc, ++ ++ (struct usb_descriptor_header *)&input_terminal_desc, ++ (struct usb_descriptor_header *)&output_terminal_desc, ++ (struct usb_descriptor_header *)&feature_unit_desc, ++ ++ (struct usb_descriptor_header *)&as_interface_alt_0_desc, ++ (struct usb_descriptor_header *)&as_interface_alt_1_desc, ++ (struct usb_descriptor_header *)&as_header_desc, ++ ++ (struct usb_descriptor_header *)&as_type_i_desc, ++ ++ (struct usb_descriptor_header *)&as_out_ep_desc, ++ (struct usb_descriptor_header *)&as_iso_out_desc, ++ NULL, ++}; ++ ++enum { ++ STR_AC_IF, ++ STR_INPUT_TERMINAL, ++ STR_INPUT_TERMINAL_CH_NAMES, ++ STR_FEAT_DESC_0, ++ STR_OUTPUT_TERMINAL, ++ STR_AS_IF_ALT0, ++ STR_AS_IF_ALT1, ++}; ++ ++static struct usb_string strings_uac1[] = { ++ [STR_AC_IF].s = "AC Interface", ++ [STR_INPUT_TERMINAL].s = "Input terminal", ++ [STR_INPUT_TERMINAL_CH_NAMES].s = "Channels", ++ [STR_FEAT_DESC_0].s = "Volume control & mute", ++ [STR_OUTPUT_TERMINAL].s = "Output terminal", ++ [STR_AS_IF_ALT0].s = "AS Interface", ++ [STR_AS_IF_ALT1].s = "AS Interface", ++ { }, ++}; ++ ++static struct usb_gadget_strings str_uac1 = { ++ .language = 0x0409, /* en-us */ ++ .strings = strings_uac1, ++}; ++ ++static struct usb_gadget_strings *uac1_strings[] = { ++ &str_uac1, ++ NULL, ++}; ++ ++/* ++ * This function is an ALSA sound card following USB Audio Class Spec 1.0. ++ */ ++ ++/*-------------------------------------------------------------------------*/ ++struct f_audio_buf { ++ u8 *buf; ++ int actual; ++ struct list_head list; ++}; ++ ++static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) ++{ ++ struct f_audio_buf *copy_buf; ++ ++ copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); ++ if (!copy_buf) ++ return ERR_PTR(-ENOMEM); ++ ++ copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); ++ if (!copy_buf->buf) { ++ kfree(copy_buf); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ return copy_buf; ++} ++ ++static void f_audio_buffer_free(struct f_audio_buf *audio_buf) ++{ ++ kfree(audio_buf->buf); ++ kfree(audio_buf); ++} ++/*-------------------------------------------------------------------------*/ ++ ++struct f_audio { ++ struct gaudio card; ++ ++ u8 ac_intf, ac_alt; ++ u8 as_intf, as_alt; ++ ++ /* endpoints handle full and/or high speeds */ ++ struct usb_ep *out_ep; ++ ++ spinlock_t lock; ++ struct f_audio_buf *copy_buf; ++ struct work_struct playback_work; ++ struct list_head play_queue; ++ ++ /* Control Set command */ ++ struct list_head cs; ++ u8 set_cmd; ++ struct usb_audio_control *set_con; ++}; ++ ++static inline struct f_audio *func_to_audio(struct usb_function *f) ++{ ++ return container_of(f, struct f_audio, card.func); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void f_audio_playback_work(struct work_struct *data) ++{ ++ struct f_audio *audio = container_of(data, struct f_audio, ++ playback_work); ++ struct f_audio_buf *play_buf; ++ ++ spin_lock_irq(&audio->lock); ++ if (list_empty(&audio->play_queue)) { ++ spin_unlock_irq(&audio->lock); ++ return; ++ } ++ play_buf = list_first_entry(&audio->play_queue, ++ struct f_audio_buf, list); ++ list_del(&play_buf->list); ++ spin_unlock_irq(&audio->lock); ++ ++ u_audio_playback(&audio->card, play_buf->buf, play_buf->actual); ++ f_audio_buffer_free(play_buf); ++} ++ ++static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct f_audio *audio = req->context; ++ struct usb_composite_dev *cdev = audio->card.func.config->cdev; ++ struct f_audio_buf *copy_buf = audio->copy_buf; ++ struct f_uac1_legacy_opts *opts; ++ int audio_buf_size; ++ int err; ++ ++ opts = container_of(audio->card.func.fi, struct f_uac1_legacy_opts, ++ func_inst); ++ audio_buf_size = opts->audio_buf_size; ++ ++ if (!copy_buf) ++ return -EINVAL; ++ ++ /* Copy buffer is full, add it to the play_queue */ ++ if (audio_buf_size - copy_buf->actual < req->actual) { ++ list_add_tail(©_buf->list, &audio->play_queue); ++ schedule_work(&audio->playback_work); ++ copy_buf = f_audio_buffer_alloc(audio_buf_size); ++ if (IS_ERR(copy_buf)) ++ return -ENOMEM; ++ } ++ ++ memcpy(copy_buf->buf + copy_buf->actual, req->buf, req->actual); ++ copy_buf->actual += req->actual; ++ audio->copy_buf = copy_buf; ++ ++ err = usb_ep_queue(ep, req, GFP_ATOMIC); ++ if (err) ++ ERROR(cdev, "%s queue req: %d\n", ep->name, err); ++ ++ return 0; ++ ++} ++ ++static void f_audio_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ struct f_audio *audio = req->context; ++ int status = req->status; ++ u32 data = 0; ++ struct usb_ep *out_ep = audio->out_ep; ++ ++ switch (status) { ++ ++ case 0: /* normal completion? */ ++ if (ep == out_ep) ++ f_audio_out_ep_complete(ep, req); ++ else if (audio->set_con) { ++ memcpy(&data, req->buf, req->length); ++ audio->set_con->set(audio->set_con, audio->set_cmd, ++ le16_to_cpu(data)); ++ audio->set_con = NULL; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static int audio_set_intf_req(struct usb_function *f, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct f_audio *audio = func_to_audio(f); ++ struct usb_composite_dev *cdev = f->config->cdev; ++ struct usb_request *req = cdev->req; ++ u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); ++ u16 len = le16_to_cpu(ctrl->wLength); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ u8 con_sel = (w_value >> 8) & 0xFF; ++ u8 cmd = (ctrl->bRequest & 0x0F); ++ struct usb_audio_control_selector *cs; ++ struct usb_audio_control *con; ++ ++ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", ++ ctrl->bRequest, w_value, len, id); ++ ++ list_for_each_entry(cs, &audio->cs, list) { ++ if (cs->id == id) { ++ list_for_each_entry(con, &cs->control, list) { ++ if (con->type == con_sel) { ++ audio->set_con = con; ++ break; ++ } ++ } ++ break; ++ } ++ } ++ ++ audio->set_cmd = cmd; ++ req->context = audio; ++ req->complete = f_audio_complete; ++ ++ return len; ++} ++ ++static int audio_get_intf_req(struct usb_function *f, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct f_audio *audio = func_to_audio(f); ++ struct usb_composite_dev *cdev = f->config->cdev; ++ struct usb_request *req = cdev->req; ++ int value = -EOPNOTSUPP; ++ u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); ++ u16 len = le16_to_cpu(ctrl->wLength); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ u8 con_sel = (w_value >> 8) & 0xFF; ++ u8 cmd = (ctrl->bRequest & 0x0F); ++ struct usb_audio_control_selector *cs; ++ struct usb_audio_control *con; ++ ++ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", ++ ctrl->bRequest, w_value, len, id); ++ ++ list_for_each_entry(cs, &audio->cs, list) { ++ if (cs->id == id) { ++ list_for_each_entry(con, &cs->control, list) { ++ if (con->type == con_sel && con->get) { ++ value = con->get(con, cmd); ++ break; ++ } ++ } ++ break; ++ } ++ } ++ ++ req->context = audio; ++ req->complete = f_audio_complete; ++ len = min_t(size_t, sizeof(value), len); ++ memcpy(req->buf, &value, len); ++ ++ return len; ++} ++ ++static int audio_set_endpoint_req(struct usb_function *f, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct usb_composite_dev *cdev = f->config->cdev; ++ int value = -EOPNOTSUPP; ++ u16 ep = le16_to_cpu(ctrl->wIndex); ++ u16 len = le16_to_cpu(ctrl->wLength); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ ++ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ++ ctrl->bRequest, w_value, len, ep); ++ ++ switch (ctrl->bRequest) { ++ case UAC_SET_CUR: ++ value = len; ++ break; ++ ++ case UAC_SET_MIN: ++ break; ++ ++ case UAC_SET_MAX: ++ break; ++ ++ case UAC_SET_RES: ++ break; ++ ++ case UAC_SET_MEM: ++ break; ++ ++ default: ++ break; ++ } ++ ++ return value; ++} ++ ++static int audio_get_endpoint_req(struct usb_function *f, ++ const struct usb_ctrlrequest *ctrl) ++{ ++ struct usb_composite_dev *cdev = f->config->cdev; ++ int value = -EOPNOTSUPP; ++ u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); ++ u16 len = le16_to_cpu(ctrl->wLength); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ ++ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ++ ctrl->bRequest, w_value, len, ep); ++ ++ switch (ctrl->bRequest) { ++ case UAC_GET_CUR: ++ case UAC_GET_MIN: ++ case UAC_GET_MAX: ++ case UAC_GET_RES: ++ value = len; ++ break; ++ case UAC_GET_MEM: ++ break; ++ default: ++ break; ++ } ++ ++ return value; ++} ++ ++static int ++f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) ++{ ++ struct usb_composite_dev *cdev = f->config->cdev; ++ struct usb_request *req = cdev->req; ++ int value = -EOPNOTSUPP; ++ u16 w_index = le16_to_cpu(ctrl->wIndex); ++ u16 w_value = le16_to_cpu(ctrl->wValue); ++ u16 w_length = le16_to_cpu(ctrl->wLength); ++ ++ /* composite driver infrastructure handles everything; interface ++ * activation uses set_alt(). ++ */ ++ switch (ctrl->bRequestType) { ++ case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: ++ value = audio_set_intf_req(f, ctrl); ++ break; ++ ++ case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: ++ value = audio_get_intf_req(f, ctrl); ++ break; ++ ++ case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: ++ value = audio_set_endpoint_req(f, ctrl); ++ break; ++ ++ case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: ++ value = audio_get_endpoint_req(f, ctrl); ++ break; ++ ++ default: ++ ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", ++ ctrl->bRequestType, ctrl->bRequest, ++ w_value, w_index, w_length); ++ } ++ ++ /* respond with data transfer or status phase? */ ++ if (value >= 0) { ++ DBG(cdev, "audio req%02x.%02x v%04x i%04x l%d\n", ++ ctrl->bRequestType, ctrl->bRequest, ++ w_value, w_index, w_length); ++ req->zero = 0; ++ req->length = value; ++ value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); ++ if (value < 0) ++ ERROR(cdev, "audio response on err %d\n", value); ++ } ++ ++ /* device either stalls (value < 0) or reports success */ ++ return value; ++} ++ ++static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) ++{ ++ struct f_audio *audio = func_to_audio(f); ++ struct usb_composite_dev *cdev = f->config->cdev; ++ struct usb_ep *out_ep = audio->out_ep; ++ struct usb_request *req; ++ struct f_uac1_legacy_opts *opts; ++ int req_buf_size, req_count, audio_buf_size; ++ int i = 0, err = 0; ++ ++ DBG(cdev, "intf %d, alt %d\n", intf, alt); ++ ++ opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst); ++ req_buf_size = opts->req_buf_size; ++ req_count = opts->req_count; ++ audio_buf_size = opts->audio_buf_size; ++ ++ /* No i/f has more than 2 alt settings */ ++ if (alt > 1) { ++ ERROR(cdev, "%s:%d Error!\n", __func__, __LINE__); ++ return -EINVAL; ++ } ++ ++ if (intf == audio->ac_intf) { ++ /* Control I/f has only 1 AltSetting - 0 */ ++ if (alt) { ++ ERROR(cdev, "%s:%d Error!\n", __func__, __LINE__); ++ return -EINVAL; ++ } ++ return 0; ++ } else if (intf == audio->as_intf) { ++ if (alt == 1) { ++ err = config_ep_by_speed(cdev->gadget, f, out_ep); ++ if (err) ++ return err; ++ ++ usb_ep_enable(out_ep); ++ audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); ++ if (IS_ERR(audio->copy_buf)) ++ return -ENOMEM; ++ ++ /* ++ * allocate a bunch of read buffers ++ * and queue them all at once. ++ */ ++ for (i = 0; i < req_count && err == 0; i++) { ++ req = usb_ep_alloc_request(out_ep, GFP_ATOMIC); ++ if (req) { ++ req->buf = kzalloc(req_buf_size, ++ GFP_ATOMIC); ++ if (req->buf) { ++ req->length = req_buf_size; ++ req->context = audio; ++ req->complete = ++ f_audio_complete; ++ err = usb_ep_queue(out_ep, ++ req, GFP_ATOMIC); ++ if (err) ++ ERROR(cdev, ++ "%s queue req: %d\n", ++ out_ep->name, err); ++ } else ++ err = -ENOMEM; ++ } else ++ err = -ENOMEM; ++ } ++ ++ } else { ++ struct f_audio_buf *copy_buf = audio->copy_buf; ++ if (copy_buf) { ++ list_add_tail(©_buf->list, ++ &audio->play_queue); ++ schedule_work(&audio->playback_work); ++ } ++ } ++ audio->as_alt = alt; ++ } ++ ++ return err; ++} ++ ++static int f_audio_get_alt(struct usb_function *f, unsigned intf) ++{ ++ struct f_audio *audio = func_to_audio(f); ++ struct usb_composite_dev *cdev = f->config->cdev; ++ ++ if (intf == audio->ac_intf) ++ return audio->ac_alt; ++ else if (intf == audio->as_intf) ++ return audio->as_alt; ++ else ++ ERROR(cdev, "%s:%d Invalid Interface %d!\n", ++ __func__, __LINE__, intf); ++ ++ return -EINVAL; ++} ++ ++static void f_audio_disable(struct usb_function *f) ++{ ++ return; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void f_audio_build_desc(struct f_audio *audio) ++{ ++ struct gaudio *card = &audio->card; ++ u8 *sam_freq; ++ int rate; ++ ++ /* Set channel numbers */ ++ input_terminal_desc.bNrChannels = u_audio_get_playback_channels(card); ++ as_type_i_desc.bNrChannels = u_audio_get_playback_channels(card); ++ ++ /* Set sample rates */ ++ rate = u_audio_get_playback_rate(card); ++ sam_freq = as_type_i_desc.tSamFreq[0]; ++ memcpy(sam_freq, &rate, 3); ++ ++ /* Todo: Set Sample bits and other parameters */ ++ ++ return; ++} ++ ++/* audio function driver setup/binding */ ++static int ++f_audio_bind(struct usb_configuration *c, struct usb_function *f) ++{ ++ struct usb_composite_dev *cdev = c->cdev; ++ struct f_audio *audio = func_to_audio(f); ++ struct usb_string *us; ++ int status; ++ struct usb_ep *ep = NULL; ++ struct f_uac1_legacy_opts *audio_opts; ++ ++ audio_opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst); ++ audio->card.gadget = c->cdev->gadget; ++ /* set up ASLA audio devices */ ++ if (!audio_opts->bound) { ++ status = gaudio_setup(&audio->card); ++ if (status < 0) ++ return status; ++ audio_opts->bound = true; ++ } ++ us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); ++ if (IS_ERR(us)) ++ return PTR_ERR(us); ++ ac_interface_desc.iInterface = us[STR_AC_IF].id; ++ input_terminal_desc.iTerminal = us[STR_INPUT_TERMINAL].id; ++ input_terminal_desc.iChannelNames = us[STR_INPUT_TERMINAL_CH_NAMES].id; ++ feature_unit_desc.iFeature = us[STR_FEAT_DESC_0].id; ++ output_terminal_desc.iTerminal = us[STR_OUTPUT_TERMINAL].id; ++ as_interface_alt_0_desc.iInterface = us[STR_AS_IF_ALT0].id; ++ as_interface_alt_1_desc.iInterface = us[STR_AS_IF_ALT1].id; ++ ++ ++ f_audio_build_desc(audio); ++ ++ /* allocate instance-specific interface IDs, and patch descriptors */ ++ status = usb_interface_id(c, f); ++ if (status < 0) ++ goto fail; ++ ac_interface_desc.bInterfaceNumber = status; ++ audio->ac_intf = status; ++ audio->ac_alt = 0; ++ ++ status = usb_interface_id(c, f); ++ if (status < 0) ++ goto fail; ++ as_interface_alt_0_desc.bInterfaceNumber = status; ++ as_interface_alt_1_desc.bInterfaceNumber = status; ++ audio->as_intf = status; ++ audio->as_alt = 0; ++ ++ status = -ENODEV; ++ ++ /* allocate instance-specific endpoints */ ++ ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); ++ if (!ep) ++ goto fail; ++ audio->out_ep = ep; ++ audio->out_ep->desc = &as_out_ep_desc; ++ ++ status = -ENOMEM; ++ ++ /* copy descriptors, and track endpoint copies */ ++ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, ++ NULL); ++ if (status) ++ goto fail; ++ return 0; ++ ++fail: ++ gaudio_cleanup(&audio->card); ++ return status; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) ++{ ++ con->data[cmd] = value; ++ ++ return 0; ++} ++ ++static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) ++{ ++ return con->data[cmd]; ++} ++ ++/* Todo: add more control selecotor dynamically */ ++static int control_selector_init(struct f_audio *audio) ++{ ++ INIT_LIST_HEAD(&audio->cs); ++ list_add(&feature_unit.list, &audio->cs); ++ ++ INIT_LIST_HEAD(&feature_unit.control); ++ list_add(&mute_control.list, &feature_unit.control); ++ list_add(&volume_control.list, &feature_unit.control); ++ ++ volume_control.data[UAC__CUR] = 0xffc0; ++ volume_control.data[UAC__MIN] = 0xe3a0; ++ volume_control.data[UAC__MAX] = 0xfff0; ++ volume_control.data[UAC__RES] = 0x0030; ++ ++ return 0; ++} ++ ++static inline ++struct f_uac1_legacy_opts *to_f_uac1_opts(struct config_item *item) ++{ ++ return container_of(to_config_group(item), struct f_uac1_legacy_opts, ++ func_inst.group); ++} ++ ++static void f_uac1_attr_release(struct config_item *item) ++{ ++ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); ++ ++ usb_put_function_instance(&opts->func_inst); ++} ++ ++static struct configfs_item_operations f_uac1_item_ops = { ++ .release = f_uac1_attr_release, ++}; ++ ++#define UAC1_INT_ATTRIBUTE(name) \ ++static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ ++ char *page) \ ++{ \ ++ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ ++ int result; \ ++ \ ++ mutex_lock(&opts->lock); \ ++ result = sprintf(page, "%u\n", opts->name); \ ++ mutex_unlock(&opts->lock); \ ++ \ ++ return result; \ ++} \ ++ \ ++static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ ++ const char *page, size_t len) \ ++{ \ ++ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ ++ int ret; \ ++ u32 num; \ ++ \ ++ mutex_lock(&opts->lock); \ ++ if (opts->refcnt) { \ ++ ret = -EBUSY; \ ++ goto end; \ ++ } \ ++ \ ++ ret = kstrtou32(page, 0, &num); \ ++ if (ret) \ ++ goto end; \ ++ \ ++ opts->name = num; \ ++ ret = len; \ ++ \ ++end: \ ++ mutex_unlock(&opts->lock); \ ++ return ret; \ ++} \ ++ \ ++CONFIGFS_ATTR(f_uac1_opts_, name) ++ ++UAC1_INT_ATTRIBUTE(req_buf_size); ++UAC1_INT_ATTRIBUTE(req_count); ++UAC1_INT_ATTRIBUTE(audio_buf_size); ++ ++#define UAC1_STR_ATTRIBUTE(name) \ ++static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ ++ char *page) \ ++{ \ ++ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ ++ int result; \ ++ \ ++ mutex_lock(&opts->lock); \ ++ result = sprintf(page, "%s\n", opts->name); \ ++ mutex_unlock(&opts->lock); \ ++ \ ++ return result; \ ++} \ ++ \ ++static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ ++ const char *page, size_t len) \ ++{ \ ++ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ ++ int ret = -EBUSY; \ ++ char *tmp; \ ++ \ ++ mutex_lock(&opts->lock); \ ++ if (opts->refcnt) \ ++ goto end; \ ++ \ ++ tmp = kstrndup(page, len, GFP_KERNEL); \ ++ if (tmp) { \ ++ ret = -ENOMEM; \ ++ goto end; \ ++ } \ ++ if (opts->name##_alloc) \ ++ kfree(opts->name); \ ++ opts->name##_alloc = true; \ ++ opts->name = tmp; \ ++ ret = len; \ ++ \ ++end: \ ++ mutex_unlock(&opts->lock); \ ++ return ret; \ ++} \ ++ \ ++CONFIGFS_ATTR(f_uac1_opts_, name) ++ ++UAC1_STR_ATTRIBUTE(fn_play); ++UAC1_STR_ATTRIBUTE(fn_cap); ++UAC1_STR_ATTRIBUTE(fn_cntl); ++ ++static struct configfs_attribute *f_uac1_attrs[] = { ++ &f_uac1_opts_attr_req_buf_size, ++ &f_uac1_opts_attr_req_count, ++ &f_uac1_opts_attr_audio_buf_size, ++ &f_uac1_opts_attr_fn_play, ++ &f_uac1_opts_attr_fn_cap, ++ &f_uac1_opts_attr_fn_cntl, ++ NULL, ++}; ++ ++static const struct config_item_type f_uac1_func_type = { ++ .ct_item_ops = &f_uac1_item_ops, ++ .ct_attrs = f_uac1_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static void f_audio_free_inst(struct usb_function_instance *f) ++{ ++ struct f_uac1_legacy_opts *opts; ++ ++ opts = container_of(f, struct f_uac1_legacy_opts, func_inst); ++ if (opts->fn_play_alloc) ++ kfree(opts->fn_play); ++ if (opts->fn_cap_alloc) ++ kfree(opts->fn_cap); ++ if (opts->fn_cntl_alloc) ++ kfree(opts->fn_cntl); ++ kfree(opts); ++} ++ ++static struct usb_function_instance *f_audio_alloc_inst(void) ++{ ++ struct f_uac1_legacy_opts *opts; ++ ++ opts = kzalloc(sizeof(*opts), GFP_KERNEL); ++ if (!opts) ++ return ERR_PTR(-ENOMEM); ++ ++ mutex_init(&opts->lock); ++ opts->func_inst.free_func_inst = f_audio_free_inst; ++ ++ config_group_init_type_name(&opts->func_inst.group, "", ++ &f_uac1_func_type); ++ ++ opts->req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE; ++ opts->req_count = UAC1_REQ_COUNT; ++ opts->audio_buf_size = UAC1_AUDIO_BUF_SIZE; ++ opts->fn_play = FILE_PCM_PLAYBACK; ++ opts->fn_cap = FILE_PCM_CAPTURE; ++ opts->fn_cntl = FILE_CONTROL; ++ return &opts->func_inst; ++} ++ ++static void f_audio_free(struct usb_function *f) ++{ ++ struct f_audio *audio = func_to_audio(f); ++ struct f_uac1_legacy_opts *opts; ++ ++ gaudio_cleanup(&audio->card); ++ opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst); ++ kfree(audio); ++ mutex_lock(&opts->lock); ++ --opts->refcnt; ++ mutex_unlock(&opts->lock); ++} ++ ++static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) ++{ ++ usb_free_all_descriptors(f); ++} ++ ++static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) ++{ ++ struct f_audio *audio; ++ struct f_uac1_legacy_opts *opts; ++ ++ /* allocate and initialize one new instance */ ++ audio = kzalloc(sizeof(*audio), GFP_KERNEL); ++ if (!audio) ++ return ERR_PTR(-ENOMEM); ++ ++ audio->card.func.name = "g_audio"; ++ ++ opts = container_of(fi, struct f_uac1_legacy_opts, func_inst); ++ mutex_lock(&opts->lock); ++ ++opts->refcnt; ++ mutex_unlock(&opts->lock); ++ INIT_LIST_HEAD(&audio->play_queue); ++ spin_lock_init(&audio->lock); ++ ++ audio->card.func.bind = f_audio_bind; ++ audio->card.func.unbind = f_audio_unbind; ++ audio->card.func.set_alt = f_audio_set_alt; ++ audio->card.func.get_alt = f_audio_get_alt; ++ audio->card.func.setup = f_audio_setup; ++ audio->card.func.disable = f_audio_disable; ++ audio->card.func.free_func = f_audio_free; ++ ++ control_selector_init(audio); ++ ++ INIT_WORK(&audio->playback_work, f_audio_playback_work); ++ ++ return &audio->card.func; ++} ++ ++DECLARE_USB_FUNCTION_INIT(uac1_legacy, f_audio_alloc_inst, f_audio_alloc); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Bryan Wu"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac2.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac2.c.patch new file mode 100644 index 00000000..c70003f8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uac2.c.patch @@ -0,0 +1,1398 @@ +--- linux-4.9.37/drivers/usb/gadget/function/f_uac2.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/f_uac2.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1,30 +1,19 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * f_uac2.c -- USB Audio Class 2.0 Function + * + * Copyright (C) 2011 + * Yadwinder Singh (yadi.brar01@gmail.com) + * Jaswinder Singh (jaswinder.singh@linaro.org) +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. + */ + + #include + #include +-#include + #include + +-#include +-#include +-#include +- ++#include "u_audio.h" + #include "u_uac2.h" + +-/* Keep everyone on toes */ +-#define USB_XFERS 2 +- + /* + * The driver implements a simple UAC_2 topology. + * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture +@@ -33,12 +22,8 @@ + * controlled by two clock sources : + * CLK_5 := c_srate, and CLK_6 := p_srate + */ +-#define USB_OUT_IT_ID 1 +-#define IO_IN_IT_ID 2 +-#define IO_OUT_OT_ID 3 +-#define USB_IN_OT_ID 4 +-#define USB_OUT_CLK_ID 5 +-#define USB_IN_CLK_ID 6 ++#define USB_OUT_CLK_ID (out_clk_src_desc.bClockID) ++#define USB_IN_CLK_ID (in_clk_src_desc.bClockID) + + #define CONTROL_ABSENT 0 + #define CONTROL_RDONLY 1 +@@ -54,504 +39,26 @@ + #define UNFLW_CTRL 8 + #define OVFLW_CTRL 10 + +-static const char *uac2_name = "snd_uac2"; +- +-struct uac2_req { +- struct uac2_rtd_params *pp; /* parent param */ +- struct usb_request *req; +-}; +- +-struct uac2_rtd_params { +- struct snd_uac2_chip *uac2; /* parent chip */ +- bool ep_enabled; /* if the ep is enabled */ +- /* Size of the ring buffer */ +- size_t dma_bytes; +- unsigned char *dma_area; +- +- struct snd_pcm_substream *ss; ++#define EPIN_EN(_opts) ((_opts)->p_chmask != 0) ++#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) + +- /* Ring buffer */ +- ssize_t hw_ptr; +- +- void *rbuf; +- +- size_t period_size; +- +- unsigned max_psize; +- struct uac2_req ureq[USB_XFERS]; +- +- spinlock_t lock; ++struct f_uac2 { ++ struct g_audio g_audio; ++ u8 ac_intf, as_in_intf, as_out_intf; ++ u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */ + }; + +-struct snd_uac2_chip { +- struct platform_device pdev; +- struct platform_driver pdrv; +- +- struct uac2_rtd_params p_prm; +- struct uac2_rtd_params c_prm; +- +- struct snd_card *card; +- struct snd_pcm *pcm; +- +- /* timekeeping for the playback endpoint */ +- unsigned int p_interval; +- unsigned int p_residue; +- +- /* pre-calculated values for playback iso completion */ +- unsigned int p_pktsize; +- unsigned int p_pktsize_residue; +- unsigned int p_framesize; +-}; +- +-#define BUFF_SIZE_MAX (PAGE_SIZE * 16) +-#define PRD_SIZE_MAX PAGE_SIZE +-#define MIN_PERIODS 4 +- +-static struct snd_pcm_hardware uac2_pcm_hardware = { +- .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER +- | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID +- | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, +- .rates = SNDRV_PCM_RATE_CONTINUOUS, +- .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX, +- .buffer_bytes_max = BUFF_SIZE_MAX, +- .period_bytes_max = PRD_SIZE_MAX, +- .periods_min = MIN_PERIODS, +-}; +- +-struct audio_dev { +- u8 ac_intf, ac_alt; +- u8 as_out_intf, as_out_alt; +- u8 as_in_intf, as_in_alt; +- +- struct usb_ep *in_ep, *out_ep; +- struct usb_function func; +- +- /* The ALSA Sound Card it represents on the USB-Client side */ +- struct snd_uac2_chip uac2; +-}; +- +-static inline +-struct audio_dev *func_to_agdev(struct usb_function *f) +-{ +- return container_of(f, struct audio_dev, func); +-} +- +-static inline +-struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u) ++static inline struct f_uac2 *func_to_uac2(struct usb_function *f) + { +- return container_of(u, struct audio_dev, uac2); ++ return container_of(f, struct f_uac2, g_audio.func); + } + + static inline +-struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p) +-{ +- return container_of(p, struct snd_uac2_chip, pdev); +-} +- +-static inline +-struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev) ++struct f_uac2_opts *g_audio_to_uac2_opts(struct g_audio *agdev) + { + return container_of(agdev->func.fi, struct f_uac2_opts, func_inst); + } + +-static inline +-uint num_channels(uint chanmask) +-{ +- uint num = 0; +- +- while (chanmask) { +- num += (chanmask & 1); +- chanmask >>= 1; +- } +- +- return num; +-} +- +-static void +-agdev_iso_complete(struct usb_ep *ep, struct usb_request *req) +-{ +- unsigned pending; +- unsigned long flags; +- unsigned int hw_ptr; +- bool update_alsa = false; +- int status = req->status; +- struct uac2_req *ur = req->context; +- struct snd_pcm_substream *substream; +- struct uac2_rtd_params *prm = ur->pp; +- struct snd_uac2_chip *uac2 = prm->uac2; +- +- /* i/f shutting down */ +- if (!prm->ep_enabled || req->status == -ESHUTDOWN) +- return; +- +- /* +- * We can't really do much about bad xfers. +- * Afterall, the ISOCH xfers could fail legitimately. +- */ +- if (status) +- pr_debug("%s: iso_complete status(%d) %d/%d\n", +- __func__, status, req->actual, req->length); +- +- substream = prm->ss; +- +- /* Do nothing if ALSA isn't active */ +- if (!substream) +- goto exit; +- +- spin_lock_irqsave(&prm->lock, flags); +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { +- /* +- * For each IN packet, take the quotient of the current data +- * rate and the endpoint's interval as the base packet size. +- * If there is a residue from this division, add it to the +- * residue accumulator. +- */ +- req->length = uac2->p_pktsize; +- uac2->p_residue += uac2->p_pktsize_residue; +- +- /* +- * Whenever there are more bytes in the accumulator than we +- * need to add one more sample frame, increase this packet's +- * size and decrease the accumulator. +- */ +- if (uac2->p_residue / uac2->p_interval >= uac2->p_framesize) { +- req->length += uac2->p_framesize; +- uac2->p_residue -= uac2->p_framesize * +- uac2->p_interval; +- } +- +- req->actual = req->length; +- } +- +- pending = prm->hw_ptr % prm->period_size; +- pending += req->actual; +- if (pending >= prm->period_size) +- update_alsa = true; +- +- hw_ptr = prm->hw_ptr; +- prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes; +- +- spin_unlock_irqrestore(&prm->lock, flags); +- +- /* Pack USB load in ALSA ring buffer */ +- pending = prm->dma_bytes - hw_ptr; +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { +- if (unlikely(pending < req->actual)) { +- memcpy(req->buf, prm->dma_area + hw_ptr, pending); +- memcpy(req->buf + pending, prm->dma_area, +- req->actual - pending); +- } else { +- memcpy(req->buf, prm->dma_area + hw_ptr, req->actual); +- } +- } else { +- if (unlikely(pending < req->actual)) { +- memcpy(prm->dma_area + hw_ptr, req->buf, pending); +- memcpy(prm->dma_area, req->buf + pending, +- req->actual - pending); +- } else { +- memcpy(prm->dma_area + hw_ptr, req->buf, req->actual); +- } +- } +- +-exit: +- if (usb_ep_queue(ep, req, GFP_ATOMIC)) +- dev_err(&uac2->pdev.dev, "%d Error!\n", __LINE__); +- +- if (update_alsa) +- snd_pcm_period_elapsed(substream); +- +- return; +-} +- +-static int +-uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +-{ +- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); +- struct uac2_rtd_params *prm; +- unsigned long flags; +- int err = 0; +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) +- prm = &uac2->p_prm; +- else +- prm = &uac2->c_prm; +- +- spin_lock_irqsave(&prm->lock, flags); +- +- /* Reset */ +- prm->hw_ptr = 0; +- +- switch (cmd) { +- case SNDRV_PCM_TRIGGER_START: +- case SNDRV_PCM_TRIGGER_RESUME: +- prm->ss = substream; +- break; +- case SNDRV_PCM_TRIGGER_STOP: +- case SNDRV_PCM_TRIGGER_SUSPEND: +- prm->ss = NULL; +- break; +- default: +- err = -EINVAL; +- } +- +- spin_unlock_irqrestore(&prm->lock, flags); +- +- /* Clear buffer after Play stops */ +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss) +- memset(prm->rbuf, 0, prm->max_psize * USB_XFERS); +- +- return err; +-} +- +-static snd_pcm_uframes_t uac2_pcm_pointer(struct snd_pcm_substream *substream) +-{ +- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); +- struct uac2_rtd_params *prm; +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) +- prm = &uac2->p_prm; +- else +- prm = &uac2->c_prm; +- +- return bytes_to_frames(substream->runtime, prm->hw_ptr); +-} +- +-static int uac2_pcm_hw_params(struct snd_pcm_substream *substream, +- struct snd_pcm_hw_params *hw_params) +-{ +- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); +- struct uac2_rtd_params *prm; +- int err; +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) +- prm = &uac2->p_prm; +- else +- prm = &uac2->c_prm; +- +- err = snd_pcm_lib_malloc_pages(substream, +- params_buffer_bytes(hw_params)); +- if (err >= 0) { +- prm->dma_bytes = substream->runtime->dma_bytes; +- prm->dma_area = substream->runtime->dma_area; +- prm->period_size = params_period_bytes(hw_params); +- } +- +- return err; +-} +- +-static int uac2_pcm_hw_free(struct snd_pcm_substream *substream) +-{ +- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); +- struct uac2_rtd_params *prm; +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) +- prm = &uac2->p_prm; +- else +- prm = &uac2->c_prm; +- +- prm->dma_area = NULL; +- prm->dma_bytes = 0; +- prm->period_size = 0; +- +- return snd_pcm_lib_free_pages(substream); +-} +- +-static int uac2_pcm_open(struct snd_pcm_substream *substream) +-{ +- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); +- struct snd_pcm_runtime *runtime = substream->runtime; +- struct audio_dev *audio_dev; +- struct f_uac2_opts *opts; +- int p_ssize, c_ssize; +- int p_srate, c_srate; +- int p_chmask, c_chmask; +- +- audio_dev = uac2_to_agdev(uac2); +- opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); +- p_ssize = opts->p_ssize; +- c_ssize = opts->c_ssize; +- p_srate = opts->p_srate; +- c_srate = opts->c_srate; +- p_chmask = opts->p_chmask; +- c_chmask = opts->c_chmask; +- uac2->p_residue = 0; +- +- runtime->hw = uac2_pcm_hardware; +- +- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { +- spin_lock_init(&uac2->p_prm.lock); +- runtime->hw.rate_min = p_srate; +- switch (p_ssize) { +- case 3: +- runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; +- break; +- case 4: +- runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; +- break; +- default: +- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; +- break; +- } +- runtime->hw.channels_min = num_channels(p_chmask); +- runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize +- / runtime->hw.periods_min; +- } else { +- spin_lock_init(&uac2->c_prm.lock); +- runtime->hw.rate_min = c_srate; +- switch (c_ssize) { +- case 3: +- runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; +- break; +- case 4: +- runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; +- break; +- default: +- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; +- break; +- } +- runtime->hw.channels_min = num_channels(c_chmask); +- runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize +- / runtime->hw.periods_min; +- } +- +- runtime->hw.rate_max = runtime->hw.rate_min; +- runtime->hw.channels_max = runtime->hw.channels_min; +- +- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); +- +- return 0; +-} +- +-/* ALSA cries without these function pointers */ +-static int uac2_pcm_null(struct snd_pcm_substream *substream) +-{ +- return 0; +-} +- +-static struct snd_pcm_ops uac2_pcm_ops = { +- .open = uac2_pcm_open, +- .close = uac2_pcm_null, +- .ioctl = snd_pcm_lib_ioctl, +- .hw_params = uac2_pcm_hw_params, +- .hw_free = uac2_pcm_hw_free, +- .trigger = uac2_pcm_trigger, +- .pointer = uac2_pcm_pointer, +- .prepare = uac2_pcm_null, +-}; +- +-static int snd_uac2_probe(struct platform_device *pdev) +-{ +- struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); +- struct snd_card *card; +- struct snd_pcm *pcm; +- struct audio_dev *audio_dev; +- struct f_uac2_opts *opts; +- int err; +- int p_chmask, c_chmask; +- +- audio_dev = uac2_to_agdev(uac2); +- opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); +- p_chmask = opts->p_chmask; +- c_chmask = opts->c_chmask; +- +- /* Choose any slot, with no id */ +- err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); +- if (err < 0) +- return err; +- +- uac2->card = card; +- +- /* +- * Create first PCM device +- * Create a substream only for non-zero channel streams +- */ +- err = snd_pcm_new(uac2->card, "UAC2 PCM", 0, +- p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm); +- if (err < 0) +- goto snd_fail; +- +- strcpy(pcm->name, "UAC2 PCM"); +- pcm->private_data = uac2; +- +- uac2->pcm = pcm; +- +- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac2_pcm_ops); +- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac2_pcm_ops); +- +- strcpy(card->driver, "UAC2_Gadget"); +- strcpy(card->shortname, "UAC2_Gadget"); +- sprintf(card->longname, "UAC2_Gadget %i", pdev->id); +- +- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, +- snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); +- +- err = snd_card_register(card); +- if (!err) { +- platform_set_drvdata(pdev, card); +- return 0; +- } +- +-snd_fail: +- snd_card_free(card); +- +- uac2->pcm = NULL; +- uac2->card = NULL; +- +- return err; +-} +- +-static int snd_uac2_remove(struct platform_device *pdev) +-{ +- struct snd_card *card = platform_get_drvdata(pdev); +- +- if (card) +- return snd_card_free(card); +- +- return 0; +-} +- +-static void snd_uac2_release(struct device *dev) +-{ +- dev_dbg(dev, "releasing '%s'\n", dev_name(dev)); +-} +- +-static int alsa_uac2_init(struct audio_dev *agdev) +-{ +- struct snd_uac2_chip *uac2 = &agdev->uac2; +- int err; +- +- uac2->pdrv.probe = snd_uac2_probe; +- uac2->pdrv.remove = snd_uac2_remove; +- uac2->pdrv.driver.name = uac2_name; +- +- uac2->pdev.id = 0; +- uac2->pdev.name = uac2_name; +- uac2->pdev.dev.release = snd_uac2_release; +- +- /* Register snd_uac2 driver */ +- err = platform_driver_register(&uac2->pdrv); +- if (err) +- return err; +- +- /* Register snd_uac2 device */ +- err = platform_device_register(&uac2->pdev); +- if (err) +- platform_driver_unregister(&uac2->pdrv); +- +- return err; +-} +- +-static void alsa_uac2_exit(struct audio_dev *agdev) +-{ +- struct snd_uac2_chip *uac2 = &agdev->uac2; +- +- platform_driver_unregister(&uac2->pdrv); +- platform_device_unregister(&uac2->pdev); +-} +- +- + /* --------- USB Function Interface ------------- */ + + enum { +@@ -627,7 +134,7 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC2_CLOCK_SOURCE, +- .bClockID = USB_IN_CLK_ID, ++ /* .bClockID = DYNAMIC */ + .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, + .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), + .bAssocTerminal = 0, +@@ -639,7 +146,7 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC2_CLOCK_SOURCE, +- .bClockID = USB_OUT_CLK_ID, ++ /* .bClockID = DYNAMIC */ + .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, + .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), + .bAssocTerminal = 0, +@@ -651,12 +158,12 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC_INPUT_TERMINAL, +- .bTerminalID = USB_OUT_IT_ID, ++ /* .bTerminalID = DYNAMIC */ + .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), + .bAssocTerminal = 0, +- .bCSourceID = USB_OUT_CLK_ID, ++ /* .bCSourceID = DYNAMIC */ + .iChannelNames = 0, +- .bmControls = (CONTROL_RDWR << COPY_CTRL), ++ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), + }; + + /* Input Terminal for I/O-In */ +@@ -665,12 +172,12 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC_INPUT_TERMINAL, +- .bTerminalID = IO_IN_IT_ID, ++ /* .bTerminalID = DYNAMIC */ + .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_UNDEFINED), + .bAssocTerminal = 0, +- .bCSourceID = USB_IN_CLK_ID, ++ /* .bCSourceID = DYNAMIC */ + .iChannelNames = 0, +- .bmControls = (CONTROL_RDWR << COPY_CTRL), ++ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), + }; + + /* Ouput Terminal for USB_IN */ +@@ -679,12 +186,12 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, +- .bTerminalID = USB_IN_OT_ID, ++ /* .bTerminalID = DYNAMIC */ + .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), + .bAssocTerminal = 0, +- .bSourceID = IO_IN_IT_ID, +- .bCSourceID = USB_IN_CLK_ID, +- .bmControls = (CONTROL_RDWR << COPY_CTRL), ++ /* .bSourceID = DYNAMIC */ ++ /* .bCSourceID = DYNAMIC */ ++ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), + }; + + /* Ouput Terminal for I/O-Out */ +@@ -693,12 +200,12 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, +- .bTerminalID = IO_OUT_OT_ID, ++ /* .bTerminalID = DYNAMIC */ + .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_UNDEFINED), + .bAssocTerminal = 0, +- .bSourceID = USB_OUT_IT_ID, +- .bCSourceID = USB_OUT_CLK_ID, +- .bmControls = (CONTROL_RDWR << COPY_CTRL), ++ /* .bSourceID = DYNAMIC */ ++ /* .bCSourceID = DYNAMIC */ ++ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), + }; + + static struct uac2_ac_header_descriptor ac_hdr_desc = { +@@ -708,9 +215,10 @@ + .bDescriptorSubtype = UAC_MS_HEADER, + .bcdADC = cpu_to_le16(0x200), + .bCategory = UAC2_FUNCTION_IO_BOX, +- .wTotalLength = sizeof in_clk_src_desc + sizeof out_clk_src_desc +- + sizeof usb_out_it_desc + sizeof io_in_it_desc +- + sizeof usb_in_ot_desc + sizeof io_out_ot_desc, ++ .wTotalLength = cpu_to_le16(sizeof in_clk_src_desc ++ + sizeof out_clk_src_desc + sizeof usb_out_it_desc ++ + sizeof io_in_it_desc + sizeof usb_in_ot_desc ++ + sizeof io_out_ot_desc), + .bmControls = 0, + }; + +@@ -744,7 +252,7 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC_AS_GENERAL, +- .bTerminalLink = USB_OUT_IT_ID, ++ /* .bTerminalLink = DYNAMIC */ + .bmControls = 0, + .bFormatType = UAC_FORMAT_TYPE_I, + .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM), +@@ -821,7 +329,7 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + + .bDescriptorSubtype = UAC_AS_GENERAL, +- .bTerminalLink = USB_IN_OT_ID, ++ /* .bTerminalLink = DYNAMIC */ + .bmControls = 0, + .bFormatType = UAC_FORMAT_TYPE_I, + .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM), +@@ -929,40 +437,16 @@ + }; + + struct cntrl_cur_lay3 { +- __u32 dCUR; ++ __le32 dCUR; + }; + + struct cntrl_range_lay3 { +- __u16 wNumSubRanges; +- __u32 dMIN; +- __u32 dMAX; +- __u32 dRES; ++ __le16 wNumSubRanges; ++ __le32 dMIN; ++ __le32 dMAX; ++ __le32 dRES; + } __packed; + +-static inline void +-free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep) +-{ +- struct snd_uac2_chip *uac2 = prm->uac2; +- int i; +- +- if (!prm->ep_enabled) +- return; +- +- prm->ep_enabled = false; +- +- for (i = 0; i < USB_XFERS; i++) { +- if (prm->ureq[i].req) { +- usb_ep_dequeue(ep, prm->ureq[i].req); +- usb_ep_free_request(ep, prm->ureq[i].req); +- prm->ureq[i].req = NULL; +- } +- } +- +- if (usb_ep_disable(ep)) +- dev_err(&uac2->pdev.dev, +- "%s:%d Error!\n", __func__, __LINE__); +-} +- + static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, + struct usb_endpoint_descriptor *ep_desc, + unsigned int factor, bool is_playback) +@@ -986,15 +470,133 @@ + le16_to_cpu(ep_desc->wMaxPacketSize))); + } + ++/* Use macro to overcome line length limitation */ ++#define USBDHDR(p) (struct usb_descriptor_header *)(p) ++ ++static void setup_descriptor(struct f_uac2_opts *opts) ++{ ++ /* patch descriptors */ ++ int i = 1; /* ID's start with 1 */ ++ ++ if (EPOUT_EN(opts)) ++ usb_out_it_desc.bTerminalID = i++; ++ if (EPIN_EN(opts)) ++ io_in_it_desc.bTerminalID = i++; ++ if (EPOUT_EN(opts)) ++ io_out_ot_desc.bTerminalID = i++; ++ if (EPIN_EN(opts)) ++ usb_in_ot_desc.bTerminalID = i++; ++ if (EPOUT_EN(opts)) ++ out_clk_src_desc.bClockID = i++; ++ if (EPIN_EN(opts)) ++ in_clk_src_desc.bClockID = i++; ++ ++ usb_out_it_desc.bCSourceID = out_clk_src_desc.bClockID; ++ usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; ++ usb_in_ot_desc.bCSourceID = in_clk_src_desc.bClockID; ++ io_in_it_desc.bCSourceID = in_clk_src_desc.bClockID; ++ io_out_ot_desc.bCSourceID = out_clk_src_desc.bClockID; ++ io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; ++ as_out_hdr_desc.bTerminalLink = usb_out_it_desc.bTerminalID; ++ as_in_hdr_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; ++ ++ iad_desc.bInterfaceCount = 1; ++ ac_hdr_desc.wTotalLength = 0; ++ ++ if (EPIN_EN(opts)) { ++ u16 len = le16_to_cpu(ac_hdr_desc.wTotalLength); ++ ++ len += sizeof(in_clk_src_desc); ++ len += sizeof(usb_in_ot_desc); ++ len += sizeof(io_in_it_desc); ++ ac_hdr_desc.wTotalLength = cpu_to_le16(len); ++ iad_desc.bInterfaceCount++; ++ } ++ if (EPOUT_EN(opts)) { ++ u16 len = le16_to_cpu(ac_hdr_desc.wTotalLength); ++ ++ len += sizeof(out_clk_src_desc); ++ len += sizeof(usb_out_it_desc); ++ len += sizeof(io_out_ot_desc); ++ ac_hdr_desc.wTotalLength = cpu_to_le16(len); ++ iad_desc.bInterfaceCount++; ++ } ++ ++ i = 0; ++ fs_audio_desc[i++] = USBDHDR(&iad_desc); ++ fs_audio_desc[i++] = USBDHDR(&std_ac_if_desc); ++ fs_audio_desc[i++] = USBDHDR(&ac_hdr_desc); ++ if (EPIN_EN(opts)) ++ fs_audio_desc[i++] = USBDHDR(&in_clk_src_desc); ++ if (EPOUT_EN(opts)) { ++ fs_audio_desc[i++] = USBDHDR(&out_clk_src_desc); ++ fs_audio_desc[i++] = USBDHDR(&usb_out_it_desc); ++ } ++ if (EPIN_EN(opts)) { ++ fs_audio_desc[i++] = USBDHDR(&io_in_it_desc); ++ fs_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); ++ } ++ if (EPOUT_EN(opts)) { ++ fs_audio_desc[i++] = USBDHDR(&io_out_ot_desc); ++ fs_audio_desc[i++] = USBDHDR(&std_as_out_if0_desc); ++ fs_audio_desc[i++] = USBDHDR(&std_as_out_if1_desc); ++ fs_audio_desc[i++] = USBDHDR(&as_out_hdr_desc); ++ fs_audio_desc[i++] = USBDHDR(&as_out_fmt1_desc); ++ fs_audio_desc[i++] = USBDHDR(&fs_epout_desc); ++ fs_audio_desc[i++] = USBDHDR(&as_iso_out_desc); ++ } ++ if (EPIN_EN(opts)) { ++ fs_audio_desc[i++] = USBDHDR(&std_as_in_if0_desc); ++ fs_audio_desc[i++] = USBDHDR(&std_as_in_if1_desc); ++ fs_audio_desc[i++] = USBDHDR(&as_in_hdr_desc); ++ fs_audio_desc[i++] = USBDHDR(&as_in_fmt1_desc); ++ fs_audio_desc[i++] = USBDHDR(&fs_epin_desc); ++ fs_audio_desc[i++] = USBDHDR(&as_iso_in_desc); ++ } ++ fs_audio_desc[i] = NULL; ++ ++ i = 0; ++ hs_audio_desc[i++] = USBDHDR(&iad_desc); ++ hs_audio_desc[i++] = USBDHDR(&std_ac_if_desc); ++ hs_audio_desc[i++] = USBDHDR(&ac_hdr_desc); ++ if (EPIN_EN(opts)) ++ hs_audio_desc[i++] = USBDHDR(&in_clk_src_desc); ++ if (EPOUT_EN(opts)) { ++ hs_audio_desc[i++] = USBDHDR(&out_clk_src_desc); ++ hs_audio_desc[i++] = USBDHDR(&usb_out_it_desc); ++ } ++ if (EPIN_EN(opts)) { ++ hs_audio_desc[i++] = USBDHDR(&io_in_it_desc); ++ hs_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); ++ } ++ if (EPOUT_EN(opts)) { ++ hs_audio_desc[i++] = USBDHDR(&io_out_ot_desc); ++ hs_audio_desc[i++] = USBDHDR(&std_as_out_if0_desc); ++ hs_audio_desc[i++] = USBDHDR(&std_as_out_if1_desc); ++ hs_audio_desc[i++] = USBDHDR(&as_out_hdr_desc); ++ hs_audio_desc[i++] = USBDHDR(&as_out_fmt1_desc); ++ hs_audio_desc[i++] = USBDHDR(&hs_epout_desc); ++ hs_audio_desc[i++] = USBDHDR(&as_iso_out_desc); ++ } ++ if (EPIN_EN(opts)) { ++ hs_audio_desc[i++] = USBDHDR(&std_as_in_if0_desc); ++ hs_audio_desc[i++] = USBDHDR(&std_as_in_if1_desc); ++ hs_audio_desc[i++] = USBDHDR(&as_in_hdr_desc); ++ hs_audio_desc[i++] = USBDHDR(&as_in_fmt1_desc); ++ hs_audio_desc[i++] = USBDHDR(&hs_epin_desc); ++ hs_audio_desc[i++] = USBDHDR(&as_iso_in_desc); ++ } ++ hs_audio_desc[i] = NULL; ++} ++ + static int + afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) + { +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; ++ struct f_uac2 *uac2 = func_to_uac2(fn); ++ struct g_audio *agdev = func_to_g_audio(fn); + struct usb_composite_dev *cdev = cfg->cdev; + struct usb_gadget *gadget = cdev->gadget; +- struct device *dev = &uac2->pdev.dev; +- struct uac2_rtd_params *prm; ++ struct device *dev = &gadget->dev; + struct f_uac2_opts *uac2_opts; + struct usb_string *us; + int ret; +@@ -1040,100 +642,103 @@ + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + return ret; + } +- std_ac_if_desc.bInterfaceNumber = ret; +- agdev->ac_intf = ret; +- agdev->ac_alt = 0; ++ iad_desc.bFirstInterface = ret; + +- ret = usb_interface_id(cfg, fn); +- if (ret < 0) { +- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); +- return ret; +- } +- std_as_out_if0_desc.bInterfaceNumber = ret; +- std_as_out_if1_desc.bInterfaceNumber = ret; +- agdev->as_out_intf = ret; +- agdev->as_out_alt = 0; +- +- ret = usb_interface_id(cfg, fn); +- if (ret < 0) { +- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); +- return ret; +- } +- std_as_in_if0_desc.bInterfaceNumber = ret; +- std_as_in_if1_desc.bInterfaceNumber = ret; +- agdev->as_in_intf = ret; +- agdev->as_in_alt = 0; ++ std_ac_if_desc.bInterfaceNumber = ret; ++ uac2->ac_intf = ret; ++ uac2->ac_alt = 0; + +- agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); +- if (!agdev->out_ep) { +- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); +- return ret; ++ if (EPOUT_EN(uac2_opts)) { ++ ret = usb_interface_id(cfg, fn); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ std_as_out_if0_desc.bInterfaceNumber = ret; ++ std_as_out_if1_desc.bInterfaceNumber = ret; ++ uac2->as_out_intf = ret; ++ uac2->as_out_alt = 0; + } + +- agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); +- if (!agdev->in_ep) { +- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); +- return ret; ++ if (EPIN_EN(uac2_opts)) { ++ ret = usb_interface_id(cfg, fn); ++ if (ret < 0) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return ret; ++ } ++ std_as_in_if0_desc.bInterfaceNumber = ret; ++ std_as_in_if1_desc.bInterfaceNumber = ret; ++ uac2->as_in_intf = ret; ++ uac2->as_in_alt = 0; + } + +- uac2->p_prm.uac2 = uac2; +- uac2->c_prm.uac2 = uac2; +- + /* Calculate wMaxPacketSize according to audio bandwidth */ + set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); + set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); + set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); + set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); + ++ if (EPOUT_EN(uac2_opts)) { ++ agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); ++ if (!agdev->out_ep) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return -ENODEV; ++ } ++ } ++ ++ if (EPIN_EN(uac2_opts)) { ++ agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); ++ if (!agdev->in_ep) { ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ return -ENODEV; ++ } ++ } ++ ++ agdev->in_ep_maxpsize = max_t(u16, ++ le16_to_cpu(fs_epin_desc.wMaxPacketSize), ++ le16_to_cpu(hs_epin_desc.wMaxPacketSize)); ++ agdev->out_ep_maxpsize = max_t(u16, ++ le16_to_cpu(fs_epout_desc.wMaxPacketSize), ++ le16_to_cpu(hs_epout_desc.wMaxPacketSize)); ++ + hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; + hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; + ++ setup_descriptor(uac2_opts); ++ + ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL, + NULL); + if (ret) + return ret; + +- prm = &agdev->uac2.c_prm; +- prm->max_psize = hs_epout_desc.wMaxPacketSize; +- prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); +- if (!prm->rbuf) { +- prm->max_psize = 0; +- goto err_free_descs; +- } +- +- prm = &agdev->uac2.p_prm; +- prm->max_psize = hs_epin_desc.wMaxPacketSize; +- prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); +- if (!prm->rbuf) { +- prm->max_psize = 0; +- goto err; +- } ++ agdev->gadget = gadget; + +- ret = alsa_uac2_init(agdev); ++ agdev->params.p_chmask = uac2_opts->p_chmask; ++ agdev->params.p_srate = uac2_opts->p_srate; ++ agdev->params.p_ssize = uac2_opts->p_ssize; ++ agdev->params.c_chmask = uac2_opts->c_chmask; ++ agdev->params.c_srate = uac2_opts->c_srate; ++ agdev->params.c_ssize = uac2_opts->c_ssize; ++ agdev->params.req_number = uac2_opts->req_number; ++ ret = g_audio_setup(agdev, "UAC2 PCM", "UAC2_Gadget"); + if (ret) +- goto err; ++ goto err_free_descs; + return 0; + +-err: +- kfree(agdev->uac2.p_prm.rbuf); +- kfree(agdev->uac2.c_prm.rbuf); + err_free_descs: + usb_free_all_descriptors(fn); +- return -EINVAL; ++ agdev->gadget = NULL; ++ return ret; + } + + static int + afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) + { + struct usb_composite_dev *cdev = fn->config->cdev; +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; ++ struct f_uac2 *uac2 = func_to_uac2(fn); + struct usb_gadget *gadget = cdev->gadget; +- struct device *dev = &uac2->pdev.dev; +- struct usb_request *req; +- struct usb_ep *ep; +- struct uac2_rtd_params *prm; +- int req_len, i; ++ struct device *dev = &gadget->dev; ++ int ret = 0; + + /* No i/f has more than 2 alt settings */ + if (alt > 1) { +@@ -1141,7 +746,7 @@ + return -EINVAL; + } + +- if (intf == agdev->ac_intf) { ++ if (intf == uac2->ac_intf) { + /* Control I/f has only 1 AltSetting - 0 */ + if (alt) { + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); +@@ -1150,96 +755,42 @@ + return 0; + } + +- if (intf == agdev->as_out_intf) { +- ep = agdev->out_ep; +- prm = &uac2->c_prm; +- config_ep_by_speed(gadget, fn, ep); +- agdev->as_out_alt = alt; +- req_len = prm->max_psize; +- } else if (intf == agdev->as_in_intf) { +- struct f_uac2_opts *opts = agdev_to_uac2_opts(agdev); +- unsigned int factor, rate; +- struct usb_endpoint_descriptor *ep_desc; +- +- ep = agdev->in_ep; +- prm = &uac2->p_prm; +- config_ep_by_speed(gadget, fn, ep); +- agdev->as_in_alt = alt; +- +- /* pre-calculate the playback endpoint's interval */ +- if (gadget->speed == USB_SPEED_FULL) { +- ep_desc = &fs_epin_desc; +- factor = 1000; +- } else { +- ep_desc = &hs_epin_desc; +- factor = 8000; +- } +- +- /* pre-compute some values for iso_complete() */ +- uac2->p_framesize = opts->p_ssize * +- num_channels(opts->p_chmask); +- rate = opts->p_srate * uac2->p_framesize; +- uac2->p_interval = factor / (1 << (ep_desc->bInterval - 1)); +- uac2->p_pktsize = min_t(unsigned int, rate / uac2->p_interval, +- prm->max_psize); ++ if (intf == uac2->as_out_intf) { ++ uac2->as_out_alt = alt; + +- if (uac2->p_pktsize < prm->max_psize) +- uac2->p_pktsize_residue = rate % uac2->p_interval; ++ if (alt) ++ ret = u_audio_start_capture(&uac2->g_audio); + else +- uac2->p_pktsize_residue = 0; ++ u_audio_stop_capture(&uac2->g_audio); ++ } else if (intf == uac2->as_in_intf) { ++ uac2->as_in_alt = alt; + +- req_len = uac2->p_pktsize; +- uac2->p_residue = 0; ++ if (alt) ++ ret = u_audio_start_playback(&uac2->g_audio); ++ else ++ u_audio_stop_playback(&uac2->g_audio); + } else { + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + return -EINVAL; + } + +- if (alt == 0) { +- free_ep(prm, ep); +- return 0; +- } +- +- prm->ep_enabled = true; +- usb_ep_enable(ep); +- +- for (i = 0; i < USB_XFERS; i++) { +- if (!prm->ureq[i].req) { +- req = usb_ep_alloc_request(ep, GFP_ATOMIC); +- if (req == NULL) +- return -ENOMEM; +- +- prm->ureq[i].req = req; +- prm->ureq[i].pp = prm; +- +- req->zero = 0; +- req->context = &prm->ureq[i]; +- req->length = req_len; +- req->complete = agdev_iso_complete; +- req->buf = prm->rbuf + i * prm->max_psize; +- } +- +- if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC)) +- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); +- } +- +- return 0; ++ return ret; + } + + static int + afunc_get_alt(struct usb_function *fn, unsigned intf) + { +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; ++ struct f_uac2 *uac2 = func_to_uac2(fn); ++ struct g_audio *agdev = func_to_g_audio(fn); + +- if (intf == agdev->ac_intf) +- return agdev->ac_alt; +- else if (intf == agdev->as_out_intf) +- return agdev->as_out_alt; +- else if (intf == agdev->as_in_intf) +- return agdev->as_in_alt; ++ if (intf == uac2->ac_intf) ++ return uac2->ac_alt; ++ else if (intf == uac2->as_out_intf) ++ return uac2->as_out_alt; ++ else if (intf == uac2->as_in_intf) ++ return uac2->as_in_alt; + else +- dev_err(&uac2->pdev.dev, ++ dev_err(&agdev->gadget->dev, + "%s:%d Invalid Interface %d!\n", + __func__, __LINE__, intf); + +@@ -1249,22 +800,19 @@ + static void + afunc_disable(struct usb_function *fn) + { +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; +- +- free_ep(&uac2->p_prm, agdev->in_ep); +- agdev->as_in_alt = 0; ++ struct f_uac2 *uac2 = func_to_uac2(fn); + +- free_ep(&uac2->c_prm, agdev->out_ep); +- agdev->as_out_alt = 0; ++ uac2->as_in_alt = 0; ++ uac2->as_out_alt = 0; ++ u_audio_stop_capture(&uac2->g_audio); ++ u_audio_stop_playback(&uac2->g_audio); + } + + static int + in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) + { + struct usb_request *req = fn->config->cdev->req; +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; ++ struct g_audio *agdev = func_to_g_audio(fn); + struct f_uac2_opts *opts; + u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); +@@ -1274,7 +822,7 @@ + int value = -EOPNOTSUPP; + int p_srate, c_srate; + +- opts = agdev_to_uac2_opts(agdev); ++ opts = g_audio_to_uac2_opts(agdev); + p_srate = opts->p_srate; + c_srate = opts->c_srate; + +@@ -1283,9 +831,9 @@ + memset(&c, 0, sizeof(struct cntrl_cur_lay3)); + + if (entity_id == USB_IN_CLK_ID) +- c.dCUR = p_srate; ++ c.dCUR = cpu_to_le32(p_srate); + else if (entity_id == USB_OUT_CLK_ID) +- c.dCUR = c_srate; ++ c.dCUR = cpu_to_le32(c_srate); + + value = min_t(unsigned, w_length, sizeof c); + memcpy(req->buf, &c, value); +@@ -1293,7 +841,7 @@ + *(u8 *)req->buf = 1; + value = min_t(unsigned, w_length, 1); + } else { +- dev_err(&uac2->pdev.dev, ++ dev_err(&agdev->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } +@@ -1305,8 +853,7 @@ + in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) + { + struct usb_request *req = fn->config->cdev->req; +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; ++ struct g_audio *agdev = func_to_g_audio(fn); + struct f_uac2_opts *opts; + u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); +@@ -1317,26 +864,26 @@ + int value = -EOPNOTSUPP; + int p_srate, c_srate; + +- opts = agdev_to_uac2_opts(agdev); ++ opts = g_audio_to_uac2_opts(agdev); + p_srate = opts->p_srate; + c_srate = opts->c_srate; + + if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { + if (entity_id == USB_IN_CLK_ID) +- r.dMIN = p_srate; ++ r.dMIN = cpu_to_le32(p_srate); + else if (entity_id == USB_OUT_CLK_ID) +- r.dMIN = c_srate; ++ r.dMIN = cpu_to_le32(c_srate); + else + return -EOPNOTSUPP; + + r.dMAX = r.dMIN; + r.dRES = 0; +- r.wNumSubRanges = 1; ++ r.wNumSubRanges = cpu_to_le16(1); + + value = min_t(unsigned, w_length, sizeof r); + memcpy(req->buf, &r, value); + } else { +- dev_err(&uac2->pdev.dev, ++ dev_err(&agdev->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } +@@ -1371,13 +918,13 @@ + static int + setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr) + { +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; ++ struct f_uac2 *uac2 = func_to_uac2(fn); ++ struct g_audio *agdev = func_to_g_audio(fn); + u16 w_index = le16_to_cpu(cr->wIndex); + u8 intf = w_index & 0xff; + +- if (intf != agdev->ac_intf) { +- dev_err(&uac2->pdev.dev, ++ if (intf != uac2->ac_intf) { ++ dev_err(&agdev->gadget->dev, + "%s:%d Error!\n", __func__, __LINE__); + return -EOPNOTSUPP; + } +@@ -1394,8 +941,7 @@ + afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) + { + struct usb_composite_dev *cdev = fn->config->cdev; +- struct audio_dev *agdev = func_to_agdev(fn); +- struct snd_uac2_chip *uac2 = &agdev->uac2; ++ struct g_audio *agdev = func_to_g_audio(fn); + struct usb_request *req = cdev->req; + u16 w_length = le16_to_cpu(cr->wLength); + int value = -EOPNOTSUPP; +@@ -1407,14 +953,15 @@ + if ((cr->bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE) + value = setup_rq_inf(fn, cr); + else +- dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); ++ dev_err(&agdev->gadget->dev, "%s:%d Error!\n", ++ __func__, __LINE__); + + if (value >= 0) { + req->length = value; + req->zero = value < w_length; + value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); + if (value < 0) { +- dev_err(&uac2->pdev.dev, ++ dev_err(&agdev->gadget->dev, + "%s:%d Error!\n", __func__, __LINE__); + req->status = 0; + } +@@ -1487,6 +1034,7 @@ + UAC2_ATTRIBUTE(c_chmask); + UAC2_ATTRIBUTE(c_srate); + UAC2_ATTRIBUTE(c_ssize); ++UAC2_ATTRIBUTE(req_number); + + static struct configfs_attribute *f_uac2_attrs[] = { + &f_uac2_opts_attr_p_chmask, +@@ -1495,6 +1043,7 @@ + &f_uac2_opts_attr_c_chmask, + &f_uac2_opts_attr_c_srate, + &f_uac2_opts_attr_c_ssize, ++ &f_uac2_opts_attr_req_number, + NULL, + }; + +@@ -1532,15 +1081,16 @@ + opts->c_chmask = UAC2_DEF_CCHMASK; + opts->c_srate = UAC2_DEF_CSRATE; + opts->c_ssize = UAC2_DEF_CSSIZE; ++ opts->req_number = UAC2_DEF_REQ_NUM; + return &opts->func_inst; + } + + static void afunc_free(struct usb_function *f) + { +- struct audio_dev *agdev; ++ struct g_audio *agdev; + struct f_uac2_opts *opts; + +- agdev = func_to_agdev(f); ++ agdev = func_to_g_audio(f); + opts = container_of(f->fi, struct f_uac2_opts, func_inst); + kfree(agdev); + mutex_lock(&opts->lock); +@@ -1550,26 +1100,21 @@ + + static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) + { +- struct audio_dev *agdev = func_to_agdev(f); +- struct uac2_rtd_params *prm; ++ struct g_audio *agdev = func_to_g_audio(f); + +- alsa_uac2_exit(agdev); +- +- prm = &agdev->uac2.p_prm; +- kfree(prm->rbuf); +- +- prm = &agdev->uac2.c_prm; +- kfree(prm->rbuf); ++ g_audio_cleanup(agdev); + usb_free_all_descriptors(f); ++ ++ agdev->gadget = NULL; + } + + static struct usb_function *afunc_alloc(struct usb_function_instance *fi) + { +- struct audio_dev *agdev; ++ struct f_uac2 *uac2; + struct f_uac2_opts *opts; + +- agdev = kzalloc(sizeof(*agdev), GFP_KERNEL); +- if (agdev == NULL) ++ uac2 = kzalloc(sizeof(*uac2), GFP_KERNEL); ++ if (uac2 == NULL) + return ERR_PTR(-ENOMEM); + + opts = container_of(fi, struct f_uac2_opts, func_inst); +@@ -1577,16 +1122,16 @@ + ++opts->refcnt; + mutex_unlock(&opts->lock); + +- agdev->func.name = "uac2_func"; +- agdev->func.bind = afunc_bind; +- agdev->func.unbind = afunc_unbind; +- agdev->func.set_alt = afunc_set_alt; +- agdev->func.get_alt = afunc_get_alt; +- agdev->func.disable = afunc_disable; +- agdev->func.setup = afunc_setup; +- agdev->func.free_func = afunc_free; ++ uac2->g_audio.func.name = "uac2_func"; ++ uac2->g_audio.func.bind = afunc_bind; ++ uac2->g_audio.func.unbind = afunc_unbind; ++ uac2->g_audio.func.set_alt = afunc_set_alt; ++ uac2->g_audio.func.get_alt = afunc_get_alt; ++ uac2->g_audio.func.disable = afunc_disable; ++ uac2->g_audio.func.setup = afunc_setup; ++ uac2->g_audio.func.free_func = afunc_free; + +- return &agdev->func; ++ return &uac2->g_audio.func; + } + + DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uvc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uvc.c.patch new file mode 100644 index 00000000..21e73de5 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-f_uvc.c.patch @@ -0,0 +1,99 @@ +--- linux-4.9.37/drivers/usb/gadget/function/f_uvc.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/f_uvc.c 2021-06-07 13:01:34.000000000 +0300 +@@ -594,6 +594,14 @@ + opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); + opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); + ++ /* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */ ++ if (opts->streaming_maxburst && ++ (opts->streaming_maxpacket % 1024) != 0) { ++ opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024); ++ INFO(cdev, "overriding streaming_maxpacket to %d\n", ++ opts->streaming_maxpacket); ++ } ++ + /* Fill in the FS/HS/SS Video Streaming specific descriptors from the + * module parameters. + * +@@ -621,7 +629,7 @@ + + uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size); + uvc_ss_streaming_ep.bInterval = opts->streaming_interval; +- uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1; ++ uvc_ss_streaming_comp.bmAttributes = 1; + uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; + uvc_ss_streaming_comp.wBytesPerInterval = + cpu_to_le16(max_packet_size * max_packet_mult * +@@ -720,7 +728,7 @@ + } + + /* Initialise video. */ +- ret = uvcg_video_init(&uvc->video); ++ ret = uvcg_video_init(&uvc->video, uvc); + if (ret < 0) + goto error; + +@@ -765,6 +773,11 @@ + struct uvc_color_matching_descriptor *md; + struct uvc_descriptor_header **ctl_cls; + ++ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; ++ /* GUID of the UVC H.264 extension unit */ ++ static char extension_guid[] = {0x41, 0x76, 0x9E, 0xA2, 0x04, 0xDE, 0xE3, 0x47, ++ 0x8B, 0x2B, 0xF4, 0x34, 0x1A, 0xFF, 0x00, 0x3B}; ++ + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return ERR_PTR(-ENOMEM); +@@ -799,6 +812,20 @@ + pd->bmControls[1] = 0; + pd->iProcessing = 0; + ++ ed = &opts->uvc_extension; ++ ed->bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 2); ++ ed->bDescriptorType = USB_DT_CS_INTERFACE; ++ ed->bDescriptorSubType = UVC_VC_EXTENSION_UNIT; ++ ed->bUnitID = 10; ++ memcpy(ed->guidExtensionCode, extension_guid, sizeof(extension_guid)); ++ ed->bNrInPins = 1; ++ ed->baSourceID[0] = 2; ++ ed->bNumControls = 15; ++ ed->bControlSize = 2; ++ ed->bmControls[0] = 1; ++ ed->bmControls[1] = 0; ++ ed->iExtension = 0; ++ + od = &opts->uvc_output_terminal; + od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE; + od->bDescriptorType = USB_DT_CS_INTERFACE; +@@ -822,8 +849,9 @@ + ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ + ctl_cls[1] = (struct uvc_descriptor_header *)cd; + ctl_cls[2] = (struct uvc_descriptor_header *)pd; +- ctl_cls[3] = (struct uvc_descriptor_header *)od; +- ctl_cls[4] = NULL; /* NULL-terminate */ ++ ctl_cls[3] = (struct uvc_descriptor_header *)ed; ++ ctl_cls[4] = (struct uvc_descriptor_header *)od; ++ ctl_cls[5] = NULL; /* NULL-terminate */ + opts->fs_control = + (const struct uvc_descriptor_header * const *)ctl_cls; + +@@ -832,13 +860,15 @@ + ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ + ctl_cls[1] = (struct uvc_descriptor_header *)cd; + ctl_cls[2] = (struct uvc_descriptor_header *)pd; +- ctl_cls[3] = (struct uvc_descriptor_header *)od; +- ctl_cls[4] = NULL; /* NULL-terminate */ ++ ctl_cls[3] = (struct uvc_descriptor_header *)ed; ++ ctl_cls[4] = (struct uvc_descriptor_header *)od; ++ ctl_cls[5] = NULL; /* NULL-terminate */ + opts->ss_control = + (const struct uvc_descriptor_header * const *)ctl_cls; + + opts->streaming_interval = 1; +- opts->streaming_maxpacket = 1024; ++ opts->streaming_maxpacket = 3072; ++ opts->streaming_maxburst = 15; + + uvcg_attach_configfs(opts); + return &opts->func_inst; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_audio.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_audio.c.patch new file mode 100644 index 00000000..c2497129 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_audio.c.patch @@ -0,0 +1,631 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_audio.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_audio.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,628 @@ ++/* ++ * ALSA audio utilities for Gadget stack ++ * ++ * Copyright (C) 2008 Bryan Wu ++ * Copyright (C) 2008 Analog Devices, Inc ++ * ++ * Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * Licensed under the GPL-2 or later. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "u_audio.h" ++ ++#define BUFF_SIZE_MAX (PAGE_SIZE * 16) ++#define PRD_SIZE_MAX PAGE_SIZE ++#define MIN_PERIODS 4 ++ ++struct uac_req { ++ struct uac_rtd_params *pp; /* parent param */ ++ struct usb_request *req; ++}; ++ ++/* Runtime data params for one stream */ ++struct uac_rtd_params { ++ struct snd_uac_chip *uac; /* parent chip */ ++ bool ep_enabled; /* if the ep is enabled */ ++ ++ struct snd_pcm_substream *ss; ++ ++ /* Ring buffer */ ++ ssize_t hw_ptr; ++ ++ void *rbuf; ++ ++ unsigned max_psize; /* MaxPacketSize of endpoint */ ++ struct uac_req *ureq; ++ ++ spinlock_t lock; ++}; ++ ++struct snd_uac_chip { ++ struct g_audio *audio_dev; ++ ++ struct uac_rtd_params p_prm; ++ struct uac_rtd_params c_prm; ++ ++ struct snd_card *card; ++ struct snd_pcm *pcm; ++ ++ /* timekeeping for the playback endpoint */ ++ unsigned int p_interval; ++ unsigned int p_residue; ++ ++ /* pre-calculated values for playback iso completion */ ++ unsigned int p_pktsize; ++ unsigned int p_pktsize_residue; ++ unsigned int p_framesize; ++}; ++ ++static const struct snd_pcm_hardware uac_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER ++ | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID ++ | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS, ++ .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX, ++ .buffer_bytes_max = BUFF_SIZE_MAX, ++ .period_bytes_max = PRD_SIZE_MAX, ++ .periods_min = MIN_PERIODS, ++}; ++ ++static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) ++{ ++ unsigned pending; ++ unsigned long flags, flags2; ++ unsigned int hw_ptr; ++ int status = req->status; ++ struct uac_req *ur = req->context; ++ struct snd_pcm_substream *substream; ++ struct snd_pcm_runtime *runtime; ++ struct uac_rtd_params *prm = ur->pp; ++ struct snd_uac_chip *uac = prm->uac; ++ ++ /* i/f shutting down */ ++ if (!prm->ep_enabled || req->status == -ESHUTDOWN) ++ return; ++ ++ /* ++ * We can't really do much about bad xfers. ++ * Afterall, the ISOCH xfers could fail legitimately. ++ */ ++ if (status) ++ pr_debug("%s: iso_complete status(%d) %d/%d\n", ++ __func__, status, req->actual, req->length); ++ ++ substream = prm->ss; ++ ++ /* Do nothing if ALSA isn't active */ ++ if (!substream) ++ goto exit; ++ ++ snd_pcm_stream_lock_irqsave(substream, flags2); ++ ++ runtime = substream->runtime; ++ if (!runtime || !snd_pcm_running(substream)) { ++ snd_pcm_stream_unlock_irqrestore(substream, flags2); ++ goto exit; ++ } ++ ++ spin_lock_irqsave(&prm->lock, flags); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ /* ++ * For each IN packet, take the quotient of the current data ++ * rate and the endpoint's interval as the base packet size. ++ * If there is a residue from this division, add it to the ++ * residue accumulator. ++ */ ++ req->length = uac->p_pktsize; ++ uac->p_residue += uac->p_pktsize_residue; ++ ++ /* ++ * Whenever there are more bytes in the accumulator than we ++ * need to add one more sample frame, increase this packet's ++ * size and decrease the accumulator. ++ */ ++ if (uac->p_residue / uac->p_interval >= uac->p_framesize) { ++ req->length += uac->p_framesize; ++ uac->p_residue -= uac->p_framesize * ++ uac->p_interval; ++ } ++ ++ req->actual = req->length; ++ } ++ ++ hw_ptr = prm->hw_ptr; ++ ++ spin_unlock_irqrestore(&prm->lock, flags); ++ ++ /* Pack USB load in ALSA ring buffer */ ++ pending = runtime->dma_bytes - hw_ptr; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ if (unlikely(pending < req->actual)) { ++ memcpy(req->buf, runtime->dma_area + hw_ptr, pending); ++ memcpy(req->buf + pending, runtime->dma_area, ++ req->actual - pending); ++ } else { ++ memcpy(req->buf, runtime->dma_area + hw_ptr, ++ req->actual); ++ } ++ } else { ++ if (unlikely(pending < req->actual)) { ++ memcpy(runtime->dma_area + hw_ptr, req->buf, pending); ++ memcpy(runtime->dma_area, req->buf + pending, ++ req->actual - pending); ++ } else { ++ memcpy(runtime->dma_area + hw_ptr, req->buf, ++ req->actual); ++ } ++ } ++ ++ spin_lock_irqsave(&prm->lock, flags); ++ /* update hw_ptr after data is copied to memory */ ++ prm->hw_ptr = (hw_ptr + req->actual) % runtime->dma_bytes; ++ hw_ptr = prm->hw_ptr; ++ spin_unlock_irqrestore(&prm->lock, flags); ++ snd_pcm_stream_unlock_irqrestore(substream, flags2); ++ ++ if ((hw_ptr % snd_pcm_lib_period_bytes(substream)) < req->actual) ++ snd_pcm_period_elapsed(substream); ++ ++exit: ++ if (usb_ep_queue(ep, req, GFP_ATOMIC)) ++ dev_err(uac->card->dev, "%d Error!\n", __LINE__); ++} ++ ++static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ++{ ++ struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); ++ struct uac_rtd_params *prm; ++ struct g_audio *audio_dev; ++ struct uac_params *params; ++ unsigned long flags; ++ int err = 0; ++ ++ audio_dev = uac->audio_dev; ++ params = &audio_dev->params; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ prm = &uac->p_prm; ++ else ++ prm = &uac->c_prm; ++ ++ spin_lock_irqsave(&prm->lock, flags); ++ ++ /* Reset */ ++ prm->hw_ptr = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ prm->ss = substream; ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ prm->ss = NULL; ++ break; ++ default: ++ err = -EINVAL; ++ } ++ ++ spin_unlock_irqrestore(&prm->lock, flags); ++ ++ /* Clear buffer after Play stops */ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss) ++ memset(prm->rbuf, 0, prm->max_psize * params->req_number); ++ ++ return err; ++} ++ ++static snd_pcm_uframes_t uac_pcm_pointer(struct snd_pcm_substream *substream) ++{ ++ struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); ++ struct uac_rtd_params *prm; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ prm = &uac->p_prm; ++ else ++ prm = &uac->c_prm; ++ ++ return bytes_to_frames(substream->runtime, prm->hw_ptr); ++} ++ ++static int uac_pcm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *hw_params) ++{ ++ return snd_pcm_lib_malloc_pages(substream, ++ params_buffer_bytes(hw_params)); ++} ++ ++static int uac_pcm_hw_free(struct snd_pcm_substream *substream) ++{ ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++static int uac_pcm_open(struct snd_pcm_substream *substream) ++{ ++ struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct g_audio *audio_dev; ++ struct uac_params *params; ++ int p_ssize, c_ssize; ++ int p_srate, c_srate; ++ int p_chmask, c_chmask; ++ ++ audio_dev = uac->audio_dev; ++ params = &audio_dev->params; ++ p_ssize = params->p_ssize; ++ c_ssize = params->c_ssize; ++ p_srate = params->p_srate; ++ c_srate = params->c_srate; ++ p_chmask = params->p_chmask; ++ c_chmask = params->c_chmask; ++ uac->p_residue = 0; ++ ++ runtime->hw = uac_pcm_hardware; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ spin_lock_init(&uac->p_prm.lock); ++ runtime->hw.rate_min = p_srate; ++ switch (p_ssize) { ++ case 3: ++ runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; ++ break; ++ case 4: ++ runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; ++ break; ++ default: ++ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; ++ break; ++ } ++ runtime->hw.channels_min = num_channels(p_chmask); ++ runtime->hw.period_bytes_min = 2 * uac->p_prm.max_psize ++ / runtime->hw.periods_min; ++ } else { ++ spin_lock_init(&uac->c_prm.lock); ++ runtime->hw.rate_min = c_srate; ++ switch (c_ssize) { ++ case 3: ++ runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; ++ break; ++ case 4: ++ runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; ++ break; ++ default: ++ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; ++ break; ++ } ++ runtime->hw.channels_min = num_channels(c_chmask); ++ runtime->hw.period_bytes_min = 2 * uac->c_prm.max_psize ++ / runtime->hw.periods_min; ++ } ++ ++ runtime->hw.rate_max = runtime->hw.rate_min; ++ runtime->hw.channels_max = runtime->hw.channels_min; ++ ++ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); ++ ++ return 0; ++} ++ ++/* ALSA cries without these function pointers */ ++static int uac_pcm_null(struct snd_pcm_substream *substream) ++{ ++ return 0; ++} ++ ++static const struct snd_pcm_ops uac_pcm_ops = { ++ .open = uac_pcm_open, ++ .close = uac_pcm_null, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = uac_pcm_hw_params, ++ .hw_free = uac_pcm_hw_free, ++ .trigger = uac_pcm_trigger, ++ .pointer = uac_pcm_pointer, ++ .prepare = uac_pcm_null, ++}; ++ ++static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) ++{ ++ struct snd_uac_chip *uac = prm->uac; ++ struct g_audio *audio_dev; ++ struct uac_params *params; ++ int i; ++ ++ if (!prm->ep_enabled) ++ return; ++ ++ prm->ep_enabled = false; ++ ++ audio_dev = uac->audio_dev; ++ params = &audio_dev->params; ++ ++ for (i = 0; i < params->req_number; i++) { ++ if (prm->ureq[i].req) { ++ usb_ep_dequeue(ep, prm->ureq[i].req); ++ usb_ep_free_request(ep, prm->ureq[i].req); ++ prm->ureq[i].req = NULL; ++ } ++ } ++ ++ if (usb_ep_disable(ep)) ++ dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); ++} ++ ++ ++int u_audio_start_capture(struct g_audio *audio_dev) ++{ ++ struct snd_uac_chip *uac = audio_dev->uac; ++ struct usb_gadget *gadget = audio_dev->gadget; ++ struct device *dev = &gadget->dev; ++ struct usb_request *req; ++ struct usb_ep *ep; ++ struct uac_rtd_params *prm; ++ struct uac_params *params = &audio_dev->params; ++ int req_len, i; ++ ++ ep = audio_dev->out_ep; ++ prm = &uac->c_prm; ++ config_ep_by_speed(gadget, &audio_dev->func, ep); ++ req_len = prm->max_psize; ++ ++ prm->ep_enabled = true; ++ usb_ep_enable(ep); ++ ++ for (i = 0; i < params->req_number; i++) { ++ if (!prm->ureq[i].req) { ++ req = usb_ep_alloc_request(ep, GFP_ATOMIC); ++ if (req == NULL) ++ return -ENOMEM; ++ ++ prm->ureq[i].req = req; ++ prm->ureq[i].pp = prm; ++ ++ req->zero = 0; ++ req->context = &prm->ureq[i]; ++ req->length = req_len; ++ req->complete = u_audio_iso_complete; ++ req->buf = prm->rbuf + i * prm->max_psize; ++ } ++ ++ if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC)) ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(u_audio_start_capture); ++ ++void u_audio_stop_capture(struct g_audio *audio_dev) ++{ ++ struct snd_uac_chip *uac = audio_dev->uac; ++ ++ free_ep(&uac->c_prm, audio_dev->out_ep); ++} ++EXPORT_SYMBOL_GPL(u_audio_stop_capture); ++ ++int u_audio_start_playback(struct g_audio *audio_dev) ++{ ++ struct snd_uac_chip *uac = audio_dev->uac; ++ struct usb_gadget *gadget = audio_dev->gadget; ++ struct device *dev = &gadget->dev; ++ struct usb_request *req; ++ struct usb_ep *ep; ++ struct uac_rtd_params *prm; ++ struct uac_params *params = &audio_dev->params; ++ unsigned int factor, rate; ++ const struct usb_endpoint_descriptor *ep_desc; ++ int req_len, i; ++ ++ ep = audio_dev->in_ep; ++ prm = &uac->p_prm; ++ config_ep_by_speed(gadget, &audio_dev->func, ep); ++ ++ ep_desc = ep->desc; ++ ++ /* pre-calculate the playback endpoint's interval */ ++ if (gadget->speed == USB_SPEED_FULL) ++ factor = 1000; ++ else ++ factor = 8000; ++ ++ /* pre-compute some values for iso_complete() */ ++ uac->p_framesize = params->p_ssize * ++ num_channels(params->p_chmask); ++ rate = params->p_srate * uac->p_framesize; ++ uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); ++ uac->p_pktsize = min_t(unsigned int, rate / uac->p_interval, ++ prm->max_psize); ++ ++ if (uac->p_pktsize < prm->max_psize) ++ uac->p_pktsize_residue = rate % uac->p_interval; ++ else ++ uac->p_pktsize_residue = 0; ++ ++ req_len = uac->p_pktsize; ++ uac->p_residue = 0; ++ ++ prm->ep_enabled = true; ++ usb_ep_enable(ep); ++ ++ for (i = 0; i < params->req_number; i++) { ++ if (!prm->ureq[i].req) { ++ req = usb_ep_alloc_request(ep, GFP_ATOMIC); ++ if (req == NULL) ++ return -ENOMEM; ++ ++ prm->ureq[i].req = req; ++ prm->ureq[i].pp = prm; ++ ++ req->zero = 0; ++ req->context = &prm->ureq[i]; ++ req->length = req_len; ++ req->complete = u_audio_iso_complete; ++ req->buf = prm->rbuf + i * prm->max_psize; ++ } ++ ++ if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC)) ++ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(u_audio_start_playback); ++ ++void u_audio_stop_playback(struct g_audio *audio_dev) ++{ ++ struct snd_uac_chip *uac = audio_dev->uac; ++ ++ free_ep(&uac->p_prm, audio_dev->in_ep); ++} ++EXPORT_SYMBOL_GPL(u_audio_stop_playback); ++ ++int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, ++ const char *card_name) ++{ ++ struct snd_uac_chip *uac; ++ struct snd_card *card; ++ struct snd_pcm *pcm; ++ struct uac_params *params; ++ int p_chmask, c_chmask; ++ int err; ++ ++ if (!g_audio) ++ return -EINVAL; ++ ++ uac = kzalloc(sizeof(*uac), GFP_KERNEL); ++ if (!uac) ++ return -ENOMEM; ++ g_audio->uac = uac; ++ uac->audio_dev = g_audio; ++ ++ params = &g_audio->params; ++ p_chmask = params->p_chmask; ++ c_chmask = params->c_chmask; ++ ++ if (c_chmask) { ++ struct uac_rtd_params *prm = &uac->c_prm; ++ ++ uac->c_prm.uac = uac; ++ prm->max_psize = g_audio->out_ep_maxpsize; ++ ++ prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req), ++ GFP_KERNEL); ++ if (!prm->ureq) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ prm->rbuf = kcalloc(params->req_number, prm->max_psize, ++ GFP_KERNEL); ++ if (!prm->rbuf) { ++ prm->max_psize = 0; ++ err = -ENOMEM; ++ goto fail; ++ } ++ } ++ ++ if (p_chmask) { ++ struct uac_rtd_params *prm = &uac->p_prm; ++ ++ uac->p_prm.uac = uac; ++ prm->max_psize = g_audio->in_ep_maxpsize; ++ ++ prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req), ++ GFP_KERNEL); ++ if (!prm->ureq) { ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ prm->rbuf = kcalloc(params->req_number, prm->max_psize, ++ GFP_KERNEL); ++ if (!prm->rbuf) { ++ prm->max_psize = 0; ++ err = -ENOMEM; ++ goto fail; ++ } ++ } ++ ++ /* Choose any slot, with no id */ ++ err = snd_card_new(&g_audio->gadget->dev, ++ -1, NULL, THIS_MODULE, 0, &card); ++ if (err < 0) ++ goto fail; ++ ++ uac->card = card; ++ ++ /* ++ * Create first PCM device ++ * Create a substream only for non-zero channel streams ++ */ ++ err = snd_pcm_new(uac->card, pcm_name, 0, ++ p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm); ++ if (err < 0) ++ goto snd_fail; ++ ++ strlcpy(pcm->name, pcm_name, sizeof(pcm->name)); ++ pcm->private_data = uac; ++ uac->pcm = pcm; ++ ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops); ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops); ++ ++ strlcpy(card->driver, card_name, sizeof(card->driver)); ++ strlcpy(card->shortname, card_name, sizeof(card->shortname)); ++ sprintf(card->longname, "%s %i", card_name, card->dev->id); ++ ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, ++ snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); ++ ++ err = snd_card_register(card); ++ ++ if (!err) ++ return 0; ++ ++snd_fail: ++ snd_card_free(card); ++fail: ++ kfree(uac->p_prm.ureq); ++ kfree(uac->c_prm.ureq); ++ kfree(uac->p_prm.rbuf); ++ kfree(uac->c_prm.rbuf); ++ kfree(uac); ++ ++ return err; ++} ++EXPORT_SYMBOL_GPL(g_audio_setup); ++ ++void g_audio_cleanup(struct g_audio *g_audio) ++{ ++ struct snd_uac_chip *uac; ++ struct snd_card *card; ++ ++ if (!g_audio || !g_audio->uac) ++ return; ++ ++ uac = g_audio->uac; ++ card = uac->card; ++ if (card) ++ snd_card_free(card); ++ ++ kfree(uac->p_prm.ureq); ++ kfree(uac->c_prm.ureq); ++ kfree(uac->p_prm.rbuf); ++ kfree(uac->c_prm.rbuf); ++ kfree(uac); ++} ++EXPORT_SYMBOL_GPL(g_audio_cleanup); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("USB gadget \"ALSA sound card\" utilities"); ++MODULE_AUTHOR("Ruslan Bilovol"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_audio.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_audio.h.patch new file mode 100644 index 00000000..378454c0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_audio.h.patch @@ -0,0 +1,91 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_audio.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_audio.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,88 @@ ++/* ++ * ALSA audio utilities for Gadget stack ++ * ++ * Copyright (C) 2008 Bryan Wu ++ * Copyright (C) 2008 Analog Devices, Inc ++ * ++ * Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * Licensed under the GPL-2 or later. ++ */ ++ ++#ifndef __U_AUDIO_H ++#define __U_AUDIO_H ++ ++#include ++ ++struct uac_params { ++ /* playback */ ++ int p_chmask; /* channel mask */ ++ int p_srate; /* rate in Hz */ ++ int p_ssize; /* sample size */ ++ ++ /* capture */ ++ int c_chmask; /* channel mask */ ++ int c_srate; /* rate in Hz */ ++ int c_ssize; /* sample size */ ++ ++ int req_number; /* number of preallocated requests */ ++}; ++ ++struct g_audio { ++ struct usb_function func; ++ struct usb_gadget *gadget; ++ ++ struct usb_ep *in_ep; ++ struct usb_ep *out_ep; ++ ++ /* Max packet size for all in_ep possible speeds */ ++ unsigned int in_ep_maxpsize; ++ /* Max packet size for all out_ep possible speeds */ ++ unsigned int out_ep_maxpsize; ++ ++ /* The ALSA Sound Card it represents on the USB-Client side */ ++ struct snd_uac_chip *uac; ++ ++ struct uac_params params; ++}; ++ ++static inline struct g_audio *func_to_g_audio(struct usb_function *f) ++{ ++ return container_of(f, struct g_audio, func); ++} ++ ++static inline uint num_channels(uint chanmask) ++{ ++ uint num = 0; ++ ++ while (chanmask) { ++ num += (chanmask & 1); ++ chanmask >>= 1; ++ } ++ ++ return num; ++} ++ ++/* ++ * g_audio_setup - initialize one virtual ALSA sound card ++ * @g_audio: struct with filled params, in_ep_maxpsize, out_ep_maxpsize ++ * @pcm_name: the id string for a PCM instance of this sound card ++ * @card_name: name of this soundcard ++ * ++ * This sets up the single virtual ALSA sound card that may be exported by a ++ * gadget driver using this framework. ++ * ++ * Context: may sleep ++ * ++ * Returns zero on success, or a negative error on failure. ++ */ ++int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, ++ const char *card_name); ++void g_audio_cleanup(struct g_audio *g_audio); ++ ++int u_audio_start_capture(struct g_audio *g_audio); ++void u_audio_stop_capture(struct g_audio *g_audio); ++int u_audio_start_playback(struct g_audio *g_audio); ++void u_audio_stop_playback(struct g_audio *g_audio); ++ ++#endif /* __U_AUDIO_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1.c.patch new file mode 100644 index 00000000..38a3b515 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1.c.patch @@ -0,0 +1,27 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_uac1.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_uac1.c 2021-06-07 13:01:34.000000000 +0300 +@@ -157,7 +157,6 @@ + struct gaudio_snd_dev *snd = &card->playback; + struct snd_pcm_substream *substream = snd->substream; + struct snd_pcm_runtime *runtime = substream->runtime; +- mm_segment_t old_fs; + ssize_t result; + snd_pcm_sframes_t frames; + +@@ -174,15 +173,11 @@ + } + + frames = bytes_to_frames(runtime, count); +- old_fs = get_fs(); +- set_fs(KERNEL_DS); +- result = snd_pcm_lib_write(snd->substream, (void __user *)buf, frames); ++ result = snd_pcm_kernel_write(snd->substream, buf, frames); + if (result != frames) { + ERROR(card, "Playback error: %d\n", (int)result); +- set_fs(old_fs); + goto try_again; + } +- set_fs(old_fs); + + return 0; + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1.h.patch new file mode 100644 index 00000000..df9f234c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1.h.patch @@ -0,0 +1,106 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_uac1.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_uac1.h 2021-06-07 13:01:34.000000000 +0300 +@@ -1,82 +1,38 @@ ++// SPDX-License-Identifier: GPL-2.0 + /* +- * u_uac1.h -- interface to USB gadget "ALSA AUDIO" utilities ++ * u_uac1.h - Utility definitions for UAC1 function + * +- * Copyright (C) 2008 Bryan Wu +- * Copyright (C) 2008 Analog Devices, Inc +- * +- * Enter bugs at http://blackfin.uclinux.org/ +- * +- * Licensed under the GPL-2 or later. ++ * Copyright (C) 2016 Ruslan Bilovol + */ + +-#ifndef __U_AUDIO_H +-#define __U_AUDIO_H ++#ifndef __U_UAC1_H ++#define __U_UAC1_H + +-#include +-#include +-#include + #include + +-#include +-#include +-#include +- +-#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" +-#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" +-#define FILE_CONTROL "/dev/snd/controlC0" +- + #define UAC1_OUT_EP_MAX_PACKET_SIZE 200 +-#define UAC1_REQ_COUNT 256 +-#define UAC1_AUDIO_BUF_SIZE 48000 ++#define UAC1_DEF_CCHMASK 0x3 ++#define UAC1_DEF_CSRATE 48000 ++#define UAC1_DEF_CSSIZE 2 ++#define UAC1_DEF_PCHMASK 0x3 ++#define UAC1_DEF_PSRATE 48000 ++#define UAC1_DEF_PSSIZE 2 ++#define UAC1_DEF_REQ_NUM 2 + +-/* +- * This represents the USB side of an audio card device, managed by a USB +- * function which provides control and stream interfaces. +- */ +- +-struct gaudio_snd_dev { +- struct gaudio *card; +- struct file *filp; +- struct snd_pcm_substream *substream; +- int access; +- int format; +- int channels; +- int rate; +-}; +- +-struct gaudio { +- struct usb_function func; +- struct usb_gadget *gadget; +- +- /* ALSA sound device interfaces */ +- struct gaudio_snd_dev control; +- struct gaudio_snd_dev playback; +- struct gaudio_snd_dev capture; +- +- /* TODO */ +-}; + + struct f_uac1_opts { + struct usb_function_instance func_inst; +- int req_buf_size; +- int req_count; +- int audio_buf_size; +- char *fn_play; +- char *fn_cap; +- char *fn_cntl; ++ int c_chmask; ++ int c_srate; ++ int c_ssize; ++ int p_chmask; ++ int p_srate; ++ int p_ssize; ++ int req_number; + unsigned bound:1; +- unsigned fn_play_alloc:1; +- unsigned fn_cap_alloc:1; +- unsigned fn_cntl_alloc:1; ++ + struct mutex lock; + int refcnt; + }; + +-int gaudio_setup(struct gaudio *card); +-void gaudio_cleanup(struct gaudio *the_card); +- +-size_t u_audio_playback(struct gaudio *card, void *buf, size_t count); +-int u_audio_get_playback_channels(struct gaudio *card); +-int u_audio_get_playback_rate(struct gaudio *card); +- +-#endif /* __U_AUDIO_H */ ++#endif /* __U_UAC1_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1_legacy.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1_legacy.c.patch new file mode 100644 index 00000000..449a80a9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1_legacy.c.patch @@ -0,0 +1,318 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_uac1_legacy.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_uac1_legacy.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,315 @@ ++/* ++ * u_uac1.c -- ALSA audio utilities for Gadget stack ++ * ++ * Copyright (C) 2008 Bryan Wu ++ * Copyright (C) 2008 Analog Devices, Inc ++ * ++ * Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * Licensed under the GPL-2 or later. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "u_uac1_legacy.h" ++ ++/* ++ * This component encapsulates the ALSA devices for USB audio gadget ++ */ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/** ++ * Some ALSA internal helper functions ++ */ ++static int snd_interval_refine_set(struct snd_interval *i, unsigned int val) ++{ ++ struct snd_interval t; ++ t.empty = 0; ++ t.min = t.max = val; ++ t.openmin = t.openmax = 0; ++ t.integer = 1; ++ return snd_interval_refine(i, &t); ++} ++ ++static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, ++ snd_pcm_hw_param_t var, unsigned int val, ++ int dir) ++{ ++ int changed; ++ if (hw_is_mask(var)) { ++ struct snd_mask *m = hw_param_mask(params, var); ++ if (val == 0 && dir < 0) { ++ changed = -EINVAL; ++ snd_mask_none(m); ++ } else { ++ if (dir > 0) ++ val++; ++ else if (dir < 0) ++ val--; ++ changed = snd_mask_refine_set( ++ hw_param_mask(params, var), val); ++ } ++ } else if (hw_is_interval(var)) { ++ struct snd_interval *i = hw_param_interval(params, var); ++ if (val == 0 && dir < 0) { ++ changed = -EINVAL; ++ snd_interval_none(i); ++ } else if (dir == 0) ++ changed = snd_interval_refine_set(i, val); ++ else { ++ struct snd_interval t; ++ t.openmin = 1; ++ t.openmax = 1; ++ t.empty = 0; ++ t.integer = 0; ++ if (dir < 0) { ++ t.min = val - 1; ++ t.max = val; ++ } else { ++ t.min = val; ++ t.max = val+1; ++ } ++ changed = snd_interval_refine(i, &t); ++ } ++ } else ++ return -EINVAL; ++ if (changed) { ++ params->cmask |= 1 << var; ++ params->rmask |= 1 << var; ++ } ++ return changed; ++} ++/*-------------------------------------------------------------------------*/ ++ ++/** ++ * Set default hardware params ++ */ ++static int playback_default_hw_params(struct gaudio_snd_dev *snd) ++{ ++ struct snd_pcm_substream *substream = snd->substream; ++ struct snd_pcm_hw_params *params; ++ snd_pcm_sframes_t result; ++ ++ /* ++ * SNDRV_PCM_ACCESS_RW_INTERLEAVED, ++ * SNDRV_PCM_FORMAT_S16_LE ++ * CHANNELS: 2 ++ * RATE: 48000 ++ */ ++ snd->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED; ++ snd->format = SNDRV_PCM_FORMAT_S16_LE; ++ snd->channels = 2; ++ snd->rate = 48000; ++ ++ params = kzalloc(sizeof(*params), GFP_KERNEL); ++ if (!params) ++ return -ENOMEM; ++ ++ _snd_pcm_hw_params_any(params); ++ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS, ++ snd->access, 0); ++ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT, ++ snd->format, 0); ++ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS, ++ snd->channels, 0); ++ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE, ++ snd->rate, 0); ++ ++ snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); ++ snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, params); ++ ++ result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); ++ if (result < 0) { ++ ERROR(snd->card, ++ "Preparing sound card failed: %d\n", (int)result); ++ kfree(params); ++ return result; ++ } ++ ++ /* Store the hardware parameters */ ++ snd->access = params_access(params); ++ snd->format = params_format(params); ++ snd->channels = params_channels(params); ++ snd->rate = params_rate(params); ++ ++ kfree(params); ++ ++ INFO(snd->card, ++ "Hardware params: access %x, format %x, channels %d, rate %d\n", ++ snd->access, snd->format, snd->channels, snd->rate); ++ ++ return 0; ++} ++ ++/** ++ * Playback audio buffer data by ALSA PCM device ++ */ ++size_t u_audio_playback(struct gaudio *card, void *buf, size_t count) ++{ ++ struct gaudio_snd_dev *snd = &card->playback; ++ struct snd_pcm_substream *substream = snd->substream; ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ mm_segment_t old_fs; ++ ssize_t result; ++ snd_pcm_sframes_t frames; ++ ++try_again: ++ if (runtime->status->state == SNDRV_PCM_STATE_XRUN || ++ runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { ++ result = snd_pcm_kernel_ioctl(substream, ++ SNDRV_PCM_IOCTL_PREPARE, NULL); ++ if (result < 0) { ++ ERROR(card, "Preparing sound card failed: %d\n", ++ (int)result); ++ return result; ++ } ++ } ++ ++ frames = bytes_to_frames(runtime, count); ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ result = snd_pcm_lib_write(snd->substream, (void __user *)buf, frames); ++ if (result != frames) { ++ ERROR(card, "Playback error: %d\n", (int)result); ++ set_fs(old_fs); ++ goto try_again; ++ } ++ set_fs(old_fs); ++ ++ return 0; ++} ++ ++int u_audio_get_playback_channels(struct gaudio *card) ++{ ++ return card->playback.channels; ++} ++ ++int u_audio_get_playback_rate(struct gaudio *card) ++{ ++ return card->playback.rate; ++} ++ ++/** ++ * Open ALSA PCM and control device files ++ * Initial the PCM or control device ++ */ ++static int gaudio_open_snd_dev(struct gaudio *card) ++{ ++ struct snd_pcm_file *pcm_file; ++ struct gaudio_snd_dev *snd; ++ struct f_uac1_legacy_opts *opts; ++ char *fn_play, *fn_cap, *fn_cntl; ++ ++ opts = container_of(card->func.fi, struct f_uac1_legacy_opts, ++ func_inst); ++ fn_play = opts->fn_play; ++ fn_cap = opts->fn_cap; ++ fn_cntl = opts->fn_cntl; ++ ++ /* Open control device */ ++ snd = &card->control; ++ snd->filp = filp_open(fn_cntl, O_RDWR, 0); ++ if (IS_ERR(snd->filp)) { ++ int ret = PTR_ERR(snd->filp); ++ ERROR(card, "unable to open sound control device file: %s\n", ++ fn_cntl); ++ snd->filp = NULL; ++ return ret; ++ } ++ snd->card = card; ++ ++ /* Open PCM playback device and setup substream */ ++ snd = &card->playback; ++ snd->filp = filp_open(fn_play, O_WRONLY, 0); ++ if (IS_ERR(snd->filp)) { ++ int ret = PTR_ERR(snd->filp); ++ ++ ERROR(card, "No such PCM playback device: %s\n", fn_play); ++ snd->filp = NULL; ++ return ret; ++ } ++ pcm_file = snd->filp->private_data; ++ snd->substream = pcm_file->substream; ++ snd->card = card; ++ playback_default_hw_params(snd); ++ ++ /* Open PCM capture device and setup substream */ ++ snd = &card->capture; ++ snd->filp = filp_open(fn_cap, O_RDONLY, 0); ++ if (IS_ERR(snd->filp)) { ++ ERROR(card, "No such PCM capture device: %s\n", fn_cap); ++ snd->substream = NULL; ++ snd->card = NULL; ++ snd->filp = NULL; ++ } else { ++ pcm_file = snd->filp->private_data; ++ snd->substream = pcm_file->substream; ++ snd->card = card; ++ } ++ ++ return 0; ++} ++ ++/** ++ * Close ALSA PCM and control device files ++ */ ++static int gaudio_close_snd_dev(struct gaudio *gau) ++{ ++ struct gaudio_snd_dev *snd; ++ ++ /* Close control device */ ++ snd = &gau->control; ++ if (snd->filp) ++ filp_close(snd->filp, NULL); ++ ++ /* Close PCM playback device and setup substream */ ++ snd = &gau->playback; ++ if (snd->filp) ++ filp_close(snd->filp, NULL); ++ ++ /* Close PCM capture device and setup substream */ ++ snd = &gau->capture; ++ if (snd->filp) ++ filp_close(snd->filp, NULL); ++ ++ return 0; ++} ++ ++/** ++ * gaudio_setup - setup ALSA interface and preparing for USB transfer ++ * ++ * This sets up PCM, mixer or MIDI ALSA devices fore USB gadget using. ++ * ++ * Returns negative errno, or zero on success ++ */ ++int gaudio_setup(struct gaudio *card) ++{ ++ int ret; ++ ++ ret = gaudio_open_snd_dev(card); ++ if (ret) ++ ERROR(card, "we need at least one control device\n"); ++ ++ return ret; ++ ++} ++ ++/** ++ * gaudio_cleanup - remove ALSA device interface ++ * ++ * This is called to free all resources allocated by @gaudio_setup(). ++ */ ++void gaudio_cleanup(struct gaudio *the_card) ++{ ++ if (the_card) ++ gaudio_close_snd_dev(the_card); ++} ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1_legacy.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1_legacy.h.patch new file mode 100644 index 00000000..9086d2da --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac1_legacy.h.patch @@ -0,0 +1,85 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_uac1_legacy.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_uac1_legacy.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,82 @@ ++/* ++ * u_uac1.c -- ALSA audio utilities for Gadget stack ++ * ++ * Copyright (C) 2008 Bryan Wu ++ * Copyright (C) 2008 Analog Devices, Inc ++ * ++ * Enter bugs at http://blackfin.uclinux.org/ ++ * ++ * Licensed under the GPL-2 or later. ++ */ ++ ++#ifndef __U_UAC1_LEGACY_H ++#define __U_UAC1_LEGACY_H ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" ++#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" ++#define FILE_CONTROL "/dev/snd/controlC0" ++ ++#define UAC1_OUT_EP_MAX_PACKET_SIZE 200 ++#define UAC1_REQ_COUNT 256 ++#define UAC1_AUDIO_BUF_SIZE 48000 ++ ++/* ++ * This represents the USB side of an audio card device, managed by a USB ++ * function which provides control and stream interfaces. ++ */ ++ ++struct gaudio_snd_dev { ++ struct gaudio *card; ++ struct file *filp; ++ struct snd_pcm_substream *substream; ++ int access; ++ int format; ++ int channels; ++ int rate; ++}; ++ ++struct gaudio { ++ struct usb_function func; ++ struct usb_gadget *gadget; ++ ++ /* ALSA sound device interfaces */ ++ struct gaudio_snd_dev control; ++ struct gaudio_snd_dev playback; ++ struct gaudio_snd_dev capture; ++ ++ /* TODO */ ++}; ++ ++struct f_uac1_legacy_opts { ++ struct usb_function_instance func_inst; ++ int req_buf_size; ++ int req_count; ++ int audio_buf_size; ++ char *fn_play; ++ char *fn_cap; ++ char *fn_cntl; ++ unsigned bound:1; ++ unsigned fn_play_alloc:1; ++ unsigned fn_cap_alloc:1; ++ unsigned fn_cntl_alloc:1; ++ struct mutex lock; ++ int refcnt; ++}; ++ ++int gaudio_setup(struct gaudio *card); ++void gaudio_cleanup(struct gaudio *the_card); ++ ++size_t u_audio_playback(struct gaudio *card, void *buf, size_t count); ++int u_audio_get_playback_channels(struct gaudio *card); ++int u_audio_get_playback_rate(struct gaudio *card); ++ ++#endif /* __U_UAC1_LEGACY_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac2.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac2.h.patch new file mode 100644 index 00000000..ded6c094 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uac2.h.patch @@ -0,0 +1,34 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_uac2.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_uac2.h 2021-06-07 13:01:34.000000000 +0300 +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0 + /* + * u_uac2.h + * +@@ -7,10 +8,6 @@ + * http://www.samsung.com + * + * Author: Andrzej Pietrasiewicz +- * +- * 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 U_UAC2_H +@@ -24,6 +21,7 @@ + #define UAC2_DEF_CCHMASK 0x3 + #define UAC2_DEF_CSRATE 64000 + #define UAC2_DEF_CSSIZE 2 ++#define UAC2_DEF_REQ_NUM 2 + + struct f_uac2_opts { + struct usb_function_instance func_inst; +@@ -33,6 +31,7 @@ + int c_chmask; + int c_srate; + int c_ssize; ++ int req_number; + bool bound; + + struct mutex lock; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uvc.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uvc.h.patch new file mode 100644 index 00000000..f9d51e1a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-u_uvc.h.patch @@ -0,0 +1,21 @@ +--- linux-4.9.37/drivers/usb/gadget/function/u_uvc.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/u_uvc.h 2021-06-07 13:01:34.000000000 +0300 +@@ -52,6 +52,7 @@ + struct uvc_processing_unit_descriptor uvc_processing; + struct uvc_output_terminal_descriptor uvc_output_terminal; + struct uvc_color_matching_descriptor uvc_color_matching; ++ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_extension; + + /* + * Control descriptors pointers arrays for full-/high-speed and +@@ -60,8 +61,8 @@ + * descriptors. Used by configfs only, must not be touched by legacy + * gadgets. + */ +- struct uvc_descriptor_header *uvc_fs_control_cls[5]; +- struct uvc_descriptor_header *uvc_ss_control_cls[5]; ++ struct uvc_descriptor_header *uvc_fs_control_cls[6]; ++ struct uvc_descriptor_header *uvc_ss_control_cls[6]; + + /* + * Streaming descriptors for full-speed, high-speed and super-speed. diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc.h.patch new file mode 100644 index 00000000..66c77a90 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc.h.patch @@ -0,0 +1,42 @@ +--- linux-4.9.37/drivers/usb/gadget/function/uvc.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/uvc.h 2021-06-07 13:01:34.000000000 +0300 +@@ -17,6 +17,7 @@ + #include + #include + ++#define UVC_SG_REQ + #define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) + #define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0) + #define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1) +@@ -95,8 +96,11 @@ + /* ------------------------------------------------------------------------ + * Driver specific constants + */ +- +-#define UVC_NUM_REQUESTS 4 ++#ifdef UVC_SG_REQ ++#define UVC_NUM_REQUESTS 1 ++#else ++#define UVC_NUM_REQUESTS 32 ++#endif + #define UVC_MAX_REQUEST_SIZE 64 + #define UVC_MAX_EVENTS 4 + +@@ -106,6 +110,7 @@ + + struct uvc_video + { ++ struct uvc_device *uvc; + struct usb_ep *ep; + + /* Frame parameters */ +@@ -116,6 +121,9 @@ + unsigned int imagesize; + struct mutex mutex; /* protects frame parameters */ + ++ unsigned int num_sgs; /* record base */ ++ __u8 *sg_buf; ++ + /* Requests */ + unsigned int req_size; + struct usb_request *req[UVC_NUM_REQUESTS]; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_configfs.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_configfs.c.patch new file mode 100644 index 00000000..5bfb001b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_configfs.c.patch @@ -0,0 +1,842 @@ +--- linux-4.9.37/drivers/usb/gadget/function/uvc_configfs.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/uvc_configfs.c 2021-06-07 13:01:34.000000000 +0300 +@@ -254,7 +254,49 @@ + return result; + } + +-UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls); ++static ssize_t uvcg_default_processing_bm_controls_store( ++ struct config_item *item, const char *page, size_t len) ++{ ++ struct uvcg_default_processing *dp = to_uvcg_default_processing(item); ++ struct f_uvc_opts *opts; ++ struct config_item *opts_item; ++ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; ++ struct uvc_processing_unit_descriptor *pd; ++ int ret, i; ++ const char *pg = page; ++ /* sign, base 2 representation, newline, terminator */ ++ char buf[1 + sizeof(u8) * 8 + 1 + 1]; ++ int idx; ++ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ ++ ++ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; ++ opts = to_f_uvc_opts(opts_item); ++ pd = &opts->uvc_processing; ++ ++ idx = 0; ++ while (pg - page < len) { ++ i = 0; ++ while (i < sizeof(buf) && (pg - page < len) && ++ *pg != '\0' && *pg != '\n') ++ buf[i++] = *pg++; ++ while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) ++ ++pg; ++ buf[i] = '\0'; ++ ret = kstrtou8(buf, 0, &pd->bmControls[idx++]); ++ if (ret < 0) ++ goto end; ++ if (idx >= pd->bControlSize) ++ break; ++ } ++ ret = len; ++end: ++ mutex_unlock(&opts->lock); ++ mutex_unlock(su_mutex); ++ return ret; ++} ++ ++UVC_ATTR(uvcg_default_processing_, bm_controls, bmControls); + + static struct configfs_attribute *uvcg_default_processing_attrs[] = { + &uvcg_default_processing_attr_b_unit_id, +@@ -281,6 +323,110 @@ + .ct_owner = THIS_MODULE, + }; + ++/* control/extension/default */ ++static struct uvcg_default_extension { ++ struct config_group group; ++} uvcg_default_extension; ++ ++static inline struct uvcg_default_extension ++*to_uvcg_default_extension(struct config_item *item) ++{ ++ return container_of(to_config_group(item), ++ struct uvcg_default_extension, group); ++} ++ ++#define UVCG_DEFAULT_EXTENSION_ATTR(cname, aname, conv) \ ++static ssize_t uvcg_default_extension_##cname##_show( \ ++ struct config_item *item, char *page) \ ++{ \ ++ struct uvcg_default_extension *dp = to_uvcg_default_extension(item); \ ++ struct f_uvc_opts *opts; \ ++ struct config_item *opts_item; \ ++ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; \ ++ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; \ ++ int result; \ ++ \ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ ++ \ ++ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; \ ++ opts = to_f_uvc_opts(opts_item); \ ++ ed = &opts->uvc_extension; \ ++ \ ++ mutex_lock(&opts->lock); \ ++ result = sprintf(page, "%d\n", conv(ed->aname)); \ ++ mutex_unlock(&opts->lock); \ ++ \ ++ mutex_unlock(su_mutex); \ ++ return result; \ ++} \ ++ \ ++UVC_ATTR_RO(uvcg_default_extension_, cname, aname) ++ ++#define identity_conv(x) (x) ++ ++UVCG_DEFAULT_EXTENSION_ATTR(b_unit_id, bUnitID, identity_conv); ++UVCG_DEFAULT_EXTENSION_ATTR(b_num_input_pins, bNrInPins, identity_conv); ++UVCG_DEFAULT_EXTENSION_ATTR(i_extension, iExtension, identity_conv); ++ ++#undef identity_conv ++ ++#undef UVCG_DEFAULT_EXTENSION_ATTR ++ ++static ssize_t uvcg_default_extension_bm_controls_show( ++ struct config_item *item, char *page) ++{ ++ struct uvcg_default_extension *dp = to_uvcg_default_extension(item); ++ struct f_uvc_opts *opts; ++ struct config_item *opts_item; ++ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; ++ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; ++ int result, i; ++ char *pg = page; ++ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ ++ ++ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; ++ opts = to_f_uvc_opts(opts_item); ++ ed = &opts->uvc_extension; ++ ++ mutex_lock(&opts->lock); ++ for (result = 0, i = 0; i < ed->bControlSize; ++i) { ++ result += sprintf(pg, "%d\n", ed->bmControls[i]); ++ pg = page + result; ++ } ++ mutex_unlock(&opts->lock); ++ ++ mutex_unlock(su_mutex); ++ ++ return result; ++} ++ ++UVC_ATTR_RO(uvcg_default_extension_, bm_controls, bmControls); ++ ++static struct configfs_attribute *uvcg_default_extension_attrs[] = { ++ &uvcg_default_extension_attr_b_unit_id, ++ &uvcg_default_extension_attr_b_num_input_pins, ++ &uvcg_default_extension_attr_bm_controls, ++ &uvcg_default_extension_attr_i_extension, ++ NULL, ++}; ++ ++static struct config_item_type uvcg_default_extension_type = { ++ .ct_attrs = uvcg_default_extension_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++/* struct uvcg_extension {}; */ ++ ++/* control/extension */ ++static struct uvcg_extension_grp { ++ struct config_group group; ++} uvcg_extension_grp; ++ ++static struct config_item_type uvcg_extension_grp_type = { ++ .ct_owner = THIS_MODULE, ++}; ++ + /* control/terminal/camera/default */ + static struct uvcg_default_camera { + struct config_group group; +@@ -368,7 +514,50 @@ + return result; + } + +-UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls); ++static ssize_t uvcg_default_camera_bm_controls_store( ++ struct config_item *item, const char *page, size_t len) ++{ ++ struct uvcg_default_camera *dc = to_uvcg_default_camera(item); ++ struct f_uvc_opts *opts; ++ struct config_item *opts_item; ++ struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; ++ struct uvc_camera_terminal_descriptor *cd; ++ int ret, i; ++ const char *pg = page; ++ /* sign, base 2 representation, newline, terminator */ ++ char buf[1 + sizeof(u8) * 8 + 1 + 1]; ++ int idx; ++ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ ++ ++ opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent-> ++ ci_parent; ++ opts = to_f_uvc_opts(opts_item); ++ cd = &opts->uvc_camera_terminal; ++ ++ idx = 0; ++ while (pg - page < len) { ++ i = 0; ++ while (i < sizeof(buf) && (pg - page < len) && ++ *pg != '\0' && *pg != '\n') ++ buf[i++] = *pg++; ++ while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) ++ ++pg; ++ buf[i] = '\0'; ++ ret = kstrtou8(buf, 0, &cd->bmControls[idx++]); ++ if (ret < 0) ++ goto end; ++ if (idx >= cd->bControlSize) ++ break; ++ } ++ ret = len; ++end: ++ mutex_unlock(&opts->lock); ++ mutex_unlock(su_mutex); ++ return ret; ++} ++ ++UVC_ATTR(uvcg_default_camera_, bm_controls, bmControls); + + static struct configfs_attribute *uvcg_default_camera_attrs[] = { + &uvcg_default_camera_attr_b_terminal_id, +@@ -626,14 +815,21 @@ + struct config_group group; + } uvcg_mjpeg_grp; + ++/* streaming/frame_based */ ++static struct uvcg_frame_based_format_grp { ++ struct config_group group; ++} uvcg_frame_based_format_grp; ++ + static struct config_item *fmt_parent[] = { + &uvcg_uncompressed_grp.group.cg_item, + &uvcg_mjpeg_grp.group.cg_item, ++ &uvcg_frame_based_format_grp.group.cg_item, + }; + + enum uvcg_format_type { + UVCG_UNCOMPRESSED = 0, + UVCG_MJPEG, ++ UVCG_FRAME_FRAME_BASED, + }; + + struct uvcg_format { +@@ -1203,6 +1399,7 @@ + return ERR_PTR(-EINVAL); + } + ++fmt->num_frames; ++ h->frame.b_frame_index = fmt->num_frames; + mutex_unlock(&opts->lock); + + config_item_init_type_name(&h->item, name, &uvcg_frame_type); +@@ -1227,6 +1424,263 @@ + mutex_unlock(&opts->lock); + } + ++struct uvcg_frame_based_frame { ++ struct { ++ u8 b_length; ++ u8 b_descriptor_type; ++ u8 b_descriptor_subtype; ++ u8 b_frame_index; ++ u8 bm_capabilities; ++ u16 w_width; ++ u16 w_height; ++ u32 dw_min_bit_rate; ++ u32 dw_max_bit_rate; ++ u32 dw_default_frame_interval; ++ u8 b_frame_interval_type; ++ u32 dw_bytes_per_line; ++ } __attribute__((packed)) frame; ++ u32 *dw_frame_interval; ++ enum uvcg_format_type fmt_type; ++ struct config_item item; ++}; ++ ++static struct uvcg_frame_based_frame *to_uvcg_frame_based_frame(struct config_item *item) ++{ ++ return container_of(item, struct uvcg_frame_based_frame, item); ++} ++ ++#define UVCG_FRAME_BASED_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \ ++static ssize_t uvcg_frame_based_frame_##cname##_show(struct config_item *item, char *page)\ ++{ \ ++ struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item); \ ++ struct f_uvc_opts *opts; \ ++ struct config_item *opts_item; \ ++ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ ++ int result; \ ++ \ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ ++ \ ++ opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ ++ opts = to_f_uvc_opts(opts_item); \ ++ \ ++ mutex_lock(&opts->lock); \ ++ result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \ ++ mutex_unlock(&opts->lock); \ ++ \ ++ mutex_unlock(su_mutex); \ ++ return result; \ ++} \ ++ \ ++static ssize_t uvcg_frame_based_frame_##cname##_store(struct config_item *item, \ ++ const char *page, size_t len)\ ++{ \ ++ struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item); \ ++ struct f_uvc_opts *opts; \ ++ struct config_item *opts_item; \ ++ struct uvcg_format *fmt; \ ++ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ ++ int ret; \ ++ u##bits num; \ ++ \ ++ ret = kstrtou##bits(page, 0, &num); \ ++ if (ret) \ ++ return ret; \ ++ \ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ ++ \ ++ opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ ++ opts = to_f_uvc_opts(opts_item); \ ++ fmt = to_uvcg_format(f->item.ci_parent); \ ++ \ ++ mutex_lock(&opts->lock); \ ++ if (fmt->linked || opts->refcnt) { \ ++ ret = -EBUSY; \ ++ goto end; \ ++ } \ ++ \ ++ f->frame.cname = to_little_endian(num); \ ++ ret = len; \ ++end: \ ++ mutex_unlock(&opts->lock); \ ++ mutex_unlock(su_mutex); \ ++ return ret; \ ++} \ ++ \ ++UVC_ATTR(uvcg_frame_based_frame_, cname, aname); ++ ++#define noop_conversion(x) (x) ++ ++UVCG_FRAME_BASED_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion, ++ noop_conversion, 8); ++UVCG_FRAME_BASED_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16); ++UVCG_FRAME_BASED_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16); ++UVCG_FRAME_BASED_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32); ++UVCG_FRAME_BASED_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32); ++UVCG_FRAME_BASED_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, ++ le32_to_cpu, cpu_to_le32, 32); ++UVCG_FRAME_BASED_FRAME_ATTR(dw_bytes_per_line, dwBytesPerLine, ++ le32_to_cpu, cpu_to_le32, 32); ++ ++#undef noop_conversion ++ ++#undef UVCG_FRAME_BASED_FRAME_ATTR ++ ++static ssize_t uvcg_frame_based_frame_dw_frame_interval_show(struct config_item *item, ++ char *page) ++{ ++ struct uvcg_frame_based_frame *frm = to_uvcg_frame_based_frame(item); ++ struct f_uvc_opts *opts; ++ struct config_item *opts_item; ++ struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; ++ int result, i; ++ char *pg = page; ++ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ ++ ++ opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; ++ opts = to_f_uvc_opts(opts_item); ++ ++ mutex_lock(&opts->lock); ++ for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { ++ result += sprintf(pg, "%d\n", ++ le32_to_cpu(frm->dw_frame_interval[i])); ++ pg = page + result; ++ } ++ mutex_unlock(&opts->lock); ++ ++ mutex_unlock(su_mutex); ++ return result; ++} ++ ++static ssize_t uvcg_frame_based_frame_dw_frame_interval_store(struct config_item *item, ++ const char *page, size_t len) ++{ ++ struct uvcg_frame_based_frame *ch = to_uvcg_frame_based_frame(item); ++ struct f_uvc_opts *opts; ++ struct config_item *opts_item; ++ struct uvcg_format *fmt; ++ struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; ++ int ret = 0, n = 0; ++ u32 *frm_intrv, *tmp; ++ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ ++ ++ opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; ++ opts = to_f_uvc_opts(opts_item); ++ fmt = to_uvcg_format(ch->item.ci_parent); ++ ++ mutex_lock(&opts->lock); ++ if (fmt->linked || opts->refcnt) { ++ ret = -EBUSY; ++ goto end; ++ } ++ ++ ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); ++ if (ret) ++ goto end; ++ ++ tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); ++ if (!frm_intrv) { ++ ret = -ENOMEM; ++ goto end; ++ } ++ ++ ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); ++ if (ret) { ++ kfree(frm_intrv); ++ goto end; ++ } ++ ++ kfree(ch->dw_frame_interval); ++ ch->dw_frame_interval = frm_intrv; ++ ch->frame.b_frame_interval_type = n; ++ ret = len; ++ ++end: ++ mutex_unlock(&opts->lock); ++ mutex_unlock(su_mutex); ++ return ret; ++} ++ ++UVC_ATTR(uvcg_frame_based_frame_, dw_frame_interval, dwFrameInterval); ++ ++static struct configfs_attribute *uvcg_frame_based_frame_attrs[] = { ++ &uvcg_frame_based_frame_attr_bm_capabilities, ++ &uvcg_frame_based_frame_attr_w_width, ++ &uvcg_frame_based_frame_attr_w_height, ++ &uvcg_frame_based_frame_attr_dw_min_bit_rate, ++ &uvcg_frame_based_frame_attr_dw_max_bit_rate, ++ &uvcg_frame_based_frame_attr_dw_default_frame_interval, ++ &uvcg_frame_based_frame_attr_dw_frame_interval, ++ &uvcg_frame_based_frame_attr_dw_bytes_per_line, ++ NULL, ++}; ++ ++static struct config_item_type uvcg_frame_based_frame_type = { ++ .ct_attrs = uvcg_frame_based_frame_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_item *uvcg_frame_based_frame_make(struct config_group *group, ++ const char *name) ++{ ++ struct uvcg_frame_based_frame *h; ++ struct uvcg_format *fmt; ++ struct f_uvc_opts *opts; ++ struct config_item *opts_item; ++ ++ h = kzalloc(sizeof(*h), GFP_KERNEL); ++ if (!h) ++ return ERR_PTR(-ENOMEM); ++ ++ h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; ++ h->frame.b_frame_index = 1; ++ h->frame.w_width = cpu_to_le16(640); ++ h->frame.w_height = cpu_to_le16(360); ++ h->frame.dw_min_bit_rate = cpu_to_le32(18432000); ++ h->frame.dw_max_bit_rate = cpu_to_le32(55296000); ++ h->frame.dw_default_frame_interval = cpu_to_le32(333333); ++ h->frame.dw_bytes_per_line = cpu_to_le32(0); ++ ++ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; ++ opts = to_f_uvc_opts(opts_item); ++ ++ mutex_lock(&opts->lock); ++ fmt = to_uvcg_format(&group->cg_item); ++ if (fmt->type == UVCG_FRAME_FRAME_BASED) { ++ h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED; ++ h->fmt_type = UVCG_FRAME_FRAME_BASED; ++ } else { ++ mutex_unlock(&opts->lock); ++ kfree(h); ++ return ERR_PTR(-EINVAL); ++ } ++ ++fmt->num_frames; ++ h->frame.b_frame_index = fmt->num_frames; ++ mutex_unlock(&opts->lock); ++ ++ config_item_init_type_name(&h->item, name, &uvcg_frame_based_frame_type); ++ ++ return &h->item; ++} ++ ++static void uvcg_frame_based_frame_drop(struct config_group *group, struct config_item *item) ++{ ++ struct uvcg_frame_based_frame *h = to_uvcg_frame_based_frame(item); ++ struct uvcg_format *fmt; ++ struct f_uvc_opts *opts; ++ struct config_item *opts_item; ++ ++ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; ++ opts = to_f_uvc_opts(opts_item); ++ ++ mutex_lock(&opts->lock); ++ fmt = to_uvcg_format(&group->cg_item); ++ --fmt->num_frames; ++ kfree(h); ++ mutex_unlock(&opts->lock); ++} ++ + /* streaming/uncompressed/ */ + struct uvcg_uncompressed { + struct uvcg_format fmt; +@@ -1438,10 +1892,17 @@ + static struct config_group *uvcg_uncompressed_make(struct config_group *group, + const char *name) + { ++#ifndef CONFIG_GOKE_MC + static char guid[] = { + 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + }; ++#else ++ static char guid[] = { ++ 'N', 'V', '2', '1', 0x00, 0x00, 0x10, 0x00, ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ++ }; ++#endif + struct uvcg_uncompressed *h; + + h = kzalloc(sizeof(*h), GFP_KERNEL); +@@ -1452,7 +1913,11 @@ + h->desc.bDescriptorType = USB_DT_CS_INTERFACE; + h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; + memcpy(h->desc.guidFormat, guid, sizeof(guid)); ++#ifndef CONFIG_GOKE_MC + h->desc.bBitsPerPixel = 16; ++#else ++ h->desc.bBitsPerPixel = 12; ++#endif + h->desc.bDefaultFrameIndex = 1; + h->desc.bAspectRatioX = 0; + h->desc.bAspectRatioY = 0; +@@ -1678,6 +2143,205 @@ + .ct_owner = THIS_MODULE, + }; + ++/* streaming/frame_based */ ++struct uvcg_frame_based_format { ++ struct uvcg_format fmt; ++ struct uvc_frame_based_format_desc desc; ++}; ++ ++static struct uvcg_frame_based_format *to_uvcg_frame_based_format(struct config_item *item) ++{ ++ return container_of( ++ container_of(to_config_group(item), struct uvcg_format, group), ++ struct uvcg_frame_based_format, fmt); ++} ++ ++static struct configfs_group_operations uvcg_frame_based_format_group_ops = { ++ .make_item = uvcg_frame_based_frame_make, ++ .drop_item = uvcg_frame_based_frame_drop, ++}; ++ ++#define UVCG_FRAME_BASED_FORMAT_ATTR_RO(cname, aname, conv) \ ++static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\ ++{ \ ++ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ ++ struct f_uvc_opts *opts; \ ++ struct config_item *opts_item; \ ++ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ ++ int result; \ ++ \ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ ++ \ ++ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ ++ opts = to_f_uvc_opts(opts_item); \ ++ \ ++ mutex_lock(&opts->lock); \ ++ result = sprintf(page, "%d\n", conv(u->desc.aname)); \ ++ mutex_unlock(&opts->lock); \ ++ \ ++ mutex_unlock(su_mutex); \ ++ return result; \ ++} \ ++ \ ++UVC_ATTR_RO(uvcg_frame_based_format_, cname, aname) ++ ++#define UVCG_FRAME_BASED_FORMAT_ATTR(cname, aname, conv) \ ++static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\ ++{ \ ++ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ ++ struct f_uvc_opts *opts; \ ++ struct config_item *opts_item; \ ++ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ ++ int result; \ ++ \ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ ++ \ ++ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ ++ opts = to_f_uvc_opts(opts_item); \ ++ \ ++ mutex_lock(&opts->lock); \ ++ result = sprintf(page, "%d\n", conv(u->desc.aname)); \ ++ mutex_unlock(&opts->lock); \ ++ \ ++ mutex_unlock(su_mutex); \ ++ return result; \ ++} \ ++ \ ++static ssize_t \ ++uvcg_frame_based_format_##cname##_store(struct config_item *item, \ ++ const char *page, size_t len) \ ++{ \ ++ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ ++ struct f_uvc_opts *opts; \ ++ struct config_item *opts_item; \ ++ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ ++ int ret; \ ++ u8 num; \ ++ \ ++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ ++ \ ++ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ ++ opts = to_f_uvc_opts(opts_item); \ ++ \ ++ mutex_lock(&opts->lock); \ ++ if (u->fmt.linked || opts->refcnt) { \ ++ ret = -EBUSY; \ ++ goto end; \ ++ } \ ++ \ ++ ret = kstrtou8(page, 0, &num); \ ++ if (ret) \ ++ goto end; \ ++ \ ++ if (num > 255) { \ ++ ret = -EINVAL; \ ++ goto end; \ ++ } \ ++ u->desc.aname = num; \ ++ ret = len; \ ++end: \ ++ mutex_unlock(&opts->lock); \ ++ mutex_unlock(su_mutex); \ ++ return ret; \ ++} \ ++ \ ++UVC_ATTR(uvcg_frame_based_format_, cname, aname) ++ ++#define identity_conv(x) (x) ++ ++UVCG_FRAME_BASED_FORMAT_ATTR(b_default_frame_index, bDefaultFrameIndex, ++ identity_conv); ++UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); ++UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); ++UVCG_FRAME_BASED_FORMAT_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); ++ ++#undef identity_conv ++ ++#undef UVCG_FRAME_BASED_FORMAT_ATTR ++#undef UVCG_FRAME_BASED_FORMAT_ATTR_RO ++ ++static inline ssize_t ++uvcg_frame_based_format_bma_controls_show(struct config_item *item, char *page) ++{ ++ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); ++ return uvcg_format_bma_controls_show(&u->fmt, page); ++} ++ ++static inline ssize_t ++uvcg_frame_based_format_bma_controls_store(struct config_item *item, ++ const char *page, size_t len) ++{ ++ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); ++ return uvcg_format_bma_controls_store(&u->fmt, page, len); ++} ++ ++UVC_ATTR(uvcg_frame_based_format_, bma_controls, bmaControls); ++ ++static struct configfs_attribute *uvcg_frame_based_format_attrs[] = { ++ &uvcg_frame_based_format_attr_b_default_frame_index, ++ &uvcg_frame_based_format_attr_b_aspect_ratio_x, ++ &uvcg_frame_based_format_attr_b_aspect_ratio_y, ++ &uvcg_frame_based_format_attr_bm_interface_flags, ++ &uvcg_frame_based_format_attr_bma_controls, ++ NULL, ++}; ++ ++static struct config_item_type uvcg_frame_based_format_type = { ++ .ct_group_ops = &uvcg_frame_based_format_group_ops, ++ .ct_attrs = uvcg_frame_based_format_attrs, ++ .ct_owner = THIS_MODULE, ++}; ++ ++static struct config_group *uvcg_frame_based_format_make(struct config_group *group, ++ const char *name) ++{ ++ static char guid[] = { /*Declear frame frame based as H264*/ ++ 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ++ }; ++ struct uvcg_frame_based_format *h; ++ ++ h = kzalloc(sizeof(*h), GFP_KERNEL); ++ if (!h) ++ return ERR_PTR(-ENOMEM); ++ ++ h->desc.bLength = UVC_DT_FRAME_BASED_FORMAT_SIZE; ++ h->desc.bDescriptorType = USB_DT_CS_INTERFACE; ++ h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED; ++ memcpy(h->desc.guidFormat, guid, sizeof(guid)); ++ h->desc.bBitsPerPixel = 16; ++ h->desc.bDefaultFrameIndex = 1; ++ h->desc.bAspectRatioX = 0; ++ h->desc.bAspectRatioY = 0; ++ h->desc.bmInterfaceFlags = 0; ++ h->desc.bCopyProtect = 0; ++ h->desc.bVariableSize = 1; ++ ++ h->fmt.type = UVCG_FRAME_FRAME_BASED; ++ config_group_init_type_name(&h->fmt.group, name, ++ &uvcg_frame_based_format_type); ++ ++ return &h->fmt.group; ++} ++ ++static void uvcg_frame_based_format_drop(struct config_group *group, ++ struct config_item *item) ++{ ++ struct uvcg_frame_based_format *h = to_uvcg_frame_based_format(item); ++ ++ kfree(h); ++} ++ ++static struct configfs_group_operations uvcg_frame_based_format_grp_ops = { ++ .make_group = uvcg_frame_based_format_make, ++ .drop_item = uvcg_frame_based_format_drop, ++}; ++ ++static struct config_item_type uvcg_frame_based_format_grp_type = { ++ .ct_group_ops = &uvcg_frame_based_format_grp_ops, ++ .ct_owner = THIS_MODULE, ++}; ++ + /* streaming/color_matching/default */ + static struct uvcg_default_color_matching { + struct config_group group; +@@ -1873,6 +2537,11 @@ + container_of(fmt, struct uvcg_mjpeg, fmt); + + *size += sizeof(m->desc); ++ } else if (fmt->type == UVCG_FRAME_FRAME_BASED) { ++ struct uvcg_frame_based_format *h = ++ container_of(fmt, struct uvcg_frame_based_format, fmt); ++ ++ *size += sizeof(h->desc); + } else { + return -EINVAL; + } +@@ -1881,7 +2550,14 @@ + case UVCG_FRAME: { + struct uvcg_frame *frm = priv1; + int sz = sizeof(frm->dw_frame_interval); ++ if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) { ++ struct uvcg_frame_based_frame *fb_frm = priv1; ++ *size += sizeof(fb_frm->frame); ++ *size += fb_frm->frame.b_frame_interval_type * sizeof(fb_frm->dw_frame_interval); + ++ ++*count; ++ return 0; ++ } + *size += sizeof(frm->frame); + *size += frm->frame.b_frame_interval_type * sz; + } +@@ -1949,6 +2625,15 @@ + *dest += sizeof(m->desc); + mjp->bNumFrameDescriptors = fmt->num_frames; + mjp->bFormatIndex = n + 1; ++ } else if (fmt->type == UVCG_FRAME_FRAME_BASED) { ++ struct uvc_frame_based_format_desc *ffb = *dest; ++ struct uvcg_frame_based_format *h = ++ container_of(fmt, struct uvcg_frame_based_format, fmt); ++ ++ memcpy(*dest, &h->desc, sizeof(h->desc)); ++ *dest += sizeof(h->desc); ++ ffb->bNumFrameDescriptors = fmt->num_frames; ++ ffb->bFormatIndex = n + 1; + } else { + return -EINVAL; + } +@@ -1958,6 +2643,19 @@ + struct uvcg_frame *frm = priv1; + struct uvc_descriptor_header *h = *dest; + ++ if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) { ++ struct uvcg_frame_based_frame *fb_frm = priv1; ++ sz = sizeof(fb_frm->frame); ++ memcpy(*dest, &fb_frm->frame, sz); ++ *dest += sz; ++ sz = fb_frm->frame.b_frame_interval_type * ++ sizeof(*fb_frm->dw_frame_interval); ++ memcpy(*dest, fb_frm->dw_frame_interval, sz); ++ *dest += sz; ++ h->bLength = UVC_DT_FRAME_BASED_FRAME_SIZE( ++ fb_frm->frame.b_frame_interval_type); ++ return 0; ++ } + sz = sizeof(frm->frame); + memcpy(*dest, &frm->frame, sz); + *dest += sz; +@@ -2224,6 +2922,13 @@ + configfs_add_default_group(&uvcg_default_processing.group, + &uvcg_processing_grp.group); + ++ config_group_init_type_name(&uvcg_default_extension.group, ++ "default", &uvcg_default_extension_type); ++ config_group_init_type_name(&uvcg_extension_grp.group, ++ "extension", &uvcg_extension_grp_type); ++ configfs_add_default_group(&uvcg_default_extension.group, ++ &uvcg_extension_grp.group); ++ + config_group_init_type_name(&uvcg_default_camera.group, + "default", &uvcg_default_camera_type); + config_group_init_type_name(&uvcg_camera_grp.group, +@@ -2278,6 +2983,9 @@ + config_group_init_type_name(&uvcg_mjpeg_grp.group, + "mjpeg", + &uvcg_mjpeg_grp_type); ++ config_group_init_type_name(&uvcg_frame_based_format_grp.group, ++ "framebased", ++ &uvcg_frame_based_format_grp_type); + config_group_init_type_name(&uvcg_default_color_matching.group, + "default", + &uvcg_default_color_matching_type); +@@ -2310,6 +3018,8 @@ + &uvcg_streaming_grp.group); + configfs_add_default_group(&uvcg_mjpeg_grp.group, + &uvcg_streaming_grp.group); ++ configfs_add_default_group(&uvcg_frame_based_format_grp.group, ++ &uvcg_streaming_grp.group); + configfs_add_default_group(&uvcg_color_matching_grp.group, + &uvcg_streaming_grp.group); + configfs_add_default_group(&uvcg_streaming_class_grp.group, diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_v4l2.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_v4l2.c.patch new file mode 100644 index 00000000..b3bc5bd3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_v4l2.c.patch @@ -0,0 +1,16 @@ +--- linux-4.9.37/drivers/usb/gadget/function/uvc_v4l2.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/uvc_v4l2.c 2021-06-07 13:01:34.000000000 +0300 +@@ -60,8 +60,13 @@ + }; + + static struct uvc_format uvc_formats[] = { ++#ifndef CONFIG_GOKE_MC + { 16, V4L2_PIX_FMT_YUYV }, ++#else ++ { 12, V4L2_PIX_FMT_NV21 }, ++#endif + { 0, V4L2_PIX_FMT_MJPEG }, ++ { 0, V4L2_PIX_FMT_H264 }, + }; + + static int diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_video.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_video.c.patch new file mode 100644 index 00000000..9aaa0b41 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_video.c.patch @@ -0,0 +1,250 @@ +--- linux-4.9.37/drivers/usb/gadget/function/uvc_video.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/uvc_video.c 2021-06-07 13:01:34.000000000 +0300 +@@ -23,6 +23,8 @@ + #include "uvc_queue.h" + #include "uvc_video.h" + ++#include ++#include + /* -------------------------------------------------------------------------- + * Video codecs + */ +@@ -102,9 +104,45 @@ + uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, + struct uvc_buffer *buf) + { ++ int ret; ++#ifdef UVC_SG_REQ ++ int len; ++ int ttllen = 0; ++ unsigned int sg_idx; ++ u8 *mem = NULL; ++ ++ for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++) { ++ mem = sg_virt(&req->sg[sg_idx]); ++ len = video->req_size; ++ ++ /* Add the header. */ ++ ret = uvc_video_encode_header(video, buf, mem, len); ++ mem += ret; ++ len -= ret; ++ ++ /* Process video data. */ ++ ret = uvc_video_encode_data(video, buf, mem, len); ++ len -= ret; ++ ++ /* Sync sg buffer len , default is 1024 or 3072 */ ++ sg_set_buf(&req->sg[sg_idx], sg_virt(&req->sg[sg_idx]), ++ video->req_size - len); ++ ttllen += video->req_size - len; ++ ++ if (buf->bytesused == video->queue.buf_used) { ++ video->queue.buf_used = 0; ++ buf->state = UVC_BUF_STATE_DONE; ++ uvcg_queue_next_buffer(&video->queue, buf); ++ video->fid ^= UVC_STREAM_FID; ++ break; ++ } ++ } ++ req->num_sgs = sg_idx + 1; ++ sg_mark_end(&req->sg[sg_idx]); ++ req->length = ttllen; ++#else + void *mem = req->buf; + int len = video->req_size; +- int ret; + + /* Add the header. */ + ret = uvc_video_encode_header(video, buf, mem, len); +@@ -123,12 +161,33 @@ + uvcg_queue_next_buffer(&video->queue, buf); + video->fid ^= UVC_STREAM_FID; + } ++#endif + } + + /* -------------------------------------------------------------------------- + * Request handling + */ + ++static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req) ++{ ++ int ret; ++ ++ /* ++ * Fixme, this is just to workaround the warning by udc core when the ep ++ * is disabled, this may happens when the uvc application is still ++ * streaming new data while the uvc gadget driver has already recieved ++ * the streamoff but the streamoff event is not yet received by the app ++ */ ++ if (!video->ep->enabled) ++ return -EINVAL; ++ ++ ret = usb_ep_queue(video->ep, req, GFP_ATOMIC); ++ if (ret < 0) ++ printk(KERN_INFO "Failed to queue request (%d).\n", ret); ++ ++ return ret; ++} ++ + /* + * I somehow feel that synchronisation won't be easy to achieve here. We have + * three events that control USB requests submission: +@@ -190,22 +249,26 @@ + spin_unlock_irqrestore(&video->queue.irqlock, flags); + goto requeue; + } +- ++#ifdef UVC_SG_REQ ++ sg_unmark_end(&req->sg[req->num_sgs - 1]); ++#endif + video->encode(req, video, buf); + +- if ((ret = usb_ep_queue(ep, req, GFP_ATOMIC)) < 0) { +- printk(KERN_INFO "Failed to queue request (%d).\n", ret); +- usb_ep_set_halt(ep); +- spin_unlock_irqrestore(&video->queue.irqlock, flags); ++ ret = uvcg_video_ep_queue(video, req); ++ spin_unlock_irqrestore(&video->queue.irqlock, flags); ++ ++ if (ret < 0) { + uvcg_queue_cancel(queue, 0); + goto requeue; + } +- spin_unlock_irqrestore(&video->queue.irqlock, flags); + + return; + + requeue: + spin_lock_irqsave(&video->req_lock, flags); ++#ifdef UVC_SG_REQ ++ sg_unmark_end(&req->sg[req->num_sgs - 1]); ++#endif + list_add_tail(&req->list, &video->req_free); + spin_unlock_irqrestore(&video->req_lock, flags); + } +@@ -214,9 +277,22 @@ + uvc_video_free_requests(struct uvc_video *video) + { + unsigned int i; ++#ifdef UVC_SG_REQ ++ unsigned int sg_idx; ++#endif + + for (i = 0; i < UVC_NUM_REQUESTS; ++i) { + if (video->req[i]) { ++#ifdef UVC_SG_REQ ++ for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++) ++ if (sg_page(&video->req[i]->sg[sg_idx])) ++ kfree(sg_virt(&video->req[i]->sg[sg_idx])); ++ ++ if (video->req[i]->sg) { ++ kfree(video->req[i]->sg); ++ video->req[i]->sg = NULL; ++ } ++#endif + usb_ep_free_request(video->ep, video->req[i]); + video->req[i] = NULL; + } +@@ -238,6 +314,11 @@ + unsigned int req_size; + unsigned int i; + int ret = -ENOMEM; ++#ifdef UVC_SG_REQ ++ struct scatterlist *sg; ++ unsigned int num_sgs; ++ unsigned int sg_idx; ++#endif + + BUG_ON(video->req_size); + +@@ -245,6 +326,35 @@ + * max_t(unsigned int, video->ep->maxburst, 1) + * (video->ep->mult); + ++#ifdef UVC_SG_REQ ++ num_sgs = ((video->imagesize / (req_size - 2)) + 1); ++ video->num_sgs = num_sgs; ++ ++ for (i = 0; i < UVC_NUM_REQUESTS; ++i) { ++ sg = kmalloc(num_sgs * sizeof(struct scatterlist), GFP_ATOMIC); ++ if (sg == NULL) ++ goto error; ++ sg_init_table(sg, num_sgs); ++ ++ video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL); ++ if (video->req[i] == NULL) ++ goto error; ++ ++ for (sg_idx = 0 ; sg_idx < num_sgs ; sg_idx++) { ++ video->sg_buf = kmalloc(req_size, GFP_KERNEL); ++ if (video->sg_buf == NULL) ++ goto error; ++ sg_set_buf(&sg[sg_idx], video->sg_buf, req_size); ++ } ++ video->req[i]->sg = sg; ++ video->req[i]->num_sgs = num_sgs; ++ video->req[i]->length = 0; ++ video->req[i]->complete = uvc_video_complete; ++ video->req[i]->context = video; ++ ++ list_add_tail(&video->req[i]->list, &video->req_free); ++ } ++#else + for (i = 0; i < UVC_NUM_REQUESTS; ++i) { + video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL); + if (video->req_buffer[i] == NULL) +@@ -261,7 +371,7 @@ + + list_add_tail(&video->req[i]->list, &video->req_free); + } +- ++#endif + video->req_size = req_size; + + return 0; +@@ -320,15 +430,13 @@ + video->encode(req, video, buf); + + /* Queue the USB request */ +- ret = usb_ep_queue(video->ep, req, GFP_ATOMIC); ++ ret = uvcg_video_ep_queue(video, req); ++ spin_unlock_irqrestore(&queue->irqlock, flags); ++ + if (ret < 0) { +- printk(KERN_INFO "Failed to queue request (%d)\n", ret); +- usb_ep_set_halt(video->ep); +- spin_unlock_irqrestore(&queue->irqlock, flags); + uvcg_queue_cancel(queue, 0); + break; + } +- spin_unlock_irqrestore(&queue->irqlock, flags); + } + + spin_lock_irqsave(&video->req_lock, flags); +@@ -379,16 +487,22 @@ + /* + * Initialize the UVC video stream. + */ +-int uvcg_video_init(struct uvc_video *video) ++int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) + { + INIT_LIST_HEAD(&video->req_free); + spin_lock_init(&video->req_lock); +- ++#ifndef CONFIG_GOKE_MC + video->fcc = V4L2_PIX_FMT_YUYV; ++ video->imagesize = 320 * 240 * 2; + video->bpp = 16; ++#else ++ video->fcc = V4L2_PIX_FMT_NV21; ++ video->imagesize = 320 * 240 * 3 / 2; /* YUV420: w*h*1.5 */ ++ video->bpp = 12; ++#endif + video->width = 320; + video->height = 240; +- video->imagesize = 320 * 240 * 2; ++ video->uvc = uvc; + + /* Initialize the video buffers queue. */ + uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT, diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_video.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_video.h.patch new file mode 100644 index 00000000..89c2e55f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-function-uvc_video.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/usb/gadget/function/uvc_video.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/function/uvc_video.h 2021-06-07 13:01:34.000000000 +0300 +@@ -19,6 +19,6 @@ + + int uvcg_video_enable(struct uvc_video *video, int enable); + +-int uvcg_video_init(struct uvc_video *video); ++int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc); + + #endif /* __UVC_VIDEO_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-Kconfig.patch new file mode 100644 index 00000000..f2696d59 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-Kconfig.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/usb/gadget/legacy/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/legacy/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -56,6 +56,7 @@ + select SND_PCM + select USB_F_UAC1 if GADGET_UAC1 + select USB_F_UAC2 if !GADGET_UAC1 ++ select USB_U_AUDIO if USB_F_UAC2 + help + This Gadget Audio driver is compatible with USB Audio Class + specification 2.0. It implements 1 AudioControl interface, diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-audio.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-audio.c.patch new file mode 100644 index 00000000..0927fc58 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-audio.c.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/usb/gadget/legacy/audio.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/legacy/audio.c 2021-06-07 13:01:34.000000000 +0300 +@@ -229,6 +229,7 @@ + uac2_opts->c_chmask = c_chmask; + uac2_opts->c_srate = c_srate; + uac2_opts->c_ssize = c_ssize; ++ uac2_opts->req_number = UAC2_DEF_REQ_NUM; + #else + uac1_opts = container_of(fi_uac1, struct f_uac1_opts, func_inst); + uac1_opts->fn_play = fn_play; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-multi.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-multi.c.patch new file mode 100644 index 00000000..2cd4ba74 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-multi.c.patch @@ -0,0 +1,99 @@ +--- linux-4.9.37/drivers/usb/gadget/legacy/multi.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/legacy/multi.c 2021-06-07 13:01:34.000000000 +0300 +@@ -162,21 +162,8 @@ + if (ret) + goto err_conf; + +- f_msg_rndis = usb_get_function(fi_msg); +- if (IS_ERR(f_msg_rndis)) { +- ret = PTR_ERR(f_msg_rndis); +- goto err_fsg; +- } +- +- ret = usb_add_function(c, f_msg_rndis); +- if (ret) +- goto err_run; +- + return 0; +-err_run: +- usb_put_function(f_msg_rndis); +-err_fsg: +- usb_remove_function(c, f_acm_rndis); ++ + err_conf: + usb_put_function(f_acm_rndis); + err_func_acm: +@@ -245,16 +232,6 @@ + if (ret) + goto err_conf; + +- f_msg_multi = usb_get_function(fi_msg); +- if (IS_ERR(f_msg_multi)) { +- ret = PTR_ERR(f_msg_multi); +- goto err_fsg; +- } +- +- ret = usb_add_function(c, f_msg_multi); +- if (ret) +- goto err_run; +- + return 0; + err_run: + usb_put_function(f_msg_multi); +@@ -304,8 +281,7 @@ + #ifdef USB_ETH_RNDIS + struct f_rndis_opts *rndis_opts; + #endif +- struct fsg_opts *fsg_opts; +- struct fsg_config config; ++ + int status; + + if (!can_support_ecm(cdev->gadget)) { +@@ -367,32 +343,6 @@ + goto fail0; + } + +- /* set up mass storage function */ +- fi_msg = usb_get_function_instance("mass_storage"); +- if (IS_ERR(fi_msg)) { +- status = PTR_ERR(fi_msg); +- goto fail1; +- } +- fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers); +- fsg_opts = fsg_opts_from_func_inst(fi_msg); +- +- fsg_opts->no_configfs = true; +- status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers); +- if (status) +- goto fail2; +- +- status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall); +- if (status) +- goto fail_set_cdev; +- +- fsg_common_set_sysfs(fsg_opts->common, true); +- status = fsg_common_create_luns(fsg_opts->common, &config); +- if (status) +- goto fail_set_cdev; +- +- fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name, +- config.product_name); +- + /* allocate string IDs */ + status = usb_string_ids_tab(cdev, strings_dev); + if (unlikely(status < 0)) +@@ -430,13 +380,6 @@ + kfree(otg_desc[0]); + otg_desc[0] = NULL; + fail_string_ids: +- fsg_common_remove_luns(fsg_opts->common); +-fail_set_cdev: +- fsg_common_free_buffers(fsg_opts->common); +-fail2: +- usb_put_function_instance(fi_msg); +-fail1: +- usb_put_function_instance(fi_acm); + fail0: + #ifdef USB_ETH_RNDIS + usb_put_function_instance(fi_rndis); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-webcam.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-webcam.c.patch new file mode 100644 index 00000000..79993989 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-legacy-webcam.c.patch @@ -0,0 +1,491 @@ +--- linux-4.9.37/drivers/usb/gadget/legacy/webcam.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/legacy/webcam.c 2021-06-07 13:01:34.000000000 +0300 +@@ -26,11 +26,11 @@ + module_param(streaming_interval, uint, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(streaming_interval, "1 - 16"); + +-static unsigned int streaming_maxpacket = 1024; ++static unsigned int streaming_maxpacket = 3072; + module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)"); + +-static unsigned int streaming_maxburst; ++static unsigned int streaming_maxburst = 14; + module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); + +@@ -49,6 +49,17 @@ + static char webcam_product_label[] = "Webcam gadget"; + static char webcam_config_label[] = "Video"; + ++/* GUID of the UVC H.264 extension unit: ++{A29E7641-DE04-47E3-8B2B-F4341AFF003B} */ ++#define GUID_UVCX_H264_XU {0x41, 0x76, 0x9E, 0xA2, 0x04, 0xDE, 0xE3, 0x47, \ ++ 0x8B, 0x2B, 0xF4, 0x34, 0x1A, 0xFF, 0x00, 0x3B} ++ ++#define UVC_GUID_BSP_CAMERA {0x91, 0x72, 0x1e, 0x9a, 0x43, 0x68, 0x83, 0x46, \ ++ 0x6d, 0x92, 0x39, 0xbc, 0x79, 0x06, 0xee, 0x49} ++ ++#define UVC_GUID_FORMAT_H264 {0x48, 0x32, 0x36, 0x34, 0x00, 0x00, 0x10, 0x00, \ ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} ++ + /* string IDs are assigned dynamically */ + + #define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX +@@ -77,7 +88,7 @@ + static struct usb_device_descriptor webcam_device_descriptor = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, +- /* .bcdUSB = DYNAMIC */ ++ .bcdUSB = cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_MISC, + .bDeviceSubClass = 0x02, + .bDeviceProtocol = 0x01, +@@ -97,7 +108,7 @@ + .bLength = UVC_DT_HEADER_SIZE(1), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VC_HEADER, +- .bcdUVC = cpu_to_le16(0x0100), ++ .bcdUVC = cpu_to_le16(0x0110), + .wTotalLength = 0, /* dynamic */ + .dwClockFrequency = cpu_to_le32(48000000), + .bInCollection = 0, /* dynamic */ +@@ -108,7 +119,7 @@ + .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VC_INPUT_TERMINAL, +- .bTerminalID = 1, ++ .bTerminalID = 2, + .wTerminalType = cpu_to_le16(0x0201), + .bAssocTerminal = 0, + .iTerminal = 0, +@@ -116,8 +127,8 @@ + .wObjectiveFocalLengthMax = cpu_to_le16(0), + .wOcularFocalLength = cpu_to_le16(0), + .bControlSize = 3, +- .bmControls[0] = 2, +- .bmControls[1] = 0, ++ .bmControls[0] = 0x1a, ++ .bmControls[1] = 0x00, + .bmControls[2] = 0, + }; + +@@ -125,15 +136,45 @@ + .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VC_PROCESSING_UNIT, +- .bUnitID = 2, ++ .bUnitID = 5, + .bSourceID = 1, + .wMaxMultiplier = cpu_to_le16(16*1024), + .bControlSize = 2, +- .bmControls[0] = 1, +- .bmControls[1] = 0, ++ .bmControls[0] = 0xff, ++ .bmControls[1] = 0xff, + .iProcessing = 0, + }; + ++static const struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_xu_h264_desc = { ++ .bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 2), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VC_EXTENSION_UNIT, ++ .bUnitID = 10, ++ .guidExtensionCode = GUID_UVCX_H264_XU, ++ .bNumControls = 15, ++ .bNrInPins = 1, ++ .baSourceID[0] = 2, ++ .bControlSize = 2, ++ .bmControls[0] = 0xff, ++ .bmControls[1] = 0xff, ++ .iExtension = 0, ++}; ++ ++static const struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_xu_camera_desc = { ++ .bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 2), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VC_EXTENSION_UNIT, ++ .bUnitID = 0x11, ++ .guidExtensionCode = UVC_GUID_BSP_CAMERA, ++ .bNumControls = 15, ++ .bNrInPins = 1, ++ .baSourceID[0] = 10, ++ .bControlSize = 2, ++ .bmControls[0] = 0xff, ++ .bmControls[1] = 0xff, ++ .iExtension = 0, ++}; ++ + static const struct uvc_output_terminal_descriptor uvc_output_terminal = { + .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, +@@ -141,7 +182,7 @@ + .bTerminalID = 3, + .wTerminalType = cpu_to_le16(0x0101), + .bAssocTerminal = 0, +- .bSourceID = 2, ++ .bSourceID = 0x11, + .iTerminal = 0, + }; + +@@ -169,11 +210,18 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, +- .bNumFrameDescriptors = 2, ++ .bNumFrameDescriptors = 3, ++#ifndef CONFIG_GOKE_MC + .guidFormat = + { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, + .bBitsPerPixel = 16, ++#else ++ .guidFormat = { ++ 'N', 'V', '2', '1', 0x00, 0x00, 0x10, 0x00, ++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, ++ .bBitsPerPixel = 12, ++#endif + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, +@@ -184,22 +232,24 @@ + DECLARE_UVC_FRAME_UNCOMPRESSED(1); + DECLARE_UVC_FRAME_UNCOMPRESSED(3); + +-static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = { +- .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), ++static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_360p = { ++ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, + .bFrameIndex = 1, + .bmCapabilities = 0, + .wWidth = cpu_to_le16(640), + .wHeight = cpu_to_le16(360), +- .dwMinBitRate = cpu_to_le32(18432000), ++ .dwMinBitRate = cpu_to_le32(55296000), + .dwMaxBitRate = cpu_to_le32(55296000), ++#ifndef CONFIG_GOKE_MC + .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), +- .dwDefaultFrameInterval = cpu_to_le32(666666), +- .bFrameIntervalType = 3, +- .dwFrameInterval[0] = cpu_to_le32(666666), +- .dwFrameInterval[1] = cpu_to_le32(1000000), +- .dwFrameInterval[2] = cpu_to_le32(5000000), ++#else ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(345600), ++#endif ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwFrameInterval[0] = cpu_to_le32(333333), + }; + + static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { +@@ -212,10 +262,54 @@ + .wHeight = cpu_to_le16(720), + .dwMinBitRate = cpu_to_le32(29491200), + .dwMaxBitRate = cpu_to_le32(29491200), ++#ifndef CONFIG_GOKE_MC + .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), +- .dwDefaultFrameInterval = cpu_to_le32(5000000), ++#else ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(1382400), ++#endif ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_1080p = { ++ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, ++ .bFrameIndex = 3, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(1920), ++ .wHeight = cpu_to_le16(1080), ++ .dwMinBitRate = cpu_to_le32(29491200), ++ .dwMaxBitRate = cpu_to_le32(29491200), ++#ifndef CONFIG_GOKE_MC ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(4147200), ++#else ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(3110400), ++#endif ++ .dwDefaultFrameInterval = cpu_to_le32(333333), + .bFrameIntervalType = 1, +- .dwFrameInterval[0] = cpu_to_le32(5000000), ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_2160p = { ++ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, ++ .bFrameIndex = 4, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(3840), ++ .wHeight = cpu_to_le16(2160), ++ .dwMinBitRate = cpu_to_le32(29491200), ++ .dwMaxBitRate = cpu_to_le32(29491200), ++#ifndef CONFIG_GOKE_MC ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(16588800), ++#else ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(12441600), ++#endif ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwFrameInterval[0] = cpu_to_le32(333333), + }; + + static const struct uvc_format_mjpeg uvc_format_mjpg = { +@@ -223,7 +317,7 @@ + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, + .bFormatIndex = 2, +- .bNumFrameDescriptors = 2, ++ .bNumFrameDescriptors = 4, + .bmFlags = 0, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, +@@ -235,22 +329,20 @@ + DECLARE_UVC_FRAME_MJPEG(1); + DECLARE_UVC_FRAME_MJPEG(3); + +-static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = { +- .bLength = UVC_DT_FRAME_MJPEG_SIZE(3), ++static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_360p = { ++ .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_FRAME_MJPEG, + .bFrameIndex = 1, + .bmCapabilities = 0, + .wWidth = cpu_to_le16(640), + .wHeight = cpu_to_le16(360), +- .dwMinBitRate = cpu_to_le32(18432000), +- .dwMaxBitRate = cpu_to_le32(55296000), ++ .dwMinBitRate = cpu_to_le32(10240000), ++ .dwMaxBitRate = cpu_to_le32(10240000), + .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), +- .dwDefaultFrameInterval = cpu_to_le32(666666), +- .bFrameIntervalType = 3, +- .dwFrameInterval[0] = cpu_to_le32(666666), +- .dwFrameInterval[1] = cpu_to_le32(1000000), +- .dwFrameInterval[2] = cpu_to_le32(5000000), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwFrameInterval[0] = cpu_to_le32(333333), + }; + + static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { +@@ -261,12 +353,125 @@ + .bmCapabilities = 0, + .wWidth = cpu_to_le16(1280), + .wHeight = cpu_to_le16(720), +- .dwMinBitRate = cpu_to_le32(29491200), +- .dwMaxBitRate = cpu_to_le32(29491200), ++ .dwMinBitRate = cpu_to_le32(20480000), ++ .dwMaxBitRate = cpu_to_le32(20480000), + .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), +- .dwDefaultFrameInterval = cpu_to_le32(5000000), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), + .bFrameIntervalType = 1, +- .dwFrameInterval[0] = cpu_to_le32(5000000), ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_1080p = { ++ .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_MJPEG, ++ .bFrameIndex = 3, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(1920), ++ .wHeight = cpu_to_le16(1080), ++ .dwMinBitRate = cpu_to_le32(40960000), ++ .dwMaxBitRate = cpu_to_le32(40960000), ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(4147200), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_2160p = { ++ .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_MJPEG, ++ .bFrameIndex = 4, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(3840), ++ .wHeight = cpu_to_le16(2160), ++ .dwMinBitRate = cpu_to_le32(61440000), ++ .dwMaxBitRate = cpu_to_le32(61440000), ++ .dwMaxVideoFrameBufferSize = cpu_to_le32(16588800), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++static const struct uvc_frame_based_format_desc uvc_frame_based_format_desc = { ++ .bLength = UVC_DT_FRAME_BASED_FORMAT_SIZE, ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED, ++ .bFormatIndex = 3, ++ .bNumFrameDescriptors = 4, ++ .guidFormat = UVC_GUID_FORMAT_H264, ++ .bBitsPerPixel = 16, ++ .bDefaultFrameIndex = 1, ++ .bAspectRatioX = 0, ++ .bAspectRatioY = 0, ++ .bmInterfaceFlags = 0, ++ .bCopyProtect = 0, ++ .bVariableSize = 1, ++}; ++DECLARE_UVC_FRAME_BASED(1); ++static const struct UVC_FRAME_BASED(1) uvc_frame_based_360p = { ++ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, ++ .bFrameIndex = 1, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(640), ++ .wHeight = cpu_to_le16(360), ++ .dwMinBitRate = cpu_to_le32(8192000), ++ .dwMaxBitRate = cpu_to_le32(8192000), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwBytesPerLine = 0, ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++static const struct UVC_FRAME_BASED(1) uvc_frame_based_720p = { ++ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, ++ .bFrameIndex = 2, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(1280), ++ .wHeight = cpu_to_le16(720), ++ .dwMinBitRate = cpu_to_le32(10240000), ++ .dwMaxBitRate = cpu_to_le32(10240000), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwBytesPerLine = 0, ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++static const struct UVC_FRAME_BASED(1) uvc_frame_based_1080p = { ++ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, ++ .bFrameIndex = 3, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(1920), ++ .wHeight = cpu_to_le16(1080), ++ .dwMinBitRate = cpu_to_le32(15360000), ++ .dwMaxBitRate = cpu_to_le32(15360000), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwBytesPerLine = 0, ++ .dwFrameInterval[0] = cpu_to_le32(333333), ++}; ++ ++ ++static const struct UVC_FRAME_BASED(1) uvc_frame_based_2160p = { ++ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), ++ .bDescriptorType = USB_DT_CS_INTERFACE, ++ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, ++ .bFrameIndex = 4, ++ .bmCapabilities = 0, ++ .wWidth = cpu_to_le16(3840), ++ .wHeight = cpu_to_le16(2160), ++ .dwMinBitRate = cpu_to_le32(30720000), ++ .dwMaxBitRate = cpu_to_le32(30720000), ++ .dwDefaultFrameInterval = cpu_to_le32(333333), ++ .bFrameIntervalType = 1, ++ .dwBytesPerLine = 0, ++ .dwFrameInterval[0] = cpu_to_le32(333333), + }; + + static const struct uvc_color_matching_descriptor uvc_color_matching = { +@@ -282,6 +487,8 @@ + (const struct uvc_descriptor_header *) &uvc_control_header, + (const struct uvc_descriptor_header *) &uvc_camera_terminal, + (const struct uvc_descriptor_header *) &uvc_processing, ++ (const struct uvc_descriptor_header *) &uvc_xu_h264_desc, ++ (const struct uvc_descriptor_header *) &uvc_xu_camera_desc, + (const struct uvc_descriptor_header *) &uvc_output_terminal, + NULL, + }; +@@ -290,6 +497,8 @@ + (const struct uvc_descriptor_header *) &uvc_control_header, + (const struct uvc_descriptor_header *) &uvc_camera_terminal, + (const struct uvc_descriptor_header *) &uvc_processing, ++ (const struct uvc_descriptor_header *) &uvc_xu_h264_desc, ++ (const struct uvc_descriptor_header *) &uvc_xu_camera_desc, + (const struct uvc_descriptor_header *) &uvc_output_terminal, + NULL, + }; +@@ -298,10 +507,19 @@ + (const struct uvc_descriptor_header *) &uvc_input_header, + (const struct uvc_descriptor_header *) &uvc_format_yuv, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, +- (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, ++// (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, ++// (const struct uvc_descriptor_header *) &uvc_frame_yuv_1080p, ++// (const struct uvc_descriptor_header *) &uvc_frame_yuv_2160p, + (const struct uvc_descriptor_header *) &uvc_format_mjpg, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, ++ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_1080p, ++ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_2160p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_format_desc, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_360p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_720p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_1080p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_2160p, + (const struct uvc_descriptor_header *) &uvc_color_matching, + NULL, + }; +@@ -310,22 +528,41 @@ + (const struct uvc_descriptor_header *) &uvc_input_header, + (const struct uvc_descriptor_header *) &uvc_format_yuv, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, +- (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, ++// (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, ++// (const struct uvc_descriptor_header *) &uvc_frame_yuv_1080p, ++// (const struct uvc_descriptor_header *) &uvc_frame_yuv_2160p, + (const struct uvc_descriptor_header *) &uvc_format_mjpg, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, ++ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_1080p, ++ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_2160p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_format_desc, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_360p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_720p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_1080p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_2160p, + (const struct uvc_descriptor_header *) &uvc_color_matching, + NULL, + }; + ++ + static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { + (const struct uvc_descriptor_header *) &uvc_input_header, + (const struct uvc_descriptor_header *) &uvc_format_yuv, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, + (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, ++ (const struct uvc_descriptor_header *) &uvc_frame_yuv_1080p, ++// (const struct uvc_descriptor_header *) &uvc_frame_yuv_2160p, + (const struct uvc_descriptor_header *) &uvc_format_mjpg, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, + (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, ++ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_1080p, ++ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_2160p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_format_desc, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_360p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_720p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_1080p, ++ (const struct uvc_descriptor_header *) &uvc_frame_based_2160p, + (const struct uvc_descriptor_header *) &uvc_color_matching, + NULL, + }; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-udc-core.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-udc-core.c.patch new file mode 100644 index 00000000..7f59a8c8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-udc-core.c.patch @@ -0,0 +1,84 @@ +--- linux-4.9.37/drivers/usb/gadget/udc/core.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/udc/core.c 2021-06-07 13:01:34.000000000 +0300 +@@ -966,15 +966,6 @@ + if (udc) + sysfs_notify(&udc->dev.kobj, NULL, "state"); + } +- +-void usb_gadget_set_state(struct usb_gadget *gadget, +- enum usb_device_state state) +-{ +- gadget->state = state; +- schedule_work(&gadget->work); +-} +-EXPORT_SYMBOL_GPL(usb_gadget_set_state); +- + /* ------------------------------------------------------------------------- */ + + static void usb_udc_connect_control(struct usb_udc *udc) +@@ -985,6 +976,24 @@ + usb_gadget_disconnect(udc->gadget); + } + ++/* should be called with udc_lock held */ ++static int check_pending_gadget_drivers(struct usb_udc *udc) ++{ ++ struct usb_gadget_driver *driver; ++ int ret = 0; ++ ++ list_for_each_entry(driver, &gadget_driver_pending_list, pending) ++ if (!driver->udc_name || strcmp(driver->udc_name, ++ dev_name(&udc->dev)) == 0) { ++ ret = udc_bind_to_driver(udc, driver); ++ if (ret != -EPROBE_DEFER) ++ list_del(&driver->pending); ++ break; ++ } ++ ++ return ret; ++} ++ + /** + * usb_udc_vbus_handler - updates the udc core vbus status, and try to + * connect or disconnect gadget +@@ -1005,6 +1014,15 @@ + } + EXPORT_SYMBOL_GPL(usb_udc_vbus_handler); + ++/* ------------------------------------------------------------------------- */ ++void usb_gadget_set_state(struct usb_gadget *gadget, ++ enum usb_device_state state) ++{ ++ gadget->state = state; ++} ++EXPORT_SYMBOL_GPL(usb_gadget_set_state); ++/* ------------------------------------------------------------------------- */ ++ + /** + * usb_gadget_udc_reset - notifies the udc core that bus reset occurs + * @gadget: The gadget which bus reset occurs +@@ -1080,24 +1098,6 @@ + dev_vdbg(dev, "%s\n", __func__); + } + +-/* should be called with udc_lock held */ +-static int check_pending_gadget_drivers(struct usb_udc *udc) +-{ +- struct usb_gadget_driver *driver; +- int ret = 0; +- +- list_for_each_entry(driver, &gadget_driver_pending_list, pending) +- if (!driver->udc_name || strcmp(driver->udc_name, +- dev_name(&udc->dev)) == 0) { +- ret = udc_bind_to_driver(udc, driver); +- if (ret != -EPROBE_DEFER) +- list_del(&driver->pending); +- break; +- } +- +- return ret; +-} +- + /** + * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list + * @parent: the parent device to this udc. Usually the controller driver's diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-udc-trace.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-udc-trace.h.patch new file mode 100644 index 00000000..20ad1da5 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-gadget-udc-trace.h.patch @@ -0,0 +1,23 @@ +--- linux-4.9.37/drivers/usb/gadget/udc/trace.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/gadget/udc/trace.h 2021-06-07 13:01:34.000000000 +0300 +@@ -236,6 +236,7 @@ + __field(unsigned, short_not_ok) + __field(int, status) + __field(int, ret) ++ __field(struct usb_request *, req) + ), + TP_fast_assign( + snprintf(__get_str(name), UDC_TRACE_STR_MAX, "%s", ep->name); +@@ -249,9 +250,10 @@ + __entry->short_not_ok = req->short_not_ok; + __entry->status = req->status; + __entry->ret = ret; ++ __entry->req = req; + ), +- TP_printk("%s: length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", +- __get_str(name), __entry->actual, __entry->length, ++ TP_printk("%s: req %p length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", ++ __get_str(name),__entry->req, __entry->actual, __entry->length, + __entry->num_mapped_sgs, __entry->num_sgs, __entry->stream_id, + __entry->zero ? "Z" : "z", + __entry->short_not_ok ? "S" : "s", diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-hub.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-hub.c.patch new file mode 100644 index 00000000..f2d56e06 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-hub.c.patch @@ -0,0 +1,25 @@ +--- linux-4.9.37/drivers/usb/host/xhci-hub.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/host/xhci-hub.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1049,13 +1049,15 @@ + break; + } + +- /* Software should not attempt to set +- * port link state above '3' (U3) and the port +- * must be enabled. +- */ +- if ((temp & PORT_PE) == 0 || +- (link_state > USB_SS_PORT_LS_U3)) { +- xhci_warn(xhci, "Cannot set link state.\n"); ++ /* port must be enabled */ ++ if (!(temp & PORT_PE)) { ++ retval = -ENODEV; ++ break; ++ } ++ /* Can't set port link state above '3' (U3)*/ ++ if (link_state > USB_SS_PORT_LS_U3) { ++ xhci_warn(xhci, "Cannot set port %d link state %d\n", ++ wIndex, link_state); + goto error; + } + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-mem.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-mem.c.patch new file mode 100644 index 00000000..4d14dff3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-mem.c.patch @@ -0,0 +1,23 @@ +--- linux-4.9.37/drivers/usb/host/xhci-mem.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/host/xhci-mem.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1404,7 +1404,7 @@ + if (udev->speed == USB_SPEED_HIGH && + (usb_endpoint_xfer_isoc(&ep->desc) || + usb_endpoint_xfer_int(&ep->desc))) +- return (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11; ++ return usb_endpoint_maxp_mult(&ep->desc) - 1; + + return 0; + } +@@ -1450,9 +1450,9 @@ + return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); + + max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); +- max_burst = (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11; ++ max_burst = usb_endpoint_maxp_mult(&ep->desc); + /* A 0 in max burst means 1 transfer per ESIT */ +- return max_packet * (max_burst + 1); ++ return max_packet * max_burst; + } + + /* Set up an endpoint with one ring segment. Do not allocate stream rings. diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-plat.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-plat.c.patch new file mode 100644 index 00000000..6d0b0232 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci-plat.c.patch @@ -0,0 +1,12 @@ +--- linux-4.9.37/drivers/usb/host/xhci-plat.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/host/xhci-plat.c 2021-06-07 13:01:34.000000000 +0300 +@@ -220,6 +220,9 @@ + goto disable_clk; + } + ++ if (device_property_read_bool(&pdev->dev, "usb2-lpm-disable")) ++ xhci->quirks |= XHCI_HW_LPM_DISABLE; ++ + if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) + xhci->quirks |= XHCI_LPM_SUPPORT; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci.c.patch new file mode 100644 index 00000000..70903081 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci.c.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/drivers/usb/host/xhci.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/host/xhci.c 2021-06-07 13:01:34.000000000 +0300 +@@ -4131,7 +4131,7 @@ + xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", + enable ? "enable" : "disable", port_num + 1); + +- if (enable) { ++ if (enable && !(xhci->quirks & XHCI_HW_LPM_DISABLE)) { + /* Host supports BESL timeout instead of HIRD */ + if (udev->usb2_hw_lpm_besl_capable) { + /* if device doesn't have a preferred BESL value use a diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci.h.patch new file mode 100644 index 00000000..0b00d046 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-usb-host-xhci.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/drivers/usb/host/xhci.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/usb/host/xhci.h 2021-06-07 13:01:34.000000000 +0300 +@@ -1661,6 +1661,7 @@ + #define XHCI_BROKEN_PORT_PED (1 << 25) + #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) + #define XHCI_U2_DISABLE_WAKE (1 << 27) ++#define XHCI_HW_LPM_DISABLE (1 << 29) + + unsigned int num_active_eps; + unsigned int limit_active_eps; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-video-fbdev-core-fbmem.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-video-fbdev-core-fbmem.c.patch new file mode 100644 index 00000000..eddaef4c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_drivers-video-fbdev-core-fbmem.c.patch @@ -0,0 +1,69 @@ +--- linux-4.9.37/drivers/video/fbdev/core/fbmem.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/drivers/video/fbdev/core/fbmem.c 2021-06-07 13:01:34.000000000 +0300 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + +@@ -1083,7 +1084,24 @@ + return ret; + } + EXPORT_SYMBOL(fb_blank); ++#ifdef CONFIG_ARCH_GOKE ++#ifdef CONFIG_DMA_SHARED_BUFFER ++int ++fb_get_dmabuf(struct fb_info *info, int flags) ++{ ++ struct dma_buf *dmabuf; ++ ++ if (info->fbops->fb_dmabuf_export == NULL) ++ return -ENOTTY; ++ ++ dmabuf = info->fbops->fb_dmabuf_export(info); ++ if (IS_ERR(dmabuf)) ++ return PTR_ERR(dmabuf); + ++ return dma_buf_fd(dmabuf, flags); ++} ++#endif ++#endif /* CONFIG_ARCH_GOKE */ + static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg) + { +@@ -1094,6 +1112,9 @@ + struct fb_cmap cmap_from; + struct fb_cmap_user cmap; + struct fb_event event; ++#if defined(CONFIG_ARCH_GOKE) && defined(CONFIG_DMA_SHARED_BUFFER) ++ struct fb_dmabuf_export dmaexp; ++#endif + void __user *argp = (void __user *)arg; + long ret = 0; + +@@ -1211,6 +1232,23 @@ + unlock_fb_info(info); + console_unlock(); + break; ++#if defined(CONFIG_ARCH_GOKE) && defined(CONFIG_DMA_SHARED_BUFFER) ++ case FBIOGET_DMABUF: ++ if (copy_from_user(&dmaexp, argp, sizeof(dmaexp))) ++ return -EFAULT; ++ ++ if (!lock_fb_info(info)) ++ return -ENODEV; ++ dmaexp.fd = fb_get_dmabuf(info, dmaexp.flags); ++ unlock_fb_info(info); ++ ++ if (dmaexp.fd < 0) ++ return dmaexp.fd; ++ ++ ret = copy_to_user(argp, &dmaexp, sizeof(dmaexp)) ++ ? -EFAULT : 0; ++ break; ++#endif /* CONFIG_ARCH_GOKE */ + default: + if (!lock_fb_info(info)) + return -ENODEV; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-Kconfig.patch new file mode 100644 index 00000000..edf2896d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-Kconfig.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/fs/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -232,6 +232,7 @@ + source "fs/befs/Kconfig" + source "fs/bfs/Kconfig" + source "fs/efs/Kconfig" ++source "fs/yaffs2/Kconfig" + source "fs/jffs2/Kconfig" + # UBIFS File system configuration + source "fs/ubifs/Kconfig" diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-Makefile.patch new file mode 100644 index 00000000..0d93e959 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-Makefile.patch @@ -0,0 +1,7 @@ +--- linux-4.9.37/fs/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -129,3 +129,4 @@ + obj-$(CONFIG_CEPH_FS) += ceph/ + obj-$(CONFIG_PSTORE) += pstore/ + obj-$(CONFIG_EFIVAR_FS) += efivarfs/ ++obj-$(CONFIG_YAFFS_FS) += yaffs2/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-buffer.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-buffer.c.patch new file mode 100644 index 00000000..b6b04bff --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-buffer.c.patch @@ -0,0 +1,44 @@ +--- linux-4.9.37/fs/buffer.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/buffer.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1276,10 +1276,17 @@ + */ + static void bh_lru_install(struct buffer_head *bh) + { +- struct buffer_head *evictee = NULL; ++#ifdef CONFIG_GOKE_MC ++ struct buffer_head *evictee = bh; ++ struct bh_lru *b; ++ int i; ++#else ++ struct buffer_head *evictee = NULL; ++#endif + + check_irqs_on(); + bh_lru_lock(); ++#ifndef CONFIG_GOKE_MC + if (__this_cpu_read(bh_lrus.bhs[0]) != bh) { + struct buffer_head *bhs[BH_LRU_SIZE]; + int in; +@@ -1310,6 +1317,22 @@ + + if (evictee) + __brelse(evictee); ++#endif ++ ++#ifdef CONFIG_GOKE_MC ++ b = this_cpu_ptr(&bh_lrus); ++ for (i = 0; i < BH_LRU_SIZE; i++) { ++ swap(evictee, b->bhs[i]); ++ if (evictee == bh) { ++ bh_lru_unlock(); ++ return; ++ } ++ } ++ ++ get_bh(bh); ++ bh_lru_unlock(); ++ brelse(evictee); ++#endif + } + + /* diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-compat_ioctl.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-compat_ioctl.c.patch new file mode 100644 index 00000000..23fb6fa1 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-compat_ioctl.c.patch @@ -0,0 +1,14 @@ +--- linux-4.9.37/fs/compat_ioctl.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/compat_ioctl.c 2021-06-07 13:01:34.000000000 +0300 +@@ -750,9 +750,9 @@ + if (!access_ok(VERIFY_READ, udata, sizeof(*udata))) + return -EFAULT; + +- if (__copy_in_user(&tdata->read_write, &udata->read_write, 2 * sizeof(u8))) ++ if (copy_in_user(&tdata->read_write, &udata->read_write, 2 * sizeof(u8))) + return -EFAULT; +- if (__copy_in_user(&tdata->size, &udata->size, 2 * sizeof(u32))) ++ if (copy_in_user(&tdata->size, &udata->size, 2 * sizeof(u32))) + return -EFAULT; + if (__get_user(datap, &udata->data) || + __put_user(compat_ptr(datap), &tdata->data)) diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-dcache.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-dcache.c.patch new file mode 100644 index 00000000..46447b0b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-dcache.c.patch @@ -0,0 +1,16 @@ +--- linux-4.9.37/fs/dcache.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/dcache.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1137,7 +1137,12 @@ + + this_cpu_sub(nr_dentry_unused, freed); + shrink_dentry_list(&dispose); +- } while (freed > 0); ++#ifdef CONFIG_GOKE_MC ++ cond_resched(); ++ } while (list_lru_count(&sb->s_dentry_lru) > 0); ++#else ++ } while (freed > 0); ++#endif + } + EXPORT_SYMBOL(shrink_dcache_sb); + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-dir.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-dir.c.patch new file mode 100644 index 00000000..49809634 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-dir.c.patch @@ -0,0 +1,403 @@ +--- linux-4.9.37/fs/fat/dir.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/fat/dir.c 2021-06-07 13:01:34.000000000 +0300 +@@ -782,6 +782,388 @@ + ret = buf.result; + return ret; + } ++#ifdef CONFIG_GOKE_MC ++/* ++ * This is the "fatfilldirall_t" function type, ++ * used by fat_ioctl_filldirall to let ++ * the kernel specify what kind of dirent layout it wants to have. ++ * This allows the kernel to read directories into kernel space or ++ * to have different dirent layouts depending on the binary type. ++ */ ++typedef int (*fatfilldirall_t)(void *__buf, const char *name, ++ int name_len, loff_t offset, u64 ino, ++ unsigned int d_type, struct msdos_dir_entry *de, ++ char *d_createtime); ++struct fatdirall_context { ++ const fatfilldirall_t actor; ++ loff_t pos; ++}; ++ ++struct fat_ioctl_filldirall_callback { ++ struct fatdirall_context ctx; ++ struct fat_direntall __user *current_dir; ++ struct fat_direntall __user *previous; ++ int count; ++ int usecount; ++ int error; ++ int result; ++ const char *longname; ++ int long_len; ++ const char *shortname; ++ int short_len; ++}; ++ ++static inline bool fat_dir_emit(struct fatdirall_context *ctx, ++ const char *name, int namelen, ++ u64 ino, unsigned type, ++ struct msdos_dir_entry *de, ++ char *d_createtime) ++{ ++ return ctx->actor(ctx, name, namelen, ctx->pos, ino, ++ type, de, d_createtime) == 0; ++} ++static inline bool fat_dir_emit_dot(struct file *file, ++ struct fatdirall_context *ctx, ++ struct msdos_dir_entry *de, ++ char *d_createtime) ++{ ++ return ctx->actor(ctx, ".", 1, ctx->pos, ++ file->f_path.dentry->d_inode->i_ino, ++ DT_DIR, de, d_createtime) == 0; ++} ++static inline bool fat_dir_emit_dotdot(struct file *file, ++ struct fatdirall_context *ctx, ++ struct msdos_dir_entry *de, ++ char *d_createtime) ++{ ++ return ctx->actor(ctx, "..", 2, ctx->pos, ++ parent_ino(file->f_path.dentry), ++ DT_DIR, de, d_createtime) == 0; ++} ++ ++static inline bool fat_dir_emit_dots(struct file *file, ++ struct fatdirall_context *ctx, ++ struct msdos_dir_entry *de, ++ char *d_createtime) ++{ ++ if (ctx->pos == 0) { ++ if (!fat_dir_emit_dot(file, ctx, de, d_createtime)) ++ return false; ++ ctx->pos = 1; ++ } ++ if (ctx->pos == 1) { ++ if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime)) ++ return false; ++ ctx->pos = 2; ++ } ++ return true; ++} ++ ++ ++static int __fat_readdirall(struct inode *inode, struct file *file, ++ struct fatdirall_context *ctx, int short_only, ++ struct fat_ioctl_filldirall_callback *both) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct msdos_sb_info *sbi = MSDOS_SB(sb); ++ struct buffer_head *bh; ++ struct msdos_dir_entry *de; ++ unsigned char nr_slots; ++ wchar_t *unicode = NULL; ++ unsigned char bufname[FAT_MAX_SHORT_SIZE]; ++ int isvfat = sbi->options.isvfat; ++ const char *fill_name = NULL; ++ int fake_offset = 0; ++ loff_t cpos; ++ int short_len = 0, fill_len = 0; ++ int ret = 0; ++ char d_createtime[8]; ++ ++ mutex_lock(&sbi->s_lock); ++ ++ cpos = ctx->pos; ++ /* Fake . and .. for the root directory. */ ++ if (inode->i_ino == MSDOS_ROOT_INO) { ++ if (!fat_dir_emit_dots(file, ctx, NULL, NULL)) ++ goto out; ++ if (ctx->pos == 2) { ++ fake_offset = 1; ++ cpos = 0; ++ } ++ } ++ if (cpos & (sizeof(struct msdos_dir_entry) - 1)) { ++ ret = -ENOENT; ++ goto out; ++ } ++ ++ bh = NULL; ++get_new: ++ if (fat_get_entry(inode, &cpos, &bh, &de) == -1) ++ goto end_of_dir; ++parse_record: ++ nr_slots = 0; ++ /* ++ * Check for long filename entry, but if short_only, we don't ++ * need to parse long filename. ++ */ ++ if (isvfat && !short_only) { ++ if (de->name[0] == DELETED_FLAG) ++ goto record_end; ++ if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME)) ++ goto record_end; ++ if (de->attr != ATTR_EXT && IS_FREE(de->name)) ++ goto record_end; ++ } else { ++ if ((de->attr & ATTR_VOLUME) || IS_FREE(de->name)) ++ goto record_end; ++ } ++ ++ if (isvfat && de->attr == ATTR_EXT) { ++ int status = fat_parse_long(inode, &cpos, &bh, &de, ++ &unicode, &nr_slots); ++ if (status < 0) { ++ ctx->pos = cpos; ++ ret = status; ++ goto out; ++ } else if (status == PARSE_INVALID) ++ goto record_end; ++ else if (status == PARSE_NOT_LONGNAME) ++ goto parse_record; ++ else if (status == PARSE_EOF) ++ goto end_of_dir; ++ ++ if (nr_slots) { ++ void *longname = unicode + FAT_MAX_UNI_CHARS; ++ int size = PATH_MAX - FAT_MAX_UNI_SIZE; ++ int len = fat_uni_to_x8(sb, unicode, longname, size); ++ ++ fill_name = longname; ++ fill_len = len; ++ ++ short_len = fat_parse_short(sb, de, bufname, ++ sbi->options.dotsOK); ++ if (short_len == 0) ++ goto record_end; ++ ++ /* hack for fat_ioctl_filldir() */ ++ both->longname = fill_name; ++ both->long_len = fill_len; ++ both->shortname = bufname; ++ both->short_len = short_len; ++ fill_name = NULL; ++ fill_len = 0; ++ goto start_filldir; ++ } ++ } ++ ++ short_len = fat_parse_short(sb, de, bufname, sbi->options.dotsOK); ++ if (short_len == 0) ++ goto record_end; ++ ++ fill_name = bufname; ++ fill_len = short_len; ++ ++start_filldir: ++ if (!fake_offset) ++ ctx->pos = cpos - (nr_slots + 1) ++ * sizeof(struct msdos_dir_entry); ++ ++ memset(d_createtime, 0, 8); ++ fat_time_fat2str(sbi, d_createtime, de->ctime, ++ de->cdate, de->ctime_cs); ++ ++ if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME)) { ++ if (!fat_dir_emit_dot(file, ctx, de, d_createtime)) ++ goto fill_failed; ++ } else if (!memcmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) { ++ if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime)) ++ goto fill_failed; ++ } else { ++ unsigned long inum; ++ loff_t i_pos = fat_make_i_pos(sb, bh, de); ++ struct inode *tmp = fat_iget(sb, i_pos); ++ ++ if (tmp) { ++ inum = tmp->i_ino; ++ iput(tmp); ++ } else ++ inum = iunique(sb, MSDOS_ROOT_INO); ++ if (!fat_dir_emit(ctx, fill_name, fill_len, inum, ++ (de->attr & ATTR_DIR) ? DT_DIR : DT_REG, ++ de, d_createtime)) ++ goto fill_failed; ++ } ++ ++record_end: ++ fake_offset = 0; ++ ctx->pos = cpos; ++ goto get_new; ++end_of_dir: ++ ctx->pos = cpos; ++fill_failed: ++ brelse(bh); ++ if (unicode) ++ __putname(unicode); ++out: ++ mutex_unlock(&sbi->s_lock); ++ return ret; ++} ++ ++static int fat_ioctl_filldirall(void *__buf, const char *name, ++ int name_len, loff_t offset, ++ u64 ino, unsigned int d_type, ++ struct msdos_dir_entry *de, ++ char *d_createtime) ++{ ++ struct fat_direntall __user *dirent; ++ struct fat_ioctl_filldirall_callback *buf; ++ unsigned long d_ino; ++ int reclen = 0; ++ const char *longname = NULL; ++ int long_len = 0; ++ const char *shortname = NULL; ++ int short_len = 0; ++ ++ buf = (struct fat_ioctl_filldirall_callback *) __buf; ++ ++ if (name != NULL) { ++ reclen = ALIGN(offsetof(struct fat_direntall, d_name) ++ + name_len + 2, sizeof(long)); ++ } else { ++ longname = buf->longname; ++ long_len = buf->long_len; ++ shortname = buf->shortname; ++ short_len = buf->short_len; ++ reclen = ALIGN(offsetof(struct fat_direntall, d_name) ++ + long_len + 2, sizeof(long)); ++ } ++ ++ buf->error = -EINVAL; /* only used if we fail.. */ ++ ++ if (reclen >= buf->count) ++ return -EINVAL; ++ ++ d_ino = ino; ++ ++ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { ++ buf->error = -EOVERFLOW; ++ return -EOVERFLOW; ++ } ++ ++ dirent = buf->previous; ++ ++ if (dirent) { ++ if (__put_user(offset, &dirent->d_off)) ++ goto efault; ++ } ++ ++ dirent = buf->current_dir; ++ ++ if (__put_user(d_ino, &dirent->d_ino)) ++ goto efault; ++ ++ if (__put_user(reclen, &dirent->d_reclen)) ++ goto efault; ++ ++ if (name != NULL) { ++ if (copy_to_user(dirent->d_name, name, name_len)) ++ goto efault; ++ if (__put_user(0, dirent->d_name + name_len)) ++ goto efault; ++ } else { ++ if (copy_to_user(dirent->d_name, longname, long_len)) ++ goto efault; ++ if (__put_user(0, dirent->d_name + long_len)) ++ goto efault; ++ } ++ ++ if (__put_user(d_type, &dirent->d_type)) ++ goto efault; ++ ++ if (de != NULL) { ++ u64 u_size = 0; ++ if (copy_to_user(&dirent->d_size, &u_size, sizeof(u64))) ++ goto efault; ++ if (copy_to_user(&dirent->d_size, &de->size, sizeof(u32))) ++ goto efault; ++ } ++ ++ if (d_createtime != NULL) { ++ if (copy_to_user(dirent->d_createtime, d_createtime, 8)) ++ goto efault; ++ } ++ buf->previous = dirent; ++ dirent = (void __user *)dirent + reclen; ++ buf->current_dir = dirent; ++ buf->count -= reclen; ++ buf->usecount += reclen; ++ return 0; ++efault: ++ buf->error = -EFAULT; ++ return -EFAULT; ++} ++ ++ ++static int fat_ioctl_readdirall(struct inode *inode, struct file *file, ++ void __user *dirent, ++ int short_only, int both) ++{ ++ struct fat_ioctl_filldirall_callback buf = { ++ .ctx.actor = fat_ioctl_filldirall, ++ }; ++ ++ struct fat_direntall_buf __user *userbuf = dirent; ++ int ret; ++ ++ buf.current_dir = &(userbuf->direntall); ++ buf.previous = NULL; ++ buf.error = 0; ++ buf.result = 0; ++ buf.usecount = 0; ++ ++ if (get_user(buf.count, &(userbuf->d_count))) ++ return -EFAULT; ++ ++ up_read(&inode->i_rwsem); ++ buf.ctx.pos = file->f_pos; ++ ret = -ENOENT; ++ if (!IS_DEADDIR(inode)) { ++ ret = __fat_readdirall(inode, file, &buf.ctx, ++ short_only, both ? &buf : NULL); ++ file->f_pos = buf.ctx.pos; ++ } ++ down_read(&inode->i_rwsem); ++ ++ if (__put_user(buf.usecount, &(userbuf->d_usecount))) ++ return -EFAULT; ++ if (ret >= 0) ++ ret = buf.result; ++ return ret; ++} ++ ++static int fat_dir_ioctl_readdirall(struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct inode *inode = filp->f_path.dentry->d_inode; ++ struct fat_direntall_buf __user *direntallbuf; ++ int short_only, both; ++ ++ direntallbuf = (struct fat_direntall_buf __user *)arg; ++ ++ if (!access_ok(VERIFY_WRITE, direntallbuf, ++ sizeof(struct fat_direntall_buf))) ++ return -EFAULT; ++ if (put_user(0, &(direntallbuf->direntall.d_reclen))) ++ return -EFAULT; ++ if (put_user(0, &(direntallbuf->d_usecount))) ++ return -EFAULT; ++ short_only = 0; ++ both = 1; ++ return fat_ioctl_readdirall(inode, filp, direntallbuf, ++ short_only, both); ++} ++#endif ++ + + static long fat_dir_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +@@ -789,7 +1171,10 @@ + struct inode *inode = file_inode(filp); + struct __fat_dirent __user *d1 = (struct __fat_dirent __user *)arg; + int short_only, both; +- ++#ifdef CONFIG_GOKE_MC ++ if (VFAT_IOCTL_READDIR_ALL == cmd) ++ return fat_dir_ioctl_readdirall(filp, cmd, arg); ++#endif + switch (cmd) { + case VFAT_IOCTL_READDIR_SHORT: + short_only = 1; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-fat.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-fat.h.patch new file mode 100644 index 00000000..f24b7118 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-fat.h.patch @@ -0,0 +1,13 @@ +--- linux-4.9.37/fs/fat/fat.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/fat/fat.h 2021-06-07 13:01:34.000000000 +0300 +@@ -409,6 +409,10 @@ + __le16 __time, __le16 __date, u8 time_cs); + extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts, + __le16 *time, __le16 *date, u8 *time_cs); ++#ifdef CONFIG_GOKE_MC ++extern void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime, ++ __le16 __time, __le16 __date, u8 time_cs); ++#endif + extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); + + int fat_cache_init(void); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-fatent.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-fatent.c.patch new file mode 100644 index 00000000..8527f6fb --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-fatent.c.patch @@ -0,0 +1,12 @@ +--- linux-4.9.37/fs/fat/fatent.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/fat/fatent.c 2021-06-07 13:01:34.000000000 +0300 +@@ -380,6 +380,9 @@ + int err, n, copy; + + err = 0; ++#ifdef CONFIG_GOKE_MC ++ return 0; ++#endif + for (copy = 1; copy < sbi->fats; copy++) { + sector_t backup_fat = sbi->fat_length * copy; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-file.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-file.c.patch new file mode 100644 index 00000000..f117fa24 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-file.c.patch @@ -0,0 +1,72 @@ +--- linux-4.9.37/fs/fat/file.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/fat/file.c 2021-06-07 13:01:34.000000000 +0300 +@@ -167,8 +167,17 @@ + + return res ? res : err; + } ++#ifdef CONFIG_GOKE_MC ++int fat_file_flush(struct file *file, fl_owner_t id) ++{ ++ struct address_space * mapping = file->f_mapping; ++ struct inode *inode = mapping->host; + ++ inode->i_sb->s_op->write_inode(inode, NULL); + ++ return 0; ++} ++#endif + const struct file_operations fat_file_operations = { + .llseek = generic_file_llseek, + .read_iter = generic_file_read_iter, +@@ -182,6 +191,9 @@ + .fsync = fat_file_fsync, + .splice_read = generic_file_splice_read, + .fallocate = fat_fallocate, ++#ifdef CONFIG_GOKE_MC ++ .flush = fat_file_flush, ++#endif + }; + + static int fat_cont_expand(struct inode *inode, loff_t size) +@@ -431,7 +443,13 @@ + /* use a default check */ + return 0; + } +- ++#ifdef CONFIG_GOKE_MC ++void reset_mmu_private(struct inode *inode, loff_t offset) ++{ ++ MSDOS_I(inode)->mmu_private = offset; ++ inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; ++} ++#endif + #define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET) + /* valid file mode bits */ + #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO) +@@ -464,6 +482,7 @@ + * hole before it. XXX: this is no longer true with new truncate + * sequence. + */ ++#ifndef CONFIG_GOKE_MC + if (attr->ia_valid & ATTR_SIZE) { + inode_dio_wait(inode); + +@@ -474,7 +493,7 @@ + attr->ia_valid &= ~ATTR_SIZE; + } + } +- ++#endif + if (((attr->ia_valid & ATTR_UID) && + (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) || + ((attr->ia_valid & ATTR_GID) && +@@ -504,6 +523,9 @@ + goto out; + down_write(&MSDOS_I(inode)->truncate_lock); + truncate_setsize(inode, attr->ia_size); ++#ifdef CONFIG_GOKE_MC ++ reset_mmu_private(inode, attr->ia_size); ++#endif + fat_truncate_blocks(inode, attr->ia_size); + up_write(&MSDOS_I(inode)->truncate_lock); + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-inode.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-inode.c.patch new file mode 100644 index 00000000..c5d89d57 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-inode.c.patch @@ -0,0 +1,124 @@ +--- linux-4.9.37/fs/fat/inode.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/fat/inode.c 2021-06-07 13:01:34.000000000 +0300 +@@ -615,8 +615,9 @@ + round_up(MSDOS_I(inode)->mmu_private, + MSDOS_SB(inode->i_sb)->cluster_size)) { + int err; +- ++#ifndef CONFIG_GOKE_MC + fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private); ++#endif + /* Fallocate results in updating the i_start/iogstart + * for the zero byte file. So, make it return to + * original state during evict and commit it to avoid +@@ -873,15 +874,87 @@ + spin_unlock(&sbi->inode_hash_lock); + mark_buffer_dirty(bh); + err = 0; +- if (wait) ++ if (wait) { + err = sync_dirty_buffer(bh); ++ } + brelse(bh); + return err; + } ++#ifdef CONFIG_GOKE_MC ++static int __fat_write_inode_(struct inode *inode, int wait) ++{ ++ struct super_block *sb = inode->i_sb; ++ struct msdos_sb_info *sbi = MSDOS_SB(sb); ++ struct buffer_head *bh; ++ struct msdos_dir_entry *raw_entry; ++ loff_t i_pos; ++ sector_t blocknr; ++ int err = 0; ++ int offset; ++ ++ if (inode->i_ino == MSDOS_ROOT_INO) ++ return 0; ++ ++retry: ++ i_pos = fat_i_pos_read(sbi, inode); ++ if (!i_pos) ++ return 0; ++ ++ fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset); ++ bh = sb_bread(sb, blocknr); ++ if (!bh) { ++ fat_msg(sb, KERN_ERR, "unable to read inode block " ++ "for updating (i_pos %lld)", i_pos); ++ return -EIO; ++ } ++ spin_lock(&sbi->inode_hash_lock); ++ if (i_pos != MSDOS_I(inode)->i_pos) { ++ spin_unlock(&sbi->inode_hash_lock); ++ brelse(bh); ++ goto retry; ++ } + ++#if 0 ++ dump_stack(); ++ printk("%s :inode %p/%s, size %llx, logstart %x, blocknr %lx, wait %d\n", ++ __func__, inode, S_ISDIR(inode->i_mode)? "dir":"file", inode->i_size, ++ MSDOS_I(inode)->i_logstart, blocknr, wait); ++#endif ++ raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset]; ++ if (S_ISDIR(inode->i_mode)) ++ raw_entry->size = 0; ++ else { ++ //raw_entry->size = cpu_to_le32(inode->i_size); ++ if ((0 != raw_entry->start) || (0 != raw_entry->starthi)) { ++ spin_unlock(&sbi->inode_hash_lock); ++ goto file_out; ++ } ++ raw_entry->size = cpu_to_le32(inode->i_size); ++ } ++ raw_entry->attr = fat_make_attrs(inode); ++ fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart); ++ fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time, ++ &raw_entry->date, NULL); ++ if (sbi->options.isvfat) { ++ __le16 atime; ++ fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime, ++ &raw_entry->cdate, &raw_entry->ctime_cs); ++ fat_time_unix2fat(sbi, &inode->i_atime, &atime, ++ &raw_entry->adate, NULL); ++ } ++ spin_unlock(&sbi->inode_hash_lock); ++ mark_buffer_dirty(bh); ++ if (wait) { ++ err = sync_dirty_buffer(bh); ++ } ++file_out: ++ brelse(bh); ++ return err; ++} ++#endif + static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) + { +- int err; ++ int err = 0; + + if (inode->i_ino == MSDOS_FSINFO_INO) { + struct super_block *sb = inode->i_sb; +@@ -889,8 +962,18 @@ + mutex_lock(&MSDOS_SB(sb)->s_lock); + err = fat_clusters_flush(sb); + mutex_unlock(&MSDOS_SB(sb)->s_lock); +- } else +- err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); ++ } else { ++#ifdef CONFIG_GOKE_MC ++ if (NULL == wbc){ ++ err = __fat_write_inode(inode, 1); ++ } ++ else{ ++ err = __fat_write_inode_(inode, wbc->sync_mode == WB_SYNC_ALL); ++ } ++#else ++ err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); ++#endif ++ } + + return err; + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-misc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-misc.c.patch new file mode 100644 index 00000000..d5269f5e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-fat-misc.c.patch @@ -0,0 +1,40 @@ +--- linux-4.9.37/fs/fat/misc.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/fat/misc.c 2021-06-07 13:01:34.000000000 +0300 +@@ -261,6 +261,37 @@ + *time_cs = (ts->tv_sec & 1) * 100 + ts->tv_nsec / 10000000; + } + EXPORT_SYMBOL_GPL(fat_time_unix2fat); ++#ifdef CONFIG_GOKE_MC ++void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime, ++ __le16 __time, __le16 __date, u8 time_cs) ++{ ++ u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date); ++ time_t day, month, year; ++ ++ year = date >> 9; ++ month = max(1, (date >> 5) & 0xf); ++ day = max(1, date & 0x1f) - 1; ++ ++ d_createtime[0] = year; ++ d_createtime[1] = month; ++ d_createtime[2] = day; ++ d_createtime[3] = (time >> 11); /*hour*/ ++ d_createtime[4] = ((time >> 5) & 0x3f); /*min*/ ++ d_createtime[5] = (time & 0x1f); /*second 2s*/ ++ ++ ++ if (!sbi->options.tz_set) ++ d_createtime[4] += sys_tz.tz_minuteswest; ++ else ++ d_createtime[4] -= sbi->options.time_offset; ++ ++ if (time_cs) { ++ /*second 1s*/ ++ d_createtime[5] += (time_cs / 100); ++ } ++} ++EXPORT_SYMBOL_GPL(fat_time_fat2str); ++#endif + + int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) + { diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-Kconfig.patch new file mode 100644 index 00000000..16234e59 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-Kconfig.patch @@ -0,0 +1,18 @@ +--- linux-4.9.37/fs/jffs2/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/jffs2/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -139,6 +139,15 @@ + This feature was added in July, 2007. Say 'N' if you need + compatibility with older bootloaders or kernels. + ++config JFFS2_LZMA ++ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS ++ select LZMA_COMPRESS ++ select LZMA_DECOMPRESS ++ depends on JFFS2_FS ++ default n ++ help ++ JFFS2 wrapper to the LZMA C SDK ++ + config JFFS2_RTIME + bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS + depends on JFFS2_FS diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-Makefile.patch new file mode 100644 index 00000000..39155988 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/fs/jffs2/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/jffs2/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -18,4 +18,7 @@ + jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o + jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o + jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o ++jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o + jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o ++ ++CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr.c.patch new file mode 100644 index 00000000..3179f586 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr.c.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/fs/jffs2/compr.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/jffs2/compr.c 2021-06-07 13:01:34.000000000 +0300 +@@ -378,6 +378,9 @@ + #ifdef CONFIG_JFFS2_LZO + jffs2_lzo_init(); + #endif ++#ifdef CONFIG_JFFS2_LZMA ++ jffs2_lzma_init(); ++#endif + /* Setting default compression mode */ + #ifdef CONFIG_JFFS2_CMODE_NONE + jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; +@@ -401,6 +404,9 @@ + int jffs2_compressors_exit(void) + { + /* Unregistering compressors */ ++#ifdef CONFIG_JFFS2_LZMA ++ jffs2_lzma_exit(); ++#endif + #ifdef CONFIG_JFFS2_LZO + jffs2_lzo_exit(); + #endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr.h.patch new file mode 100644 index 00000000..20386bbc --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr.h.patch @@ -0,0 +1,29 @@ +--- linux-4.9.37/fs/jffs2/compr.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/jffs2/compr.h 2021-06-07 13:01:34.000000000 +0300 +@@ -29,9 +29,15 @@ + #define JFFS2_DYNRUBIN_PRIORITY 20 + #define JFFS2_LZARI_PRIORITY 30 + #define JFFS2_RTIME_PRIORITY 50 ++ ++#ifdef CONFIG_GOKE_MC ++#define JFFS2_LZMA_PRIORITY 70 ++#define JFFS2_ZLIB_PRIORITY 80 ++#define JFFS2_LZO_PRIORITY 90 ++#else + #define JFFS2_ZLIB_PRIORITY 60 + #define JFFS2_LZO_PRIORITY 80 +- ++#endif + + #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ + #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ +@@ -101,5 +107,9 @@ + int jffs2_lzo_init(void); + void jffs2_lzo_exit(void); + #endif ++#ifdef CONFIG_JFFS2_LZMA ++int jffs2_lzma_init(void); ++void jffs2_lzma_exit(void); ++#endif + + #endif /* __JFFS2_COMPR_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr_lzma.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr_lzma.c.patch new file mode 100644 index 00000000..200f8174 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-compr_lzma.c.patch @@ -0,0 +1,128 @@ +--- linux-4.9.37/fs/jffs2/compr_lzma.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/jffs2/compr_lzma.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,125 @@ ++/* ++ * JFFS2 -- Journalling Flash File System, Version 2. ++ * ++ * For licensing information, see the file 'LICENCE' in this directory. ++ * ++ * JFFS2 wrapper to the LZMA C SDK ++ * ++ */ ++ ++#include ++#include "compr.h" ++ ++#ifdef __KERNEL__ ++ static DEFINE_MUTEX(deflate_mutex); ++#endif ++ ++CLzmaEncHandle *p; ++Byte propsEncoded[LZMA_PROPS_SIZE]; ++SizeT propsSize = sizeof(propsEncoded); ++ ++STATIC void lzma_free_workspace(void) ++{ ++ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); ++} ++ ++STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) ++{ ++ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) { ++ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); ++ return -ENOMEM; ++ } ++ ++ if (LzmaEnc_SetProps(p, props) != SZ_OK) { ++ lzma_free_workspace(); ++ return -1; ++ } ++ ++ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) { ++ lzma_free_workspace(); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t *sourcelen, uint32_t *dstlen) ++{ ++ SizeT compress_size = (SizeT)(*dstlen); ++ int ret; ++ ++#ifdef __KERNEL__ ++ mutex_lock(&deflate_mutex); ++#endif ++ ++ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, ++ 0, NULL, &lzma_alloc, &lzma_alloc); ++ ++#ifdef __KERNEL__ ++ mutex_unlock(&deflate_mutex); ++#endif ++ ++ if (ret != SZ_OK) ++ return -1; ++ ++ *dstlen = (uint32_t)compress_size; ++ ++ return 0; ++} ++ ++STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, ++ uint32_t srclen, uint32_t destlen) ++{ ++ int ret; ++ SizeT dl = (SizeT)destlen; ++ SizeT sl = (SizeT)srclen; ++ ELzmaStatus status; ++ ++ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, ++ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); ++ ++ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) ++ return -1; ++ ++ return 0; ++} ++ ++static struct jffs2_compressor jffs2_lzma_comp = { ++ .priority = JFFS2_LZMA_PRIORITY, ++ .name = "lzma", ++ .compr = JFFS2_COMPR_LZMA, ++ .compress = &jffs2_lzma_compress, ++ .decompress = &jffs2_lzma_decompress, ++ .disabled = 0, ++}; ++ ++int INIT jffs2_lzma_init(void) ++{ ++ int ret; ++ CLzmaEncProps props; ++ LzmaEncProps_Init(&props); ++ ++ props.dictSize = LZMA_BEST_DICT(0x2000); ++ props.level = LZMA_BEST_LEVEL; ++ props.lc = LZMA_BEST_LC; ++ props.lp = LZMA_BEST_LP; ++ props.pb = LZMA_BEST_PB; ++ props.fb = LZMA_BEST_FB; ++ ++ ret = lzma_alloc_workspace(&props); ++ if (ret < 0) ++ return ret; ++ ++ ret = jffs2_register_compressor(&jffs2_lzma_comp); ++ if (ret) ++ lzma_free_workspace(); ++ ++ return ret; ++} ++ ++void jffs2_lzma_exit(void) ++{ ++ jffs2_unregister_compressor(&jffs2_lzma_comp); ++ lzma_free_workspace(); ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-super.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-super.c.patch new file mode 100644 index 00000000..d4396167 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-jffs2-super.c.patch @@ -0,0 +1,47 @@ +--- linux-4.9.37/fs/jffs2/super.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/jffs2/super.c 2021-06-07 13:01:34.000000000 +0300 +@@ -372,14 +372,41 @@ + BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); + BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); + +- pr_info("version 2.2." ++ pr_info("version 2.2" + #ifdef CONFIG_JFFS2_FS_WRITEBUFFER + " (NAND)" + #endif + #ifdef CONFIG_JFFS2_SUMMARY +- " (SUMMARY) " ++ " (SUMMARY)" + #endif +- " © 2001-2006 Red Hat, Inc.\n"); ++#ifdef CONFIG_JFFS2_ZLIB ++ " (ZLIB)" ++#endif ++#ifdef CONFIG_JFFS2_LZO ++ " (LZO)" ++#endif ++#ifdef CONFIG_JFFS2_LZMA ++ " (LZMA)" ++#endif ++#ifdef CONFIG_JFFS2_RTIME ++ " (RTIME)" ++#endif ++#ifdef CONFIG_JFFS2_RUBIN ++ " (RUBIN)" ++#endif ++#ifdef CONFIG_JFFS2_CMODE_NONE ++ " (CMODE_NONE)" ++#endif ++#ifdef CONFIG_JFFS2_CMODE_PRIORITY ++ " (CMODE_PRIORITY)" ++#endif ++#ifdef CONFIG_JFFS2_CMODE_SIZE ++ " (CMODE_SIZE)" ++#endif ++#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO ++ " (CMODE_FAVOURLZO)" ++#endif ++ " (c) 2001-2006 Red Hat, Inc.\n"); + + jffs2_inode_cachep = kmem_cache_create("jffs2_i", + sizeof(struct jffs2_inode_info), diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-xfs-xfs_buf.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-xfs-xfs_buf.c.patch new file mode 100644 index 00000000..e41c3385 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-xfs-xfs_buf.c.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/fs/xfs/xfs_buf.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/xfs/xfs_buf.c 2021-06-07 13:01:34.000000000 +0300 +@@ -116,7 +116,7 @@ + __xfs_buf_ioacct_dec( + struct xfs_buf *bp) + { +- ASSERT(spin_is_locked(&bp->b_lock)); ++ lockdep_assert_held(&bp->b_lock); + + if (bp->b_state & XFS_BSTATE_IN_FLIGHT) { + bp->b_state &= ~XFS_BSTATE_IN_FLIGHT; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-xfs-xfs_icache.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-xfs-xfs_icache.c.patch new file mode 100644 index 00000000..0ab25225 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-xfs-xfs_icache.c.patch @@ -0,0 +1,28 @@ +--- linux-4.9.37/fs/xfs/xfs_icache.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/fs/xfs/xfs_icache.c 2021-06-07 13:01:34.000000000 +0300 +@@ -66,7 +66,6 @@ + + XFS_STATS_INC(mp, vn_active); + ASSERT(atomic_read(&ip->i_pincount) == 0); +- ASSERT(!spin_is_locked(&ip->i_flags_lock)); + ASSERT(!xfs_isiflocked(ip)); + ASSERT(ip->i_ino == 0); + +@@ -192,7 +191,7 @@ + { + struct xfs_mount *mp = pag->pag_mount; + +- ASSERT(spin_is_locked(&pag->pag_ici_lock)); ++ lockdep_assert_held(&pag->pag_ici_lock); + if (pag->pag_ici_reclaimable++) + return; + +@@ -214,7 +213,7 @@ + { + struct xfs_mount *mp = pag->pag_mount; + +- ASSERT(spin_is_locked(&pag->pag_ici_lock)); ++ lockdep_assert_held(&pag->pag_ici_lock); + if (--pag->pag_ici_reclaimable) + return; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-Kconfig.patch new file mode 100644 index 00000000..3295e71f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-Kconfig.patch @@ -0,0 +1,174 @@ +--- linux-4.9.37/fs/yaffs2/Kconfig 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,171 @@ ++# ++# yaffs file system configurations ++# ++ ++config YAFFS_FS ++ tristate "yaffs2 file system support" ++ default n ++ depends on MTD_BLOCK ++ select YAFFS_YAFFS1 ++ select YAFFS_YAFFS2 ++ help ++ yaffs2, or Yet Another Flash File System, is a file system ++ optimised for NAND Flash chips. ++ ++ To compile the yaffs2 file system support as a module, choose M ++ here: the module will be called yaffs2. ++ ++ If unsure, say N. ++ ++ Further information on yaffs2 is available at ++ . ++ ++config YAFFS_YAFFS1 ++ bool "512 byte / page devices" ++ depends on YAFFS_FS ++ default y ++ help ++ Enable yaffs1 support -- yaffs for 512 byte / page devices ++ ++ Not needed for 2K-page devices. ++ ++ If unsure, say Y. ++ ++config YAFFS_9BYTE_TAGS ++ bool "Use older-style on-NAND data format with pageStatus byte" ++ depends on YAFFS_YAFFS1 ++ default n ++ help ++ ++ Older-style on-NAND data format has a "pageStatus" byte to record ++ chunk/page state. This byte is zero when the page is discarded. ++ Choose this option if you have existing on-NAND data using this ++ format that you need to continue to support. New data written ++ also uses the older-style format. Note: Use of this option ++ generally requires that MTD's oob layout be adjusted to use the ++ older-style format. See notes on tags formats and MTD versions ++ in yaffs_mtdif1.c. ++ ++ If unsure, say N. ++ ++config YAFFS_DOES_ECC ++ bool "Lets yaffs do its own ECC" ++ depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS ++ default n ++ help ++ This enables yaffs to use its own ECC functions instead of using ++ the ones from the generic MTD-NAND driver. ++ ++ If unsure, say N. ++ ++config YAFFS_ECC_WRONG_ORDER ++ bool "Use the same ecc byte order as Steven Hill's nand_ecc.c" ++ depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS ++ default n ++ help ++ This makes yaffs_ecc.c use the same ecc byte order as Steven ++ Hill's nand_ecc.c. If not set, then you get the same ecc byte ++ order as SmartMedia. ++ ++ If unsure, say N. ++ ++config YAFFS_YAFFS2 ++ bool "2048 byte (or larger) / page devices" ++ depends on YAFFS_FS ++ default y ++ help ++ Enable yaffs2 support -- yaffs for >= 2K bytes per page devices ++ ++ If unsure, say Y. ++ ++config YAFFS_AUTO_YAFFS2 ++ bool "Autoselect yaffs2 format" ++ depends on YAFFS_YAFFS2 ++ default y ++ help ++ Without this, you need to explicitely use yaffs2 as the file ++ system type. With this, you can say "yaffs" and yaffs or yaffs2 ++ will be used depending on the device page size (yaffs on ++ 512-byte page devices, yaffs2 on 2K page devices). ++ ++ If unsure, say Y. ++ ++config YAFFS_DISABLE_TAGS_ECC ++ bool "Disable yaffs from doing ECC on tags by default" ++ depends on YAFFS_FS && YAFFS_YAFFS2 ++ default n ++ help ++ This defaults yaffs to using its own ECC calculations on tags instead of ++ just relying on the MTD. ++ This behavior can also be overridden with tags_ecc_on and ++ tags_ecc_off mount options. ++ ++ If unsure, say N. ++ ++config YAFFS_ALWAYS_CHECK_CHUNK_ERASED ++ bool "Force chunk erase check" ++ depends on YAFFS_FS ++ default n ++ help ++ Normally yaffs only checks chunks before writing until an erased ++ chunk is found. This helps to detect any partially written ++ chunks that might have happened due to power loss. ++ ++ Enabling this forces on the test that chunks are erased in flash ++ before writing to them. This takes more time but is potentially ++ a bit more secure. ++ ++ Suggest setting Y during development and ironing out driver ++ issues etc. Suggest setting to N if you want faster writing. ++ ++ If unsure, say Y. ++ ++config YAFFS_EMPTY_LOST_AND_FOUND ++ bool "Empty lost and found on boot" ++ depends on YAFFS_FS ++ default n ++ help ++ If this is enabled then the contents of lost and found is ++ automatically dumped at mount. ++ ++ If unsure, say N. ++ ++config YAFFS_DISABLE_BLOCK_REFRESHING ++ bool "Disable yaffs2 block refreshing" ++ depends on YAFFS_FS ++ default n ++ help ++ If this is set, then block refreshing is disabled. ++ Block refreshing infrequently refreshes the oldest block in ++ a yaffs2 file system. This mechanism helps to refresh flash to ++ mitigate against data loss. This is particularly useful for MLC. ++ ++ If unsure, say N. ++ ++config YAFFS_DISABLE_BACKGROUND ++ bool "Disable yaffs2 background processing" ++ depends on YAFFS_FS ++ default n ++ help ++ If this is set, then background processing is disabled. ++ Background processing makes many foreground activities faster. ++ ++ If unsure, say N. ++ ++config YAFFS_DISABLE_BAD_BLOCK_MARKING ++ bool "Disable yaffs2 bad block marking" ++ depends on YAFFS_FS ++ default n ++ help ++ Useful during early flash bring up to prevent problems causing ++ lots of bad block marking. ++ ++ If unsure, say N. ++ ++config YAFFS_XATTR ++ bool "Enable yaffs2 xattr support" ++ depends on YAFFS_FS ++ default y ++ help ++ If this is set then yaffs2 will provide xattr support. ++ If unsure, say Y. diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-Makefile.patch new file mode 100644 index 00000000..ad02e9c0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-Makefile.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/fs/yaffs2/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,19 @@ ++# ++# Makefile for the linux YAFFS filesystem routines. ++# ++ ++obj-$(CONFIG_YAFFS_FS) += yaffs.o ++ ++yaffs-y := yaffs_ecc.o yaffs_vfs.o yaffs_guts.o yaffs_checkptrw.o ++yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o ++yaffs-y += yaffs_tagscompat.o yaffs_tagsmarshall.o ++yaffs-y += yaffs_endian.o ++yaffs-y += yaffs_mtdif.o ++yaffs-y += yaffs_nameval.o yaffs_attribs.o ++yaffs-y += yaffs_allocator.o ++yaffs-y += yaffs_yaffs1.o ++yaffs-y += yaffs_yaffs2.o ++yaffs-y += yaffs_bitmap.o ++yaffs-y += yaffs_summary.o ++yaffs-y += yaffs_verify.o ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_allocator.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_allocator.c.patch new file mode 100644 index 00000000..cb9d9c11 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_allocator.c.patch @@ -0,0 +1,360 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_allocator.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_allocator.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,357 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_allocator.h" ++#include "yaffs_guts.h" ++#include "yaffs_trace.h" ++#include "yportenv.h" ++ ++/* ++ * Each entry in yaffs_tnode_list and yaffs_obj_list hold blocks ++ * of approx 100 objects that are themn allocated singly. ++ * This is basically a simplified slab allocator. ++ * ++ * We don't use the Linux slab allocator because slab does not allow ++ * us to dump all the objects in one hit when we do a umount and tear ++ * down all the tnodes and objects. slab requires that we first free ++ * the individual objects. ++ * ++ * Once yaffs has been mainlined I shall try to motivate for a change ++ * to slab to provide the extra features we need here. ++ */ ++ ++struct yaffs_tnode_list { ++ struct yaffs_tnode_list *next; ++ struct yaffs_tnode *tnodes; ++}; ++ ++struct yaffs_obj_list { ++ struct yaffs_obj_list *next; ++ struct yaffs_obj *objects; ++}; ++ ++struct yaffs_allocator { ++ int n_tnodes_created; ++ struct yaffs_tnode *free_tnodes; ++ int n_free_tnodes; ++ struct yaffs_tnode_list *alloc_tnode_list; ++ ++ int n_obj_created; ++ struct list_head free_objs; ++ int n_free_objects; ++ ++ struct yaffs_obj_list *allocated_obj_list; ++}; ++ ++static void yaffs_deinit_raw_tnodes(struct yaffs_dev *dev) ++{ ++ struct yaffs_allocator *allocator = ++ (struct yaffs_allocator *)dev->allocator; ++ struct yaffs_tnode_list *tmp; ++ ++ if (!allocator) { ++ BUG(); ++ return; ++ } ++ ++ while (allocator->alloc_tnode_list) { ++ tmp = allocator->alloc_tnode_list->next; ++ ++ kfree(allocator->alloc_tnode_list->tnodes); ++ kfree(allocator->alloc_tnode_list); ++ allocator->alloc_tnode_list = tmp; ++ } ++ ++ allocator->free_tnodes = NULL; ++ allocator->n_free_tnodes = 0; ++ allocator->n_tnodes_created = 0; ++} ++ ++static void yaffs_init_raw_tnodes(struct yaffs_dev *dev) ++{ ++ struct yaffs_allocator *allocator = dev->allocator; ++ ++ if (!allocator) { ++ BUG(); ++ return; ++ } ++ ++ allocator->alloc_tnode_list = NULL; ++ allocator->free_tnodes = NULL; ++ allocator->n_free_tnodes = 0; ++ allocator->n_tnodes_created = 0; ++} ++ ++static int yaffs_create_tnodes(struct yaffs_dev *dev, int n_tnodes) ++{ ++ struct yaffs_allocator *allocator = ++ (struct yaffs_allocator *)dev->allocator; ++ int i; ++ struct yaffs_tnode *new_tnodes; ++ u8 *mem; ++ struct yaffs_tnode *curr; ++ struct yaffs_tnode *next; ++ struct yaffs_tnode_list *tnl; ++ ++ if (!allocator) { ++ BUG(); ++ return YAFFS_FAIL; ++ } ++ ++ if (n_tnodes < 1) ++ return YAFFS_OK; ++ ++ /* make these things */ ++ new_tnodes = kmalloc(n_tnodes * dev->tnode_size, GFP_NOFS); ++ mem = (u8 *) new_tnodes; ++ ++ if (!new_tnodes) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs: Could not allocate Tnodes"); ++ return YAFFS_FAIL; ++ } ++ ++ /* New hookup for wide tnodes */ ++ for (i = 0; i < n_tnodes - 1; i++) { ++ curr = (struct yaffs_tnode *)&mem[i * dev->tnode_size]; ++ next = (struct yaffs_tnode *)&mem[(i + 1) * dev->tnode_size]; ++ curr->internal[0] = next; ++ } ++ ++ curr = (struct yaffs_tnode *)&mem[(n_tnodes - 1) * dev->tnode_size]; ++ curr->internal[0] = allocator->free_tnodes; ++ allocator->free_tnodes = (struct yaffs_tnode *)mem; ++ ++ allocator->n_free_tnodes += n_tnodes; ++ allocator->n_tnodes_created += n_tnodes; ++ ++ /* Now add this bunch of tnodes to a list for freeing up. ++ * NB If we can't add this to the management list it isn't fatal ++ * but it just means we can't free this bunch of tnodes later. ++ */ ++ tnl = kmalloc(sizeof(struct yaffs_tnode_list), GFP_NOFS); ++ if (!tnl) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "Could not add tnodes to management list"); ++ return YAFFS_FAIL; ++ } else { ++ tnl->tnodes = new_tnodes; ++ tnl->next = allocator->alloc_tnode_list; ++ allocator->alloc_tnode_list = tnl; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_ALLOCATE, "Tnodes added"); ++ ++ return YAFFS_OK; ++} ++ ++struct yaffs_tnode *yaffs_alloc_raw_tnode(struct yaffs_dev *dev) ++{ ++ struct yaffs_allocator *allocator = ++ (struct yaffs_allocator *)dev->allocator; ++ struct yaffs_tnode *tn = NULL; ++ ++ if (!allocator) { ++ BUG(); ++ return NULL; ++ } ++ ++ /* If there are none left make more */ ++ if (!allocator->free_tnodes) ++ yaffs_create_tnodes(dev, YAFFS_ALLOCATION_NTNODES); ++ ++ if (allocator->free_tnodes) { ++ tn = allocator->free_tnodes; ++ allocator->free_tnodes = allocator->free_tnodes->internal[0]; ++ allocator->n_free_tnodes--; ++ } ++ ++ return tn; ++} ++ ++/* FreeTnode frees up a tnode and puts it back on the free list */ ++void yaffs_free_raw_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn) ++{ ++ struct yaffs_allocator *allocator = dev->allocator; ++ ++ if (!allocator) { ++ BUG(); ++ return; ++ } ++ ++ if (tn) { ++ tn->internal[0] = allocator->free_tnodes; ++ allocator->free_tnodes = tn; ++ allocator->n_free_tnodes++; ++ } ++ dev->checkpoint_blocks_required = 0; /* force recalculation */ ++} ++ ++/*--------------- yaffs_obj alloaction ------------------------ ++ * ++ * Free yaffs_objs are stored in a list using obj->siblings. ++ * The blocks of allocated objects are stored in a linked list. ++ */ ++ ++static void yaffs_init_raw_objs(struct yaffs_dev *dev) ++{ ++ struct yaffs_allocator *allocator = dev->allocator; ++ ++ if (!allocator) { ++ BUG(); ++ return; ++ } ++ ++ allocator->allocated_obj_list = NULL; ++ INIT_LIST_HEAD(&allocator->free_objs); ++ allocator->n_free_objects = 0; ++} ++ ++static void yaffs_deinit_raw_objs(struct yaffs_dev *dev) ++{ ++ struct yaffs_allocator *allocator = dev->allocator; ++ struct yaffs_obj_list *tmp; ++ ++ if (!allocator) { ++ BUG(); ++ return; ++ } ++ ++ while (allocator->allocated_obj_list) { ++ tmp = allocator->allocated_obj_list->next; ++ kfree(allocator->allocated_obj_list->objects); ++ kfree(allocator->allocated_obj_list); ++ allocator->allocated_obj_list = tmp; ++ } ++ ++ INIT_LIST_HEAD(&allocator->free_objs); ++ allocator->n_free_objects = 0; ++ allocator->n_obj_created = 0; ++} ++ ++static int yaffs_create_free_objs(struct yaffs_dev *dev, int n_obj) ++{ ++ struct yaffs_allocator *allocator = dev->allocator; ++ int i; ++ struct yaffs_obj *new_objs; ++ struct yaffs_obj_list *list; ++ ++ if (!allocator) { ++ BUG(); ++ return YAFFS_FAIL; ++ } ++ ++ if (n_obj < 1) ++ return YAFFS_OK; ++ ++ /* make these things */ ++ new_objs = kmalloc(n_obj * sizeof(struct yaffs_obj), GFP_NOFS); ++ list = kmalloc(sizeof(struct yaffs_obj_list), GFP_NOFS); ++ ++ if (!new_objs || !list) { ++ kfree(new_objs); ++ new_objs = NULL; ++ kfree(list); ++ list = NULL; ++ yaffs_trace(YAFFS_TRACE_ALLOCATE, ++ "Could not allocate more objects"); ++ return YAFFS_FAIL; ++ } ++ ++ /* Hook them into the free list */ ++ for (i = 0; i < n_obj; i++) ++ list_add(&new_objs[i].siblings, &allocator->free_objs); ++ ++ allocator->n_free_objects += n_obj; ++ allocator->n_obj_created += n_obj; ++ ++ /* Now add this bunch of Objects to a list for freeing up. */ ++ ++ list->objects = new_objs; ++ list->next = allocator->allocated_obj_list; ++ allocator->allocated_obj_list = list; ++ ++ return YAFFS_OK; ++} ++ ++struct yaffs_obj *yaffs_alloc_raw_obj(struct yaffs_dev *dev) ++{ ++ struct yaffs_obj *obj = NULL; ++ struct list_head *lh; ++ struct yaffs_allocator *allocator = dev->allocator; ++ ++ if (!allocator) { ++ BUG(); ++ return obj; ++ } ++ ++ /* If there are none left make more */ ++ if (list_empty(&allocator->free_objs)) ++ yaffs_create_free_objs(dev, YAFFS_ALLOCATION_NOBJECTS); ++ ++ if (!list_empty(&allocator->free_objs)) { ++ lh = allocator->free_objs.next; ++ obj = list_entry(lh, struct yaffs_obj, siblings); ++ list_del_init(lh); ++ allocator->n_free_objects--; ++ } ++ ++ return obj; ++} ++ ++void yaffs_free_raw_obj(struct yaffs_dev *dev, struct yaffs_obj *obj) ++{ ++ ++ struct yaffs_allocator *allocator = dev->allocator; ++ ++ if (!allocator) { ++ BUG(); ++ return; ++ } ++ ++ /* Link into the free list. */ ++ list_add(&obj->siblings, &allocator->free_objs); ++ allocator->n_free_objects++; ++} ++ ++void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev) ++{ ++ ++ if (!dev->allocator) { ++ BUG(); ++ return; ++ } ++ ++ yaffs_deinit_raw_tnodes(dev); ++ yaffs_deinit_raw_objs(dev); ++ kfree(dev->allocator); ++ dev->allocator = NULL; ++} ++ ++void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev) ++{ ++ struct yaffs_allocator *allocator; ++ ++ if (dev->allocator) { ++ BUG(); ++ return; ++ } ++ ++ allocator = kmalloc(sizeof(struct yaffs_allocator), GFP_NOFS); ++ if (allocator) { ++ dev->allocator = allocator; ++ yaffs_init_raw_tnodes(dev); ++ yaffs_init_raw_objs(dev); ++ } ++} ++ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_allocator.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_allocator.h.patch new file mode 100644 index 00000000..449dce7a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_allocator.h.patch @@ -0,0 +1,33 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_allocator.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_allocator.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,30 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_ALLOCATOR_H__ ++#define __YAFFS_ALLOCATOR_H__ ++ ++#include "yaffs_guts.h" ++ ++void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev); ++void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev); ++ ++struct yaffs_tnode *yaffs_alloc_raw_tnode(struct yaffs_dev *dev); ++void yaffs_free_raw_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn); ++ ++struct yaffs_obj *yaffs_alloc_raw_obj(struct yaffs_dev *dev); ++void yaffs_free_raw_obj(struct yaffs_dev *dev, struct yaffs_obj *obj); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_attribs.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_attribs.c.patch new file mode 100644 index 00000000..09c8e404 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_attribs.c.patch @@ -0,0 +1,139 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_attribs.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_attribs.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,136 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_guts.h" ++#include "yaffs_attribs.h" ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) ++#define IATTR_UID ia_uid ++#define IATTR_GID ia_gid ++#else ++#define IATTR_UID ia_uid.val ++#define IATTR_GID ia_gid.val ++#endif ++ ++/* ++ * Loading attibs from/to object header assumes the object header ++ * is in cpu endian. ++ */ ++void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh) ++{ ++ obj->yst_uid = oh->yst_uid; ++ obj->yst_gid = oh->yst_gid; ++ obj->yst_atime = oh->yst_atime; ++ obj->yst_mtime = oh->yst_mtime; ++ obj->yst_ctime = oh->yst_ctime; ++ obj->yst_rdev = oh->yst_rdev; ++} ++ ++void yaffs_load_attribs_oh(struct yaffs_obj_hdr *oh, struct yaffs_obj *obj) ++{ ++ oh->yst_uid = obj->yst_uid; ++ oh->yst_gid = obj->yst_gid; ++ oh->yst_atime = obj->yst_atime; ++ oh->yst_mtime = obj->yst_mtime; ++ oh->yst_ctime = obj->yst_ctime; ++ oh->yst_rdev = obj->yst_rdev; ++ ++} ++ ++void yaffs_load_current_time(struct yaffs_obj *obj, int do_a, int do_c) ++{ ++ obj->yst_mtime = Y_CURRENT_TIME; ++ if (do_a) ++ obj->yst_atime = obj->yst_mtime; ++ if (do_c) ++ obj->yst_ctime = obj->yst_mtime; ++} ++ ++void yaffs_attribs_init(struct yaffs_obj *obj, u32 gid, u32 uid, u32 rdev) ++{ ++ yaffs_load_current_time(obj, 1, 1); ++ obj->yst_rdev = rdev; ++ obj->yst_uid = uid; ++ obj->yst_gid = gid; ++} ++ ++static loff_t yaffs_get_file_size(struct yaffs_obj *obj) ++{ ++ YCHAR *alias = NULL; ++ obj = yaffs_get_equivalent_obj(obj); ++ ++ switch (obj->variant_type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ return obj->variant.file_variant.file_size; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ alias = obj->variant.symlink_variant.alias; ++ if (!alias) ++ return 0; ++ return strnlen(alias, YAFFS_MAX_ALIAS_LENGTH); ++ default: ++ return 0; ++ } ++} ++ ++int yaffs_set_attribs(struct yaffs_obj *obj, struct iattr *attr) ++{ ++ unsigned int valid = attr->ia_valid; ++ ++ if (valid & ATTR_MODE) ++ obj->yst_mode = attr->ia_mode; ++ if (valid & ATTR_UID) ++ obj->yst_uid = attr->IATTR_UID; ++ if (valid & ATTR_GID) ++ obj->yst_gid = attr->IATTR_GID; ++ ++ if (valid & ATTR_ATIME) ++ obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime); ++ if (valid & ATTR_CTIME) ++ obj->yst_ctime = Y_TIME_CONVERT(attr->ia_ctime); ++ if (valid & ATTR_MTIME) ++ obj->yst_mtime = Y_TIME_CONVERT(attr->ia_mtime); ++ ++ if (valid & ATTR_SIZE) ++ yaffs_resize_file(obj, attr->ia_size); ++ ++ yaffs_update_oh(obj, NULL, 1, 0, 0, NULL); ++ ++ return YAFFS_OK; ++ ++} ++ ++int yaffs_get_attribs(struct yaffs_obj *obj, struct iattr *attr) ++{ ++ unsigned int valid = 0; ++ ++ attr->ia_mode = obj->yst_mode; ++ valid |= ATTR_MODE; ++ attr->IATTR_UID = obj->yst_uid; ++ valid |= ATTR_UID; ++ attr->IATTR_GID = obj->yst_gid; ++ valid |= ATTR_GID; ++ ++ Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime; ++ valid |= ATTR_ATIME; ++ Y_TIME_CONVERT(attr->ia_ctime) = obj->yst_ctime; ++ valid |= ATTR_CTIME; ++ Y_TIME_CONVERT(attr->ia_mtime) = obj->yst_mtime; ++ valid |= ATTR_MTIME; ++ ++ attr->ia_size = yaffs_get_file_size(obj); ++ valid |= ATTR_SIZE; ++ ++ attr->ia_valid = valid; ++ ++ return YAFFS_OK; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_attribs.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_attribs.h.patch new file mode 100644 index 00000000..35bf9f53 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_attribs.h.patch @@ -0,0 +1,31 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_attribs.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_attribs.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,28 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_ATTRIBS_H__ ++#define __YAFFS_ATTRIBS_H__ ++ ++#include "yaffs_guts.h" ++ ++void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh); ++void yaffs_load_attribs_oh(struct yaffs_obj_hdr *oh, struct yaffs_obj *obj); ++void yaffs_attribs_init(struct yaffs_obj *obj, u32 gid, u32 uid, u32 rdev); ++void yaffs_load_current_time(struct yaffs_obj *obj, int do_a, int do_c); ++int yaffs_set_attribs(struct yaffs_obj *obj, struct iattr *attr); ++int yaffs_get_attribs(struct yaffs_obj *obj, struct iattr *attr); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_bitmap.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_bitmap.c.patch new file mode 100644 index 00000000..20e888ff --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_bitmap.c.patch @@ -0,0 +1,102 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_bitmap.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_bitmap.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,99 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_bitmap.h" ++#include "yaffs_trace.h" ++/* ++ * Chunk bitmap manipulations ++ */ ++ ++static inline u8 *yaffs_block_bits(struct yaffs_dev *dev, int blk) ++{ ++ if (blk < (int)dev->internal_start_block || ++ blk > (int)dev->internal_end_block) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "BlockBits block %d is not valid", ++ blk); ++ BUG(); ++ } ++ return dev->chunk_bits + ++ (dev->chunk_bit_stride * (blk - dev->internal_start_block)); ++} ++ ++void yaffs_verify_chunk_bit_id(struct yaffs_dev *dev, int blk, int chunk) ++{ ++ if (blk < (int)dev->internal_start_block || ++ blk > (int)dev->internal_end_block || ++ chunk < 0 || chunk >= (int)dev->param.chunks_per_block) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "Chunk Id (%d:%d) invalid", ++ blk, chunk); ++ BUG(); ++ } ++} ++ ++void yaffs_clear_chunk_bits(struct yaffs_dev *dev, int blk) ++{ ++ u8 *blk_bits = yaffs_block_bits(dev, blk); ++ ++ memset(blk_bits, 0, dev->chunk_bit_stride); ++} ++ ++void yaffs_clear_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) ++{ ++ u8 *blk_bits = yaffs_block_bits(dev, blk); ++ ++ yaffs_verify_chunk_bit_id(dev, blk, chunk); ++ blk_bits[chunk / 8] &= ~(1 << (chunk & 7)); ++} ++ ++void yaffs_set_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) ++{ ++ u8 *blk_bits = yaffs_block_bits(dev, blk); ++ ++ yaffs_verify_chunk_bit_id(dev, blk, chunk); ++ blk_bits[chunk / 8] |= (1 << (chunk & 7)); ++} ++ ++int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) ++{ ++ u8 *blk_bits = yaffs_block_bits(dev, blk); ++ ++ yaffs_verify_chunk_bit_id(dev, blk, chunk); ++ return (blk_bits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0; ++} ++ ++int yaffs_still_some_chunks(struct yaffs_dev *dev, int blk) ++{ ++ u8 *blk_bits = yaffs_block_bits(dev, blk); ++ int i; ++ ++ for (i = 0; i < dev->chunk_bit_stride; i++) { ++ if (*blk_bits) ++ return 1; ++ blk_bits++; ++ } ++ return 0; ++} ++ ++int yaffs_count_chunk_bits(struct yaffs_dev *dev, int blk) ++{ ++ u8 *blk_bits = yaffs_block_bits(dev, blk); ++ int i; ++ int n = 0; ++ ++ for (i = 0; i < dev->chunk_bit_stride; i++, blk_bits++) ++ n += hweight8(*blk_bits); ++ ++ return n; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_bitmap.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_bitmap.h.patch new file mode 100644 index 00000000..6011f04f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_bitmap.h.patch @@ -0,0 +1,36 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_bitmap.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_bitmap.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,33 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++/* ++ * Chunk bitmap manipulations ++ */ ++ ++#ifndef __YAFFS_BITMAP_H__ ++#define __YAFFS_BITMAP_H__ ++ ++#include "yaffs_guts.h" ++ ++void yaffs_verify_chunk_bit_id(struct yaffs_dev *dev, int blk, int chunk); ++void yaffs_clear_chunk_bits(struct yaffs_dev *dev, int blk); ++void yaffs_clear_chunk_bit(struct yaffs_dev *dev, int blk, int chunk); ++void yaffs_set_chunk_bit(struct yaffs_dev *dev, int blk, int chunk); ++int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk); ++int yaffs_still_some_chunks(struct yaffs_dev *dev, int blk); ++int yaffs_count_chunk_bits(struct yaffs_dev *dev, int blk); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_checkptrw.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_checkptrw.c.patch new file mode 100644 index 00000000..58b10e23 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_checkptrw.c.patch @@ -0,0 +1,484 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_checkptrw.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_checkptrw.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,481 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_checkptrw.h" ++#include "yaffs_getblockinfo.h" ++#include "yaffs_endian.h" ++ ++struct yaffs_checkpt_chunk_hdr { ++ int version; ++ int seq; ++ u32 sum; ++ u32 xor; ++} ; ++ ++ ++static int apply_chunk_offset(struct yaffs_dev *dev, int chunk) ++{ ++ return chunk - dev->chunk_offset; ++} ++ ++static int apply_block_offset(struct yaffs_dev *dev, int block) ++{ ++ return block - dev->block_offset; ++} ++ ++ ++static void yaffs2_do_endian_hdr(struct yaffs_dev *dev, ++ struct yaffs_checkpt_chunk_hdr *hdr) ++{ ++ if (!dev->swap_endian) ++ return; ++ hdr->version = swap_s32(hdr->version); ++ hdr->seq = swap_s32(hdr->seq); ++ hdr->sum = swap_u32(hdr->sum); ++ hdr->xor = swap_u32(hdr->xor); ++} ++ ++static void yaffs2_checkpt_init_chunk_hdr(struct yaffs_dev *dev) ++{ ++ struct yaffs_checkpt_chunk_hdr hdr; ++ ++ hdr.version = YAFFS_CHECKPOINT_VERSION; ++ hdr.seq = dev->checkpt_page_seq; ++ hdr.sum = dev->checkpt_sum; ++ hdr.xor = dev->checkpt_xor; ++ ++ dev->checkpt_byte_offs = sizeof(hdr); ++ ++ yaffs2_do_endian_hdr(dev, &hdr); ++ memcpy(dev->checkpt_buffer, &hdr, sizeof(hdr)); ++} ++ ++static int yaffs2_checkpt_check_chunk_hdr(struct yaffs_dev *dev) ++{ ++ struct yaffs_checkpt_chunk_hdr hdr; ++ ++ memcpy(&hdr, dev->checkpt_buffer, sizeof(hdr)); ++ yaffs2_do_endian_hdr(dev, &hdr); ++ ++ dev->checkpt_byte_offs = sizeof(hdr); ++ ++ return hdr.version == YAFFS_CHECKPOINT_VERSION && ++ hdr.seq == dev->checkpt_page_seq && ++ hdr.sum == dev->checkpt_sum && ++ hdr.xor == dev->checkpt_xor; ++} ++ ++static int yaffs2_checkpt_space_ok(struct yaffs_dev *dev) ++{ ++ int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks; ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "checkpt blocks_avail = %d", blocks_avail); ++ ++ return (blocks_avail <= 0) ? 0 : 1; ++} ++ ++static int yaffs_checkpt_erase(struct yaffs_dev *dev) ++{ ++ u32 i; ++ ++ if (!dev->drv.drv_erase_fn) ++ return 0; ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "checking blocks %d to %d", ++ dev->internal_start_block, dev->internal_end_block); ++ ++ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, i); ++ int offset_i = apply_block_offset(dev, i); ++ int result; ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "erasing checkpt block %d", i); ++ ++ dev->n_erasures++; ++ ++ result = dev->drv.drv_erase_fn(dev, offset_i); ++ if(result) { ++ bi->block_state = YAFFS_BLOCK_STATE_EMPTY; ++ dev->n_erased_blocks++; ++ dev->n_free_chunks += ++ dev->param.chunks_per_block; ++ } else { ++ dev->drv.drv_mark_bad_fn(dev, offset_i); ++ bi->block_state = YAFFS_BLOCK_STATE_DEAD; ++ } ++ } ++ } ++ ++ dev->blocks_in_checkpt = 0; ++ ++ return 1; ++} ++ ++static void yaffs2_checkpt_find_erased_block(struct yaffs_dev *dev) ++{ ++ u32 i; ++ int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks; ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "allocating checkpt block: erased %d reserved %d avail %d next %d ", ++ dev->n_erased_blocks, dev->param.n_reserved_blocks, ++ blocks_avail, dev->checkpt_next_block); ++ ++ if (dev->checkpt_next_block >= 0 && ++ dev->checkpt_next_block <= (int)dev->internal_end_block && ++ blocks_avail > 0) { ++ ++ for (i = dev->checkpt_next_block; i <= dev->internal_end_block; ++ i++) { ++ struct yaffs_block_info *bi; ++ ++ bi = yaffs_get_block_info(dev, i); ++ if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) { ++ dev->checkpt_next_block = i + 1; ++ dev->checkpt_cur_block = i; ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "allocating checkpt block %d", i); ++ return; ++ } ++ } ++ } ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, "out of checkpt blocks"); ++ ++ dev->checkpt_next_block = -1; ++ dev->checkpt_cur_block = -1; ++} ++ ++static void yaffs2_checkpt_find_block(struct yaffs_dev *dev) ++{ ++ u32 i; ++ struct yaffs_ext_tags tags; ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "find next checkpt block: start: blocks %d next %d", ++ dev->blocks_in_checkpt, dev->checkpt_next_block); ++ ++ if (dev->blocks_in_checkpt < dev->checkpt_max_blocks) ++ for (i = dev->checkpt_next_block; i <= dev->internal_end_block; ++ i++) { ++ int chunk = i * dev->param.chunks_per_block; ++ enum yaffs_block_state state; ++ u32 seq; ++ ++ dev->tagger.read_chunk_tags_fn(dev, ++ apply_chunk_offset(dev, chunk), ++ NULL, &tags); ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "find next checkpt block: search: block %d state %d oid %d seq %d eccr %d", ++ i, (int) state, ++ tags.obj_id, tags.seq_number, ++ tags.ecc_result); ++ ++ if (tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA) ++ continue; ++ ++ dev->tagger.query_block_fn(dev, ++ apply_block_offset(dev, i), ++ &state, &seq); ++ if (state == YAFFS_BLOCK_STATE_DEAD) ++ continue; ++ ++ /* Right kind of block */ ++ dev->checkpt_next_block = tags.obj_id; ++ dev->checkpt_cur_block = i; ++ dev->checkpt_block_list[dev->blocks_in_checkpt] = i; ++ dev->blocks_in_checkpt++; ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "found checkpt block %d", i); ++ return; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, "found no more checkpt blocks"); ++ ++ dev->checkpt_next_block = -1; ++ dev->checkpt_cur_block = -1; ++} ++ ++int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing) ++{ ++ u32 i; ++ ++ dev->checkpt_open_write = writing; ++ ++ /* Got the functions we need? */ ++ if (!dev->tagger.write_chunk_tags_fn || ++ !dev->tagger.read_chunk_tags_fn || ++ !dev->drv.drv_erase_fn || ++ !dev->drv.drv_mark_bad_fn) ++ return 0; ++ ++ if (writing && !yaffs2_checkpt_space_ok(dev)) ++ return 0; ++ ++ if (!dev->checkpt_buffer) ++ dev->checkpt_buffer = ++ kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); ++ if (!dev->checkpt_buffer) ++ return 0; ++ ++ dev->checkpt_page_seq = 0; ++ dev->checkpt_byte_count = 0; ++ dev->checkpt_sum = 0; ++ dev->checkpt_xor = 0; ++ dev->checkpt_cur_block = -1; ++ dev->checkpt_cur_chunk = -1; ++ dev->checkpt_next_block = dev->internal_start_block; ++ ++ if (writing) { ++ memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk); ++ yaffs2_checkpt_init_chunk_hdr(dev); ++ return yaffs_checkpt_erase(dev); ++ } ++ ++ /* Opening for a read */ ++ /* Set to a value that will kick off a read */ ++ dev->checkpt_byte_offs = dev->data_bytes_per_chunk; ++ /* A checkpoint block list of 1 checkpoint block per 16 block is ++ * (hopefully) going to be way more than we need */ ++ dev->blocks_in_checkpt = 0; ++ dev->checkpt_max_blocks = ++ (dev->internal_end_block - dev->internal_start_block) / 16 + 2; ++ if (!dev->checkpt_block_list) ++ dev->checkpt_block_list = ++ kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS); ++ ++ if (!dev->checkpt_block_list) ++ return 0; ++ ++ for (i = 0; i < dev->checkpt_max_blocks; i++) ++ dev->checkpt_block_list[i] = -1; ++ ++ return 1; ++} ++ ++int yaffs2_get_checkpt_sum(struct yaffs_dev *dev, u32 * sum) ++{ ++ u32 composite_sum; ++ ++ composite_sum = (dev->checkpt_sum << 8) | (dev->checkpt_xor & 0xff); ++ *sum = composite_sum; ++ return 1; ++} ++ ++static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev) ++{ ++ int chunk; ++ int offset_chunk; ++ struct yaffs_ext_tags tags; ++ ++ if (dev->checkpt_cur_block < 0) { ++ yaffs2_checkpt_find_erased_block(dev); ++ dev->checkpt_cur_chunk = 0; ++ } ++ ++ if (dev->checkpt_cur_block < 0) ++ return 0; ++ ++ tags.is_deleted = 0; ++ tags.obj_id = dev->checkpt_next_block; /* Hint to next place to look */ ++ tags.chunk_id = dev->checkpt_page_seq + 1; ++ tags.seq_number = YAFFS_SEQUENCE_CHECKPOINT_DATA; ++ tags.n_bytes = dev->data_bytes_per_chunk; ++ if (dev->checkpt_cur_chunk == 0) { ++ /* First chunk we write for the block? Set block state to ++ checkpoint */ ++ struct yaffs_block_info *bi = ++ yaffs_get_block_info(dev, dev->checkpt_cur_block); ++ bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT; ++ dev->blocks_in_checkpt++; ++ } ++ ++ chunk = ++ dev->checkpt_cur_block * dev->param.chunks_per_block + ++ dev->checkpt_cur_chunk; ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "checkpoint wite buffer nand %d(%d:%d) objid %d chId %d", ++ chunk, dev->checkpt_cur_block, dev->checkpt_cur_chunk, ++ tags.obj_id, tags.chunk_id); ++ ++ offset_chunk = apply_chunk_offset(dev, chunk); ++ ++ dev->n_page_writes++; ++ ++ dev->tagger.write_chunk_tags_fn(dev, offset_chunk, ++ dev->checkpt_buffer, &tags); ++ dev->checkpt_page_seq++; ++ dev->checkpt_cur_chunk++; ++ if (dev->checkpt_cur_chunk >= (int)dev->param.chunks_per_block) { ++ dev->checkpt_cur_chunk = 0; ++ dev->checkpt_cur_block = -1; ++ } ++ memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk); ++ ++ yaffs2_checkpt_init_chunk_hdr(dev); ++ ++ ++ return 1; ++} ++ ++int yaffs2_checkpt_wr(struct yaffs_dev *dev, const void *data, int n_bytes) ++{ ++ int i = 0; ++ int ok = 1; ++ u8 *data_bytes = (u8 *) data; ++ ++ if (!dev->checkpt_buffer) ++ return 0; ++ ++ if (!dev->checkpt_open_write) ++ return -1; ++ ++ while (i < n_bytes && ok) { ++ dev->checkpt_buffer[dev->checkpt_byte_offs] = *data_bytes; ++ dev->checkpt_sum += *data_bytes; ++ dev->checkpt_xor ^= *data_bytes; ++ ++ dev->checkpt_byte_offs++; ++ i++; ++ data_bytes++; ++ dev->checkpt_byte_count++; ++ ++ if (dev->checkpt_byte_offs < 0 || ++ dev->checkpt_byte_offs >= (int)dev->data_bytes_per_chunk) ++ ok = yaffs2_checkpt_flush_buffer(dev); ++ } ++ ++ return i; ++} ++ ++int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes) ++{ ++ int i = 0; ++ struct yaffs_ext_tags tags; ++ int chunk; ++ int offset_chunk; ++ u8 *data_bytes = (u8 *) data; ++ ++ if (!dev->checkpt_buffer) ++ return 0; ++ ++ if (dev->checkpt_open_write) ++ return -1; ++ ++ while (i < n_bytes) { ++ ++ if (dev->checkpt_byte_offs < 0 || ++ dev->checkpt_byte_offs >= (int)dev->data_bytes_per_chunk) { ++ ++ if (dev->checkpt_cur_block < 0) { ++ yaffs2_checkpt_find_block(dev); ++ dev->checkpt_cur_chunk = 0; ++ } ++ ++ /* Bail out if we can't find a checpoint block */ ++ if (dev->checkpt_cur_block < 0) ++ break; ++ ++ chunk = dev->checkpt_cur_block * ++ dev->param.chunks_per_block + ++ dev->checkpt_cur_chunk; ++ ++ offset_chunk = apply_chunk_offset(dev, chunk); ++ dev->n_page_reads++; ++ ++ /* Read in the next chunk */ ++ dev->tagger.read_chunk_tags_fn(dev, ++ offset_chunk, ++ dev->checkpt_buffer, ++ &tags); ++ ++ /* Bail out if the chunk is corrupted. */ ++ if (tags.chunk_id != (u32)(dev->checkpt_page_seq + 1) || ++ tags.ecc_result > YAFFS_ECC_RESULT_FIXED || ++ tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA) ++ break; ++ ++ /* Bail out if it is not a checkpoint chunk. */ ++ if(!yaffs2_checkpt_check_chunk_hdr(dev)) ++ break; ++ ++ dev->checkpt_page_seq++; ++ dev->checkpt_cur_chunk++; ++ ++ if (dev->checkpt_cur_chunk >= ++ (int)dev->param.chunks_per_block) ++ dev->checkpt_cur_block = -1; ++ ++ } ++ ++ *data_bytes = dev->checkpt_buffer[dev->checkpt_byte_offs]; ++ dev->checkpt_sum += *data_bytes; ++ dev->checkpt_xor ^= *data_bytes; ++ dev->checkpt_byte_offs++; ++ i++; ++ data_bytes++; ++ dev->checkpt_byte_count++; ++ } ++ ++ return i; /* Number of bytes read */ ++} ++ ++int yaffs_checkpt_close(struct yaffs_dev *dev) ++{ ++ u32 i; ++ ++ if (dev->checkpt_open_write) { ++ if (dev->checkpt_byte_offs != ++ sizeof(sizeof(struct yaffs_checkpt_chunk_hdr))) ++ yaffs2_checkpt_flush_buffer(dev); ++ } else if (dev->checkpt_block_list) { ++ for (i = 0; ++ i < dev->blocks_in_checkpt && ++ dev->checkpt_block_list[i] >= 0; i++) { ++ int blk = dev->checkpt_block_list[i]; ++ struct yaffs_block_info *bi = NULL; ++ ++ if ((int)dev->internal_start_block <= blk && ++ blk <= (int)dev->internal_end_block) ++ bi = yaffs_get_block_info(dev, blk); ++ if (bi && bi->block_state == YAFFS_BLOCK_STATE_EMPTY) ++ bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT; ++ } ++ } ++ ++ dev->n_free_chunks -= ++ dev->blocks_in_checkpt * dev->param.chunks_per_block; ++ dev->n_erased_blocks -= dev->blocks_in_checkpt; ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, "checkpoint byte count %d", ++ dev->checkpt_byte_count); ++ ++ if (dev->checkpt_buffer) ++ return 1; ++ else ++ return 0; ++} ++ ++int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev) ++{ ++ /* Erase the checkpoint data */ ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "checkpoint invalidate of %d blocks", ++ dev->blocks_in_checkpt); ++ ++ return yaffs_checkpt_erase(dev); ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_checkptrw.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_checkptrw.h.patch new file mode 100644 index 00000000..0b66e8dc --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_checkptrw.h.patch @@ -0,0 +1,36 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_checkptrw.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_checkptrw.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,33 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_CHECKPTRW_H__ ++#define __YAFFS_CHECKPTRW_H__ ++ ++#include "yaffs_guts.h" ++ ++int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing); ++ ++int yaffs2_checkpt_wr(struct yaffs_dev *dev, const void *data, int n_bytes); ++ ++int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes); ++ ++int yaffs2_get_checkpt_sum(struct yaffs_dev *dev, u32 * sum); ++ ++int yaffs_checkpt_close(struct yaffs_dev *dev); ++ ++int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_ecc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_ecc.c.patch new file mode 100644 index 00000000..e4f0e708 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_ecc.c.patch @@ -0,0 +1,284 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_ecc.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_ecc.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,281 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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. ++ */ ++ ++/* ++ * This code implements the ECC algorithm used in SmartMedia. ++ * ++ * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. ++ * The two unused bit are set to 1. ++ * The ECC can correct single bit errors in a 256-byte page of data. Thus, two ++ * such ECC blocks are used on a 512-byte NAND page. ++ * ++ */ ++ ++#include "yportenv.h" ++ ++#include "yaffs_ecc.h" ++ ++/* Table generated by gen-ecc.c ++ * Using a table means we do not have to calculate p1..p4 and p1'..p4' ++ * for each byte of data. These are instead provided in a table in bits7..2. ++ * Bit 0 of each entry indicates whether the entry has an odd or even parity, ++ * and therefore this bytes influence on the line parity. ++ */ ++ ++static const unsigned char column_parity_table[] = { ++ 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, ++ 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, ++ 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, ++ 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, ++ 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, ++ 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, ++ 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, ++ 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, ++ 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, ++ 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, ++ 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, ++ 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, ++ 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, ++ 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, ++ 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, ++ 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, ++ 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, ++ 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, ++ 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, ++ 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, ++ 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, ++ 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, ++ 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, ++ 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, ++ 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, ++ 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, ++ 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, ++ 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, ++ 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, ++ 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, ++ 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, ++ 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, ++}; ++ ++ ++/* Calculate the ECC for a 256-byte block of data */ ++void yaffs_ecc_calc(const unsigned char *data, unsigned char *ecc) ++{ ++ unsigned int i; ++ unsigned char col_parity = 0; ++ unsigned char line_parity = 0; ++ unsigned char line_parity_prime = 0; ++ unsigned char t; ++ unsigned char b; ++ ++ for (i = 0; i < 256; i++) { ++ b = column_parity_table[*data++]; ++ col_parity ^= b; ++ ++ if (b & 0x01) { /* odd number of bits in the byte */ ++ line_parity ^= i; ++ line_parity_prime ^= ~i; ++ } ++ } ++ ++ ecc[2] = (~col_parity) | 0x03; ++ ++ t = 0; ++ if (line_parity & 0x80) ++ t |= 0x80; ++ if (line_parity_prime & 0x80) ++ t |= 0x40; ++ if (line_parity & 0x40) ++ t |= 0x20; ++ if (line_parity_prime & 0x40) ++ t |= 0x10; ++ if (line_parity & 0x20) ++ t |= 0x08; ++ if (line_parity_prime & 0x20) ++ t |= 0x04; ++ if (line_parity & 0x10) ++ t |= 0x02; ++ if (line_parity_prime & 0x10) ++ t |= 0x01; ++ ecc[1] = ~t; ++ ++ t = 0; ++ if (line_parity & 0x08) ++ t |= 0x80; ++ if (line_parity_prime & 0x08) ++ t |= 0x40; ++ if (line_parity & 0x04) ++ t |= 0x20; ++ if (line_parity_prime & 0x04) ++ t |= 0x10; ++ if (line_parity & 0x02) ++ t |= 0x08; ++ if (line_parity_prime & 0x02) ++ t |= 0x04; ++ if (line_parity & 0x01) ++ t |= 0x02; ++ if (line_parity_prime & 0x01) ++ t |= 0x01; ++ ecc[0] = ~t; ++ ++} ++ ++/* Correct the ECC on a 256 byte block of data */ ++ ++int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc, ++ const unsigned char *test_ecc) ++{ ++ unsigned char d0, d1, d2; /* deltas */ ++ ++ d0 = read_ecc[0] ^ test_ecc[0]; ++ d1 = read_ecc[1] ^ test_ecc[1]; ++ d2 = read_ecc[2] ^ test_ecc[2]; ++ ++ if ((d0 | d1 | d2) == 0) ++ return 0; /* no error */ ++ ++ if (((d0 ^ (d0 >> 1)) & 0x55) == 0x55 && ++ ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 && ++ ((d2 ^ (d2 >> 1)) & 0x54) == 0x54) { ++ /* Single bit (recoverable) error in data */ ++ ++ unsigned byte; ++ unsigned bit; ++ ++ bit = byte = 0; ++ ++ if (d1 & 0x80) ++ byte |= 0x80; ++ if (d1 & 0x20) ++ byte |= 0x40; ++ if (d1 & 0x08) ++ byte |= 0x20; ++ if (d1 & 0x02) ++ byte |= 0x10; ++ if (d0 & 0x80) ++ byte |= 0x08; ++ if (d0 & 0x20) ++ byte |= 0x04; ++ if (d0 & 0x08) ++ byte |= 0x02; ++ if (d0 & 0x02) ++ byte |= 0x01; ++ ++ if (d2 & 0x80) ++ bit |= 0x04; ++ if (d2 & 0x20) ++ bit |= 0x02; ++ if (d2 & 0x08) ++ bit |= 0x01; ++ ++ data[byte] ^= (1 << bit); ++ ++ return 1; /* Corrected the error */ ++ } ++ ++ if ((hweight8(d0) + hweight8(d1) + hweight8(d2)) == 1) { ++ /* Reccoverable error in ecc */ ++ ++ read_ecc[0] = test_ecc[0]; ++ read_ecc[1] = test_ecc[1]; ++ read_ecc[2] = test_ecc[2]; ++ ++ return 1; /* Corrected the error */ ++ } ++ ++ /* Unrecoverable error */ ++ ++ return -1; ++ ++} ++ ++/* ++ * ECCxxxOther does ECC calcs on arbitrary n bytes of data ++ */ ++void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes, ++ struct yaffs_ecc_other *ecc_other) ++{ ++ unsigned int i; ++ unsigned char col_parity = 0; ++ unsigned line_parity = 0; ++ unsigned line_parity_prime = 0; ++ unsigned char b; ++ ++ for (i = 0; i < n_bytes; i++) { ++ b = column_parity_table[*data++]; ++ col_parity ^= b; ++ ++ if (b & 0x01) { ++ /* odd number of bits in the byte */ ++ line_parity ^= i; ++ line_parity_prime ^= ~i; ++ } ++ ++ } ++ ++ ecc_other->col_parity = (col_parity >> 2) & 0x3f; ++ ecc_other->line_parity = line_parity; ++ ecc_other->line_parity_prime = line_parity_prime; ++} ++ ++int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes, ++ struct yaffs_ecc_other *read_ecc, ++ const struct yaffs_ecc_other *test_ecc) ++{ ++ unsigned char delta_col; /* column parity delta */ ++ unsigned delta_line; /* line parity delta */ ++ unsigned delta_line_prime; /* line parity delta */ ++ unsigned bit; ++ ++ delta_col = read_ecc->col_parity ^ test_ecc->col_parity; ++ delta_line = read_ecc->line_parity ^ test_ecc->line_parity; ++ delta_line_prime = ++ read_ecc->line_parity_prime ^ test_ecc->line_parity_prime; ++ ++ if ((delta_col | delta_line | delta_line_prime) == 0) ++ return 0; /* no error */ ++ ++ if (delta_line == ~delta_line_prime && ++ (((delta_col ^ (delta_col >> 1)) & 0x15) == 0x15)) { ++ /* Single bit (recoverable) error in data */ ++ ++ bit = 0; ++ ++ if (delta_col & 0x20) ++ bit |= 0x04; ++ if (delta_col & 0x08) ++ bit |= 0x02; ++ if (delta_col & 0x02) ++ bit |= 0x01; ++ ++ if (delta_line >= n_bytes) ++ return -1; ++ ++ data[delta_line] ^= (1 << bit); ++ ++ return 1; /* corrected */ ++ } ++ ++ if ((hweight32(delta_line) + ++ hweight32(delta_line_prime) + ++ hweight8(delta_col)) == 1) { ++ /* Reccoverable error in ecc */ ++ ++ *read_ecc = *test_ecc; ++ return 1; /* corrected */ ++ } ++ ++ /* Unrecoverable error */ ++ ++ return -1; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_ecc.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_ecc.h.patch new file mode 100644 index 00000000..75d1f1f5 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_ecc.h.patch @@ -0,0 +1,47 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_ecc.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_ecc.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,44 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++/* ++ * This code implements the ECC algorithm used in SmartMedia. ++ * ++ * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. ++ * The two unused bit are set to 1. ++ * The ECC can correct single bit errors in a 256-byte page of data. ++ * Thus, two such ECC blocks are used on a 512-byte NAND page. ++ * ++ */ ++ ++#ifndef __YAFFS_ECC_H__ ++#define __YAFFS_ECC_H__ ++ ++struct yaffs_ecc_other { ++ unsigned char col_parity; ++ unsigned line_parity; ++ unsigned line_parity_prime; ++}; ++ ++void yaffs_ecc_calc(const unsigned char *data, unsigned char *ecc); ++int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc, ++ const unsigned char *test_ecc); ++ ++void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes, ++ struct yaffs_ecc_other *ecc); ++int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes, ++ struct yaffs_ecc_other *read_ecc, ++ const struct yaffs_ecc_other *test_ecc); ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_endian.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_endian.c.patch new file mode 100644 index 00000000..44c97b0f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_endian.c.patch @@ -0,0 +1,109 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_endian.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_endian.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,106 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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. ++ * ++ * Endian processing functions. ++ */ ++ ++#include "yaffs_endian.h" ++#include "yaffs_guts.h" ++ ++ ++void yaffs_do_endian_u32(struct yaffs_dev *dev, u32 *val) ++{ ++ if (!dev->swap_endian) ++ return; ++ *val = swap_u32(*val); ++} ++ ++void yaffs_do_endian_s32(struct yaffs_dev *dev, s32 *val) ++{ ++ if (!dev->swap_endian) ++ return; ++ *val = swap_s32(*val); ++} ++ ++void yaffs_do_endian_oh(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh) ++{ ++ if (!dev->swap_endian) ++ return; ++ /* Change every field */ ++ oh->type = swap_u32(oh->type); ++ oh->parent_obj_id = swap_u32(oh->parent_obj_id); ++ ++ oh->yst_mode = swap_u32(oh->yst_mode); ++ ++ oh->yst_uid = swap_u32(oh->yst_uid); ++ oh->yst_gid = swap_u32(oh->yst_gid); ++ oh->yst_atime = swap_u32(oh->yst_atime); ++ oh->yst_mtime = swap_u32(oh->yst_mtime); ++ oh->yst_ctime = swap_u32(oh->yst_ctime); ++ ++ oh->file_size_low = swap_u32(oh->file_size_low); ++ ++ oh->equiv_id = swap_u32(oh->equiv_id); ++ ++ oh->yst_rdev = swap_u32(oh->yst_rdev); ++ ++ oh->win_ctime[0] = swap_u32(oh->win_ctime[0]); ++ oh->win_ctime[1] = swap_u32(oh->win_ctime[1]); ++ oh->win_atime[0] = swap_u32(oh->win_atime[0]); ++ oh->win_atime[1] = swap_u32(oh->win_atime[1]); ++ oh->win_mtime[0] = swap_u32(oh->win_mtime[0]); ++ oh->win_mtime[1] = swap_u32(oh->win_mtime[1]); ++ ++ oh->inband_shadowed_obj_id = swap_u32(oh->inband_shadowed_obj_id); ++ oh->inband_is_shrink = swap_u32(oh->inband_is_shrink); ++ ++ oh->file_size_high = swap_u32(oh->file_size_high); ++ oh->reserved[0] = swap_u32(oh->reserved[0]); ++ oh->shadows_obj = swap_s32(oh->shadows_obj); ++ ++ oh->is_shrink = swap_u32(oh->is_shrink); ++} ++ ++ ++void yaffs_do_endian_packed_tags2(struct yaffs_dev *dev, ++ struct yaffs_packed_tags2_tags_only *ptt) ++{ ++ if (!dev->swap_endian) ++ return; ++ ptt->seq_number = swap_u32(ptt->seq_number); ++ ptt->obj_id = swap_u32(ptt->obj_id); ++ ptt->chunk_id = swap_u32(ptt->chunk_id); ++ ptt->n_bytes = swap_u32(ptt->n_bytes); ++} ++ ++void yaffs_endian_config(struct yaffs_dev *dev) ++{ ++ u32 x = 1; ++ ++ if (dev->tnode_size < 1) ++ BUG(); ++ ++ dev->swap_endian = 0; ++ ++ if (((char *)&x)[0] == 1) { ++ /* Little Endian. */ ++ if (dev->param.stored_endian == 2 /* big endian */) ++ dev->swap_endian = 1; ++ } else { ++ /* Big Endian. */ ++ if (dev->param.stored_endian == 1 /* little endian */) ++ dev->swap_endian = 1; ++ } ++ ++ if (dev->swap_endian) ++ dev->tn_swap_buffer = kmalloc(dev->tnode_size, GFP_NOFS); ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_endian.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_endian.h.patch new file mode 100644 index 00000000..7ba03cdf --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_endian.h.patch @@ -0,0 +1,58 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_endian.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_endian.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,55 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_ENDIAN_H__ ++#define __YAFFS_ENDIAN_H__ ++#include "yaffs_guts.h" ++#include "yaffs_packedtags2.h" ++ ++static inline u32 swap_u32(u32 val) ++{ ++ return ((val >>24) & 0x000000ff) | ++ ((val >> 8) & 0x0000ff00) | ++ ((val << 8) & 0x00ff0000) | ++ ((val <<24) & 0xff000000); ++} ++ ++#define swap_s32(val) \ ++ (s32)(swap_u32((u32)(val))) ++ ++static inline loff_t swap_loff_t(loff_t lval) ++{ ++ u32 vall = swap_u32(FSIZE_LOW(lval)); ++ u32 valh; ++ ++ if (sizeof(loff_t) == sizeof(u32)) ++ return (loff_t) vall; ++ ++ valh = swap_u32(FSIZE_HIGH(lval)); ++ ++ return FSIZE_COMBINE(vall, valh); /*NB: h and l are swapped. */ ++} ++ ++ ++ ++struct yaffs_dev; ++void yaffs_do_endian_s32(struct yaffs_dev *dev, s32 *val); ++void yaffs_do_endian_u32(struct yaffs_dev *dev, u32 *val); ++void yaffs_do_endian_oh(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh); ++void yaffs_do_endian_packed_tags2(struct yaffs_dev *dev, ++ struct yaffs_packed_tags2_tags_only *ptt); ++void yaffs_endian_config(struct yaffs_dev *dev); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_getblockinfo.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_getblockinfo.h.patch new file mode 100644 index 00000000..ac03468d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_getblockinfo.h.patch @@ -0,0 +1,39 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_getblockinfo.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_getblockinfo.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,36 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_GETBLOCKINFO_H__ ++#define __YAFFS_GETBLOCKINFO_H__ ++ ++#include "yaffs_guts.h" ++#include "yaffs_trace.h" ++ ++/* Function to manipulate block info */ ++static inline struct yaffs_block_info *yaffs_get_block_info(struct yaffs_dev ++ *dev, int blk) ++{ ++ if (blk < (int)dev->internal_start_block || ++ blk > (int)dev->internal_end_block) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "**>> yaffs: get_block_info block %d is not valid", ++ blk); ++ BUG(); ++ } ++ return &dev->block_info[blk - dev->internal_start_block]; ++} ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_guts.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_guts.c.patch new file mode 100644 index 00000000..821d9974 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_guts.c.patch @@ -0,0 +1,5218 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_guts.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_guts.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,5215 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yportenv.h" ++#include "yaffs_trace.h" ++ ++#include "yaffs_guts.h" ++#include "yaffs_endian.h" ++#include "yaffs_getblockinfo.h" ++#include "yaffs_tagscompat.h" ++#include "yaffs_tagsmarshall.h" ++#include "yaffs_nand.h" ++#include "yaffs_yaffs1.h" ++#include "yaffs_yaffs2.h" ++#include "yaffs_bitmap.h" ++#include "yaffs_verify.h" ++#include "yaffs_nand.h" ++#include "yaffs_packedtags2.h" ++#include "yaffs_nameval.h" ++#include "yaffs_allocator.h" ++#include "yaffs_attribs.h" ++#include "yaffs_summary.h" ++ ++/* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */ ++#define YAFFS_GC_GOOD_ENOUGH 2 ++#define YAFFS_GC_PASSIVE_THRESHOLD 4 ++ ++#include "yaffs_ecc.h" ++ ++/* Forward declarations */ ++ ++static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, ++ const u8 *buffer, int n_bytes, int use_reserve); ++ ++static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name, ++ int buffer_size); ++ ++/* Function to calculate chunk and offset */ ++ ++void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr, ++ int *chunk_out, u32 *offset_out) ++{ ++ int chunk; ++ u32 offset; ++ ++ chunk = (u32) (addr >> dev->chunk_shift); ++ ++ if (dev->chunk_div == 1) { ++ /* easy power of 2 case */ ++ offset = (u32) (addr & dev->chunk_mask); ++ } else { ++ /* Non power-of-2 case */ ++ ++ loff_t chunk_base; ++ ++ chunk /= dev->chunk_div; ++ ++ chunk_base = ((loff_t) chunk) * dev->data_bytes_per_chunk; ++ offset = (u32) (addr - chunk_base); ++ } ++ ++ *chunk_out = chunk; ++ *offset_out = offset; ++} ++ ++/* Function to return the number of shifts for a power of 2 greater than or ++ * equal to the given number ++ * Note we don't try to cater for all possible numbers and this does not have to ++ * be hellishly efficient. ++ */ ++ ++static inline u32 calc_shifts_ceiling(u32 x) ++{ ++ int extra_bits; ++ int shifts; ++ ++ shifts = extra_bits = 0; ++ ++ while (x > 1) { ++ if (x & 1) ++ extra_bits++; ++ x >>= 1; ++ shifts++; ++ } ++ ++ if (extra_bits) ++ shifts++; ++ ++ return shifts; ++} ++ ++/* Function to return the number of shifts to get a 1 in bit 0 ++ */ ++ ++static inline u32 calc_shifts(u32 x) ++{ ++ u32 shifts; ++ ++ shifts = 0; ++ ++ if (!x) ++ return 0; ++ ++ while (!(x & 1)) { ++ x >>= 1; ++ shifts++; ++ } ++ ++ return shifts; ++} ++ ++/* ++ * Temporary buffer manipulations. ++ */ ++ ++static int yaffs_init_tmp_buffers(struct yaffs_dev *dev) ++{ ++ int i; ++ u8 *buf = (u8 *) 1; ++ ++ memset(dev->temp_buffer, 0, sizeof(dev->temp_buffer)); ++ ++ for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) { ++ dev->temp_buffer[i].in_use = 0; ++ buf = kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); ++ dev->temp_buffer[i].buffer = buf; ++ } ++ ++ return buf ? YAFFS_OK : YAFFS_FAIL; ++} ++ ++u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev) ++{ ++ int i; ++ ++ dev->temp_in_use++; ++ if (dev->temp_in_use > dev->max_temp) ++ dev->max_temp = dev->temp_in_use; ++ ++ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { ++ if (dev->temp_buffer[i].in_use == 0) { ++ dev->temp_buffer[i].in_use = 1; ++ return dev->temp_buffer[i].buffer; ++ } ++ } ++ ++ yaffs_trace(YAFFS_TRACE_BUFFERS, "Out of temp buffers"); ++ /* ++ * If we got here then we have to allocate an unmanaged one ++ * This is not good. ++ */ ++ ++ dev->unmanaged_buffer_allocs++; ++ return kmalloc(dev->data_bytes_per_chunk, GFP_NOFS); ++ ++} ++ ++void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer) ++{ ++ int i; ++ ++ dev->temp_in_use--; ++ ++ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { ++ if (dev->temp_buffer[i].buffer == buffer) { ++ dev->temp_buffer[i].in_use = 0; ++ return; ++ } ++ } ++ ++ if (buffer) { ++ /* assume it is an unmanaged one. */ ++ yaffs_trace(YAFFS_TRACE_BUFFERS, ++ "Releasing unmanaged temp buffer"); ++ kfree(buffer); ++ dev->unmanaged_buffer_deallocs++; ++ } ++ ++} ++ ++/* ++ * Functions for robustisizing TODO ++ * ++ */ ++ ++static void yaffs_handle_chunk_wr_ok(struct yaffs_dev *dev, int nand_chunk, ++ const u8 *data, ++ const struct yaffs_ext_tags *tags) ++{ ++ (void) dev; ++ (void) nand_chunk; ++ (void) data; ++ (void) tags; ++} ++ ++static void yaffs_handle_chunk_update(struct yaffs_dev *dev, int nand_chunk, ++ const struct yaffs_ext_tags *tags) ++{ ++ (void) dev; ++ (void) nand_chunk; ++ (void) tags; ++} ++ ++void yaffs_handle_chunk_error(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi) ++{ ++ if (!bi->gc_prioritise) { ++ bi->gc_prioritise = 1; ++ dev->has_pending_prioritised_gc = 1; ++ bi->chunk_error_strikes++; ++ ++ if (bi->chunk_error_strikes > 3) { ++ bi->needs_retiring = 1; /* Too many stikes, so retire */ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs: Block struck out"); ++ ++ } ++ } ++} ++ ++static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, int nand_chunk, ++ int erased_ok) ++{ ++ int flash_block = nand_chunk / dev->param.chunks_per_block; ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block); ++ ++ yaffs_handle_chunk_error(dev, bi); ++ ++ if (erased_ok) { ++ /* Was an actual write failure, ++ * so mark the block for retirement.*/ ++ bi->needs_retiring = 1; ++ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, ++ "**>> Block %d needs retiring", flash_block); ++ } ++ ++ /* Delete the chunk */ ++ yaffs_chunk_del(dev, nand_chunk, 1, __LINE__); ++ yaffs_skip_rest_of_block(dev); ++} ++ ++/* ++ * Verification code ++ */ ++ ++/* ++ * Simple hash function. Needs to have a reasonable spread ++ */ ++ ++static inline int yaffs_hash_fn(int n) ++{ ++ if (n < 0) ++ n = -n; ++ return n % YAFFS_NOBJECT_BUCKETS; ++} ++ ++/* ++ * Access functions to useful fake objects. ++ * Note that root might have a presence in NAND if permissions are set. ++ */ ++ ++struct yaffs_obj *yaffs_root(struct yaffs_dev *dev) ++{ ++ return dev->root_dir; ++} ++ ++struct yaffs_obj *yaffs_lost_n_found(struct yaffs_dev *dev) ++{ ++ return dev->lost_n_found; ++} ++ ++/* ++ * Erased NAND checking functions ++ */ ++ ++int yaffs_check_ff(u8 *buffer, int n_bytes) ++{ ++ /* Horrible, slow implementation */ ++ while (n_bytes--) { ++ if (*buffer != 0xff) ++ return 0; ++ buffer++; ++ } ++ return 1; ++} ++ ++static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk) ++{ ++ int retval = YAFFS_OK; ++ u8 *data = yaffs_get_temp_buffer(dev); ++ struct yaffs_ext_tags tags; ++ int result; ++ ++ result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags); ++ ++ if (result == YAFFS_FAIL || ++ tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR) ++ retval = YAFFS_FAIL; ++ ++ if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) || ++ tags.chunk_used) { ++ yaffs_trace(YAFFS_TRACE_NANDACCESS, ++ "Chunk %d not erased", nand_chunk); ++ retval = YAFFS_FAIL; ++ } ++ ++ yaffs_release_temp_buffer(dev, data); ++ ++ return retval; ++ ++} ++ ++static int yaffs_verify_chunk_written(struct yaffs_dev *dev, ++ int nand_chunk, ++ const u8 *data, ++ struct yaffs_ext_tags *tags) ++{ ++ int retval = YAFFS_OK; ++ struct yaffs_ext_tags temp_tags; ++ u8 *buffer = yaffs_get_temp_buffer(dev); ++ int result; ++ ++ result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags); ++ if (result == YAFFS_FAIL || ++ memcmp(buffer, data, dev->data_bytes_per_chunk) || ++ temp_tags.obj_id != tags->obj_id || ++ temp_tags.chunk_id != tags->chunk_id || ++ temp_tags.n_bytes != tags->n_bytes) ++ retval = YAFFS_FAIL; ++ ++ yaffs_release_temp_buffer(dev, buffer); ++ ++ return retval; ++} ++ ++ ++int yaffs_check_alloc_available(struct yaffs_dev *dev, int n_chunks) ++{ ++ int reserved_chunks; ++ int reserved_blocks = dev->param.n_reserved_blocks; ++ int checkpt_blocks; ++ ++ checkpt_blocks = yaffs_calc_checkpt_blocks_required(dev); ++ ++ reserved_chunks = ++ (reserved_blocks + checkpt_blocks) * dev->param.chunks_per_block; ++ ++ return (dev->n_free_chunks > (reserved_chunks + n_chunks)); ++} ++ ++static int yaffs_find_alloc_block(struct yaffs_dev *dev) ++{ ++ u32 i; ++ struct yaffs_block_info *bi; ++ ++ if (dev->n_erased_blocks < 1) { ++ /* Hoosterman we've got a problem. ++ * Can't get space to gc ++ */ ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs tragedy: no more erased blocks"); ++ ++ return -1; ++ } ++ ++ /* Find an empty block. */ ++ ++ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { ++ dev->alloc_block_finder++; ++ if (dev->alloc_block_finder < (int)dev->internal_start_block ++ || dev->alloc_block_finder > (int)dev->internal_end_block) { ++ dev->alloc_block_finder = dev->internal_start_block; ++ } ++ ++ bi = yaffs_get_block_info(dev, dev->alloc_block_finder); ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) { ++ bi->block_state = YAFFS_BLOCK_STATE_ALLOCATING; ++ dev->seq_number++; ++ bi->seq_number = dev->seq_number; ++ dev->n_erased_blocks--; ++ yaffs_trace(YAFFS_TRACE_ALLOCATE, ++ "Allocated block %d, seq %d, %d left" , ++ dev->alloc_block_finder, dev->seq_number, ++ dev->n_erased_blocks); ++ return dev->alloc_block_finder; ++ } ++ } ++ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs tragedy: no more erased blocks, but there should have been %d", ++ dev->n_erased_blocks); ++ ++ return -1; ++} ++ ++static int yaffs_alloc_chunk(struct yaffs_dev *dev, int use_reserver, ++ struct yaffs_block_info **block_ptr) ++{ ++ int ret_val; ++ struct yaffs_block_info *bi; ++ ++ if (dev->alloc_block < 0) { ++ /* Get next block to allocate off */ ++ dev->alloc_block = yaffs_find_alloc_block(dev); ++ dev->alloc_page = 0; ++ } ++ ++ if (!use_reserver && !yaffs_check_alloc_available(dev, 1)) { ++ /* No space unless we're allowed to use the reserve. */ ++ return -1; ++ } ++ ++ if (dev->n_erased_blocks < (int)dev->param.n_reserved_blocks ++ && dev->alloc_page == 0) ++ yaffs_trace(YAFFS_TRACE_ALLOCATE, "Allocating reserve"); ++ ++ /* Next page please.... */ ++ if (dev->alloc_block >= 0) { ++ bi = yaffs_get_block_info(dev, dev->alloc_block); ++ ++ ret_val = (dev->alloc_block * dev->param.chunks_per_block) + ++ dev->alloc_page; ++ bi->pages_in_use++; ++ yaffs_set_chunk_bit(dev, dev->alloc_block, dev->alloc_page); ++ ++ dev->alloc_page++; ++ ++ dev->n_free_chunks--; ++ ++ /* If the block is full set the state to full */ ++ if (dev->alloc_page >= dev->param.chunks_per_block) { ++ bi->block_state = YAFFS_BLOCK_STATE_FULL; ++ dev->alloc_block = -1; ++ } ++ ++ if (block_ptr) ++ *block_ptr = bi; ++ ++ return ret_val; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!"); ++ ++ return -1; ++} ++ ++static int yaffs_get_erased_chunks(struct yaffs_dev *dev) ++{ ++ int n; ++ ++ n = dev->n_erased_blocks * dev->param.chunks_per_block; ++ ++ if (dev->alloc_block > 0) ++ n += (dev->param.chunks_per_block - dev->alloc_page); ++ ++ return n; ++ ++} ++ ++/* ++ * yaffs_skip_rest_of_block() skips over the rest of the allocation block ++ * if we don't want to write to it. ++ */ ++void yaffs_skip_rest_of_block(struct yaffs_dev *dev) ++{ ++ struct yaffs_block_info *bi; ++ ++ if (dev->alloc_block > 0) { ++ bi = yaffs_get_block_info(dev, dev->alloc_block); ++ if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) { ++ bi->block_state = YAFFS_BLOCK_STATE_FULL; ++ dev->alloc_block = -1; ++ } ++ } ++} ++ ++static int yaffs_write_new_chunk(struct yaffs_dev *dev, ++ const u8 *data, ++ struct yaffs_ext_tags *tags, int use_reserver) ++{ ++ u32 attempts = 0; ++ int write_ok = 0; ++ int chunk; ++ ++ yaffs2_checkpt_invalidate(dev); ++ ++ do { ++ struct yaffs_block_info *bi = 0; ++ int erased_ok = 0; ++ ++ chunk = yaffs_alloc_chunk(dev, use_reserver, &bi); ++ if (chunk < 0) { ++ /* no space */ ++ break; ++ } ++ ++ /* First check this chunk is erased, if it needs ++ * checking. The checking policy (unless forced ++ * always on) is as follows: ++ * ++ * Check the first page we try to write in a block. ++ * If the check passes then we don't need to check any ++ * more. If the check fails, we check again... ++ * If the block has been erased, we don't need to check. ++ * ++ * However, if the block has been prioritised for gc, ++ * then we think there might be something odd about ++ * this block and stop using it. ++ * ++ * Rationale: We should only ever see chunks that have ++ * not been erased if there was a partially written ++ * chunk due to power loss. This checking policy should ++ * catch that case with very few checks and thus save a ++ * lot of checks that are most likely not needed. ++ * ++ * Mods to the above ++ * If an erase check fails or the write fails we skip the ++ * rest of the block. ++ */ ++ ++ /* let's give it a try */ ++ attempts++; ++ ++ if (dev->param.always_check_erased) ++ bi->skip_erased_check = 0; ++ ++ if (!bi->skip_erased_check) { ++ erased_ok = yaffs_check_chunk_erased(dev, chunk); ++ if (erased_ok != YAFFS_OK) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "**>> yaffs chunk %d was not erased", ++ chunk); ++ ++ /* If not erased, delete this one, ++ * skip rest of block and ++ * try another chunk */ ++ yaffs_chunk_del(dev, chunk, 1, __LINE__); ++ yaffs_skip_rest_of_block(dev); ++ continue; ++ } ++ } ++ ++ write_ok = yaffs_wr_chunk_tags_nand(dev, chunk, data, tags); ++ ++ if (!bi->skip_erased_check) ++ write_ok = ++ yaffs_verify_chunk_written(dev, chunk, data, tags); ++ ++ if (write_ok != YAFFS_OK) { ++ /* Clean up aborted write, skip to next block and ++ * try another chunk */ ++ yaffs_handle_chunk_wr_error(dev, chunk, erased_ok); ++ continue; ++ } ++ ++ bi->skip_erased_check = 1; ++ ++ /* Copy the data into the robustification buffer */ ++ yaffs_handle_chunk_wr_ok(dev, chunk, data, tags); ++ ++ } while (write_ok != YAFFS_OK && ++ (yaffs_wr_attempts == 0 || attempts <= yaffs_wr_attempts)); ++ ++ if (!write_ok) ++ chunk = -1; ++ ++ if (attempts > 1) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "**>> yaffs write required %d attempts", ++ attempts); ++ dev->n_retried_writes += (attempts - 1); ++ } ++ ++ return chunk; ++} ++ ++/* ++ * Block retiring for handling a broken block. ++ */ ++ ++static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block) ++{ ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block); ++ ++ yaffs2_checkpt_invalidate(dev); ++ ++ yaffs2_clear_oldest_dirty_seq(dev, bi); ++ ++ if (yaffs_mark_bad(dev, flash_block) != YAFFS_OK) { ++ if (yaffs_erase_block(dev, flash_block) != YAFFS_OK) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs: Failed to mark bad and erase block %d", ++ flash_block); ++ } else { ++ struct yaffs_ext_tags tags; ++ int chunk_id = ++ flash_block * dev->param.chunks_per_block; ++ ++ u8 *buffer = yaffs_get_temp_buffer(dev); ++ ++ memset(buffer, 0xff, dev->data_bytes_per_chunk); ++ memset(&tags, 0, sizeof(tags)); ++ tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK; ++ if (dev->tagger.write_chunk_tags_fn(dev, chunk_id - ++ dev->chunk_offset, ++ buffer, ++ &tags) != YAFFS_OK) ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs: Failed to write bad block marker to block %d", ++ flash_block); ++ ++ yaffs_release_temp_buffer(dev, buffer); ++ } ++ } ++ ++ bi->block_state = YAFFS_BLOCK_STATE_DEAD; ++ bi->gc_prioritise = 0; ++ bi->needs_retiring = 0; ++ ++ dev->n_retired_blocks++; ++} ++ ++/*---------------- Name handling functions ------------*/ ++ ++static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name, ++ const YCHAR *oh_name, int buff_size) ++{ ++#ifdef CONFIG_YAFFS_AUTO_UNICODE ++ if (dev->param.auto_unicode) { ++ if (*oh_name) { ++ /* It is an ASCII name, do an ASCII to ++ * unicode conversion */ ++ const char *ascii_oh_name = (const char *)oh_name; ++ int n = buff_size - 1; ++ while (n > 0 && *ascii_oh_name) { ++ *name = *ascii_oh_name; ++ name++; ++ ascii_oh_name++; ++ n--; ++ } ++ } else { ++ strncpy(name, oh_name + 1, buff_size - 1); ++ } ++ } else { ++#else ++ (void) dev; ++ { ++#endif ++ strncpy(name, oh_name, buff_size - 1); ++ } ++} ++ ++static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name, ++ const YCHAR *name) ++{ ++#ifdef CONFIG_YAFFS_AUTO_UNICODE ++ ++ int is_ascii; ++ const YCHAR *w; ++ ++ if (dev->param.auto_unicode) { ++ ++ is_ascii = 1; ++ w = name; ++ ++ /* Figure out if the name will fit in ascii character set */ ++ while (is_ascii && *w) { ++ if ((*w) & 0xff00) ++ is_ascii = 0; ++ w++; ++ } ++ ++ if (is_ascii) { ++ /* It is an ASCII name, so convert unicode to ascii */ ++ char *ascii_oh_name = (char *)oh_name; ++ int n = YAFFS_MAX_NAME_LENGTH - 1; ++ while (n > 0 && *name) { ++ *ascii_oh_name = *name; ++ name++; ++ ascii_oh_name++; ++ n--; ++ } ++ } else { ++ /* Unicode name, so save starting at the second YCHAR */ ++ *oh_name = 0; ++ strncpy(oh_name + 1, name, YAFFS_MAX_NAME_LENGTH - 2); ++ } ++ } else { ++#else ++ dev = dev; ++ { ++#endif ++ strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1); ++ } ++} ++ ++static u16 yaffs_calc_name_sum(const YCHAR *name) ++{ ++ u16 sum = 0; ++ u16 i = 1; ++ ++ if (!name) ++ return 0; ++ ++ while ((*name) && i < (YAFFS_MAX_NAME_LENGTH / 2)) { ++ ++ /* 0x1f mask is case insensitive */ ++ sum += ((*name) & 0x1f) * i; ++ i++; ++ name++; ++ } ++ return sum; ++} ++ ++ ++void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name) ++{ ++ memset(obj->short_name, 0, sizeof(obj->short_name)); ++ ++ if (name && !name[0]) { ++ yaffs_fix_null_name(obj, obj->short_name, ++ YAFFS_SHORT_NAME_LENGTH); ++ name = obj->short_name; ++ } else if (name && ++ strnlen(name, YAFFS_SHORT_NAME_LENGTH + 1) <= ++ YAFFS_SHORT_NAME_LENGTH) { ++ strcpy(obj->short_name, name); ++ } ++ ++ obj->sum = yaffs_calc_name_sum(name); ++} ++ ++void yaffs_set_obj_name_from_oh(struct yaffs_obj *obj, ++ const struct yaffs_obj_hdr *oh) ++{ ++#ifdef CONFIG_YAFFS_AUTO_UNICODE ++ YCHAR tmp_name[YAFFS_MAX_NAME_LENGTH + 1]; ++ memset(tmp_name, 0, sizeof(tmp_name)); ++ yaffs_load_name_from_oh(obj->my_dev, tmp_name, oh->name, ++ YAFFS_MAX_NAME_LENGTH + 1); ++ yaffs_set_obj_name(obj, tmp_name); ++#else ++ yaffs_set_obj_name(obj, oh->name); ++#endif ++} ++ ++loff_t yaffs_max_file_size(struct yaffs_dev *dev) ++{ ++ if (sizeof(loff_t) < 8) ++ return YAFFS_MAX_FILE_SIZE_32; ++ else ++ return ((loff_t) YAFFS_MAX_CHUNK_ID) * dev->data_bytes_per_chunk; ++} ++ ++/*-------------------- TNODES ------------------- ++ ++ * List of spare tnodes ++ * The list is hooked together using the first pointer ++ * in the tnode. ++ */ ++ ++struct yaffs_tnode *yaffs_get_tnode(struct yaffs_dev *dev) ++{ ++ struct yaffs_tnode *tn = yaffs_alloc_raw_tnode(dev); ++ ++ if (tn) { ++ memset(tn, 0, dev->tnode_size); ++ dev->n_tnodes++; ++ } ++ ++ dev->checkpoint_blocks_required = 0; /* force recalculation */ ++ ++ return tn; ++} ++ ++/* FreeTnode frees up a tnode and puts it back on the free list */ ++static void yaffs_free_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn) ++{ ++ yaffs_free_raw_tnode(dev, tn); ++ dev->n_tnodes--; ++ dev->checkpoint_blocks_required = 0; /* force recalculation */ ++} ++ ++static void yaffs_deinit_tnodes_and_objs(struct yaffs_dev *dev) ++{ ++ yaffs_deinit_raw_tnodes_and_objs(dev); ++ dev->n_obj = 0; ++ dev->n_tnodes = 0; ++} ++ ++static void yaffs_load_tnode_0(struct yaffs_dev *dev, struct yaffs_tnode *tn, ++ unsigned pos, unsigned val) ++{ ++ u32 *map = (u32 *) tn; ++ u32 bit_in_map; ++ u32 bit_in_word; ++ u32 word_in_map; ++ u32 mask; ++ ++ pos &= YAFFS_TNODES_LEVEL0_MASK; ++ val >>= dev->chunk_grp_bits; ++ ++ bit_in_map = pos * dev->tnode_width; ++ word_in_map = bit_in_map / 32; ++ bit_in_word = bit_in_map & (32 - 1); ++ ++ mask = dev->tnode_mask << bit_in_word; ++ ++ map[word_in_map] &= ~mask; ++ map[word_in_map] |= (mask & (val << bit_in_word)); ++ ++ if (dev->tnode_width > (32 - bit_in_word)) { ++ bit_in_word = (32 - bit_in_word); ++ word_in_map++; ++ mask = ++ dev->tnode_mask >> bit_in_word; ++ map[word_in_map] &= ~mask; ++ map[word_in_map] |= (mask & (val >> bit_in_word)); ++ } ++} ++ ++u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn, ++ unsigned pos) ++{ ++ u32 *map = (u32 *) tn; ++ u32 bit_in_map; ++ u32 bit_in_word; ++ u32 word_in_map; ++ u32 val; ++ ++ pos &= YAFFS_TNODES_LEVEL0_MASK; ++ ++ bit_in_map = pos * dev->tnode_width; ++ word_in_map = bit_in_map / 32; ++ bit_in_word = bit_in_map & (32 - 1); ++ ++ val = map[word_in_map] >> bit_in_word; ++ ++ if (dev->tnode_width > (32 - bit_in_word)) { ++ bit_in_word = (32 - bit_in_word); ++ word_in_map++; ++ val |= (map[word_in_map] << bit_in_word); ++ } ++ ++ val &= dev->tnode_mask; ++ val <<= dev->chunk_grp_bits; ++ ++ return val; ++} ++ ++/* ------------------- End of individual tnode manipulation -----------------*/ ++ ++/* ---------Functions to manipulate the look-up tree (made up of tnodes) ------ ++ * The look up tree is represented by the top tnode and the number of top_level ++ * in the tree. 0 means only the level 0 tnode is in the tree. ++ */ ++ ++/* FindLevel0Tnode finds the level 0 tnode, if one exists. */ ++struct yaffs_tnode *yaffs_find_tnode_0(struct yaffs_dev *dev, ++ struct yaffs_file_var *file_struct, ++ u32 chunk_id) ++{ ++ struct yaffs_tnode *tn = file_struct->top; ++ u32 i; ++ int required_depth; ++ int level = file_struct->top_level; ++ ++ (void) dev; ++ ++ /* Check sane level and chunk Id */ ++ if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL) ++ return NULL; ++ ++ if (chunk_id > YAFFS_MAX_CHUNK_ID) ++ return NULL; ++ ++ /* First check we're tall enough (ie enough top_level) */ ++ ++ i = chunk_id >> YAFFS_TNODES_LEVEL0_BITS; ++ required_depth = 0; ++ while (i) { ++ i >>= YAFFS_TNODES_INTERNAL_BITS; ++ required_depth++; ++ } ++ ++ if (required_depth > file_struct->top_level) ++ return NULL; /* Not tall enough, so we can't find it */ ++ ++ /* Traverse down to level 0 */ ++ while (level > 0 && tn) { ++ tn = tn->internal[(chunk_id >> ++ (YAFFS_TNODES_LEVEL0_BITS + ++ (level - 1) * ++ YAFFS_TNODES_INTERNAL_BITS)) & ++ YAFFS_TNODES_INTERNAL_MASK]; ++ level--; ++ } ++ ++ return tn; ++} ++ ++/* add_find_tnode_0 finds the level 0 tnode if it exists, ++ * otherwise first expands the tree. ++ * This happens in two steps: ++ * 1. If the tree isn't tall enough, then make it taller. ++ * 2. Scan down the tree towards the level 0 tnode adding tnodes if required. ++ * ++ * Used when modifying the tree. ++ * ++ * If the tn argument is NULL, then a fresh tnode will be added otherwise the ++ * specified tn will be plugged into the ttree. ++ */ ++ ++struct yaffs_tnode *yaffs_add_find_tnode_0(struct yaffs_dev *dev, ++ struct yaffs_file_var *file_struct, ++ u32 chunk_id, ++ struct yaffs_tnode *passed_tn) ++{ ++ int required_depth; ++ int i; ++ int l; ++ struct yaffs_tnode *tn; ++ u32 x; ++ ++ /* Check sane level and page Id */ ++ if (file_struct->top_level < 0 || ++ file_struct->top_level > YAFFS_TNODES_MAX_LEVEL) ++ return NULL; ++ ++ if (chunk_id > YAFFS_MAX_CHUNK_ID) ++ return NULL; ++ ++ /* First check we're tall enough (ie enough top_level) */ ++ ++ x = chunk_id >> YAFFS_TNODES_LEVEL0_BITS; ++ required_depth = 0; ++ while (x) { ++ x >>= YAFFS_TNODES_INTERNAL_BITS; ++ required_depth++; ++ } ++ ++ if (required_depth > file_struct->top_level) { ++ /* Not tall enough, gotta make the tree taller */ ++ for (i = file_struct->top_level; i < required_depth; i++) { ++ ++ tn = yaffs_get_tnode(dev); ++ ++ if (tn) { ++ tn->internal[0] = file_struct->top; ++ file_struct->top = tn; ++ file_struct->top_level++; ++ } else { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs: no more tnodes"); ++ return NULL; ++ } ++ } ++ } ++ ++ /* Traverse down to level 0, adding anything we need */ ++ ++ l = file_struct->top_level; ++ tn = file_struct->top; ++ ++ if (l > 0) { ++ while (l > 0 && tn) { ++ x = (chunk_id >> ++ (YAFFS_TNODES_LEVEL0_BITS + ++ (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) & ++ YAFFS_TNODES_INTERNAL_MASK; ++ ++ if ((l > 1) && !tn->internal[x]) { ++ /* Add missing non-level-zero tnode */ ++ tn->internal[x] = yaffs_get_tnode(dev); ++ if (!tn->internal[x]) ++ return NULL; ++ } else if (l == 1) { ++ /* Looking from level 1 at level 0 */ ++ if (passed_tn) { ++ /* If we already have one, release it */ ++ if (tn->internal[x]) ++ yaffs_free_tnode(dev, ++ tn->internal[x]); ++ tn->internal[x] = passed_tn; ++ ++ } else if (!tn->internal[x]) { ++ /* Don't have one, none passed in */ ++ tn->internal[x] = yaffs_get_tnode(dev); ++ if (!tn->internal[x]) ++ return NULL; ++ } ++ } ++ ++ tn = tn->internal[x]; ++ l--; ++ } ++ } else { ++ /* top is level 0 */ ++ if (passed_tn) { ++ memcpy(tn, passed_tn, ++ (dev->tnode_width * YAFFS_NTNODES_LEVEL0) / 8); ++ yaffs_free_tnode(dev, passed_tn); ++ } ++ } ++ ++ return tn; ++} ++ ++static int yaffs_tags_match(const struct yaffs_ext_tags *tags, int obj_id, ++ int chunk_obj) ++{ ++ return (tags->chunk_id == (u32)chunk_obj && ++ tags->obj_id == (u32)obj_id && ++ !tags->is_deleted) ? 1 : 0; ++ ++} ++ ++static int yaffs_find_chunk_in_group(struct yaffs_dev *dev, int the_chunk, ++ struct yaffs_ext_tags *tags, int obj_id, ++ int inode_chunk) ++{ ++ int j; ++ ++ for (j = 0; the_chunk && j < dev->chunk_grp_size; j++) { ++ if (yaffs_check_chunk_bit ++ (dev, the_chunk / dev->param.chunks_per_block, ++ the_chunk % dev->param.chunks_per_block)) { ++ ++ if (dev->chunk_grp_size == 1) ++ return the_chunk; ++ else { ++ yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL, ++ tags); ++ if (yaffs_tags_match(tags, ++ obj_id, inode_chunk)) { ++ /* found it; */ ++ return the_chunk; ++ } ++ } ++ } ++ the_chunk++; ++ } ++ return -1; ++} ++ ++int yaffs_find_chunk_in_file(struct yaffs_obj *in, int inode_chunk, ++ struct yaffs_ext_tags *tags) ++{ ++ /*Get the Tnode, then get the level 0 offset chunk offset */ ++ struct yaffs_tnode *tn; ++ int the_chunk = -1; ++ struct yaffs_ext_tags local_tags; ++ int ret_val = -1; ++ struct yaffs_dev *dev = in->my_dev; ++ ++ if (!tags) { ++ /* Passed a NULL, so use our own tags space */ ++ tags = &local_tags; ++ } ++ ++ tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk); ++ ++ if (!tn) ++ return ret_val; ++ ++ the_chunk = yaffs_get_group_base(dev, tn, inode_chunk); ++ ++ ret_val = yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id, ++ inode_chunk); ++ return ret_val; ++} ++ ++static int yaffs_find_del_file_chunk(struct yaffs_obj *in, int inode_chunk, ++ struct yaffs_ext_tags *tags) ++{ ++ /* Get the Tnode, then get the level 0 offset chunk offset */ ++ struct yaffs_tnode *tn; ++ int the_chunk = -1; ++ struct yaffs_ext_tags local_tags; ++ struct yaffs_dev *dev = in->my_dev; ++ int ret_val = -1; ++ ++ if (!tags) { ++ /* Passed a NULL, so use our own tags space */ ++ tags = &local_tags; ++ } ++ ++ tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk); ++ ++ if (!tn) ++ return ret_val; ++ ++ the_chunk = yaffs_get_group_base(dev, tn, inode_chunk); ++ ++ ret_val = yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id, ++ inode_chunk); ++ ++ /* Delete the entry in the filestructure (if found) */ ++ if (ret_val != -1) ++ yaffs_load_tnode_0(dev, tn, inode_chunk, 0); ++ ++ return ret_val; ++} ++ ++int yaffs_put_chunk_in_file(struct yaffs_obj *in, int inode_chunk, ++ int nand_chunk, int in_scan) ++{ ++ /* NB in_scan is zero unless scanning. ++ * For forward scanning, in_scan is > 0; ++ * for backward scanning in_scan is < 0 ++ * ++ * nand_chunk = 0 is a dummy insert to make sure the tnodes are there. ++ */ ++ ++ struct yaffs_tnode *tn; ++ struct yaffs_dev *dev = in->my_dev; ++ int existing_cunk; ++ struct yaffs_ext_tags existing_tags; ++ struct yaffs_ext_tags new_tags; ++ unsigned existing_serial, new_serial; ++ ++ if (in->variant_type != YAFFS_OBJECT_TYPE_FILE) { ++ /* Just ignore an attempt at putting a chunk into a non-file ++ * during scanning. ++ * If it is not during Scanning then something went wrong! ++ */ ++ if (!in_scan) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs tragedy:attempt to put data chunk into a non-file" ++ ); ++ BUG(); ++ } ++ ++ yaffs_chunk_del(dev, nand_chunk, 1, __LINE__); ++ return YAFFS_OK; ++ } ++ ++ tn = yaffs_add_find_tnode_0(dev, ++ &in->variant.file_variant, ++ inode_chunk, NULL); ++ if (!tn) ++ return YAFFS_FAIL; ++ ++ if (!nand_chunk) ++ /* Dummy insert, bail now */ ++ return YAFFS_OK; ++ ++ existing_cunk = yaffs_get_group_base(dev, tn, inode_chunk); ++ ++ if (in_scan != 0) { ++ /* If we're scanning then we need to test for duplicates ++ * NB This does not need to be efficient since it should only ++ * happen when the power fails during a write, then only one ++ * chunk should ever be affected. ++ * ++ * Correction for YAFFS2: This could happen quite a lot and we ++ * need to think about efficiency! TODO ++ * Update: For backward scanning we don't need to re-read tags ++ * so this is quite cheap. ++ */ ++ ++ if (existing_cunk > 0) { ++ /* NB Right now existing chunk will not be real ++ * chunk_id if the chunk group size > 1 ++ * thus we have to do a FindChunkInFile to get the ++ * real chunk id. ++ * ++ * We have a duplicate now we need to decide which ++ * one to use: ++ * ++ * Backwards scanning YAFFS2: The old one is what ++ * we use, dump the new one. ++ * YAFFS1: Get both sets of tags and compare serial ++ * numbers. ++ */ ++ ++ if (in_scan > 0) { ++ /* Only do this for forward scanning */ ++ yaffs_rd_chunk_tags_nand(dev, ++ nand_chunk, ++ NULL, &new_tags); ++ ++ /* Do a proper find */ ++ existing_cunk = ++ yaffs_find_chunk_in_file(in, inode_chunk, ++ &existing_tags); ++ } ++ ++ if (existing_cunk <= 0) { ++ /*Hoosterman - how did this happen? */ ++ ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs tragedy: existing chunk < 0 in scan" ++ ); ++ ++ } ++ ++ /* NB The deleted flags should be false, otherwise ++ * the chunks will not be loaded during a scan ++ */ ++ ++ if (in_scan > 0) { ++ new_serial = new_tags.serial_number; ++ existing_serial = existing_tags.serial_number; ++ } ++ ++ if ((in_scan > 0) && ++ (existing_cunk <= 0 || ++ ((existing_serial + 1) & 3) == new_serial)) { ++ /* Forward scanning. ++ * Use new ++ * Delete the old one and drop through to ++ * update the tnode ++ */ ++ yaffs_chunk_del(dev, existing_cunk, 1, ++ __LINE__); ++ } else { ++ /* Backward scanning or we want to use the ++ * existing one ++ * Delete the new one and return early so that ++ * the tnode isn't changed ++ */ ++ yaffs_chunk_del(dev, nand_chunk, 1, __LINE__); ++ return YAFFS_OK; ++ } ++ } ++ ++ } ++ ++ if (existing_cunk == 0) ++ in->n_data_chunks++; ++ ++ yaffs_load_tnode_0(dev, tn, inode_chunk, nand_chunk); ++ ++ return YAFFS_OK; ++} ++ ++static void yaffs_soft_del_chunk(struct yaffs_dev *dev, int chunk) ++{ ++ struct yaffs_block_info *the_block; ++ unsigned block_no; ++ ++ yaffs_trace(YAFFS_TRACE_DELETION, "soft delete chunk %d", chunk); ++ ++ block_no = chunk / dev->param.chunks_per_block; ++ the_block = yaffs_get_block_info(dev, block_no); ++ if (the_block) { ++ the_block->soft_del_pages++; ++ dev->n_free_chunks++; ++ yaffs2_update_oldest_dirty_seq(dev, block_no, the_block); ++ } ++} ++ ++/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all ++ * the chunks in the file. ++ * All soft deleting does is increment the block's softdelete count and pulls ++ * the chunk out of the tnode. ++ * Thus, essentially this is the same as DeleteWorker except that the chunks ++ * are soft deleted. ++ */ ++ ++static int yaffs_soft_del_worker(struct yaffs_obj *in, struct yaffs_tnode *tn, ++ u32 level, int chunk_offset) ++{ ++ int i; ++ int the_chunk; ++ int all_done = 1; ++ struct yaffs_dev *dev = in->my_dev; ++ ++ if (!tn) ++ return 1; ++ ++ if (level > 0) { ++ for (i = YAFFS_NTNODES_INTERNAL - 1; ++ all_done && i >= 0; ++ i--) { ++ if (tn->internal[i]) { ++ all_done = ++ yaffs_soft_del_worker(in, ++ tn->internal[i], ++ level - 1, ++ (chunk_offset << ++ YAFFS_TNODES_INTERNAL_BITS) ++ + i); ++ if (all_done) { ++ yaffs_free_tnode(dev, ++ tn->internal[i]); ++ tn->internal[i] = NULL; ++ } else { ++ /* Can this happen? */ ++ } ++ } ++ } ++ return (all_done) ? 1 : 0; ++ } ++ ++ /* level 0 */ ++ for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) { ++ the_chunk = yaffs_get_group_base(dev, tn, i); ++ if (the_chunk) { ++ yaffs_soft_del_chunk(dev, the_chunk); ++ yaffs_load_tnode_0(dev, tn, i, 0); ++ } ++ } ++ return 1; ++} ++ ++static void yaffs_remove_obj_from_dir(struct yaffs_obj *obj) ++{ ++ struct yaffs_dev *dev = obj->my_dev; ++ struct yaffs_obj *parent; ++ ++ yaffs_verify_obj_in_dir(obj); ++ parent = obj->parent; ++ ++ yaffs_verify_dir(parent); ++ ++ if (dev && dev->param.remove_obj_fn) ++ dev->param.remove_obj_fn(obj); ++ ++ list_del_init(&obj->siblings); ++ obj->parent = NULL; ++ ++ yaffs_verify_dir(parent); ++} ++ ++void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj) ++{ ++ if (!directory) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "tragedy: Trying to add an object to a null pointer directory" ++ ); ++ BUG(); ++ return; ++ } ++ if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "tragedy: Trying to add an object to a non-directory" ++ ); ++ BUG(); ++ } ++ ++ if (obj->siblings.prev == NULL) { ++ /* Not initialised */ ++ BUG(); ++ } ++ ++ yaffs_verify_dir(directory); ++ ++ yaffs_remove_obj_from_dir(obj); ++ ++ /* Now add it */ ++ list_add(&obj->siblings, &directory->variant.dir_variant.children); ++ obj->parent = directory; ++ ++ if (directory == obj->my_dev->unlinked_dir ++ || directory == obj->my_dev->del_dir) { ++ obj->unlinked = 1; ++ obj->my_dev->n_unlinked_files++; ++ obj->rename_allowed = 0; ++ } ++ ++ yaffs_verify_dir(directory); ++ yaffs_verify_obj_in_dir(obj); ++} ++ ++static int yaffs_change_obj_name(struct yaffs_obj *obj, ++ struct yaffs_obj *new_dir, ++ const YCHAR *new_name, int force, int shadows) ++{ ++ int unlink_op; ++ int del_op; ++ struct yaffs_obj *existing_target; ++ ++ if (new_dir == NULL) ++ new_dir = obj->parent; /* use the old directory */ ++ ++ if (new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "tragedy: yaffs_change_obj_name: new_dir is not a directory" ++ ); ++ BUG(); ++ } ++ ++ unlink_op = (new_dir == obj->my_dev->unlinked_dir); ++ del_op = (new_dir == obj->my_dev->del_dir); ++ ++ existing_target = yaffs_find_by_name(new_dir, new_name); ++ ++ /* If the object is a file going into the unlinked directory, ++ * then it is OK to just stuff it in since duplicate names are OK. ++ * else only proceed if the new name does not exist and we're putting ++ * it into a directory. ++ */ ++ if (!(unlink_op || del_op || force || ++ shadows > 0 || !existing_target) || ++ new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) ++ return YAFFS_FAIL; ++ ++ yaffs_set_obj_name(obj, new_name); ++ obj->dirty = 1; ++ yaffs_add_obj_to_dir(new_dir, obj); ++ ++ if (unlink_op) ++ obj->unlinked = 1; ++ ++ /* If it is a deletion then we mark it as a shrink for gc */ ++ if (yaffs_update_oh(obj, new_name, 0, del_op, shadows, NULL) >= 0) ++ return YAFFS_OK; ++ ++ return YAFFS_FAIL; ++} ++ ++/*------------------------ Short Operations Cache ------------------------------ ++ * In many situations where there is no high level buffering a lot of ++ * reads might be short sequential reads, and a lot of writes may be short ++ * sequential writes. eg. scanning/writing a jpeg file. ++ * In these cases, a short read/write cache can provide a huge perfomance ++ * benefit with dumb-as-a-rock code. ++ * In Linux, the page cache provides read buffering and the short op cache ++ * provides write buffering. ++ * ++ * There are a small number (~10) of cache chunks per device so that we don't ++ * need a very intelligent search. ++ */ ++ ++static int yaffs_obj_cache_dirty(struct yaffs_obj *obj) ++{ ++ struct yaffs_dev *dev = obj->my_dev; ++ int i; ++ struct yaffs_cache *cache; ++ int n_caches = obj->my_dev->param.n_caches; ++ ++ for (i = 0; i < n_caches; i++) { ++ cache = &dev->cache[i]; ++ if (cache->object == obj && cache->dirty) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void yaffs_flush_single_cache(struct yaffs_cache *cache, int discard) ++{ ++ ++ if (!cache || cache->locked) ++ return; ++ ++ /* Write it out and free it up if need be.*/ ++ if (cache->dirty) { ++ yaffs_wr_data_obj(cache->object, ++ cache->chunk_id, ++ cache->data, ++ cache->n_bytes, ++ 1); ++ ++ cache->dirty = 0; ++ } ++ ++ if (discard) ++ cache->object = NULL; ++} ++ ++static void yaffs_flush_file_cache(struct yaffs_obj *obj, int discard) ++{ ++ struct yaffs_dev *dev = obj->my_dev; ++ int i; ++ struct yaffs_cache *cache; ++ int n_caches = obj->my_dev->param.n_caches; ++ ++ if (n_caches < 1) ++ return; ++ ++ ++ /* Find the chunks for this object and flush them. */ ++ for (i = 0; i < n_caches; i++) { ++ cache = &dev->cache[i]; ++ if (cache->object == obj) ++ yaffs_flush_single_cache(cache, discard); ++ } ++ ++} ++ ++ ++void yaffs_flush_whole_cache(struct yaffs_dev *dev, int discard) ++{ ++ struct yaffs_obj *obj; ++ int n_caches = dev->param.n_caches; ++ int i; ++ ++ /* Find a dirty object in the cache and flush it... ++ * until there are no further dirty objects. ++ */ ++ do { ++ obj = NULL; ++ for (i = 0; i < n_caches && !obj; i++) { ++ if (dev->cache[i].object && dev->cache[i].dirty) ++ obj = dev->cache[i].object; ++ } ++ if (obj) ++ yaffs_flush_file_cache(obj, discard); ++ } while (obj); ++ ++} ++ ++/* Grab us an unused cache chunk for use. ++ * First look for an empty one. ++ * Then look for the least recently used non-dirty one. ++ * Then look for the least recently used dirty one...., flush and look again. ++ */ ++static struct yaffs_cache *yaffs_grab_chunk_worker(struct yaffs_dev *dev) ++{ ++ u32 i; ++ ++ if (dev->param.n_caches > 0) { ++ for (i = 0; i < dev->param.n_caches; i++) { ++ if (!dev->cache[i].object) ++ return &dev->cache[i]; ++ } ++ } ++ ++ return NULL; ++} ++ ++static struct yaffs_cache *yaffs_grab_chunk_cache(struct yaffs_dev *dev) ++{ ++ struct yaffs_cache *cache; ++ int usage; ++ u32 i; ++ ++ if (dev->param.n_caches < 1) ++ return NULL; ++ ++ /* First look for an unused cache */ ++ ++ cache = yaffs_grab_chunk_worker(dev); ++ ++ if (cache) ++ return cache; ++ ++ /* ++ * Thery were all in use. ++ * Find the LRU cache and flush it if it is dirty. ++ */ ++ ++ usage = -1; ++ cache = NULL; ++ ++ for (i = 0; i < dev->param.n_caches; i++) { ++ if (dev->cache[i].object && ++ !dev->cache[i].locked && ++ (dev->cache[i].last_use < usage || !cache)) { ++ usage = dev->cache[i].last_use; ++ cache = &dev->cache[i]; ++ } ++ } ++ ++#if 1 ++ yaffs_flush_single_cache(cache, 1); ++#else ++ yaffs_flush_file_cache(cache->object, 1); ++ cache = yaffs_grab_chunk_worker(dev); ++#endif ++ ++ return cache; ++} ++ ++/* Find a cached chunk */ ++static struct yaffs_cache *yaffs_find_chunk_cache(const struct yaffs_obj *obj, ++ int chunk_id) ++{ ++ struct yaffs_dev *dev = obj->my_dev; ++ u32 i; ++ ++ if (dev->param.n_caches < 1) ++ return NULL; ++ ++ for (i = 0; i < dev->param.n_caches; i++) { ++ if (dev->cache[i].object == obj && ++ dev->cache[i].chunk_id == chunk_id) { ++ dev->cache_hits++; ++ ++ return &dev->cache[i]; ++ } ++ } ++ return NULL; ++} ++ ++/* Mark the chunk for the least recently used algorithym */ ++static void yaffs_use_cache(struct yaffs_dev *dev, struct yaffs_cache *cache, ++ int is_write) ++{ ++ u32 i; ++ ++ if (dev->param.n_caches < 1) ++ return; ++ ++ if (dev->cache_last_use < 0 || ++ dev->cache_last_use > 100000000) { ++ /* Reset the cache usages */ ++ for (i = 1; i < dev->param.n_caches; i++) ++ dev->cache[i].last_use = 0; ++ ++ dev->cache_last_use = 0; ++ } ++ dev->cache_last_use++; ++ cache->last_use = dev->cache_last_use; ++ ++ if (is_write) ++ cache->dirty = 1; ++} ++ ++/* Invalidate a single cache page. ++ * Do this when a whole page gets written, ++ * ie the short cache for this page is no longer valid. ++ */ ++static void yaffs_invalidate_chunk_cache(struct yaffs_obj *object, int chunk_id) ++{ ++ struct yaffs_cache *cache; ++ ++ if (object->my_dev->param.n_caches > 0) { ++ cache = yaffs_find_chunk_cache(object, chunk_id); ++ ++ if (cache) ++ cache->object = NULL; ++ } ++} ++ ++/* Invalidate all the cache pages associated with this object ++ * Do this whenever ther file is deleted or resized. ++ */ ++static void yaffs_invalidate_whole_cache(struct yaffs_obj *in) ++{ ++ u32 i; ++ struct yaffs_dev *dev = in->my_dev; ++ ++ if (dev->param.n_caches > 0) { ++ /* Invalidate it. */ ++ for (i = 0; i < dev->param.n_caches; i++) { ++ if (dev->cache[i].object == in) ++ dev->cache[i].object = NULL; ++ } ++ } ++} ++ ++static void yaffs_unhash_obj(struct yaffs_obj *obj) ++{ ++ int bucket; ++ struct yaffs_dev *dev = obj->my_dev; ++ ++ /* If it is still linked into the bucket list, free from the list */ ++ if (!list_empty(&obj->hash_link)) { ++ list_del_init(&obj->hash_link); ++ bucket = yaffs_hash_fn(obj->obj_id); ++ dev->obj_bucket[bucket].count--; ++ } ++} ++ ++/* FreeObject frees up a Object and puts it back on the free list */ ++static void yaffs_free_obj(struct yaffs_obj *obj) ++{ ++ struct yaffs_dev *dev; ++ ++ if (!obj) { ++ BUG(); ++ return; ++ } ++ dev = obj->my_dev; ++ yaffs_trace(YAFFS_TRACE_OS, "FreeObject %p inode %p", ++ obj, obj->my_inode); ++ if (obj->parent) ++ BUG(); ++ if (!list_empty(&obj->siblings)) ++ BUG(); ++ ++ if (obj->my_inode) { ++ /* We're still hooked up to a cached inode. ++ * Don't delete now, but mark for later deletion ++ */ ++ obj->defered_free = 1; ++ return; ++ } ++ ++ yaffs_unhash_obj(obj); ++ ++ yaffs_free_raw_obj(dev, obj); ++ dev->n_obj--; ++ dev->checkpoint_blocks_required = 0; /* force recalculation */ ++} ++ ++void yaffs_handle_defered_free(struct yaffs_obj *obj) ++{ ++ if (obj->defered_free) ++ yaffs_free_obj(obj); ++} ++ ++static int yaffs_generic_obj_del(struct yaffs_obj *in) ++{ ++ /* Iinvalidate the file's data in the cache, without flushing. */ ++ yaffs_invalidate_whole_cache(in); ++ ++ if (in->my_dev->param.is_yaffs2 && in->parent != in->my_dev->del_dir) { ++ /* Move to unlinked directory so we have a deletion record */ ++ yaffs_change_obj_name(in, in->my_dev->del_dir, _Y("deleted"), 0, ++ 0); ++ } ++ ++ yaffs_remove_obj_from_dir(in); ++ yaffs_chunk_del(in->my_dev, in->hdr_chunk, 1, __LINE__); ++ in->hdr_chunk = 0; ++ ++ yaffs_free_obj(in); ++ return YAFFS_OK; ++ ++} ++ ++static void yaffs_soft_del_file(struct yaffs_obj *obj) ++{ ++ if (!obj->deleted || ++ obj->variant_type != YAFFS_OBJECT_TYPE_FILE || ++ obj->soft_del) ++ return; ++ ++ if (obj->n_data_chunks <= 0) { ++ /* Empty file with no duplicate object headers, ++ * just delete it immediately */ ++ yaffs_free_tnode(obj->my_dev, obj->variant.file_variant.top); ++ obj->variant.file_variant.top = NULL; ++ yaffs_trace(YAFFS_TRACE_TRACING, ++ "yaffs: Deleting empty file %d", ++ obj->obj_id); ++ yaffs_generic_obj_del(obj); ++ } else { ++ yaffs_soft_del_worker(obj, ++ obj->variant.file_variant.top, ++ obj->variant. ++ file_variant.top_level, 0); ++ obj->soft_del = 1; ++ } ++} ++ ++/* Pruning removes any part of the file structure tree that is beyond the ++ * bounds of the file (ie that does not point to chunks). ++ * ++ * A file should only get pruned when its size is reduced. ++ * ++ * Before pruning, the chunks must be pulled from the tree and the ++ * level 0 tnode entries must be zeroed out. ++ * Could also use this for file deletion, but that's probably better handled ++ * by a special case. ++ * ++ * This function is recursive. For levels > 0 the function is called again on ++ * any sub-tree. For level == 0 we just check if the sub-tree has data. ++ * If there is no data in a subtree then it is pruned. ++ */ ++ ++static struct yaffs_tnode *yaffs_prune_worker(struct yaffs_dev *dev, ++ struct yaffs_tnode *tn, u32 level, ++ int del0) ++{ ++ int i; ++ int has_data; ++ ++ if (!tn) ++ return tn; ++ ++ has_data = 0; ++ ++ if (level > 0) { ++ for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) { ++ if (tn->internal[i]) { ++ tn->internal[i] = ++ yaffs_prune_worker(dev, ++ tn->internal[i], ++ level - 1, ++ (i == 0) ? del0 : 1); ++ } ++ ++ if (tn->internal[i]) ++ has_data++; ++ } ++ } else { ++ int tnode_size_u32 = dev->tnode_size / sizeof(u32); ++ u32 *map = (u32 *) tn; ++ ++ for (i = 0; !has_data && i < tnode_size_u32; i++) { ++ if (map[i]) ++ has_data++; ++ } ++ } ++ ++ if (has_data == 0 && del0) { ++ /* Free and return NULL */ ++ yaffs_free_tnode(dev, tn); ++ tn = NULL; ++ } ++ return tn; ++} ++ ++static int yaffs_prune_tree(struct yaffs_dev *dev, ++ struct yaffs_file_var *file_struct) ++{ ++ int i; ++ int has_data; ++ int done = 0; ++ struct yaffs_tnode *tn; ++ ++ if (file_struct->top_level < 1) ++ return YAFFS_OK; ++ ++ file_struct->top = ++ yaffs_prune_worker(dev, file_struct->top, file_struct->top_level, 0); ++ ++ /* Now we have a tree with all the non-zero branches NULL but ++ * the height is the same as it was. ++ * Let's see if we can trim internal tnodes to shorten the tree. ++ * We can do this if only the 0th element in the tnode is in use ++ * (ie all the non-zero are NULL) ++ */ ++ ++ while (file_struct->top_level && !done) { ++ tn = file_struct->top; ++ ++ has_data = 0; ++ for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) { ++ if (tn->internal[i]) ++ has_data++; ++ } ++ ++ if (!has_data) { ++ file_struct->top = tn->internal[0]; ++ file_struct->top_level--; ++ yaffs_free_tnode(dev, tn); ++ } else { ++ done = 1; ++ } ++ } ++ ++ return YAFFS_OK; ++} ++ ++/*-------------------- End of File Structure functions.-------------------*/ ++ ++/* alloc_empty_obj gets us a clean Object.*/ ++static struct yaffs_obj *yaffs_alloc_empty_obj(struct yaffs_dev *dev) ++{ ++ struct yaffs_obj *obj = yaffs_alloc_raw_obj(dev); ++ ++ if (!obj) ++ return obj; ++ ++ dev->n_obj++; ++ ++ /* Now sweeten it up... */ ++ ++ memset(obj, 0, sizeof(struct yaffs_obj)); ++ obj->being_created = 1; ++ ++ obj->my_dev = dev; ++ obj->hdr_chunk = 0; ++ obj->variant_type = YAFFS_OBJECT_TYPE_UNKNOWN; ++ INIT_LIST_HEAD(&(obj->hard_links)); ++ INIT_LIST_HEAD(&(obj->hash_link)); ++ INIT_LIST_HEAD(&obj->siblings); ++ ++ /* Now make the directory sane */ ++ if (dev->root_dir) { ++ obj->parent = dev->root_dir; ++ list_add(&(obj->siblings), ++ &dev->root_dir->variant.dir_variant.children); ++ } ++ ++ /* Add it to the lost and found directory. ++ * NB Can't put root or lost-n-found in lost-n-found so ++ * check if lost-n-found exists first ++ */ ++ if (dev->lost_n_found) ++ yaffs_add_obj_to_dir(dev->lost_n_found, obj); ++ ++ obj->being_created = 0; ++ ++ dev->checkpoint_blocks_required = 0; /* force recalculation */ ++ ++ return obj; ++} ++ ++static int yaffs_find_nice_bucket(struct yaffs_dev *dev) ++{ ++ int i; ++ int l = 999; ++ int lowest = 999999; ++ ++ /* Search for the shortest list or one that ++ * isn't too long. ++ */ ++ ++ for (i = 0; i < 10 && lowest > 4; i++) { ++ dev->bucket_finder++; ++ dev->bucket_finder %= YAFFS_NOBJECT_BUCKETS; ++ if (dev->obj_bucket[dev->bucket_finder].count < lowest) { ++ lowest = dev->obj_bucket[dev->bucket_finder].count; ++ l = dev->bucket_finder; ++ } ++ } ++ ++ return l; ++} ++ ++static int yaffs_new_obj_id(struct yaffs_dev *dev) ++{ ++ int bucket = yaffs_find_nice_bucket(dev); ++ int found = 0; ++ struct list_head *i; ++ u32 n = (u32) bucket; ++ ++ /* ++ * Now find an object value that has not already been taken ++ * by scanning the list, incrementing each time by number of buckets. ++ */ ++ while (!found) { ++ found = 1; ++ n += YAFFS_NOBJECT_BUCKETS; ++ list_for_each(i, &dev->obj_bucket[bucket].list) { ++ /* Check if this value is already taken. */ ++ if (i && list_entry(i, struct yaffs_obj, ++ hash_link)->obj_id == n) ++ found = 0; ++ } ++ } ++ return n; ++} ++ ++static void yaffs_hash_obj(struct yaffs_obj *in) ++{ ++ int bucket = yaffs_hash_fn(in->obj_id); ++ struct yaffs_dev *dev = in->my_dev; ++ ++ list_add(&in->hash_link, &dev->obj_bucket[bucket].list); ++ dev->obj_bucket[bucket].count++; ++} ++ ++struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number) ++{ ++ int bucket = yaffs_hash_fn(number); ++ struct list_head *i; ++ struct yaffs_obj *in; ++ ++ list_for_each(i, &dev->obj_bucket[bucket].list) { ++ /* Look if it is in the list */ ++ in = list_entry(i, struct yaffs_obj, hash_link); ++ if (in->obj_id == number) { ++ /* Don't show if it is defered free */ ++ if (in->defered_free) ++ return NULL; ++ return in; ++ } ++ } ++ ++ return NULL; ++} ++ ++static struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number, ++ enum yaffs_obj_type type) ++{ ++ struct yaffs_obj *the_obj = NULL; ++ struct yaffs_tnode *tn = NULL; ++ ++ if (number < 0) ++ number = yaffs_new_obj_id(dev); ++ ++ if (type == YAFFS_OBJECT_TYPE_FILE) { ++ tn = yaffs_get_tnode(dev); ++ if (!tn) ++ return NULL; ++ } ++ ++ the_obj = yaffs_alloc_empty_obj(dev); ++ if (!the_obj) { ++ if (tn) ++ yaffs_free_tnode(dev, tn); ++ return NULL; ++ } ++ ++ the_obj->fake = 0; ++ the_obj->rename_allowed = 1; ++ the_obj->unlink_allowed = 1; ++ the_obj->obj_id = number; ++ yaffs_hash_obj(the_obj); ++ the_obj->variant_type = type; ++ yaffs_load_current_time(the_obj, 1, 1); ++ ++ switch (type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ the_obj->variant.file_variant.file_size = 0; ++ the_obj->variant.file_variant.stored_size = 0; ++ the_obj->variant.file_variant.shrink_size = ++ yaffs_max_file_size(dev); ++ the_obj->variant.file_variant.top_level = 0; ++ the_obj->variant.file_variant.top = tn; ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ INIT_LIST_HEAD(&the_obj->variant.dir_variant.children); ++ INIT_LIST_HEAD(&the_obj->variant.dir_variant.dirty); ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ /* No action required */ ++ break; ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ /* todo this should not happen */ ++ break; ++ } ++ return the_obj; ++} ++ ++static struct yaffs_obj *yaffs_create_fake_dir(struct yaffs_dev *dev, ++ int number, u32 mode) ++{ ++ ++ struct yaffs_obj *obj = ++ yaffs_new_obj(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY); ++ ++ if (!obj) ++ return NULL; ++ ++ obj->fake = 1; /* it is fake so it might not use NAND */ ++ obj->rename_allowed = 0; ++ obj->unlink_allowed = 0; ++ obj->deleted = 0; ++ obj->unlinked = 0; ++ obj->yst_mode = mode; ++ obj->my_dev = dev; ++ obj->hdr_chunk = 0; /* Not a valid chunk. */ ++ return obj; ++ ++} ++ ++ ++static void yaffs_init_tnodes_and_objs(struct yaffs_dev *dev) ++{ ++ int i; ++ ++ dev->n_obj = 0; ++ dev->n_tnodes = 0; ++ yaffs_init_raw_tnodes_and_objs(dev); ++ ++ for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) { ++ INIT_LIST_HEAD(&dev->obj_bucket[i].list); ++ dev->obj_bucket[i].count = 0; ++ } ++} ++ ++struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev, ++ int number, ++ enum yaffs_obj_type type) ++{ ++ struct yaffs_obj *the_obj = NULL; ++ ++ if (number > 0) ++ the_obj = yaffs_find_by_number(dev, number); ++ ++ if (!the_obj) ++ the_obj = yaffs_new_obj(dev, number, type); ++ ++ return the_obj; ++ ++} ++ ++YCHAR *yaffs_clone_str(const YCHAR *str) ++{ ++ YCHAR *new_str = NULL; ++ int len; ++ ++ if (!str) ++ str = _Y(""); ++ ++ len = strnlen(str, YAFFS_MAX_ALIAS_LENGTH); ++ new_str = kmalloc((len + 1) * sizeof(YCHAR), GFP_NOFS); ++ if (new_str) { ++ strncpy(new_str, str, len); ++ new_str[len] = 0; ++ } ++ return new_str; ++ ++} ++/* ++ *yaffs_update_parent() handles fixing a directories mtime and ctime when a new ++ * link (ie. name) is created or deleted in the directory. ++ * ++ * ie. ++ * create dir/a : update dir's mtime/ctime ++ * rm dir/a: update dir's mtime/ctime ++ * modify dir/a: don't update dir's mtimme/ctime ++ * ++ * This can be handled immediately or defered. Defering helps reduce the number ++ * of updates when many files in a directory are changed within a brief period. ++ * ++ * If the directory updating is defered then yaffs_update_dirty_dirs must be ++ * called periodically. ++ */ ++ ++static void yaffs_update_parent(struct yaffs_obj *obj) ++{ ++ struct yaffs_dev *dev; ++ ++ if (!obj) ++ return; ++ dev = obj->my_dev; ++ obj->dirty = 1; ++ yaffs_load_current_time(obj, 0, 1); ++ if (dev->param.defered_dir_update) { ++ struct list_head *link = &obj->variant.dir_variant.dirty; ++ ++ if (list_empty(link)) { ++ list_add(link, &dev->dirty_dirs); ++ yaffs_trace(YAFFS_TRACE_BACKGROUND, ++ "Added object %d to dirty directories", ++ obj->obj_id); ++ } ++ ++ } else { ++ yaffs_update_oh(obj, NULL, 0, 0, 0, NULL); ++ } ++} ++ ++void yaffs_update_dirty_dirs(struct yaffs_dev *dev) ++{ ++ struct list_head *link; ++ struct yaffs_obj *obj; ++ struct yaffs_dir_var *d_s; ++ union yaffs_obj_var *o_v; ++ ++ yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update dirty directories"); ++ ++ while (!list_empty(&dev->dirty_dirs)) { ++ link = dev->dirty_dirs.next; ++ list_del_init(link); ++ ++ d_s = list_entry(link, struct yaffs_dir_var, dirty); ++ o_v = list_entry(d_s, union yaffs_obj_var, dir_variant); ++ obj = list_entry(o_v, struct yaffs_obj, variant); ++ ++ yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update directory %d", ++ obj->obj_id); ++ ++ if (obj->dirty) ++ yaffs_update_oh(obj, NULL, 0, 0, 0, NULL); ++ } ++} ++ ++/* ++ * Mknod (create) a new object. ++ * equiv_obj only has meaning for a hard link; ++ * alias_str only has meaning for a symlink. ++ * rdev only has meaning for devices (a subset of special objects) ++ */ ++ ++static struct yaffs_obj *yaffs_create_obj(enum yaffs_obj_type type, ++ struct yaffs_obj *parent, ++ const YCHAR *name, ++ u32 mode, ++ u32 uid, ++ u32 gid, ++ struct yaffs_obj *equiv_obj, ++ const YCHAR *alias_str, u32 rdev) ++{ ++ struct yaffs_obj *in; ++ YCHAR *str = NULL; ++ struct yaffs_dev *dev = parent->my_dev; ++ ++ /* Check if the entry exists. ++ * If it does then fail the call since we don't want a dup. */ ++ if (yaffs_find_by_name(parent, name)) ++ return NULL; ++ ++ if (type == YAFFS_OBJECT_TYPE_SYMLINK) { ++ str = yaffs_clone_str(alias_str); ++ if (!str) ++ return NULL; ++ } ++ ++ in = yaffs_new_obj(dev, -1, type); ++ ++ if (!in) { ++ kfree(str); ++ return NULL; ++ } ++ ++ in->hdr_chunk = 0; ++ in->valid = 1; ++ in->variant_type = type; ++ ++ in->yst_mode = mode; ++ ++ yaffs_attribs_init(in, gid, uid, rdev); ++ ++ in->n_data_chunks = 0; ++ ++ yaffs_set_obj_name(in, name); ++ in->dirty = 1; ++ ++ yaffs_add_obj_to_dir(parent, in); ++ ++ in->my_dev = parent->my_dev; ++ ++ switch (type) { ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ in->variant.symlink_variant.alias = str; ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ in->variant.hardlink_variant.equiv_obj = equiv_obj; ++ in->variant.hardlink_variant.equiv_id = equiv_obj->obj_id; ++ list_add(&in->hard_links, &equiv_obj->hard_links); ++ break; ++ case YAFFS_OBJECT_TYPE_FILE: ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ /* do nothing */ ++ break; ++ } ++ ++ if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) { ++ /* Could not create the object header, fail */ ++ yaffs_del_obj(in); ++ in = NULL; ++ } ++ ++ if (in) ++ yaffs_update_parent(parent); ++ ++ return in; ++} ++ ++struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent, ++ const YCHAR *name, u32 mode, u32 uid, ++ u32 gid) ++{ ++ return yaffs_create_obj(YAFFS_OBJECT_TYPE_FILE, parent, name, mode, ++ uid, gid, NULL, NULL, 0); ++} ++ ++struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name, ++ u32 mode, u32 uid, u32 gid) ++{ ++ return yaffs_create_obj(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name, ++ mode, uid, gid, NULL, NULL, 0); ++} ++ ++struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent, ++ const YCHAR *name, u32 mode, u32 uid, ++ u32 gid, u32 rdev) ++{ ++ return yaffs_create_obj(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode, ++ uid, gid, NULL, NULL, rdev); ++} ++ ++struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent, ++ const YCHAR *name, u32 mode, u32 uid, ++ u32 gid, const YCHAR *alias) ++{ ++ return yaffs_create_obj(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode, ++ uid, gid, NULL, alias, 0); ++} ++ ++/* yaffs_link_obj returns the object id of the equivalent object.*/ ++struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR * name, ++ struct yaffs_obj *equiv_obj) ++{ ++ /* Get the real object in case we were fed a hard link obj */ ++ equiv_obj = yaffs_get_equivalent_obj(equiv_obj); ++ ++ if (yaffs_create_obj(YAFFS_OBJECT_TYPE_HARDLINK, ++ parent, name, 0, 0, 0, ++ equiv_obj, NULL, 0)) ++ return equiv_obj; ++ ++ return NULL; ++ ++} ++ ++ ++ ++/*---------------------- Block Management and Page Allocation -------------*/ ++ ++static void yaffs_deinit_blocks(struct yaffs_dev *dev) ++{ ++ if (dev->block_info_alt && dev->block_info) ++ vfree(dev->block_info); ++ else ++ kfree(dev->block_info); ++ ++ dev->block_info_alt = 0; ++ ++ dev->block_info = NULL; ++ ++ if (dev->chunk_bits_alt && dev->chunk_bits) ++ vfree(dev->chunk_bits); ++ else ++ kfree(dev->chunk_bits); ++ dev->chunk_bits_alt = 0; ++ dev->chunk_bits = NULL; ++} ++ ++static int yaffs_init_blocks(struct yaffs_dev *dev) ++{ ++ int n_blocks = dev->internal_end_block - dev->internal_start_block + 1; ++ ++ dev->block_info = NULL; ++ dev->chunk_bits = NULL; ++ dev->alloc_block = -1; /* force it to get a new one */ ++ ++ /* If the first allocation strategy fails, thry the alternate one */ ++ dev->block_info = ++ kmalloc(n_blocks * sizeof(struct yaffs_block_info), GFP_NOFS); ++ if (!dev->block_info) { ++ dev->block_info = ++ vmalloc(n_blocks * sizeof(struct yaffs_block_info)); ++ dev->block_info_alt = 1; ++ } else { ++ dev->block_info_alt = 0; ++ } ++ ++ if (!dev->block_info) ++ goto alloc_error; ++ ++ /* Set up dynamic blockinfo stuff. Round up bytes. */ ++ dev->chunk_bit_stride = (dev->param.chunks_per_block + 7) / 8; ++ dev->chunk_bits = ++ kmalloc(dev->chunk_bit_stride * n_blocks, GFP_NOFS); ++ if (!dev->chunk_bits) { ++ dev->chunk_bits = ++ vmalloc(dev->chunk_bit_stride * n_blocks); ++ dev->chunk_bits_alt = 1; ++ } else { ++ dev->chunk_bits_alt = 0; ++ } ++ if (!dev->chunk_bits) ++ goto alloc_error; ++ ++ ++ memset(dev->block_info, 0, n_blocks * sizeof(struct yaffs_block_info)); ++ memset(dev->chunk_bits, 0, dev->chunk_bit_stride * n_blocks); ++ return YAFFS_OK; ++ ++alloc_error: ++ yaffs_deinit_blocks(dev); ++ return YAFFS_FAIL; ++} ++ ++ ++void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no) ++{ ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, block_no); ++ int erased_ok = 0; ++ u32 i; ++ ++ /* If the block is still healthy erase it and mark as clean. ++ * If the block has had a data failure, then retire it. ++ */ ++ ++ yaffs_trace(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE, ++ "yaffs_block_became_dirty block %d state %d %s", ++ block_no, bi->block_state, ++ (bi->needs_retiring) ? "needs retiring" : ""); ++ ++ yaffs2_clear_oldest_dirty_seq(dev, bi); ++ ++ bi->block_state = YAFFS_BLOCK_STATE_DIRTY; ++ ++ /* If this is the block being garbage collected then stop gc'ing */ ++ if (block_no == (int)dev->gc_block) ++ dev->gc_block = 0; ++ ++ /* If this block is currently the best candidate for gc ++ * then drop as a candidate */ ++ if (block_no == (int)dev->gc_dirtiest) { ++ dev->gc_dirtiest = 0; ++ dev->gc_pages_in_use = 0; ++ } ++ ++ if (!bi->needs_retiring) { ++ yaffs2_checkpt_invalidate(dev); ++ erased_ok = yaffs_erase_block(dev, block_no); ++ if (!erased_ok) { ++ dev->n_erase_failures++; ++ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, ++ "**>> Erasure failed %d", block_no); ++ } ++ } ++ ++ /* Verify erasure if needed */ ++ if (erased_ok && ++ ((yaffs_trace_mask & YAFFS_TRACE_ERASE) || ++ !yaffs_skip_verification(dev))) { ++ for (i = 0; i < dev->param.chunks_per_block; i++) { ++ if (!yaffs_check_chunk_erased(dev, ++ block_no * dev->param.chunks_per_block + i)) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ ">>Block %d erasure supposedly OK, but chunk %d not erased", ++ block_no, i); ++ } ++ } ++ } ++ ++ if (!erased_ok) { ++ /* We lost a block of free space */ ++ dev->n_free_chunks -= dev->param.chunks_per_block; ++ yaffs_retire_block(dev, block_no); ++ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, ++ "**>> Block %d retired", block_no); ++ return; ++ } ++ ++ /* Clean it up... */ ++ bi->block_state = YAFFS_BLOCK_STATE_EMPTY; ++ bi->seq_number = 0; ++ dev->n_erased_blocks++; ++ bi->pages_in_use = 0; ++ bi->soft_del_pages = 0; ++ bi->has_shrink_hdr = 0; ++ bi->skip_erased_check = 1; /* Clean, so no need to check */ ++ bi->gc_prioritise = 0; ++ bi->has_summary = 0; ++ ++ yaffs_clear_chunk_bits(dev, block_no); ++ ++ yaffs_trace(YAFFS_TRACE_ERASE, "Erased block %d", block_no); ++} ++ ++static inline int yaffs_gc_process_chunk(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi, ++ int old_chunk, u8 *buffer) ++{ ++ int new_chunk; ++ int mark_flash = 1; ++ struct yaffs_ext_tags tags; ++ struct yaffs_obj *object; ++ int matching_chunk; ++ int ret_val = YAFFS_OK; ++ ++ memset(&tags, 0, sizeof(tags)); ++ yaffs_rd_chunk_tags_nand(dev, old_chunk, ++ buffer, &tags); ++ object = yaffs_find_by_number(dev, tags.obj_id); ++ ++ yaffs_trace(YAFFS_TRACE_GC_DETAIL, ++ "Collecting chunk in block %d, %d %d %d ", ++ dev->gc_chunk, tags.obj_id, ++ tags.chunk_id, tags.n_bytes); ++ ++ if (object && !yaffs_skip_verification(dev)) { ++ if (tags.chunk_id == 0) ++ matching_chunk = ++ object->hdr_chunk; ++ else if (object->soft_del) ++ /* Defeat the test */ ++ matching_chunk = old_chunk; ++ else ++ matching_chunk = ++ yaffs_find_chunk_in_file ++ (object, tags.chunk_id, ++ NULL); ++ ++ if (old_chunk != matching_chunk) ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "gc: page in gc mismatch: %d %d %d %d", ++ old_chunk, ++ matching_chunk, ++ tags.obj_id, ++ tags.chunk_id); ++ } ++ ++ if (!object) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "page %d in gc has no object: %d %d %d ", ++ old_chunk, ++ tags.obj_id, tags.chunk_id, ++ tags.n_bytes); ++ } ++ ++ if (object && ++ object->deleted && ++ object->soft_del && tags.chunk_id != 0) { ++ /* Data chunk in a soft deleted file, ++ * throw it away. ++ * It's a soft deleted data chunk, ++ * No need to copy this, just forget ++ * about it and fix up the object. ++ */ ++ ++ /* Free chunks already includes ++ * softdeleted chunks, how ever this ++ * chunk is going to soon be really ++ * deleted which will increment free ++ * chunks. We have to decrement free ++ * chunks so this works out properly. ++ */ ++ dev->n_free_chunks--; ++ bi->soft_del_pages--; ++ ++ object->n_data_chunks--; ++ if (object->n_data_chunks <= 0) { ++ /* remeber to clean up obj */ ++ dev->gc_cleanup_list[dev->n_clean_ups] = tags.obj_id; ++ dev->n_clean_ups++; ++ } ++ mark_flash = 0; ++ } else if (object) { ++ /* It's either a data chunk in a live ++ * file or an ObjectHeader, so we're ++ * interested in it. ++ * NB Need to keep the ObjectHeaders of ++ * deleted files until the whole file ++ * has been deleted off ++ */ ++ tags.serial_number++; ++ dev->n_gc_copies++; ++ ++ if (tags.chunk_id == 0) { ++ /* It is an object Id, ++ * We need to nuke the shrinkheader flags since its ++ * work is done. ++ * Also need to clean up shadowing. ++ * NB We don't want to do all the work of translating ++ * object header endianism back and forth so we leave ++ * the oh endian in its stored order. ++ */ ++ ++ struct yaffs_obj_hdr *oh; ++ oh = (struct yaffs_obj_hdr *) buffer; ++ ++ oh->is_shrink = 0; ++ tags.extra_is_shrink = 0; ++ oh->shadows_obj = 0; ++ oh->inband_shadowed_obj_id = 0; ++ tags.extra_shadows = 0; ++ ++ /* Update file size */ ++ if (object->variant_type == YAFFS_OBJECT_TYPE_FILE) { ++ yaffs_oh_size_load(dev, oh, ++ object->variant.file_variant.stored_size, 1); ++ tags.extra_file_size = ++ object->variant.file_variant.stored_size; ++ } ++ ++ yaffs_verify_oh(object, oh, &tags, 1); ++ new_chunk = ++ yaffs_write_new_chunk(dev, (u8 *) oh, &tags, 1); ++ } else { ++ new_chunk = ++ yaffs_write_new_chunk(dev, buffer, &tags, 1); ++ } ++ ++ if (new_chunk < 0) { ++ ret_val = YAFFS_FAIL; ++ } else { ++ ++ /* Now fix up the Tnodes etc. */ ++ ++ if (tags.chunk_id == 0) { ++ /* It's a header */ ++ object->hdr_chunk = new_chunk; ++ object->serial = tags.serial_number; ++ } else { ++ /* It's a data chunk */ ++ yaffs_put_chunk_in_file(object, tags.chunk_id, ++ new_chunk, 0); ++ } ++ } ++ } ++ if (ret_val == YAFFS_OK) ++ yaffs_chunk_del(dev, old_chunk, mark_flash, __LINE__); ++ return ret_val; ++} ++ ++static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block) ++{ ++ int old_chunk; ++ int ret_val = YAFFS_OK; ++ u32 i; ++ int is_checkpt_block; ++ int max_copies; ++ int chunks_before = yaffs_get_erased_chunks(dev); ++ int chunks_after; ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, block); ++ ++ is_checkpt_block = (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT); ++ ++ yaffs_trace(YAFFS_TRACE_TRACING, ++ "Collecting block %d, in use %d, shrink %d, whole_block %d", ++ block, bi->pages_in_use, bi->has_shrink_hdr, ++ whole_block); ++ ++ /*yaffs_verify_free_chunks(dev); */ ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_FULL) ++ bi->block_state = YAFFS_BLOCK_STATE_COLLECTING; ++ ++ bi->has_shrink_hdr = 0; /* clear the flag so that the block can erase */ ++ ++ dev->gc_disable = 1; ++ ++ yaffs_summary_gc(dev, block); ++ ++ if (is_checkpt_block || !yaffs_still_some_chunks(dev, block)) { ++ yaffs_trace(YAFFS_TRACE_TRACING, ++ "Collecting block %d that has no chunks in use", ++ block); ++ yaffs_block_became_dirty(dev, block); ++ } else { ++ ++ u8 *buffer = yaffs_get_temp_buffer(dev); ++ ++ yaffs_verify_blk(dev, bi, block); ++ ++ max_copies = (whole_block) ? dev->param.chunks_per_block : 5; ++ old_chunk = block * dev->param.chunks_per_block + dev->gc_chunk; ++ ++ for (/* init already done */ ; ++ ret_val == YAFFS_OK && ++ dev->gc_chunk < dev->param.chunks_per_block && ++ (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) && ++ max_copies > 0; ++ dev->gc_chunk++, old_chunk++) { ++ if (yaffs_check_chunk_bit(dev, block, dev->gc_chunk)) { ++ /* Page is in use and might need to be copied */ ++ max_copies--; ++ ret_val = yaffs_gc_process_chunk(dev, bi, ++ old_chunk, buffer); ++ } ++ } ++ yaffs_release_temp_buffer(dev, buffer); ++ } ++ ++ yaffs_verify_collected_blk(dev, bi, block); ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) { ++ /* ++ * The gc did not complete. Set block state back to FULL ++ * because checkpointing does not restore gc. ++ */ ++ bi->block_state = YAFFS_BLOCK_STATE_FULL; ++ } else { ++ /* The gc completed. */ ++ /* Do any required cleanups */ ++ for (i = 0; i < dev->n_clean_ups; i++) { ++ /* Time to delete the file too */ ++ struct yaffs_obj *object = ++ yaffs_find_by_number(dev, dev->gc_cleanup_list[i]); ++ if (object) { ++ yaffs_free_tnode(dev, ++ object->variant.file_variant.top); ++ object->variant.file_variant.top = NULL; ++ yaffs_trace(YAFFS_TRACE_GC, ++ "yaffs: About to finally delete object %d", ++ object->obj_id); ++ yaffs_generic_obj_del(object); ++ object->my_dev->n_deleted_files--; ++ } ++ ++ } ++ chunks_after = yaffs_get_erased_chunks(dev); ++ if (chunks_before >= chunks_after) ++ yaffs_trace(YAFFS_TRACE_GC, ++ "gc did not increase free chunks before %d after %d", ++ chunks_before, chunks_after); ++ dev->gc_block = 0; ++ dev->gc_chunk = 0; ++ dev->n_clean_ups = 0; ++ } ++ ++ dev->gc_disable = 0; ++ ++ return ret_val; ++} ++ ++/* ++ * find_gc_block() selects the dirtiest block (or close enough) ++ * for garbage collection. ++ */ ++ ++static unsigned yaffs_find_gc_block(struct yaffs_dev *dev, ++ int aggressive, int background) ++{ ++ u32 i; ++ u32 iterations; ++ u32 selected = 0; ++ int prioritised = 0; ++ int prioritised_exist = 0; ++ struct yaffs_block_info *bi; ++ u32 threshold; ++ ++ /* First let's see if we need to grab a prioritised block */ ++ if (dev->has_pending_prioritised_gc && !aggressive) { ++ dev->gc_dirtiest = 0; ++ bi = dev->block_info; ++ for (i = dev->internal_start_block; ++ i <= dev->internal_end_block && !selected; i++) { ++ ++ if (bi->gc_prioritise) { ++ prioritised_exist = 1; ++ if (bi->block_state == YAFFS_BLOCK_STATE_FULL && ++ yaffs_block_ok_for_gc(dev, bi)) { ++ selected = i; ++ prioritised = 1; ++ } ++ } ++ bi++; ++ } ++ ++ /* ++ * If there is a prioritised block and none was selected then ++ * this happened because there is at least one old dirty block ++ * gumming up the works. Let's gc the oldest dirty block. ++ */ ++ ++ if (prioritised_exist && ++ !selected && dev->oldest_dirty_block > 0) ++ selected = dev->oldest_dirty_block; ++ ++ if (!prioritised_exist) /* None found, so we can clear this */ ++ dev->has_pending_prioritised_gc = 0; ++ } ++ ++ /* If we're doing aggressive GC then we are happy to take a less-dirty ++ * block, and search harder. ++ * else (leasurely gc), then we only bother to do this if the ++ * block has only a few pages in use. ++ */ ++ ++ if (!selected) { ++ u32 pages_used; ++ int n_blocks = ++ dev->internal_end_block - dev->internal_start_block + 1; ++ if (aggressive) { ++ threshold = dev->param.chunks_per_block; ++ iterations = n_blocks; ++ } else { ++ u32 max_threshold; ++ ++ if (background) ++ max_threshold = dev->param.chunks_per_block / 2; ++ else ++ max_threshold = dev->param.chunks_per_block / 8; ++ ++ if (max_threshold < YAFFS_GC_PASSIVE_THRESHOLD) ++ max_threshold = YAFFS_GC_PASSIVE_THRESHOLD; ++ ++ threshold = background ? (dev->gc_not_done + 2) * 2 : 0; ++ if (threshold < YAFFS_GC_PASSIVE_THRESHOLD) ++ threshold = YAFFS_GC_PASSIVE_THRESHOLD; ++ if (threshold > max_threshold) ++ threshold = max_threshold; ++ ++ iterations = n_blocks / 16 + 1; ++ if (iterations > 100) ++ iterations = 100; ++ } ++ ++ for (i = 0; ++ i < iterations && ++ (dev->gc_dirtiest < 1 || ++ dev->gc_pages_in_use > YAFFS_GC_GOOD_ENOUGH); ++ i++) { ++ dev->gc_block_finder++; ++ if (dev->gc_block_finder < dev->internal_start_block || ++ dev->gc_block_finder > dev->internal_end_block) ++ dev->gc_block_finder = ++ dev->internal_start_block; ++ ++ bi = yaffs_get_block_info(dev, dev->gc_block_finder); ++ ++ pages_used = bi->pages_in_use - bi->soft_del_pages; ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_FULL && ++ pages_used < dev->param.chunks_per_block && ++ (dev->gc_dirtiest < 1 || ++ pages_used < dev->gc_pages_in_use) && ++ yaffs_block_ok_for_gc(dev, bi)) { ++ dev->gc_dirtiest = dev->gc_block_finder; ++ dev->gc_pages_in_use = pages_used; ++ } ++ } ++ ++ if (dev->gc_dirtiest > 0 && dev->gc_pages_in_use <= threshold) ++ selected = dev->gc_dirtiest; ++ } ++ ++ /* ++ * If nothing has been selected for a while, try the oldest dirty ++ * because that's gumming up the works. ++ */ ++ ++ if (!selected && dev->param.is_yaffs2 && ++ dev->gc_not_done >= (background ? 10 : 20)) { ++ yaffs2_find_oldest_dirty_seq(dev); ++ if (dev->oldest_dirty_block > 0) { ++ selected = dev->oldest_dirty_block; ++ dev->gc_dirtiest = selected; ++ dev->oldest_dirty_gc_count++; ++ bi = yaffs_get_block_info(dev, selected); ++ dev->gc_pages_in_use = ++ bi->pages_in_use - bi->soft_del_pages; ++ } else { ++ dev->gc_not_done = 0; ++ } ++ } ++ ++ if (selected) { ++ yaffs_trace(YAFFS_TRACE_GC, ++ "GC Selected block %d with %d free, prioritised:%d", ++ selected, ++ dev->param.chunks_per_block - dev->gc_pages_in_use, ++ prioritised); ++ ++ dev->n_gc_blocks++; ++ if (background) ++ dev->bg_gcs++; ++ ++ dev->gc_dirtiest = 0; ++ dev->gc_pages_in_use = 0; ++ dev->gc_not_done = 0; ++ if (dev->refresh_skip > 0) ++ dev->refresh_skip--; ++ } else { ++ dev->gc_not_done++; ++ yaffs_trace(YAFFS_TRACE_GC, ++ "GC none: finder %d skip %d threshold %d dirtiest %d using %d oldest %d%s", ++ dev->gc_block_finder, dev->gc_not_done, threshold, ++ dev->gc_dirtiest, dev->gc_pages_in_use, ++ dev->oldest_dirty_block, background ? " bg" : ""); ++ } ++ ++ return selected; ++} ++ ++/* New garbage collector ++ * If we're very low on erased blocks then we do aggressive garbage collection ++ * otherwise we do "leasurely" garbage collection. ++ * Aggressive gc looks further (whole array) and will accept less dirty blocks. ++ * Passive gc only inspects smaller areas and only accepts more dirty blocks. ++ * ++ * The idea is to help clear out space in a more spread-out manner. ++ * Dunno if it really does anything useful. ++ */ ++static int yaffs_check_gc(struct yaffs_dev *dev, int background) ++{ ++ int aggressive = 0; ++ int gc_ok = YAFFS_OK; ++ int max_tries = 0; ++ int min_erased; ++ int erased_chunks; ++ int checkpt_block_adjust; ++ ++ if (dev->param.gc_control_fn && ++ (dev->param.gc_control_fn(dev) & 1) == 0) ++ return YAFFS_OK; ++ ++ if (dev->gc_disable) ++ /* Bail out so we don't get recursive gc */ ++ return YAFFS_OK; ++ ++ /* This loop should pass the first time. ++ * Only loops here if the collection does not increase space. ++ */ ++ ++ do { ++ max_tries++; ++ ++ checkpt_block_adjust = yaffs_calc_checkpt_blocks_required(dev); ++ ++ min_erased = ++ dev->param.n_reserved_blocks + checkpt_block_adjust + 1; ++ erased_chunks = ++ dev->n_erased_blocks * dev->param.chunks_per_block; ++ ++ /* If we need a block soon then do aggressive gc. */ ++ if (dev->n_erased_blocks < min_erased) ++ aggressive = 1; ++ else { ++ if (!background ++ && erased_chunks > (dev->n_free_chunks / 4)) ++ break; ++ ++ if (dev->gc_skip > 20) ++ dev->gc_skip = 20; ++ if (erased_chunks < dev->n_free_chunks / 2 || ++ dev->gc_skip < 1 || background) ++ aggressive = 0; ++ else { ++ dev->gc_skip--; ++ break; ++ } ++ } ++ ++ dev->gc_skip = 5; ++ ++ /* If we don't already have a block being gc'd then see if we ++ * should start another */ ++ ++ if (dev->gc_block < 1 && !aggressive) { ++ dev->gc_block = yaffs2_find_refresh_block(dev); ++ dev->gc_chunk = 0; ++ dev->n_clean_ups = 0; ++ } ++ if (dev->gc_block < 1) { ++ dev->gc_block = ++ yaffs_find_gc_block(dev, aggressive, background); ++ dev->gc_chunk = 0; ++ dev->n_clean_ups = 0; ++ } ++ ++ if (dev->gc_block > 0) { ++ dev->all_gcs++; ++ if (!aggressive) ++ dev->passive_gc_count++; ++ ++ yaffs_trace(YAFFS_TRACE_GC, ++ "yaffs: GC n_erased_blocks %d aggressive %d", ++ dev->n_erased_blocks, aggressive); ++ ++ gc_ok = yaffs_gc_block(dev, dev->gc_block, aggressive); ++ } ++ ++ if (dev->n_erased_blocks < (int)dev->param.n_reserved_blocks && ++ dev->gc_block > 0) { ++ yaffs_trace(YAFFS_TRACE_GC, ++ "yaffs: GC !!!no reclaim!!! n_erased_blocks %d after try %d block %d", ++ dev->n_erased_blocks, max_tries, ++ dev->gc_block); ++ } ++ } while ((dev->n_erased_blocks < (int)dev->param.n_reserved_blocks) && ++ (dev->gc_block > 0) && (max_tries < 2)); ++ ++ return aggressive ? gc_ok : YAFFS_OK; ++} ++ ++/* ++ * yaffs_bg_gc() ++ * Garbage collects. Intended to be called from a background thread. ++ * Returns non-zero if at least half the free chunks are erased. ++ */ ++int yaffs_bg_gc(struct yaffs_dev *dev, unsigned urgency) ++{ ++ int erased_chunks = dev->n_erased_blocks * dev->param.chunks_per_block; ++ ++ yaffs_trace(YAFFS_TRACE_BACKGROUND, "Background gc %u", urgency); ++ ++ yaffs_check_gc(dev, 1); ++ return erased_chunks > dev->n_free_chunks / 2; ++} ++ ++/*-------------------- Data file manipulation -----------------*/ ++ ++static int yaffs_rd_data_obj(struct yaffs_obj *in, int inode_chunk, u8 * buffer) ++{ ++ int nand_chunk = yaffs_find_chunk_in_file(in, inode_chunk, NULL); ++ ++ if (nand_chunk >= 0) ++ return yaffs_rd_chunk_tags_nand(in->my_dev, nand_chunk, ++ buffer, NULL); ++ else { ++ yaffs_trace(YAFFS_TRACE_NANDACCESS, ++ "Chunk %d not found zero instead", ++ nand_chunk); ++ /* get sane (zero) data if you read a hole */ ++ memset(buffer, 0, in->my_dev->data_bytes_per_chunk); ++ return 0; ++ } ++ ++} ++ ++void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash, ++ int lyn) ++{ ++ int block; ++ int page; ++ struct yaffs_ext_tags tags; ++ struct yaffs_block_info *bi; ++ ++ if (chunk_id <= 0) ++ return; ++ ++ dev->n_deletions++; ++ block = chunk_id / dev->param.chunks_per_block; ++ page = chunk_id % dev->param.chunks_per_block; ++ ++ if (!yaffs_check_chunk_bit(dev, block, page)) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Deleting invalid chunk %d", chunk_id); ++ ++ bi = yaffs_get_block_info(dev, block); ++ ++ yaffs2_update_oldest_dirty_seq(dev, block, bi); ++ ++ yaffs_trace(YAFFS_TRACE_DELETION, ++ "line %d delete of chunk %d", ++ lyn, chunk_id); ++ ++ if (!dev->param.is_yaffs2 && mark_flash && ++ bi->block_state != YAFFS_BLOCK_STATE_COLLECTING) { ++ ++ memset(&tags, 0, sizeof(tags)); ++ tags.is_deleted = 1; ++ yaffs_wr_chunk_tags_nand(dev, chunk_id, NULL, &tags); ++ yaffs_handle_chunk_update(dev, chunk_id, &tags); ++ } else { ++ dev->n_unmarked_deletions++; ++ } ++ ++ /* Pull out of the management area. ++ * If the whole block became dirty, this will kick off an erasure. ++ */ ++ if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING || ++ bi->block_state == YAFFS_BLOCK_STATE_FULL || ++ bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN || ++ bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) { ++ dev->n_free_chunks++; ++ yaffs_clear_chunk_bit(dev, block, page); ++ bi->pages_in_use--; ++ ++ if (bi->pages_in_use == 0 && ++ !bi->has_shrink_hdr && ++ bi->block_state != YAFFS_BLOCK_STATE_ALLOCATING && ++ bi->block_state != YAFFS_BLOCK_STATE_NEEDS_SCAN) { ++ yaffs_block_became_dirty(dev, block); ++ } ++ } ++} ++ ++static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, ++ const u8 *buffer, int n_bytes, int use_reserve) ++{ ++ /* Find old chunk Need to do this to get serial number ++ * Write new one and patch into tree. ++ * Invalidate old tags. ++ */ ++ ++ int prev_chunk_id; ++ struct yaffs_ext_tags prev_tags; ++ int new_chunk_id; ++ struct yaffs_ext_tags new_tags; ++ struct yaffs_dev *dev = in->my_dev; ++ loff_t endpos; ++ ++ yaffs_check_gc(dev, 0); ++ ++ /* Get the previous chunk at this location in the file if it exists. ++ * If it does not exist then put a zero into the tree. This creates ++ * the tnode now, rather than later when it is harder to clean up. ++ */ ++ prev_chunk_id = yaffs_find_chunk_in_file(in, inode_chunk, &prev_tags); ++ if (prev_chunk_id < 1 && ++ !yaffs_put_chunk_in_file(in, inode_chunk, 0, 0)) ++ return 0; ++ ++ /* Set up new tags */ ++ memset(&new_tags, 0, sizeof(new_tags)); ++ ++ new_tags.chunk_id = inode_chunk; ++ new_tags.obj_id = in->obj_id; ++ new_tags.serial_number = ++ (prev_chunk_id > 0) ? prev_tags.serial_number + 1 : 1; ++ new_tags.n_bytes = n_bytes; ++ ++ if (n_bytes < 1 || n_bytes > (int)dev->data_bytes_per_chunk) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "Writing %d bytes to chunk!!!!!!!!!", ++ n_bytes); ++ BUG(); ++ } ++ ++ /* ++ * If this is a data chunk and the write goes past the end of the stored ++ * size then update the stored_size. ++ */ ++ if (inode_chunk > 0) { ++ endpos = (inode_chunk - 1) * dev->data_bytes_per_chunk + ++ n_bytes; ++ if (in->variant.file_variant.stored_size < endpos) ++ in->variant.file_variant.stored_size = endpos; ++ } ++ ++ new_chunk_id = ++ yaffs_write_new_chunk(dev, buffer, &new_tags, use_reserve); ++ ++ if (new_chunk_id > 0) { ++ yaffs_put_chunk_in_file(in, inode_chunk, new_chunk_id, 0); ++ ++ if (prev_chunk_id > 0) ++ yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__); ++ ++ yaffs_verify_file_sane(in); ++ } ++ return new_chunk_id; ++} ++ ++ ++ ++static int yaffs_do_xattrib_mod(struct yaffs_obj *obj, int set, ++ const YCHAR *name, const void *value, int size, ++ int flags) ++{ ++ struct yaffs_xattr_mod xmod; ++ int result; ++ ++ xmod.set = set; ++ xmod.name = name; ++ xmod.data = value; ++ xmod.size = size; ++ xmod.flags = flags; ++ xmod.result = -ENOSPC; ++ ++ result = yaffs_update_oh(obj, NULL, 0, 0, 0, &xmod); ++ ++ if (result > 0) ++ return xmod.result; ++ else ++ return -ENOSPC; ++} ++ ++static int yaffs_apply_xattrib_mod(struct yaffs_obj *obj, char *buffer, ++ struct yaffs_xattr_mod *xmod) ++{ ++ int retval = 0; ++ int x_offs = sizeof(struct yaffs_obj_hdr); ++ struct yaffs_dev *dev = obj->my_dev; ++ int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr); ++ char *x_buffer = buffer + x_offs; ++ ++ if (xmod->set) ++ retval = ++ nval_set(dev, x_buffer, x_size, xmod->name, xmod->data, ++ xmod->size, xmod->flags); ++ else ++ retval = nval_del(dev, x_buffer, x_size, xmod->name); ++ ++ obj->has_xattr = nval_hasvalues(dev, x_buffer, x_size); ++ obj->xattr_known = 1; ++ xmod->result = retval; ++ ++ return retval; ++} ++ ++static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR *name, ++ void *value, int size) ++{ ++ char *buffer = NULL; ++ int result; ++ struct yaffs_ext_tags tags; ++ struct yaffs_dev *dev = obj->my_dev; ++ int x_offs = sizeof(struct yaffs_obj_hdr); ++ int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr); ++ char *x_buffer; ++ int retval = 0; ++ ++ if (obj->hdr_chunk < 1) ++ return -ENODATA; ++ ++ /* If we know that the object has no xattribs then don't do all the ++ * reading and parsing. ++ */ ++ if (obj->xattr_known && !obj->has_xattr) { ++ if (name) ++ return -ENODATA; ++ else ++ return 0; ++ } ++ ++ buffer = (char *)yaffs_get_temp_buffer(dev); ++ if (!buffer) ++ return -ENOMEM; ++ ++ result = ++ yaffs_rd_chunk_tags_nand(dev, obj->hdr_chunk, (u8 *) buffer, &tags); ++ ++ if (result != YAFFS_OK) ++ retval = -ENOENT; ++ else { ++ x_buffer = buffer + x_offs; ++ ++ if (!obj->xattr_known) { ++ obj->has_xattr = nval_hasvalues(dev, x_buffer, x_size); ++ obj->xattr_known = 1; ++ } ++ ++ if (name) ++ retval = nval_get(dev, x_buffer, x_size, ++ name, value, size); ++ else ++ retval = nval_list(dev, x_buffer, x_size, value, size); ++ } ++ yaffs_release_temp_buffer(dev, (u8 *) buffer); ++ return retval; ++} ++ ++int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR * name, ++ const void *value, int size, int flags) ++{ ++ return yaffs_do_xattrib_mod(obj, 1, name, value, size, flags); ++} ++ ++int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR * name) ++{ ++ return yaffs_do_xattrib_mod(obj, 0, name, NULL, 0, 0); ++} ++ ++int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR * name, void *value, ++ int size) ++{ ++ return yaffs_do_xattrib_fetch(obj, name, value, size); ++} ++ ++int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size) ++{ ++ return yaffs_do_xattrib_fetch(obj, NULL, buffer, size); ++} ++ ++static void yaffs_check_obj_details_loaded(struct yaffs_obj *in) ++{ ++ u8 *buf; ++ struct yaffs_obj_hdr *oh; ++ struct yaffs_dev *dev; ++ struct yaffs_ext_tags tags; ++ int result; ++ ++ if (!in || !in->lazy_loaded || in->hdr_chunk < 1) ++ return; ++ ++ dev = in->my_dev; ++ buf = yaffs_get_temp_buffer(dev); ++ ++ result = yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, buf, &tags); ++ ++ if (result == YAFFS_FAIL) ++ return; ++ ++ oh = (struct yaffs_obj_hdr *)buf; ++ ++ yaffs_do_endian_oh(dev, oh); ++ ++ in->lazy_loaded = 0; ++ in->yst_mode = oh->yst_mode; ++ yaffs_load_attribs(in, oh); ++ yaffs_set_obj_name_from_oh(in, oh); ++ ++ if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) ++ in->variant.symlink_variant.alias = ++ yaffs_clone_str(oh->alias); ++ yaffs_release_temp_buffer(dev, buf); ++} ++ ++/* UpdateObjectHeader updates the header on NAND for an object. ++ * If name is not NULL, then that new name is used. ++ * ++ * We're always creating the obj header from scratch (except reading ++ * the old name) so first set up in cpu endianness then run it through ++ * endian fixing at the end. ++ * ++ * However, a twist: If there are xattribs we leave them as they were. ++ * ++ * Careful! The buffer holds the whole chunk. Part of the chunk holds the ++ * object header and the rest holds the xattribs, therefore we use a buffer ++ * pointer and an oh pointer to point to the same memory. ++ */ ++ ++int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force, ++ int is_shrink, int shadows, struct yaffs_xattr_mod *xmod) ++{ ++ ++ struct yaffs_block_info *bi; ++ struct yaffs_dev *dev = in->my_dev; ++ int prev_chunk_id; ++ int ret_val = 0; ++ int result = 0; ++ int new_chunk_id; ++ struct yaffs_ext_tags new_tags; ++ struct yaffs_ext_tags old_tags; ++ const YCHAR *alias = NULL; ++ u8 *buffer = NULL; ++ YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1]; ++ struct yaffs_obj_hdr *oh = NULL; ++ loff_t file_size = 0; ++ ++ strcpy(old_name, _Y("silly old name")); ++ ++ if (in->fake && in != dev->root_dir && !force && !xmod) ++ return ret_val; ++ ++ yaffs_check_gc(dev, 0); ++ yaffs_check_obj_details_loaded(in); ++ ++ buffer = yaffs_get_temp_buffer(in->my_dev); ++ oh = (struct yaffs_obj_hdr *)buffer; ++ ++ prev_chunk_id = in->hdr_chunk; ++ ++ if (prev_chunk_id > 0) { ++ /* Access the old obj header just to read the name. */ ++ result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id, ++ buffer, &old_tags); ++ if (result == YAFFS_OK) { ++ yaffs_verify_oh(in, oh, &old_tags, 0); ++ memcpy(old_name, oh->name, sizeof(oh->name)); ++ ++ /* ++ * NB We only wipe the object header area because the rest of ++ * the buffer might contain xattribs. ++ */ ++ memset(oh, 0xff, sizeof(*oh)); ++ } ++ } else { ++ memset(buffer, 0xff, dev->data_bytes_per_chunk); ++ } ++ ++ oh->type = in->variant_type; ++ oh->yst_mode = in->yst_mode; ++ oh->shadows_obj = oh->inband_shadowed_obj_id = shadows; ++ ++ yaffs_load_attribs_oh(oh, in); ++ ++ if (in->parent) ++ oh->parent_obj_id = in->parent->obj_id; ++ else ++ oh->parent_obj_id = 0; ++ ++ if (name && *name) { ++ memset(oh->name, 0, sizeof(oh->name)); ++ yaffs_load_oh_from_name(dev, oh->name, name); ++ } else if (prev_chunk_id > 0) { ++ memcpy(oh->name, old_name, sizeof(oh->name)); ++ } else { ++ memset(oh->name, 0, sizeof(oh->name)); ++ } ++ ++ oh->is_shrink = is_shrink; ++ ++ switch (in->variant_type) { ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ /* Should not happen */ ++ break; ++ case YAFFS_OBJECT_TYPE_FILE: ++ if (oh->parent_obj_id != YAFFS_OBJECTID_DELETED && ++ oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED) ++ file_size = in->variant.file_variant.stored_size; ++ yaffs_oh_size_load(dev, oh, file_size, 0); ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ oh->equiv_id = in->variant.hardlink_variant.equiv_id; ++ break; ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ /* Do nothing */ ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ /* Do nothing */ ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ alias = in->variant.symlink_variant.alias; ++ if (!alias) ++ alias = _Y("no alias"); ++ strncpy(oh->alias, alias, YAFFS_MAX_ALIAS_LENGTH); ++ oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0; ++ break; ++ } ++ ++ /* process any xattrib modifications */ ++ if (xmod) ++ yaffs_apply_xattrib_mod(in, (char *)buffer, xmod); ++ ++ /* Tags */ ++ memset(&new_tags, 0, sizeof(new_tags)); ++ in->serial++; ++ new_tags.chunk_id = 0; ++ new_tags.obj_id = in->obj_id; ++ new_tags.serial_number = in->serial; ++ ++ /* Add extra info for file header */ ++ new_tags.extra_available = 1; ++ new_tags.extra_parent_id = oh->parent_obj_id; ++ new_tags.extra_file_size = file_size; ++ new_tags.extra_is_shrink = oh->is_shrink; ++ new_tags.extra_equiv_id = oh->equiv_id; ++ new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0; ++ new_tags.extra_obj_type = in->variant_type; ++ ++ /* Now endian swizzle the oh if needed. */ ++ yaffs_do_endian_oh(dev, oh); ++ ++ yaffs_verify_oh(in, oh, &new_tags, 1); ++ ++ /* Create new chunk in NAND */ ++ new_chunk_id = ++ yaffs_write_new_chunk(dev, buffer, &new_tags, ++ (prev_chunk_id > 0) ? 1 : 0); ++ ++ if (buffer) ++ yaffs_release_temp_buffer(dev, buffer); ++ ++ if (new_chunk_id < 0) ++ return new_chunk_id; ++ ++ in->hdr_chunk = new_chunk_id; ++ ++ if (prev_chunk_id > 0) ++ yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__); ++ ++ if (!yaffs_obj_cache_dirty(in)) ++ in->dirty = 0; ++ ++ /* If this was a shrink, then mark the block ++ * that the chunk lives on */ ++ if (is_shrink) { ++ bi = yaffs_get_block_info(in->my_dev, ++ new_chunk_id / ++ in->my_dev->param.chunks_per_block); ++ bi->has_shrink_hdr = 1; ++ } ++ ++ ++ return new_chunk_id; ++} ++ ++/*--------------------- File read/write ------------------------ ++ * Read and write have very similar structures. ++ * In general the read/write has three parts to it ++ * An incomplete chunk to start with (if the read/write is not chunk-aligned) ++ * Some complete chunks ++ * An incomplete chunk to end off with ++ * ++ * Curve-balls: the first chunk might also be the last chunk. ++ */ ++ ++int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, int n_bytes) ++{ ++ int chunk; ++ u32 start; ++ int n_copy; ++ int n = n_bytes; ++ int n_done = 0; ++ struct yaffs_cache *cache; ++ struct yaffs_dev *dev; ++ ++ dev = in->my_dev; ++ ++ while (n > 0) { ++ yaffs_addr_to_chunk(dev, offset, &chunk, &start); ++ chunk++; ++ ++ /* OK now check for the curveball where the start and end are in ++ * the same chunk. ++ */ ++ if ((start + n) < dev->data_bytes_per_chunk) ++ n_copy = n; ++ else ++ n_copy = dev->data_bytes_per_chunk - start; ++ ++ cache = yaffs_find_chunk_cache(in, chunk); ++ ++ /* If the chunk is already in the cache or it is less than ++ * a whole chunk or we're using inband tags then use the cache ++ * (if there is caching) else bypass the cache. ++ */ ++ if (cache || n_copy != (int)dev->data_bytes_per_chunk || ++ dev->param.inband_tags) { ++ if (dev->param.n_caches > 0) { ++ ++ /* If we can't find the data in the cache, ++ * then load it up. */ ++ ++ if (!cache) { ++ cache = ++ yaffs_grab_chunk_cache(in->my_dev); ++ cache->object = in; ++ cache->chunk_id = chunk; ++ cache->dirty = 0; ++ cache->locked = 0; ++ yaffs_rd_data_obj(in, chunk, ++ cache->data); ++ cache->n_bytes = 0; ++ } ++ ++ yaffs_use_cache(dev, cache, 0); ++ ++ cache->locked = 1; ++ ++ memcpy(buffer, &cache->data[start], n_copy); ++ ++ cache->locked = 0; ++ } else { ++ /* Read into the local buffer then copy.. */ ++ ++ u8 *local_buffer = ++ yaffs_get_temp_buffer(dev); ++ yaffs_rd_data_obj(in, chunk, local_buffer); ++ ++ memcpy(buffer, &local_buffer[start], n_copy); ++ ++ yaffs_release_temp_buffer(dev, local_buffer); ++ } ++ } else { ++ /* A full chunk. Read directly into the buffer. */ ++ yaffs_rd_data_obj(in, chunk, buffer); ++ } ++ n -= n_copy; ++ offset += n_copy; ++ buffer += n_copy; ++ n_done += n_copy; ++ } ++ return n_done; ++} ++ ++int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset, ++ int n_bytes, int write_through) ++{ ++ ++ int chunk; ++ u32 start; ++ int n_copy; ++ int n = n_bytes; ++ int n_done = 0; ++ int n_writeback; ++ loff_t start_write = offset; ++ int chunk_written = 0; ++ u32 n_bytes_read; ++ loff_t chunk_start; ++ struct yaffs_dev *dev; ++ ++ dev = in->my_dev; ++ ++ while (n > 0 && chunk_written >= 0) { ++ yaffs_addr_to_chunk(dev, offset, &chunk, &start); ++ ++ if (((loff_t)chunk) * ++ dev->data_bytes_per_chunk + start != offset || ++ start >= dev->data_bytes_per_chunk) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "AddrToChunk of offset %lld gives chunk %d start %d", ++ (long long)offset, chunk, start); ++ } ++ chunk++; /* File pos to chunk in file offset */ ++ ++ /* OK now check for the curveball where the start and end are in ++ * the same chunk. ++ */ ++ ++ if ((start + n) < dev->data_bytes_per_chunk) { ++ n_copy = n; ++ ++ /* Now calculate how many bytes to write back.... ++ * If we're overwriting and not writing to then end of ++ * file then we need to write back as much as was there ++ * before. ++ */ ++ ++ chunk_start = (((loff_t)(chunk - 1)) * ++ dev->data_bytes_per_chunk); ++ ++ if (chunk_start > in->variant.file_variant.file_size) ++ n_bytes_read = 0; /* Past end of file */ ++ else ++ n_bytes_read = ++ in->variant.file_variant.file_size - ++ chunk_start; ++ ++ if (n_bytes_read > dev->data_bytes_per_chunk) ++ n_bytes_read = dev->data_bytes_per_chunk; ++ ++ n_writeback = ++ (n_bytes_read > ++ (start + n)) ? n_bytes_read : (start + n); ++ ++ if (n_writeback < 0 || ++ n_writeback > (int)dev->data_bytes_per_chunk) ++ BUG(); ++ ++ } else { ++ n_copy = dev->data_bytes_per_chunk - start; ++ n_writeback = dev->data_bytes_per_chunk; ++ } ++ ++ if (n_copy != (int)dev->data_bytes_per_chunk || ++ !dev->param.cache_bypass_aligned || ++ dev->param.inband_tags) { ++ /* An incomplete start or end chunk (or maybe both ++ * start and end chunk), or we're using inband tags, ++ * or we're forcing writes through the cache, ++ * so we want to use the cache buffers. ++ */ ++ if (dev->param.n_caches > 0) { ++ struct yaffs_cache *cache; ++ ++ /* If we can't find the data in the cache, then ++ * load the cache */ ++ cache = yaffs_find_chunk_cache(in, chunk); ++ ++ if (!cache && ++ yaffs_check_alloc_available(dev, 1)) { ++ cache = yaffs_grab_chunk_cache(dev); ++ cache->object = in; ++ cache->chunk_id = chunk; ++ cache->dirty = 0; ++ cache->locked = 0; ++ yaffs_rd_data_obj(in, chunk, ++ cache->data); ++ } else if (cache && ++ !cache->dirty && ++ !yaffs_check_alloc_available(dev, ++ 1)) { ++ /* Drop the cache if it was a read cache ++ * item and no space check has been made ++ * for it. ++ */ ++ cache = NULL; ++ } ++ ++ if (cache) { ++ yaffs_use_cache(dev, cache, 1); ++ cache->locked = 1; ++ ++ memcpy(&cache->data[start], buffer, ++ n_copy); ++ ++ cache->locked = 0; ++ cache->n_bytes = n_writeback; ++ ++ if (write_through) { ++ chunk_written = ++ yaffs_wr_data_obj ++ (cache->object, ++ cache->chunk_id, ++ cache->data, ++ cache->n_bytes, 1); ++ cache->dirty = 0; ++ } ++ } else { ++ chunk_written = -1; /* fail write */ ++ } ++ } else { ++ /* An incomplete start or end chunk (or maybe ++ * both start and end chunk). Read into the ++ * local buffer then copy over and write back. ++ */ ++ ++ u8 *local_buffer = yaffs_get_temp_buffer(dev); ++ ++ yaffs_rd_data_obj(in, chunk, local_buffer); ++ memcpy(&local_buffer[start], buffer, n_copy); ++ ++ chunk_written = ++ yaffs_wr_data_obj(in, chunk, ++ local_buffer, ++ n_writeback, 0); ++ ++ yaffs_release_temp_buffer(dev, local_buffer); ++ } ++ } else { ++ /* A full chunk. Write directly from the buffer. */ ++ ++ chunk_written = ++ yaffs_wr_data_obj(in, chunk, buffer, ++ dev->data_bytes_per_chunk, 0); ++ ++ /* Since we've overwritten the cached data, ++ * we better invalidate it. */ ++ yaffs_invalidate_chunk_cache(in, chunk); ++ } ++ ++ if (chunk_written >= 0) { ++ n -= n_copy; ++ offset += n_copy; ++ buffer += n_copy; ++ n_done += n_copy; ++ } ++ } ++ ++ /* Update file object */ ++ ++ if ((start_write + n_done) > in->variant.file_variant.file_size) ++ in->variant.file_variant.file_size = (start_write + n_done); ++ ++ in->dirty = 1; ++ return n_done; ++} ++ ++int yaffs_wr_file(struct yaffs_obj *in, const u8 *buffer, loff_t offset, ++ int n_bytes, int write_through) ++{ ++ yaffs2_handle_hole(in, offset); ++ return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_through); ++} ++ ++/* ---------------------- File resizing stuff ------------------ */ ++ ++static void yaffs_prune_chunks(struct yaffs_obj *in, loff_t new_size) ++{ ++ ++ struct yaffs_dev *dev = in->my_dev; ++ loff_t old_size = in->variant.file_variant.file_size; ++ int i; ++ int chunk_id; ++ u32 dummy; ++ int last_del; ++ int start_del; ++ ++ if (old_size > 0) ++ yaffs_addr_to_chunk(dev, old_size - 1, &last_del, &dummy); ++ else ++ last_del = 0; ++ ++ yaffs_addr_to_chunk(dev, new_size + dev->data_bytes_per_chunk - 1, ++ &start_del, &dummy); ++ last_del++; ++ start_del++; ++ ++ /* Delete backwards so that we don't end up with holes if ++ * power is lost part-way through the operation. ++ */ ++ for (i = last_del; i >= start_del; i--) { ++ /* NB this could be optimised somewhat, ++ * eg. could retrieve the tags and write them without ++ * using yaffs_chunk_del ++ */ ++ ++ chunk_id = yaffs_find_del_file_chunk(in, i, NULL); ++ ++ if (chunk_id < 1) ++ continue; ++ ++ if ((u32)chunk_id < ++ (dev->internal_start_block * dev->param.chunks_per_block) || ++ (u32)chunk_id >= ++ ((dev->internal_end_block + 1) * ++ dev->param.chunks_per_block)) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "Found daft chunk_id %d for %d", ++ chunk_id, i); ++ } else { ++ in->n_data_chunks--; ++ yaffs_chunk_del(dev, chunk_id, 1, __LINE__); ++ } ++ } ++} ++ ++void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size) ++{ ++ int new_full; ++ u32 new_partial; ++ struct yaffs_dev *dev = obj->my_dev; ++ ++ yaffs_addr_to_chunk(dev, new_size, &new_full, &new_partial); ++ ++ yaffs_prune_chunks(obj, new_size); ++ ++ if (new_partial != 0) { ++ int last_chunk = 1 + new_full; ++ u8 *local_buffer = yaffs_get_temp_buffer(dev); ++ ++ /* Rewrite the last chunk with its new size and zero pad */ ++ yaffs_rd_data_obj(obj, last_chunk, local_buffer); ++ memset(local_buffer + new_partial, 0, ++ dev->data_bytes_per_chunk - new_partial); ++ ++ yaffs_wr_data_obj(obj, last_chunk, local_buffer, ++ new_partial, 1); ++ ++ yaffs_release_temp_buffer(dev, local_buffer); ++ } ++ ++ obj->variant.file_variant.file_size = new_size; ++ obj->variant.file_variant.stored_size = new_size; ++ ++ yaffs_prune_tree(dev, &obj->variant.file_variant); ++} ++ ++int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size) ++{ ++ struct yaffs_dev *dev = in->my_dev; ++ loff_t old_size = in->variant.file_variant.file_size; ++ ++ yaffs_flush_file_cache(in, 1); ++ yaffs_invalidate_whole_cache(in); ++ ++ yaffs_check_gc(dev, 0); ++ ++ if (in->variant_type != YAFFS_OBJECT_TYPE_FILE) ++ return YAFFS_FAIL; ++ ++ if (new_size == old_size) ++ return YAFFS_OK; ++ ++ if (new_size > old_size) { ++ yaffs2_handle_hole(in, new_size); ++ in->variant.file_variant.file_size = new_size; ++ } else { ++ /* new_size < old_size */ ++ yaffs_resize_file_down(in, new_size); ++ } ++ ++ /* Write a new object header to reflect the resize. ++ * show we've shrunk the file, if need be ++ * Do this only if the file is not in the deleted directories ++ * and is not shadowed. ++ */ ++ if (in->parent && ++ !in->is_shadowed && ++ in->parent->obj_id != YAFFS_OBJECTID_UNLINKED && ++ in->parent->obj_id != YAFFS_OBJECTID_DELETED) ++ yaffs_update_oh(in, NULL, 0, 0, 0, NULL); ++ ++ return YAFFS_OK; ++} ++ ++int yaffs_flush_file(struct yaffs_obj *in, ++ int update_time, ++ int data_sync, ++ int discard_cache) ++{ ++ if (!in->dirty) ++ return YAFFS_OK; ++ ++ yaffs_flush_file_cache(in, discard_cache); ++ ++ if (data_sync) ++ return YAFFS_OK; ++ ++ if (update_time) ++ yaffs_load_current_time(in, 0, 0); ++ ++ return (yaffs_update_oh(in, NULL, 0, 0, 0, NULL) >= 0) ? ++ YAFFS_OK : YAFFS_FAIL; ++} ++ ++ ++/* yaffs_del_file deletes the whole file data ++ * and the inode associated with the file. ++ * It does not delete the links associated with the file. ++ */ ++static int yaffs_unlink_file_if_needed(struct yaffs_obj *in) ++{ ++ int ret_val; ++ int del_now = 0; ++ struct yaffs_dev *dev = in->my_dev; ++ ++ if (!in->my_inode) ++ del_now = 1; ++ ++ if (del_now) { ++ ret_val = ++ yaffs_change_obj_name(in, in->my_dev->del_dir, ++ _Y("deleted"), 0, 0); ++ yaffs_trace(YAFFS_TRACE_TRACING, ++ "yaffs: immediate deletion of file %d", ++ in->obj_id); ++ in->deleted = 1; ++ in->my_dev->n_deleted_files++; ++ if (dev->param.disable_soft_del || dev->param.is_yaffs2) ++ yaffs_resize_file(in, 0); ++ yaffs_soft_del_file(in); ++ } else { ++ ret_val = ++ yaffs_change_obj_name(in, in->my_dev->unlinked_dir, ++ _Y("unlinked"), 0, 0); ++ } ++ return ret_val; ++} ++ ++static int yaffs_del_file(struct yaffs_obj *in) ++{ ++ int ret_val = YAFFS_OK; ++ int deleted; /* Need to cache value on stack if in is freed */ ++ struct yaffs_dev *dev = in->my_dev; ++ ++ if (dev->param.disable_soft_del || dev->param.is_yaffs2) ++ yaffs_resize_file(in, 0); ++ ++ if (in->n_data_chunks > 0) { ++ /* Use soft deletion if there is data in the file. ++ * That won't be the case if it has been resized to zero. ++ */ ++ if (!in->unlinked) ++ ret_val = yaffs_unlink_file_if_needed(in); ++ ++ deleted = in->deleted; ++ ++ if (ret_val == YAFFS_OK && in->unlinked && !in->deleted) { ++ in->deleted = 1; ++ deleted = 1; ++ in->my_dev->n_deleted_files++; ++ yaffs_soft_del_file(in); ++ } ++ return deleted ? YAFFS_OK : YAFFS_FAIL; ++ } else { ++ /* The file has no data chunks so we toss it immediately */ ++ yaffs_free_tnode(in->my_dev, in->variant.file_variant.top); ++ in->variant.file_variant.top = NULL; ++ yaffs_generic_obj_del(in); ++ ++ return YAFFS_OK; ++ } ++} ++ ++int yaffs_is_non_empty_dir(struct yaffs_obj *obj) ++{ ++ return (obj && ++ obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) && ++ !(list_empty(&obj->variant.dir_variant.children)); ++} ++ ++static int yaffs_del_dir(struct yaffs_obj *obj) ++{ ++ /* First check that the directory is empty. */ ++ if (yaffs_is_non_empty_dir(obj)) ++ return YAFFS_FAIL; ++ ++ return yaffs_generic_obj_del(obj); ++} ++ ++static int yaffs_del_symlink(struct yaffs_obj *in) ++{ ++ kfree(in->variant.symlink_variant.alias); ++ in->variant.symlink_variant.alias = NULL; ++ ++ return yaffs_generic_obj_del(in); ++} ++ ++static int yaffs_del_link(struct yaffs_obj *in) ++{ ++ /* remove this hardlink from the list associated with the equivalent ++ * object ++ */ ++ list_del_init(&in->hard_links); ++ return yaffs_generic_obj_del(in); ++} ++ ++int yaffs_del_obj(struct yaffs_obj *obj) ++{ ++ int ret_val = -1; ++ ++ switch (obj->variant_type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ ret_val = yaffs_del_file(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ if (!list_empty(&obj->variant.dir_variant.dirty)) { ++ yaffs_trace(YAFFS_TRACE_BACKGROUND, ++ "Remove object %d from dirty directories", ++ obj->obj_id); ++ list_del_init(&obj->variant.dir_variant.dirty); ++ } ++ return yaffs_del_dir(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ ret_val = yaffs_del_symlink(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ ret_val = yaffs_del_link(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ ret_val = yaffs_generic_obj_del(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ ret_val = 0; ++ break; /* should not happen. */ ++ } ++ return ret_val; ++} ++ ++ ++static void yaffs_empty_dir_to_dir(struct yaffs_obj *from_dir, ++ struct yaffs_obj *to_dir) ++{ ++ struct yaffs_obj *obj; ++ struct list_head *lh; ++ struct list_head *n; ++ ++ list_for_each_safe(lh, n, &from_dir->variant.dir_variant.children) { ++ obj = list_entry(lh, struct yaffs_obj, siblings); ++ yaffs_add_obj_to_dir(to_dir, obj); ++ } ++} ++ ++struct yaffs_obj *yaffs_retype_obj(struct yaffs_obj *obj, ++ enum yaffs_obj_type type) ++{ ++ /* Tear down the old variant */ ++ switch (obj->variant_type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ /* Nuke file data */ ++ yaffs_resize_file(obj, 0); ++ yaffs_free_tnode(obj->my_dev, obj->variant.file_variant.top); ++ obj->variant.file_variant.top = NULL; ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ /* Put the children in lost and found. */ ++ yaffs_empty_dir_to_dir(obj, obj->my_dev->lost_n_found); ++ if (!list_empty(&obj->variant.dir_variant.dirty)) ++ list_del_init(&obj->variant.dir_variant.dirty); ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ /* Nuke symplink data */ ++ kfree(obj->variant.symlink_variant.alias); ++ obj->variant.symlink_variant.alias = NULL; ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ list_del_init(&obj->hard_links); ++ break; ++ default: ++ break; ++ } ++ ++ memset(&obj->variant, 0, sizeof(obj->variant)); ++ ++ /*Set up new variant if the memset is not enough. */ ++ switch (type) { ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ INIT_LIST_HEAD(&obj->variant.dir_variant.children); ++ INIT_LIST_HEAD(&obj->variant.dir_variant.dirty); ++ break; ++ case YAFFS_OBJECT_TYPE_FILE: ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ default: ++ break; ++ } ++ ++ obj->variant_type = type; ++ ++ return obj; ++ ++} ++ ++static int yaffs_unlink_worker(struct yaffs_obj *obj) ++{ ++ int del_now = 0; ++ ++ if (!obj) ++ return YAFFS_FAIL; ++ ++ if (!obj->my_inode) ++ del_now = 1; ++ ++ yaffs_update_parent(obj->parent); ++ ++ if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) { ++ return yaffs_del_link(obj); ++ } else if (!list_empty(&obj->hard_links)) { ++ /* Curve ball: We're unlinking an object that has a hardlink. ++ * ++ * This problem arises because we are not strictly following ++ * The Linux link/inode model. ++ * ++ * We can't really delete the object. ++ * Instead, we do the following: ++ * - Select a hardlink. ++ * - Unhook it from the hard links ++ * - Move it from its parent directory so that the rename works. ++ * - Rename the object to the hardlink's name. ++ * - Delete the hardlink ++ */ ++ ++ struct yaffs_obj *hl; ++ struct yaffs_obj *parent; ++ int ret_val; ++ YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; ++ ++ hl = list_entry(obj->hard_links.next, struct yaffs_obj, ++ hard_links); ++ ++ yaffs_get_obj_name(hl, name, YAFFS_MAX_NAME_LENGTH + 1); ++ parent = hl->parent; ++ ++ list_del_init(&hl->hard_links); ++ ++ yaffs_add_obj_to_dir(obj->my_dev->unlinked_dir, hl); ++ ++ ret_val = yaffs_change_obj_name(obj, parent, name, 0, 0); ++ ++ if (ret_val == YAFFS_OK) ++ ret_val = yaffs_generic_obj_del(hl); ++ ++ return ret_val; ++ ++ } else if (del_now) { ++ switch (obj->variant_type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ return yaffs_del_file(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ list_del_init(&obj->variant.dir_variant.dirty); ++ return yaffs_del_dir(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ return yaffs_del_symlink(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ return yaffs_generic_obj_del(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ default: ++ return YAFFS_FAIL; ++ } ++ } else if (yaffs_is_non_empty_dir(obj)) { ++ return YAFFS_FAIL; ++ } else { ++ return yaffs_change_obj_name(obj, obj->my_dev->unlinked_dir, ++ _Y("unlinked"), 0, 0); ++ } ++} ++ ++int yaffs_unlink_obj(struct yaffs_obj *obj) ++{ ++ if (obj && obj->unlink_allowed) ++ return yaffs_unlink_worker(obj); ++ ++ return YAFFS_FAIL; ++} ++ ++int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR *name) ++{ ++ struct yaffs_obj *obj; ++ ++ obj = yaffs_find_by_name(dir, name); ++ return yaffs_unlink_obj(obj); ++} ++ ++/* Note: ++ * If old_name is NULL then we take old_dir as the object to be renamed. ++ */ ++int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR *old_name, ++ struct yaffs_obj *new_dir, const YCHAR *new_name) ++{ ++ struct yaffs_obj *obj = NULL; ++ struct yaffs_obj *existing_target = NULL; ++ int force = 0; ++ int result; ++ struct yaffs_dev *dev; ++ ++ if (!old_dir || old_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ BUG(); ++ return YAFFS_FAIL; ++ } ++ if (!new_dir || new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ BUG(); ++ return YAFFS_FAIL; ++ } ++ ++ dev = old_dir->my_dev; ++ ++#ifdef CONFIG_YAFFS_CASE_INSENSITIVE ++ /* Special case for case insemsitive systems. ++ * While look-up is case insensitive, the name isn't. ++ * Therefore we might want to change x.txt to X.txt ++ */ ++ if (old_dir == new_dir && ++ old_name && new_name && ++ strcmp(old_name, new_name) == 0) ++ force = 1; ++#endif ++ ++ if (strnlen(new_name, YAFFS_MAX_NAME_LENGTH + 1) > ++ YAFFS_MAX_NAME_LENGTH) ++ /* ENAMETOOLONG */ ++ return YAFFS_FAIL; ++ ++ if (old_name) ++ obj = yaffs_find_by_name(old_dir, old_name); ++ else{ ++ obj = old_dir; ++ old_dir = obj->parent; ++ } ++ ++ if (obj && obj->rename_allowed) { ++ /* Now handle an existing target, if there is one */ ++ existing_target = yaffs_find_by_name(new_dir, new_name); ++ if (yaffs_is_non_empty_dir(existing_target)) { ++ return YAFFS_FAIL; /* ENOTEMPTY */ ++ } else if (existing_target && existing_target != obj) { ++ /* Nuke the target first, using shadowing, ++ * but only if it isn't the same object. ++ * ++ * Note we must disable gc here otherwise it can mess ++ * up the shadowing. ++ * ++ */ ++ dev->gc_disable = 1; ++ yaffs_change_obj_name(obj, new_dir, new_name, force, ++ existing_target->obj_id); ++ existing_target->is_shadowed = 1; ++ yaffs_unlink_obj(existing_target); ++ dev->gc_disable = 0; ++ } ++ ++ result = yaffs_change_obj_name(obj, new_dir, new_name, 1, 0); ++ ++ yaffs_update_parent(old_dir); ++ if (new_dir != old_dir) ++ yaffs_update_parent(new_dir); ++ ++ return result; ++ } ++ return YAFFS_FAIL; ++} ++ ++/*----------------------- Initialisation Scanning ---------------------- */ ++ ++void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id, ++ int backward_scanning) ++{ ++ struct yaffs_obj *obj; ++ ++ if (backward_scanning) { ++ /* Handle YAFFS2 case (backward scanning) ++ * If the shadowed object exists then ignore. ++ */ ++ obj = yaffs_find_by_number(dev, obj_id); ++ if (obj) ++ return; ++ } ++ ++ /* Let's create it (if it does not exist) assuming it is a file so that ++ * it can do shrinking etc. ++ * We put it in unlinked dir to be cleaned up after the scanning ++ */ ++ obj = ++ yaffs_find_or_create_by_number(dev, obj_id, YAFFS_OBJECT_TYPE_FILE); ++ if (!obj) ++ return; ++ obj->is_shadowed = 1; ++ yaffs_add_obj_to_dir(dev->unlinked_dir, obj); ++ obj->variant.file_variant.shrink_size = 0; ++ obj->valid = 1; /* So that we don't read any other info. */ ++} ++ ++void yaffs_link_fixup(struct yaffs_dev *dev, struct list_head *hard_list) ++{ ++ struct list_head *lh; ++ struct list_head *save; ++ struct yaffs_obj *hl; ++ struct yaffs_obj *in; ++ ++ list_for_each_safe(lh, save, hard_list) { ++ hl = list_entry(lh, struct yaffs_obj, hard_links); ++ in = yaffs_find_by_number(dev, ++ hl->variant.hardlink_variant.equiv_id); ++ ++ if (in) { ++ /* Add the hardlink pointers */ ++ hl->variant.hardlink_variant.equiv_obj = in; ++ list_add(&hl->hard_links, &in->hard_links); ++ } else { ++ /* Todo Need to report/handle this better. ++ * Got a problem... hardlink to a non-existant object ++ */ ++ hl->variant.hardlink_variant.equiv_obj = NULL; ++ INIT_LIST_HEAD(&hl->hard_links); ++ } ++ } ++} ++ ++static void yaffs_strip_deleted_objs(struct yaffs_dev *dev) ++{ ++ /* ++ * Sort out state of unlinked and deleted objects after scanning. ++ */ ++ struct list_head *i; ++ struct list_head *n; ++ struct yaffs_obj *l; ++ ++ if (dev->read_only) ++ return; ++ ++ /* Soft delete all the unlinked files */ ++ list_for_each_safe(i, n, ++ &dev->unlinked_dir->variant.dir_variant.children) { ++ l = list_entry(i, struct yaffs_obj, siblings); ++ yaffs_del_obj(l); ++ } ++ ++ list_for_each_safe(i, n, &dev->del_dir->variant.dir_variant.children) { ++ l = list_entry(i, struct yaffs_obj, siblings); ++ yaffs_del_obj(l); ++ } ++} ++ ++/* ++ * This code iterates through all the objects making sure that they are rooted. ++ * Any unrooted objects are re-rooted in lost+found. ++ * An object needs to be in one of: ++ * - Directly under deleted, unlinked ++ * - Directly or indirectly under root. ++ * ++ * Note: ++ * This code assumes that we don't ever change the current relationships ++ * between directories: ++ * root_dir->parent == unlinked_dir->parent == del_dir->parent == NULL ++ * lost-n-found->parent == root_dir ++ * ++ * This fixes the problem where directories might have inadvertently been ++ * deleted leaving the object "hanging" without being rooted in the ++ * directory tree. ++ */ ++ ++static int yaffs_has_null_parent(struct yaffs_dev *dev, struct yaffs_obj *obj) ++{ ++ return (obj == dev->del_dir || ++ obj == dev->unlinked_dir || obj == dev->root_dir); ++} ++ ++static void yaffs_fix_hanging_objs(struct yaffs_dev *dev) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_obj *parent; ++ int i; ++ struct list_head *lh; ++ struct list_head *n; ++ int depth_limit; ++ int hanging; ++ ++ if (dev->read_only) ++ return; ++ ++ /* Iterate through the objects in each hash entry, ++ * looking at each object. ++ * Make sure it is rooted. ++ */ ++ ++ for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) { ++ list_for_each_safe(lh, n, &dev->obj_bucket[i].list) { ++ obj = list_entry(lh, struct yaffs_obj, hash_link); ++ parent = obj->parent; ++ ++ if (yaffs_has_null_parent(dev, obj)) { ++ /* These directories are not hanging */ ++ hanging = 0; ++ } else if (!parent || ++ parent->variant_type != ++ YAFFS_OBJECT_TYPE_DIRECTORY) { ++ hanging = 1; ++ } else if (yaffs_has_null_parent(dev, parent)) { ++ hanging = 0; ++ } else { ++ /* ++ * Need to follow the parent chain to ++ * see if it is hanging. ++ */ ++ hanging = 0; ++ depth_limit = 100; ++ ++ while (parent != dev->root_dir && ++ parent->parent && ++ parent->parent->variant_type == ++ YAFFS_OBJECT_TYPE_DIRECTORY && ++ depth_limit > 0) { ++ parent = parent->parent; ++ depth_limit--; ++ } ++ if (parent != dev->root_dir) ++ hanging = 1; ++ } ++ if (hanging) { ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "Hanging object %d moved to lost and found", ++ obj->obj_id); ++ yaffs_add_obj_to_dir(dev->lost_n_found, obj); ++ } ++ } ++ } ++} ++ ++/* ++ * Delete directory contents for cleaning up lost and found. ++ */ ++static void yaffs_del_dir_contents(struct yaffs_obj *dir) ++{ ++ struct yaffs_obj *obj; ++ struct list_head *lh; ++ struct list_head *n; ++ ++ if (dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) ++ BUG(); ++ ++ list_for_each_safe(lh, n, &dir->variant.dir_variant.children) { ++ obj = list_entry(lh, struct yaffs_obj, siblings); ++ if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) ++ yaffs_del_dir_contents(obj); ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "Deleting lost_found object %d", ++ obj->obj_id); ++ yaffs_unlink_obj(obj); ++ } ++} ++ ++static void yaffs_empty_l_n_f(struct yaffs_dev *dev) ++{ ++ yaffs_del_dir_contents(dev->lost_n_found); ++} ++ ++ ++struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *directory, ++ const YCHAR *name) ++{ ++ int sum; ++ struct list_head *i; ++ YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1]; ++ struct yaffs_obj *l; ++ ++ if (!name) ++ return NULL; ++ ++ if (!directory) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "tragedy: yaffs_find_by_name: null pointer directory" ++ ); ++ BUG(); ++ return NULL; ++ } ++ if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "tragedy: yaffs_find_by_name: non-directory" ++ ); ++ BUG(); ++ } ++ ++ sum = yaffs_calc_name_sum(name); ++ ++ list_for_each(i, &directory->variant.dir_variant.children) { ++ l = list_entry(i, struct yaffs_obj, siblings); ++ ++ if (l->parent != directory) ++ BUG(); ++ ++ yaffs_check_obj_details_loaded(l); ++ ++ /* Special case for lost-n-found */ ++ if (l->obj_id == YAFFS_OBJECTID_LOSTNFOUND) { ++ if (!strcmp(name, YAFFS_LOSTNFOUND_NAME)) ++ return l; ++ } else if (l->sum == sum || l->hdr_chunk <= 0) { ++ /* LostnFound chunk called Objxxx ++ * Do a real check ++ */ ++ yaffs_get_obj_name(l, buffer, ++ YAFFS_MAX_NAME_LENGTH + 1); ++ if (!strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH)) ++ return l; ++ } ++ } ++ return NULL; ++} ++ ++/* GetEquivalentObject dereferences any hard links to get to the ++ * actual object. ++ */ ++ ++struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj) ++{ ++ if (obj && obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) { ++ obj = obj->variant.hardlink_variant.equiv_obj; ++ yaffs_check_obj_details_loaded(obj); ++ } ++ return obj; ++} ++ ++/* ++ * A note or two on object names. ++ * * If the object name is missing, we then make one up in the form objnnn ++ * ++ * * ASCII names are stored in the object header's name field from byte zero ++ * * Unicode names are historically stored starting from byte zero. ++ * ++ * Then there are automatic Unicode names... ++ * The purpose of these is to save names in a way that can be read as ++ * ASCII or Unicode names as appropriate, thus allowing a Unicode and ASCII ++ * system to share files. ++ * ++ * These automatic unicode are stored slightly differently... ++ * - If the name can fit in the ASCII character space then they are saved as ++ * ascii names as per above. ++ * - If the name needs Unicode then the name is saved in Unicode ++ * starting at oh->name[1]. ++ ++ */ ++static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name, ++ int buffer_size) ++{ ++ /* Create an object name if we could not find one. */ ++ if (strnlen(name, YAFFS_MAX_NAME_LENGTH) == 0) { ++ YCHAR local_name[20]; ++ YCHAR num_string[20]; ++ YCHAR *x = &num_string[19]; ++ unsigned v = obj->obj_id; ++ num_string[19] = 0; ++ while (v > 0) { ++ x--; ++ *x = '0' + (v % 10); ++ v /= 10; ++ } ++ /* make up a name */ ++ strcpy(local_name, YAFFS_LOSTNFOUND_PREFIX); ++ strcat(local_name, x); ++ strncpy(name, local_name, buffer_size - 1); ++ } ++} ++ ++int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR *name, int buffer_size) ++{ ++ memset(name, 0, buffer_size * sizeof(YCHAR)); ++ yaffs_check_obj_details_loaded(obj); ++ if (obj->obj_id == YAFFS_OBJECTID_LOSTNFOUND) { ++ strncpy(name, YAFFS_LOSTNFOUND_NAME, buffer_size - 1); ++ } else if (obj->short_name[0]) { ++ strcpy(name, obj->short_name); ++ } else if (obj->hdr_chunk > 0) { ++ int result = 0; ++ u8 *buffer = yaffs_get_temp_buffer(obj->my_dev); ++ ++ struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)buffer; ++ ++ memset(buffer, 0, obj->my_dev->data_bytes_per_chunk); ++ ++ if (obj->hdr_chunk > 0) { ++ result = yaffs_rd_chunk_tags_nand(obj->my_dev, ++ obj->hdr_chunk, ++ buffer, NULL); ++ } ++ if (result == YAFFS_OK) ++ yaffs_load_name_from_oh(obj->my_dev, name, oh->name, ++ buffer_size); ++ ++ yaffs_release_temp_buffer(obj->my_dev, buffer); ++ } ++ ++ yaffs_fix_null_name(obj, name, buffer_size); ++ ++ return strnlen(name, YAFFS_MAX_NAME_LENGTH); ++} ++ ++loff_t yaffs_get_obj_length(struct yaffs_obj *obj) ++{ ++ /* Dereference any hard linking */ ++ obj = yaffs_get_equivalent_obj(obj); ++ ++ if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) ++ return obj->variant.file_variant.file_size; ++ if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) { ++ if (!obj->variant.symlink_variant.alias) ++ return 0; ++ return strnlen(obj->variant.symlink_variant.alias, ++ YAFFS_MAX_ALIAS_LENGTH); ++ } else { ++ /* Only a directory should drop through to here */ ++ return obj->my_dev->data_bytes_per_chunk; ++ } ++} ++ ++int yaffs_get_obj_link_count(struct yaffs_obj *obj) ++{ ++ int count = 0; ++ struct list_head *i; ++ ++ if (!obj->unlinked) ++ count++; /* the object itself */ ++ ++ list_for_each(i, &obj->hard_links) ++ count++; /* add the hard links; */ ++ ++ return count; ++} ++ ++int yaffs_get_obj_inode(struct yaffs_obj *obj) ++{ ++ obj = yaffs_get_equivalent_obj(obj); ++ ++ return obj->obj_id; ++} ++ ++unsigned yaffs_get_obj_type(struct yaffs_obj *obj) ++{ ++ obj = yaffs_get_equivalent_obj(obj); ++ ++ switch (obj->variant_type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ return DT_REG; ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ return DT_DIR; ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ return DT_LNK; ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ return DT_REG; ++ break; ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ if (S_ISFIFO(obj->yst_mode)) ++ return DT_FIFO; ++ if (S_ISCHR(obj->yst_mode)) ++ return DT_CHR; ++ if (S_ISBLK(obj->yst_mode)) ++ return DT_BLK; ++ if (S_ISSOCK(obj->yst_mode)) ++ return DT_SOCK; ++ return DT_REG; ++ break; ++ default: ++ return DT_REG; ++ break; ++ } ++} ++ ++YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj) ++{ ++ obj = yaffs_get_equivalent_obj(obj); ++ if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) ++ return yaffs_clone_str(obj->variant.symlink_variant.alias); ++ else ++ return yaffs_clone_str(_Y("")); ++} ++ ++/*--------------------------- Initialisation code -------------------------- */ ++ ++static int yaffs_check_dev_fns(struct yaffs_dev *dev) ++{ ++ struct yaffs_driver *drv = &dev->drv; ++ struct yaffs_tags_handler *tagger = &dev->tagger; ++ ++ /* Common functions, gotta have */ ++ if (!drv->drv_read_chunk_fn || ++ !drv->drv_write_chunk_fn || ++ !drv->drv_erase_fn) ++ return 0; ++ ++ if (dev->param.is_yaffs2 && ++ (!drv->drv_mark_bad_fn || !drv->drv_check_bad_fn)) ++ return 0; ++ ++ /* Install the default tags marshalling functions if needed. */ ++ yaffs_tags_compat_install(dev); ++ yaffs_tags_marshall_install(dev); ++ ++ /* Check we now have the marshalling functions required. */ ++ if (!tagger->write_chunk_tags_fn || ++ !tagger->read_chunk_tags_fn || ++ !tagger->query_block_fn || ++ !tagger->mark_bad_fn) ++ return 0; ++ ++ return 1; ++} ++ ++static int yaffs_create_initial_dir(struct yaffs_dev *dev) ++{ ++ /* Initialise the unlinked, deleted, root and lost+found directories */ ++ dev->lost_n_found = NULL; ++ dev->root_dir = NULL; ++ dev->unlinked_dir = NULL; ++ dev->del_dir = NULL; ++ ++ dev->unlinked_dir = ++ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR); ++ dev->del_dir = ++ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_DELETED, S_IFDIR); ++ dev->root_dir = ++ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_ROOT, ++ YAFFS_ROOT_MODE | S_IFDIR); ++ dev->lost_n_found = ++ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_LOSTNFOUND, ++ YAFFS_LOSTNFOUND_MODE | S_IFDIR); ++ ++ if (dev->lost_n_found && ++ dev->root_dir && ++ dev->unlinked_dir && ++ dev->del_dir) { ++ /* If lost-n-found is hidden then yank it out of the directory tree. */ ++ if (dev->param.hide_lost_n_found) ++ list_del_init(&dev->lost_n_found->siblings); ++ else ++ yaffs_add_obj_to_dir(dev->root_dir, dev->lost_n_found); ++ return YAFFS_OK; ++ } ++ return YAFFS_FAIL; ++} ++ ++/* Low level init. ++ * Typically only used by yaffs_guts_initialise, but also used by the ++ * Low level yaffs driver tests. ++ */ ++ ++int yaffs_guts_ll_init(struct yaffs_dev *dev) ++{ ++ ++ ++ yaffs_trace(YAFFS_TRACE_TRACING, "yaffs: yaffs_ll_init()"); ++ ++ if (!dev) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs: Need a device" ++ ); ++ return YAFFS_FAIL; ++ } ++ ++ if (dev->ll_init) ++ return YAFFS_OK; ++ ++ dev->internal_start_block = dev->param.start_block; ++ dev->internal_end_block = dev->param.end_block; ++ dev->block_offset = 0; ++ dev->chunk_offset = 0; ++ dev->n_free_chunks = 0; ++ ++ dev->gc_block = 0; ++ ++ if (dev->param.start_block == 0) { ++ dev->internal_start_block = dev->param.start_block + 1; ++ dev->internal_end_block = dev->param.end_block + 1; ++ dev->block_offset = 1; ++ dev->chunk_offset = dev->param.chunks_per_block; ++ } ++ ++ /* Check geometry parameters. */ ++ ++ if ((!dev->param.inband_tags && dev->param.is_yaffs2 && ++ dev->param.total_bytes_per_chunk < 1024) || ++ (!dev->param.is_yaffs2 && ++ dev->param.total_bytes_per_chunk < 512) || ++ (dev->param.inband_tags && !dev->param.is_yaffs2) || ++ dev->param.chunks_per_block < 2 || ++ dev->param.n_reserved_blocks < 2 || ++ dev->internal_start_block <= 0 || ++ dev->internal_end_block <= 0 || ++ dev->internal_end_block <= ++ (dev->internal_start_block + dev->param.n_reserved_blocks + 2) ++ ) { ++ /* otherwise it is too small */ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "NAND geometry problems: chunk size %d, type is yaffs%s, inband_tags %d ", ++ dev->param.total_bytes_per_chunk, ++ dev->param.is_yaffs2 ? "2" : "", ++ dev->param.inband_tags); ++ return YAFFS_FAIL; ++ } ++ ++ /* Sort out space for inband tags, if required */ ++ if (dev->param.inband_tags) ++ dev->data_bytes_per_chunk = ++ dev->param.total_bytes_per_chunk - ++ sizeof(struct yaffs_packed_tags2_tags_only); ++ else ++ dev->data_bytes_per_chunk = dev->param.total_bytes_per_chunk; ++ ++ /* Got the right mix of functions? */ ++ if (!yaffs_check_dev_fns(dev)) { ++ /* Function missing */ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "device function(s) missing or wrong"); ++ ++ return YAFFS_FAIL; ++ } ++ ++ if (yaffs_init_nand(dev) != YAFFS_OK) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "InitialiseNAND failed"); ++ return YAFFS_FAIL; ++ } ++ ++ return YAFFS_OK; ++} ++ ++ ++int yaffs_guts_format_dev(struct yaffs_dev *dev) ++{ ++ u32 i; ++ enum yaffs_block_state state; ++ u32 dummy; ++ ++ if(yaffs_guts_ll_init(dev) != YAFFS_OK) ++ return YAFFS_FAIL; ++ ++ if(dev->is_mounted) ++ return YAFFS_FAIL; ++ ++ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { ++ yaffs_query_init_block_state(dev, i, &state, &dummy); ++ if (state != YAFFS_BLOCK_STATE_DEAD) ++ yaffs_erase_block(dev, i); ++ } ++ ++ return YAFFS_OK; ++} ++ ++ ++int yaffs_guts_initialise(struct yaffs_dev *dev) ++{ ++ int init_failed = 0; ++ u32 x; ++ u32 bits; ++ ++ if(yaffs_guts_ll_init(dev) != YAFFS_OK) ++ return YAFFS_FAIL; ++ ++ if (dev->is_mounted) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "device already mounted"); ++ return YAFFS_FAIL; ++ } ++ ++ dev->is_mounted = 1; ++ ++ /* OK now calculate a few things for the device */ ++ ++ /* ++ * Calculate all the chunk size manipulation numbers: ++ */ ++ x = dev->data_bytes_per_chunk; ++ /* We always use dev->chunk_shift and dev->chunk_div */ ++ dev->chunk_shift = calc_shifts(x); ++ x >>= dev->chunk_shift; ++ dev->chunk_div = x; ++ /* We only use chunk mask if chunk_div is 1 */ ++ dev->chunk_mask = (1 << dev->chunk_shift) - 1; ++ ++ /* ++ * Calculate chunk_grp_bits. ++ * We need to find the next power of 2 > than internal_end_block ++ */ ++ ++ x = dev->param.chunks_per_block * (dev->internal_end_block + 1); ++ ++ bits = calc_shifts_ceiling(x); ++ ++ /* Set up tnode width if wide tnodes are enabled. */ ++ if (!dev->param.wide_tnodes_disabled) { ++ /* bits must be even so that we end up with 32-bit words */ ++ if (bits & 1) ++ bits++; ++ if (bits < 16) ++ dev->tnode_width = 16; ++ else ++ dev->tnode_width = bits; ++ } else { ++ dev->tnode_width = 16; ++ } ++ ++ dev->tnode_mask = (1 << dev->tnode_width) - 1; ++ ++ /* Level0 Tnodes are 16 bits or wider (if wide tnodes are enabled), ++ * so if the bitwidth of the ++ * chunk range we're using is greater than 16 we need ++ * to figure out chunk shift and chunk_grp_size ++ */ ++ ++ if (bits <= dev->tnode_width) ++ dev->chunk_grp_bits = 0; ++ else ++ dev->chunk_grp_bits = bits - dev->tnode_width; ++ ++ dev->tnode_size = (dev->tnode_width * YAFFS_NTNODES_LEVEL0) / 8; ++ if (dev->tnode_size < sizeof(struct yaffs_tnode)) ++ dev->tnode_size = sizeof(struct yaffs_tnode); ++ ++ dev->chunk_grp_size = 1 << dev->chunk_grp_bits; ++ ++ if (dev->param.chunks_per_block < dev->chunk_grp_size) { ++ /* We have a problem because the soft delete won't work if ++ * the chunk group size > chunks per block. ++ * This can be remedied by using larger "virtual blocks". ++ */ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "chunk group too large"); ++ ++ return YAFFS_FAIL; ++ } ++ ++ /* Finished verifying the device, continue with initialisation */ ++ ++ /* More device initialisation */ ++ dev->all_gcs = 0; ++ dev->passive_gc_count = 0; ++ dev->oldest_dirty_gc_count = 0; ++ dev->bg_gcs = 0; ++ dev->gc_block_finder = 0; ++ dev->buffered_block = -1; ++ dev->doing_buffered_block_rewrite = 0; ++ dev->n_deleted_files = 0; ++ dev->n_bg_deletions = 0; ++ dev->n_unlinked_files = 0; ++ dev->n_ecc_fixed = 0; ++ dev->n_ecc_unfixed = 0; ++ dev->n_tags_ecc_fixed = 0; ++ dev->n_tags_ecc_unfixed = 0; ++ dev->n_erase_failures = 0; ++ dev->n_erased_blocks = 0; ++ dev->gc_disable = 0; ++ dev->has_pending_prioritised_gc = 1; /* Assume the worst for now, ++ * will get fixed on first GC */ ++ INIT_LIST_HEAD(&dev->dirty_dirs); ++ dev->oldest_dirty_seq = 0; ++ dev->oldest_dirty_block = 0; ++ ++ yaffs_endian_config(dev); ++ ++ /* Initialise temporary buffers and caches. */ ++ if (!yaffs_init_tmp_buffers(dev)) ++ init_failed = 1; ++ ++ dev->cache = NULL; ++ dev->gc_cleanup_list = NULL; ++ ++ if (!init_failed && dev->param.n_caches > 0) { ++ u32 i; ++ void *buf; ++ u32 cache_bytes = ++ dev->param.n_caches * sizeof(struct yaffs_cache); ++ ++ if (dev->param.n_caches > YAFFS_MAX_SHORT_OP_CACHES) ++ dev->param.n_caches = YAFFS_MAX_SHORT_OP_CACHES; ++ ++ dev->cache = kmalloc(cache_bytes, GFP_NOFS); ++ ++ buf = (u8 *) dev->cache; ++ ++ if (dev->cache) ++ memset(dev->cache, 0, cache_bytes); ++ ++ for (i = 0; i < dev->param.n_caches && buf; i++) { ++ dev->cache[i].object = NULL; ++ dev->cache[i].last_use = 0; ++ dev->cache[i].dirty = 0; ++ dev->cache[i].data = buf = ++ kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); ++ } ++ if (!buf) ++ init_failed = 1; ++ ++ dev->cache_last_use = 0; ++ } ++ ++ dev->cache_hits = 0; ++ ++ if (!init_failed) { ++ dev->gc_cleanup_list = ++ kmalloc(dev->param.chunks_per_block * sizeof(u32), ++ GFP_NOFS); ++ if (!dev->gc_cleanup_list) ++ init_failed = 1; ++ } ++ ++ if (dev->param.is_yaffs2) ++ dev->param.use_header_file_size = 1; ++ ++ if (!init_failed && !yaffs_init_blocks(dev)) ++ init_failed = 1; ++ ++ yaffs_init_tnodes_and_objs(dev); ++ ++ if (!init_failed && !yaffs_create_initial_dir(dev)) ++ init_failed = 1; ++ ++ if (!init_failed && dev->param.is_yaffs2 && ++ !dev->param.disable_summary && ++ !yaffs_summary_init(dev)) ++ init_failed = 1; ++ ++ if (!init_failed) { ++ /* Now scan the flash. */ ++ if (dev->param.is_yaffs2) { ++ if (yaffs2_checkpt_restore(dev)) { ++ yaffs_check_obj_details_loaded(dev->root_dir); ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT | ++ YAFFS_TRACE_MOUNT, ++ "yaffs: restored from checkpoint" ++ ); ++ } else { ++ ++ /* Clean up the mess caused by an aborted ++ * checkpoint load then scan backwards. ++ */ ++ yaffs_deinit_blocks(dev); ++ ++ yaffs_deinit_tnodes_and_objs(dev); ++ ++ dev->n_erased_blocks = 0; ++ dev->n_free_chunks = 0; ++ dev->alloc_block = -1; ++ dev->alloc_page = -1; ++ dev->n_deleted_files = 0; ++ dev->n_unlinked_files = 0; ++ dev->n_bg_deletions = 0; ++ ++ if (!init_failed && !yaffs_init_blocks(dev)) ++ init_failed = 1; ++ ++ yaffs_init_tnodes_and_objs(dev); ++ ++ if (!init_failed ++ && !yaffs_create_initial_dir(dev)) ++ init_failed = 1; ++ ++ if (!init_failed && !yaffs2_scan_backwards(dev)) ++ init_failed = 1; ++ } ++ } else if (!yaffs1_scan(dev)) { ++ init_failed = 1; ++ } ++ ++ yaffs_strip_deleted_objs(dev); ++ yaffs_fix_hanging_objs(dev); ++ if (dev->param.empty_lost_n_found) ++ yaffs_empty_l_n_f(dev); ++ } ++ ++ if (init_failed) { ++ /* Clean up the mess */ ++ yaffs_trace(YAFFS_TRACE_TRACING, ++ "yaffs: yaffs_guts_initialise() aborted."); ++ ++ yaffs_deinitialise(dev); ++ return YAFFS_FAIL; ++ } ++ ++ /* Zero out stats */ ++ dev->n_page_reads = 0; ++ dev->n_page_writes = 0; ++ dev->n_erasures = 0; ++ dev->n_gc_copies = 0; ++ dev->n_retried_writes = 0; ++ ++ dev->n_retired_blocks = 0; ++ ++ yaffs_verify_free_chunks(dev); ++ yaffs_verify_blocks(dev); ++ ++ /* Clean up any aborted checkpoint data */ ++ if (!dev->is_checkpointed && dev->blocks_in_checkpt > 0) ++ yaffs2_checkpt_invalidate(dev); ++ ++ yaffs_trace(YAFFS_TRACE_TRACING, ++ "yaffs: yaffs_guts_initialise() done."); ++ return YAFFS_OK; ++} ++ ++void yaffs_deinitialise(struct yaffs_dev *dev) ++{ ++ if (dev->is_mounted) { ++ u32 i; ++ ++ yaffs_deinit_blocks(dev); ++ yaffs_deinit_tnodes_and_objs(dev); ++ yaffs_summary_deinit(dev); ++ ++ if (dev->param.n_caches > 0 && dev->cache) { ++ ++ for (i = 0; i < dev->param.n_caches; i++) { ++ kfree(dev->cache[i].data); ++ dev->cache[i].data = NULL; ++ } ++ ++ kfree(dev->cache); ++ dev->cache = NULL; ++ } ++ ++ kfree(dev->gc_cleanup_list); ++ ++ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { ++ kfree(dev->temp_buffer[i].buffer); ++ dev->temp_buffer[i].buffer = NULL; ++ } ++ ++ kfree(dev->checkpt_buffer); ++ dev->checkpt_buffer = NULL; ++ kfree(dev->checkpt_block_list); ++ dev->checkpt_block_list = NULL; ++ ++ dev->is_mounted = 0; ++ ++ yaffs_deinit_nand(dev); ++ } ++} ++ ++int yaffs_count_free_chunks(struct yaffs_dev *dev) ++{ ++ int n_free = 0; ++ u32 b; ++ struct yaffs_block_info *blk; ++ ++ blk = dev->block_info; ++ for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) { ++ switch (blk->block_state) { ++ case YAFFS_BLOCK_STATE_EMPTY: ++ case YAFFS_BLOCK_STATE_ALLOCATING: ++ case YAFFS_BLOCK_STATE_COLLECTING: ++ case YAFFS_BLOCK_STATE_FULL: ++ n_free += ++ (dev->param.chunks_per_block - blk->pages_in_use + ++ blk->soft_del_pages); ++ break; ++ default: ++ break; ++ } ++ blk++; ++ } ++ return n_free; ++} ++ ++int yaffs_get_n_free_chunks(struct yaffs_dev *dev) ++{ ++ /* This is what we report to the outside world */ ++ int n_free; ++ int n_dirty_caches; ++ int blocks_for_checkpt; ++ u32 i; ++ ++ n_free = dev->n_free_chunks; ++ n_free += dev->n_deleted_files; ++ ++ /* Now count and subtract the number of dirty chunks in the cache. */ ++ ++ for (n_dirty_caches = 0, i = 0; i < dev->param.n_caches; i++) { ++ if (dev->cache[i].dirty) ++ n_dirty_caches++; ++ } ++ ++ n_free -= n_dirty_caches; ++ ++ n_free -= ++ ((dev->param.n_reserved_blocks + 1) * dev->param.chunks_per_block); ++ ++ /* Now figure checkpoint space and report that... */ ++ blocks_for_checkpt = yaffs_calc_checkpt_blocks_required(dev); ++ ++ n_free -= (blocks_for_checkpt * dev->param.chunks_per_block); ++ ++ if (n_free < 0) ++ n_free = 0; ++ ++ return n_free; ++} ++ ++ ++/* ++ * Marshalling functions to get loff_t file sizes into and out of ++ * object headers. ++ */ ++void yaffs_oh_size_load(struct yaffs_dev *dev, ++ struct yaffs_obj_hdr *oh, ++ loff_t fsize, ++ int do_endian) ++{ ++ oh->file_size_low = FSIZE_LOW(fsize); ++ ++ oh->file_size_high = FSIZE_HIGH(fsize); ++ ++ if (do_endian) { ++ yaffs_do_endian_u32(dev, &oh->file_size_low); ++ yaffs_do_endian_u32(dev, &oh->file_size_high); ++ } ++} ++ ++loff_t yaffs_oh_to_size(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh, ++ int do_endian) ++{ ++ loff_t retval; ++ ++ ++ if (sizeof(loff_t) >= 8 && ~(oh->file_size_high)) { ++ u32 low = oh->file_size_low; ++ u32 high = oh->file_size_high; ++ ++ if (do_endian) { ++ yaffs_do_endian_u32 (dev, &low); ++ yaffs_do_endian_u32 (dev, &high); ++ } ++ retval = FSIZE_COMBINE(high, low); ++ } else { ++ u32 low = oh->file_size_low; ++ ++ if (do_endian) ++ yaffs_do_endian_u32(dev, &low); ++ retval = (loff_t)low; ++ } ++ ++ return retval; ++} ++ ++ ++void yaffs_count_blocks_by_state(struct yaffs_dev *dev, int bs[10]) ++{ ++ u32 i; ++ struct yaffs_block_info *bi; ++ int s; ++ ++ for(i = 0; i < 10; i++) ++ bs[i] = 0; ++ ++ for(i = dev->internal_start_block; i <= dev->internal_end_block; i++) { ++ bi = yaffs_get_block_info(dev, i); ++ s = bi->block_state; ++ if(s > YAFFS_BLOCK_STATE_DEAD || s < YAFFS_BLOCK_STATE_UNKNOWN) ++ bs[0]++; ++ else ++ bs[s]++; ++ } ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_guts.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_guts.h.patch new file mode 100644 index 00000000..e11d96a0 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_guts.h.patch @@ -0,0 +1,1073 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_guts.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_guts.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,1070 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_GUTS_H__ ++#define __YAFFS_GUTS_H__ ++ ++#include "yportenv.h" ++ ++#define YAFFS_OK 1 ++#define YAFFS_FAIL 0 ++ ++/* Give us a Y=0x59, ++ * Give us an A=0x41, ++ * Give us an FF=0xff ++ * Give us an S=0x53 ++ * And what have we got... ++ */ ++#define YAFFS_MAGIC 0x5941ff53 ++ ++/* ++ * Tnodes form a tree with the tnodes in "levels" ++ * Levels greater than 0 hold 8 slots which point to other tnodes. ++ * Those at level 0 hold 16 slots which point to chunks in NAND. ++ * ++ * A maximum level of 8 thust supports files of size up to: ++ * ++ * 2^(3*MAX_LEVEL+4) ++ * ++ * Thus a max level of 8 supports files with up to 2^^28 chunks which gives ++ * a maximum file size of around 512Gbytees with 2k chunks. ++ */ ++#define YAFFS_NTNODES_LEVEL0 16 ++#define YAFFS_TNODES_LEVEL0_BITS 4 ++#define YAFFS_TNODES_LEVEL0_MASK 0xf ++ ++#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2) ++#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1) ++#define YAFFS_TNODES_INTERNAL_MASK 0x7 ++#define YAFFS_TNODES_MAX_LEVEL 8 ++#define YAFFS_TNODES_MAX_BITS (YAFFS_TNODES_LEVEL0_BITS + \ ++ YAFFS_TNODES_INTERNAL_BITS * \ ++ YAFFS_TNODES_MAX_LEVEL) ++#define YAFFS_MAX_CHUNK_ID ((1 << YAFFS_TNODES_MAX_BITS) - 1) ++ ++#define YAFFS_MAX_FILE_SIZE_32 0x7fffffff ++ ++/* Constants for YAFFS1 mode */ ++#define YAFFS_BYTES_PER_SPARE 16 ++#define YAFFS_BYTES_PER_CHUNK 512 ++#define YAFFS_CHUNK_SIZE_SHIFT 9 ++#define YAFFS_CHUNKS_PER_BLOCK 32 ++#define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK) ++ ++#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024 ++#define YAFFS_MIN_YAFFS2_SPARE_SIZE 32 ++ ++ ++ ++#define YAFFS_ALLOCATION_NOBJECTS 100 ++#define YAFFS_ALLOCATION_NTNODES 100 ++#define YAFFS_ALLOCATION_NLINKS 100 ++ ++#define YAFFS_NOBJECT_BUCKETS 256 ++ ++#define YAFFS_OBJECT_SPACE 0x40000 ++#define YAFFS_MAX_OBJECT_ID (YAFFS_OBJECT_SPACE - 1) ++ ++/* Binary data version stamps */ ++#define YAFFS_SUMMARY_VERSION 1 ++ ++#ifdef CONFIG_YAFFS_UNICODE ++#define YAFFS_MAX_NAME_LENGTH 127 ++#define YAFFS_MAX_ALIAS_LENGTH 79 ++#else ++#define YAFFS_MAX_NAME_LENGTH 255 ++#define YAFFS_MAX_ALIAS_LENGTH 159 ++#endif ++ ++#define YAFFS_SHORT_NAME_LENGTH 15 ++ ++/* Some special object ids for pseudo objects */ ++#define YAFFS_OBJECTID_ROOT 1 ++#define YAFFS_OBJECTID_LOSTNFOUND 2 ++#define YAFFS_OBJECTID_UNLINKED 3 ++#define YAFFS_OBJECTID_DELETED 4 ++ ++/* Fake object Id for summary data */ ++#define YAFFS_OBJECTID_SUMMARY 0x10 ++ ++/* Pseudo object ids for checkpointing */ ++#define YAFFS_OBJECTID_CHECKPOINT_DATA 0x20 ++#define YAFFS_SEQUENCE_CHECKPOINT_DATA 0x21 ++ ++#define YAFFS_MAX_SHORT_OP_CACHES 20 ++ ++#define YAFFS_N_TEMP_BUFFERS 6 ++ ++/* We limit the number attempts at sucessfully saving a chunk of data. ++ * Small-page devices have 32 pages per block; large-page devices have 64. ++ * Default to something in the order of 5 to 10 blocks worth of chunks. ++ */ ++#define YAFFS_WR_ATTEMPTS (5*64) ++ ++/* Sequence numbers are used in YAFFS2 to determine block allocation order. ++ * The range is limited slightly to help distinguish bad numbers from good. ++ * This also allows us to perhaps in the future use special numbers for ++ * special purposes. ++ * EFFFFF00 allows the allocation of 8 blocks/second (~1Mbytes) for 15 years, ++ * and is a larger number than the lifetime of a 2GB device. ++ */ ++#define YAFFS_LOWEST_SEQUENCE_NUMBER 0x00001000 ++#define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xefffff00 ++ ++/* Special sequence number for bad block that failed to be marked bad */ ++#define YAFFS_SEQUENCE_BAD_BLOCK 0xffff0000 ++ ++/* ChunkCache is used for short read/write operations.*/ ++struct yaffs_cache { ++ struct yaffs_obj *object; ++ int chunk_id; ++ int last_use; ++ int dirty; ++ int n_bytes; /* Only valid if the cache is dirty */ ++ int locked; /* Can't push out or flush while locked. */ ++ u8 *data; ++}; ++ ++/* yaffs1 tags structures in RAM ++ * NB This uses bitfield. Bitfields should not straddle a u32 boundary ++ * otherwise the structure size will get blown out. ++ */ ++ ++struct yaffs_tags { ++ u32 chunk_id:20; ++ u32 serial_number:2; ++ u32 n_bytes_lsb:10; ++ u32 obj_id:18; ++ u32 ecc:12; ++ u32 n_bytes_msb:2; ++}; ++ ++union yaffs_tags_union { ++ struct yaffs_tags as_tags; ++ u8 as_bytes[8]; ++ u32 as_u32[2]; ++}; ++ ++ ++/* Stuff used for extended tags in YAFFS2 */ ++ ++enum yaffs_ecc_result { ++ YAFFS_ECC_RESULT_UNKNOWN, ++ YAFFS_ECC_RESULT_NO_ERROR, ++ YAFFS_ECC_RESULT_FIXED, ++ YAFFS_ECC_RESULT_UNFIXED ++}; ++ ++/* ++ * Object type enum: ++ * When this is stored in flash we store it as a u32 instead ++ * to prevent any alignment change issues as compiler variants change. ++ */ ++ ++enum yaffs_obj_type { ++ YAFFS_OBJECT_TYPE_UNKNOWN, ++ YAFFS_OBJECT_TYPE_FILE, ++ YAFFS_OBJECT_TYPE_SYMLINK, ++ YAFFS_OBJECT_TYPE_DIRECTORY, ++ YAFFS_OBJECT_TYPE_HARDLINK, ++ YAFFS_OBJECT_TYPE_SPECIAL ++}; ++ ++#define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL ++ ++struct yaffs_ext_tags { ++ unsigned chunk_used; /* Status of the chunk: used or unused */ ++ unsigned obj_id; /* If 0 this is not used */ ++ unsigned chunk_id; /* If 0 this is a header, else a data chunk */ ++ unsigned n_bytes; /* Only valid for data chunks */ ++ ++ /* The following stuff only has meaning when we read */ ++ enum yaffs_ecc_result ecc_result; ++ unsigned block_bad; ++ ++ /* YAFFS 1 stuff */ ++ unsigned is_deleted; /* The chunk is marked deleted */ ++ unsigned serial_number; /* Yaffs1 2-bit serial number */ ++ ++ /* YAFFS2 stuff */ ++ unsigned seq_number; /* The sequence number of this block */ ++ ++ /* Extra info if this is an object header (YAFFS2 only) */ ++ ++ unsigned extra_available; /* Extra info available if not zero */ ++ unsigned extra_parent_id; /* The parent object */ ++ unsigned extra_is_shrink; /* Is it a shrink header? */ ++ unsigned extra_shadows; /* Does this shadow another object? */ ++ ++ enum yaffs_obj_type extra_obj_type; /* What object type? */ ++ ++ loff_t extra_file_size; /* Length if it is a file */ ++ unsigned extra_equiv_id; /* Equivalent object for a hard link */ ++}; ++ ++/* Spare structure for YAFFS1 */ ++struct yaffs_spare { ++ u8 tb0; ++ u8 tb1; ++ u8 tb2; ++ u8 tb3; ++ u8 page_status; /* set to 0 to delete the chunk */ ++ u8 block_status; ++ u8 tb4; ++ u8 tb5; ++ u8 ecc1[3]; ++ u8 tb6; ++ u8 tb7; ++ u8 ecc2[3]; ++}; ++ ++/*Special structure for passing through to mtd */ ++struct yaffs_nand_spare { ++ struct yaffs_spare spare; ++ int eccres1; ++ int eccres2; ++}; ++ ++/* Block data in RAM */ ++ ++enum yaffs_block_state { ++ YAFFS_BLOCK_STATE_UNKNOWN = 0, ++ ++ YAFFS_BLOCK_STATE_SCANNING, ++ /* Being scanned */ ++ ++ YAFFS_BLOCK_STATE_NEEDS_SCAN, ++ /* The block might have something on it (ie it is allocating or full, ++ * perhaps empty) but it needs to be scanned to determine its true ++ * state. ++ * This state is only valid during scanning. ++ * NB We tolerate empty because the pre-scanner might be incapable of ++ * deciding ++ * However, if this state is returned on a YAFFS2 device, ++ * then we expect a sequence number ++ */ ++ ++ YAFFS_BLOCK_STATE_EMPTY, ++ /* This block is empty */ ++ ++ YAFFS_BLOCK_STATE_ALLOCATING, ++ /* This block is partially allocated. ++ * At least one page holds valid data. ++ * This is the one currently being used for page ++ * allocation. Should never be more than one of these. ++ * If a block is only partially allocated at mount it is treated as ++ * full. ++ */ ++ ++ YAFFS_BLOCK_STATE_FULL, ++ /* All the pages in this block have been allocated. ++ * If a block was only partially allocated when mounted we treat ++ * it as fully allocated. ++ */ ++ ++ YAFFS_BLOCK_STATE_DIRTY, ++ /* The block was full and now all chunks have been deleted. ++ * Erase me, reuse me. ++ */ ++ ++ YAFFS_BLOCK_STATE_CHECKPOINT, ++ /* This block is assigned to holding checkpoint data. */ ++ ++ YAFFS_BLOCK_STATE_COLLECTING, ++ /* This block is being garbage collected */ ++ ++ YAFFS_BLOCK_STATE_DEAD ++ /* This block has failed and is not in use */ ++}; ++ ++#define YAFFS_NUMBER_OF_BLOCK_STATES (YAFFS_BLOCK_STATE_DEAD + 1) ++ ++struct yaffs_block_info { ++ ++ s32 soft_del_pages:10; /* number of soft deleted pages */ ++ s32 pages_in_use:10; /* number of pages in use */ ++ u32 block_state:4; /* One of the above block states. */ ++ /* NB use unsigned because enum is sometimes ++ * an int */ ++ u32 needs_retiring:1; /* Data has failed on this block, */ ++ /*need to get valid data off and retire*/ ++ u32 skip_erased_check:1;/* Skip the erased check on this block */ ++ u32 gc_prioritise:1; /* An ECC check or blank check has failed. ++ Block should be prioritised for GC */ ++ u32 chunk_error_strikes:3; /* How many times we've had ecc etc ++ failures on this block and tried to reuse it */ ++ u32 has_summary:1; /* The block has a summary */ ++ ++ u32 has_shrink_hdr:1; /* This block has at least one shrink header */ ++ u32 seq_number; /* block sequence number for yaffs2 */ ++ ++}; ++ ++union yaffs_block_info_union { ++ struct yaffs_block_info bi; ++ u32 as_u32[2]; ++}; ++ ++/* -------------------------- Object structure -------------------------------*/ ++/* This is the object structure as stored on NAND */ ++ ++struct yaffs_obj_hdr { ++ u32 type; /* enum yaffs_obj_type */ ++ ++ /* Apply to everything */ ++ u32 parent_obj_id; ++ u16 sum_no_longer_used; /* checksum of name. No longer used */ ++ YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; ++ ++ /* The following apply to all object types except for hard links */ ++ u32 yst_mode; /* protection */ ++ ++ u32 yst_uid; ++ u32 yst_gid; ++ u32 yst_atime; ++ u32 yst_mtime; ++ u32 yst_ctime; ++ ++ /* File size applies to files only */ ++ u32 file_size_low; ++ ++ /* Equivalent object id applies to hard links only. */ ++ int equiv_id; ++ ++ /* Alias is for symlinks only. */ ++ YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1]; ++ ++ u32 yst_rdev; /* stuff for block and char devices (major/min) */ ++ ++ u32 win_ctime[2]; ++ u32 win_atime[2]; ++ u32 win_mtime[2]; ++ ++ u32 inband_shadowed_obj_id; ++ u32 inband_is_shrink; ++ ++ u32 file_size_high; ++ u32 reserved[1]; ++ int shadows_obj; /* This object header shadows the ++ specified object if > 0 */ ++ ++ /* is_shrink applies to object headers written when wemake a hole. */ ++ u32 is_shrink; ++ ++}; ++ ++/*--------------------------- Tnode -------------------------- */ ++ ++struct yaffs_tnode { ++ struct yaffs_tnode *internal[YAFFS_NTNODES_INTERNAL]; ++}; ++ ++/*------------------------ Object -----------------------------*/ ++/* An object can be one of: ++ * - a directory (no data, has children links ++ * - a regular file (data.... not prunes :->). ++ * - a symlink [symbolic link] (the alias). ++ * - a hard link ++ */ ++ ++/* The file variant has three file sizes: ++ * - file_size : size of file as written into Yaffs - including data in cache. ++ * - stored_size - size of file as stored on media. ++ * - shrink_size - size of file that has been shrunk back to. ++ * ++ * The stored_size and file_size might be different because the data written ++ * into the cache will increase the file_size but the stored_size will only ++ * change when the data is actually stored. ++ * ++ */ ++struct yaffs_file_var { ++ loff_t file_size; ++ loff_t stored_size; ++ loff_t shrink_size; ++ int top_level; ++ struct yaffs_tnode *top; ++}; ++ ++struct yaffs_dir_var { ++ struct list_head children; /* list of child links */ ++ struct list_head dirty; /* Entry for list of dirty directories */ ++}; ++ ++struct yaffs_symlink_var { ++ YCHAR *alias; ++}; ++ ++struct yaffs_hardlink_var { ++ struct yaffs_obj *equiv_obj; ++ u32 equiv_id; ++}; ++ ++union yaffs_obj_var { ++ struct yaffs_file_var file_variant; ++ struct yaffs_dir_var dir_variant; ++ struct yaffs_symlink_var symlink_variant; ++ struct yaffs_hardlink_var hardlink_variant; ++}; ++ ++struct yaffs_obj { ++ u8 deleted:1; /* This should only apply to unlinked files. */ ++ u8 soft_del:1; /* it has also been soft deleted */ ++ u8 unlinked:1; /* An unlinked file.*/ ++ u8 fake:1; /* A fake object has no presence on NAND. */ ++ u8 rename_allowed:1; /* Some objects cannot be renamed. */ ++ u8 unlink_allowed:1; ++ u8 dirty:1; /* the object needs to be written to flash */ ++ u8 valid:1; /* When the file system is being loaded up, this ++ * object might be created before the data ++ * is available ++ * ie. file data chunks encountered before ++ * the header. ++ */ ++ u8 lazy_loaded:1; /* This object has been lazy loaded and ++ * is missing some detail */ ++ ++ u8 defered_free:1; /* Object is removed from NAND, but is ++ * still in the inode cache. ++ * Free of object is defered. ++ * until the inode is released. ++ */ ++ u8 being_created:1; /* This object is still being created ++ * so skip some verification checks. */ ++ u8 is_shadowed:1; /* This object is shadowed on the way ++ * to being renamed. */ ++ ++ u8 xattr_known:1; /* We know if this has object has xattribs ++ * or not. */ ++ u8 has_xattr:1; /* This object has xattribs. ++ * Only valid if xattr_known. */ ++ ++ u8 serial; /* serial number of chunk in NAND.*/ ++ u16 sum; /* sum of the name to speed searching */ ++ ++ struct yaffs_dev *my_dev; /* The device I'm on */ ++ ++ struct list_head hash_link; /* list of objects in hash bucket */ ++ ++ struct list_head hard_links; /* hard linked object chain*/ ++ ++ /* directory structure stuff */ ++ /* also used for linking up the free list */ ++ struct yaffs_obj *parent; ++ struct list_head siblings; ++ ++ /* Where's my object header in NAND? */ ++ int hdr_chunk; ++ ++ int n_data_chunks; /* Number of data chunks for this file. */ ++ ++ u32 obj_id; /* the object id value */ ++ ++ u32 yst_mode; ++ ++ YCHAR short_name[YAFFS_SHORT_NAME_LENGTH + 1]; ++ ++#ifdef CONFIG_YAFFS_WINCE ++ u32 win_ctime[2]; ++ u32 win_mtime[2]; ++ u32 win_atime[2]; ++#else ++ u32 yst_uid; ++ u32 yst_gid; ++ u32 yst_atime; ++ u32 yst_mtime; ++ u32 yst_ctime; ++#endif ++ ++ u32 yst_rdev; ++ ++ void *my_inode; ++ ++ u32 variant_type; /* enum yaffs_object_type */ ++ ++ union yaffs_obj_var variant; ++ ++}; ++ ++struct yaffs_obj_bucket { ++ struct list_head list; ++ int count; ++}; ++ ++ ++/*--------------------- Temporary buffers ---------------- ++ * ++ * These are chunk-sized working buffers. Each device has a few. ++ */ ++ ++struct yaffs_buffer { ++ u8 *buffer; ++ int in_use; ++}; ++ ++/*----------------- Device ---------------------------------*/ ++ ++struct yaffs_param { ++ const YCHAR *name; ++ ++ /* ++ * Entry parameters set up way early. Yaffs sets up the rest. ++ * The structure should be zeroed out before use so that unused ++ * and default values are zero. ++ */ ++ ++ int inband_tags; /* Use unband tags */ ++ u32 total_bytes_per_chunk; /* Should be >= 512, does not need to ++ be a power of 2 */ ++ u32 chunks_per_block; /* does not need to be a power of 2 */ ++ u32 spare_bytes_per_chunk; /* spare area size */ ++ u32 start_block; /* Start block we're allowed to use */ ++ u32 end_block; /* End block we're allowed to use */ ++ u32 n_reserved_blocks; /* Tuneable so that we can reduce ++ * reserved blocks on NOR and RAM. */ ++ ++ u32 n_caches; /* If == 0, then short op caching is disabled, ++ * else the number of short op caches. ++ */ ++ int cache_bypass_aligned; /* If non-zero then bypass the cache for ++ * aligned writes. ++ */ ++ ++ int use_nand_ecc; /* Flag to decide whether or not to use ++ * NAND driver ECC on data (yaffs1) */ ++ int tags_9bytes; /* Use 9 byte tags */ ++ int no_tags_ecc; /* Flag to decide whether or not to do ECC ++ * on packed tags (yaffs2) */ ++ ++ int is_yaffs2; /* Use yaffs2 mode on this device */ ++ ++ int empty_lost_n_found; /* Auto-empty lost+found directory on mount */ ++ ++ int refresh_period; /* How often to check for a block refresh */ ++ ++ /* Checkpoint control. Can be set before or after initialisation */ ++ u8 skip_checkpt_rd; ++ u8 skip_checkpt_wr; ++ ++ int enable_xattr; /* Enable xattribs */ ++ ++ int max_objects; /* ++ * Set to limit the number of objects created. ++ * 0 = no limit. ++ */ ++ ++ int hide_lost_n_found; /* Set non-zero to hide the lost-n-found dir. */ ++ ++ int stored_endian; /* 0=cpu endian, 1=little endian, 2=big endian */ ++ ++ /* The remove_obj_fn function must be supplied by OS flavours that ++ * need it. ++ * yaffs direct uses it to implement the faster readdir. ++ * Linux uses it to protect the directory during unlocking. ++ */ ++ void (*remove_obj_fn) (struct yaffs_obj *obj); ++ ++ /* Callback to mark the superblock dirty */ ++ void (*sb_dirty_fn) (struct yaffs_dev *dev); ++ ++ /* Callback to control garbage collection. */ ++ unsigned (*gc_control_fn) (struct yaffs_dev *dev); ++ ++ /* Debug control flags. Don't use unless you know what you're doing */ ++ int use_header_file_size; /* Flag to determine if we should use ++ * file sizes from the header */ ++ int disable_lazy_load; /* Disable lazy loading on this device */ ++ int wide_tnodes_disabled; /* Set to disable wide tnodes */ ++ int disable_soft_del; /* yaffs 1 only: Set to disable the use of ++ * softdeletion. */ ++ ++ int defered_dir_update; /* Set to defer directory updates */ ++ ++#ifdef CONFIG_YAFFS_AUTO_UNICODE ++ int auto_unicode; ++#endif ++ int always_check_erased; /* Force chunk erased check always on */ ++ ++ int disable_summary; ++ int disable_bad_block_marking; ++ ++}; ++ ++struct yaffs_driver { ++ int (*drv_write_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, ++ const u8 *data, int data_len, ++ const u8 *oob, int oob_len); ++ int (*drv_read_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, ++ u8 *data, int data_len, ++ u8 *oob, int oob_len, ++ enum yaffs_ecc_result *ecc_result); ++ int (*drv_erase_fn) (struct yaffs_dev *dev, int block_no); ++ int (*drv_mark_bad_fn) (struct yaffs_dev *dev, int block_no); ++ int (*drv_check_bad_fn) (struct yaffs_dev *dev, int block_no); ++ int (*drv_initialise_fn) (struct yaffs_dev *dev); ++ int (*drv_deinitialise_fn) (struct yaffs_dev *dev); ++}; ++ ++struct yaffs_tags_handler { ++ int (*write_chunk_tags_fn) (struct yaffs_dev *dev, ++ int nand_chunk, const u8 *data, ++ const struct yaffs_ext_tags *tags); ++ int (*read_chunk_tags_fn) (struct yaffs_dev *dev, ++ int nand_chunk, u8 *data, ++ struct yaffs_ext_tags *tags); ++ ++ int (*query_block_fn) (struct yaffs_dev *dev, int block_no, ++ enum yaffs_block_state *state, ++ u32 *seq_number); ++ int (*mark_bad_fn) (struct yaffs_dev *dev, int block_no); ++}; ++ ++struct yaffs_dev { ++ struct yaffs_param param; ++ struct yaffs_driver drv; ++ struct yaffs_tags_handler tagger; ++ ++ /* Context storage. Holds extra OS specific data for this device */ ++ ++ void *os_context; ++ void *driver_context; ++ ++ struct list_head dev_list; ++ ++ int ll_init; ++ /* Runtime parameters. Set up by YAFFS. */ ++ u32 data_bytes_per_chunk; ++ ++ /* Non-wide tnode stuff */ ++ u16 chunk_grp_bits; /* Number of bits that need to be resolved if ++ * the tnodes are not wide enough. ++ */ ++ u16 chunk_grp_size; /* == 2^^chunk_grp_bits */ ++ ++ struct yaffs_tnode *tn_swap_buffer; ++ ++ /* Stuff to support wide tnodes */ ++ u32 tnode_width; ++ u32 tnode_mask; ++ u32 tnode_size; ++ ++ /* Stuff for figuring out file offset to chunk conversions */ ++ u32 chunk_shift; /* Shift value */ ++ u32 chunk_div; /* Divisor after shifting: 1 for 2^n sizes */ ++ u32 chunk_mask; /* Mask to use for power-of-2 case */ ++ ++ int is_mounted; ++ int read_only; ++ int is_checkpointed; ++ int swap_endian; /* Stored endian needs endian swap. */ ++ ++ /* Stuff to support block offsetting to support start block zero */ ++ u32 internal_start_block; ++ u32 internal_end_block; ++ int block_offset; ++ int chunk_offset; ++ ++ /* Runtime checkpointing stuff */ ++ int checkpt_page_seq; /* running sequence number of checkpt pages */ ++ int checkpt_byte_count; ++ int checkpt_byte_offs; ++ u8 *checkpt_buffer; ++ int checkpt_open_write; ++ u32 blocks_in_checkpt; ++ int checkpt_cur_chunk; ++ int checkpt_cur_block; ++ int checkpt_next_block; ++ int *checkpt_block_list; ++ u32 checkpt_max_blocks; ++ u32 checkpt_sum; ++ u32 checkpt_xor; ++ ++ int checkpoint_blocks_required; /* Number of blocks needed to store ++ * current checkpoint set */ ++ ++ /* Block Info */ ++ struct yaffs_block_info *block_info; ++ u8 *chunk_bits; /* bitmap of chunks in use */ ++ u8 block_info_alt:1; /* allocated using alternative alloc */ ++ u8 chunk_bits_alt:1; /* allocated using alternative alloc */ ++ int chunk_bit_stride; /* Number of bytes of chunk_bits per block. ++ * Must be consistent with chunks_per_block. ++ */ ++ ++ int n_erased_blocks; ++ int alloc_block; /* Current block being allocated off */ ++ u32 alloc_page; ++ int alloc_block_finder; /* Used to search for next allocation block */ ++ ++ /* Object and Tnode memory management */ ++ void *allocator; ++ int n_obj; ++ int n_tnodes; ++ ++ int n_hardlinks; ++ ++ struct yaffs_obj_bucket obj_bucket[YAFFS_NOBJECT_BUCKETS]; ++ u32 bucket_finder; ++ ++ int n_free_chunks; ++ ++ /* Garbage collection control */ ++ u32 *gc_cleanup_list; /* objects to delete at the end of a GC. */ ++ u32 n_clean_ups; ++ ++ unsigned has_pending_prioritised_gc; /* We think this device might ++ have pending prioritised gcs */ ++ unsigned gc_disable; ++ unsigned gc_block_finder; ++ unsigned gc_dirtiest; ++ unsigned gc_pages_in_use; ++ unsigned gc_not_done; ++ unsigned gc_block; ++ unsigned gc_chunk; ++ unsigned gc_skip; ++ struct yaffs_summary_tags *gc_sum_tags; ++ ++ /* Special directories */ ++ struct yaffs_obj *root_dir; ++ struct yaffs_obj *lost_n_found; ++ ++ int buffered_block; /* Which block is buffered here? */ ++ int doing_buffered_block_rewrite; ++ ++ struct yaffs_cache *cache; ++ int cache_last_use; ++ ++ /* Stuff for background deletion and unlinked files. */ ++ struct yaffs_obj *unlinked_dir; /* Directory where unlinked and deleted ++ files live. */ ++ struct yaffs_obj *del_dir; /* Directory where deleted objects are ++ sent to disappear. */ ++ struct yaffs_obj *unlinked_deletion; /* Current file being ++ background deleted. */ ++ int n_deleted_files; /* Count of files awaiting deletion; */ ++ int n_unlinked_files; /* Count of unlinked files. */ ++ int n_bg_deletions; /* Count of background deletions. */ ++ ++ /* Temporary buffer management */ ++ struct yaffs_buffer temp_buffer[YAFFS_N_TEMP_BUFFERS]; ++ int max_temp; ++ int temp_in_use; ++ int unmanaged_buffer_allocs; ++ int unmanaged_buffer_deallocs; ++ ++ /* yaffs2 runtime stuff */ ++ unsigned seq_number; /* Sequence number of currently ++ allocating block */ ++ unsigned oldest_dirty_seq; ++ unsigned oldest_dirty_block; ++ ++ /* Block refreshing */ ++ int refresh_skip; /* A skip down counter. ++ * Refresh happens when this gets to zero. */ ++ ++ /* Dirty directory handling */ ++ struct list_head dirty_dirs; /* List of dirty directories */ ++ ++ /* Summary */ ++ int chunks_per_summary; ++ struct yaffs_summary_tags *sum_tags; ++ ++ /* Statistics */ ++ u32 n_page_writes; ++ u32 n_page_reads; ++ u32 n_erasures; ++ u32 n_bad_queries; ++ u32 n_bad_markings; ++ u32 n_erase_failures; ++ u32 n_gc_copies; ++ u32 all_gcs; ++ u32 passive_gc_count; ++ u32 oldest_dirty_gc_count; ++ u32 n_gc_blocks; ++ u32 bg_gcs; ++ u32 n_retried_writes; ++ u32 n_retired_blocks; ++ u32 n_ecc_fixed; ++ u32 n_ecc_unfixed; ++ u32 n_tags_ecc_fixed; ++ u32 n_tags_ecc_unfixed; ++ u32 n_deletions; ++ u32 n_unmarked_deletions; ++ u32 refresh_count; ++ u32 cache_hits; ++ u32 tags_used; ++ u32 summary_used; ++ ++}; ++ ++/* ++ * Checkpointing definitions. ++ */ ++ ++#define YAFFS_CHECKPOINT_VERSION 8 ++ ++/* yaffs_checkpt_obj holds the definition of an object as dumped ++ * by checkpointing. ++ */ ++ ++ ++/* Checkpint object bits in bitfield: offset, length */ ++#define CHECKPOINT_VARIANT_BITS 0, 3 ++#define CHECKPOINT_DELETED_BITS 3, 1 ++#define CHECKPOINT_SOFT_DEL_BITS 4, 1 ++#define CHECKPOINT_UNLINKED_BITS 5, 1 ++#define CHECKPOINT_FAKE_BITS 6, 1 ++#define CHECKPOINT_RENAME_ALLOWED_BITS 7, 1 ++#define CHECKPOINT_UNLINK_ALLOWED_BITS 8, 1 ++#define CHECKPOINT_SERIAL_BITS 9, 8 ++ ++struct yaffs_checkpt_obj { ++ int struct_type; ++ u32 obj_id; ++ u32 parent_id; ++ int hdr_chunk; ++ u32 bit_field; ++ int n_data_chunks; ++ loff_t size_or_equiv_obj; ++}; ++ ++/* The CheckpointDevice structure holds the device information that changes ++ *at runtime and must be preserved over unmount/mount cycles. ++ */ ++struct yaffs_checkpt_dev { ++ int struct_type; ++ int n_erased_blocks; ++ int alloc_block; /* Current block being allocated off */ ++ u32 alloc_page; ++ int n_free_chunks; ++ ++ int n_deleted_files; /* Count of files awaiting deletion; */ ++ int n_unlinked_files; /* Count of unlinked files. */ ++ int n_bg_deletions; /* Count of background deletions. */ ++ ++ /* yaffs2 runtime stuff */ ++ unsigned seq_number; /* Sequence number of currently ++ * allocating block */ ++ ++}; ++ ++struct yaffs_checkpt_validity { ++ int struct_type; ++ u32 magic; ++ u32 version; ++ u32 head; ++}; ++ ++struct yaffs_shadow_fixer { ++ int obj_id; ++ int shadowed_id; ++ struct yaffs_shadow_fixer *next; ++}; ++ ++/* Structure for doing xattr modifications */ ++struct yaffs_xattr_mod { ++ int set; /* If 0 then this is a deletion */ ++ const YCHAR *name; ++ const void *data; ++ int size; ++ int flags; ++ int result; ++}; ++ ++/*----------------------- YAFFS Functions -----------------------*/ ++ ++int yaffs_guts_initialise(struct yaffs_dev *dev); ++void yaffs_deinitialise(struct yaffs_dev *dev); ++ ++int yaffs_get_n_free_chunks(struct yaffs_dev *dev); ++ ++int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR * old_name, ++ struct yaffs_obj *new_dir, const YCHAR * new_name); ++ ++int yaffs_unlink_obj(struct yaffs_obj *obj); ++ ++int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR * name); ++int yaffs_del_obj(struct yaffs_obj *obj); ++struct yaffs_obj *yaffs_retype_obj(struct yaffs_obj *obj, ++ enum yaffs_obj_type type); ++ ++ ++int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size); ++loff_t yaffs_get_obj_length(struct yaffs_obj *obj); ++int yaffs_get_obj_inode(struct yaffs_obj *obj); ++unsigned yaffs_get_obj_type(struct yaffs_obj *obj); ++int yaffs_get_obj_link_count(struct yaffs_obj *obj); ++ ++/* File operations */ ++int yaffs_file_rd(struct yaffs_obj *obj, u8 * buffer, loff_t offset, ++ int n_bytes); ++int yaffs_wr_file(struct yaffs_obj *obj, const u8 * buffer, loff_t offset, ++ int n_bytes, int write_trhrough); ++int yaffs_resize_file(struct yaffs_obj *obj, loff_t new_size); ++ ++struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent, ++ const YCHAR *name, u32 mode, u32 uid, ++ u32 gid); ++ ++int yaffs_flush_file(struct yaffs_obj *in, ++ int update_time, ++ int data_sync, ++ int discard_cache); ++ ++/* Flushing and checkpointing */ ++void yaffs_flush_whole_cache(struct yaffs_dev *dev, int discard); ++ ++int yaffs_checkpoint_save(struct yaffs_dev *dev); ++int yaffs_checkpoint_restore(struct yaffs_dev *dev); ++ ++/* Directory operations */ ++struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name, ++ u32 mode, u32 uid, u32 gid); ++struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *the_dir, ++ const YCHAR *name); ++struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number); ++ ++/* Link operations */ ++struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR *name, ++ struct yaffs_obj *equiv_obj); ++ ++struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj); ++ ++/* Symlink operations */ ++struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent, ++ const YCHAR *name, u32 mode, u32 uid, ++ u32 gid, const YCHAR *alias); ++YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj); ++ ++/* Special inodes (fifos, sockets and devices) */ ++struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent, ++ const YCHAR *name, u32 mode, u32 uid, ++ u32 gid, u32 rdev); ++ ++int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR *name, ++ const void *value, int size, int flags); ++int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR *name, void *value, ++ int size); ++int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size); ++int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR *name); ++ ++/* Special directories */ ++struct yaffs_obj *yaffs_root(struct yaffs_dev *dev); ++struct yaffs_obj *yaffs_lost_n_found(struct yaffs_dev *dev); ++ ++void yaffs_handle_defered_free(struct yaffs_obj *obj); ++ ++void yaffs_update_dirty_dirs(struct yaffs_dev *dev); ++ ++int yaffs_bg_gc(struct yaffs_dev *dev, unsigned urgency); ++ ++/* Debug dump */ ++int yaffs_dump_obj(struct yaffs_obj *obj); ++ ++void yaffs_guts_test(struct yaffs_dev *dev); ++int yaffs_guts_ll_init(struct yaffs_dev *dev); ++ ++ ++/* A few useful functions to be used within the core files*/ ++void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash, ++ int lyn); ++int yaffs_check_ff(u8 *buffer, int n_bytes); ++void yaffs_handle_chunk_error(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi); ++ ++u8 *yaffs_get_temp_buffer(struct yaffs_dev *dev); ++void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer); ++ ++struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev, ++ int number, ++ enum yaffs_obj_type type); ++int yaffs_put_chunk_in_file(struct yaffs_obj *in, int inode_chunk, ++ int nand_chunk, int in_scan); ++void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR *name); ++void yaffs_set_obj_name_from_oh(struct yaffs_obj *obj, ++ const struct yaffs_obj_hdr *oh); ++void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj); ++YCHAR *yaffs_clone_str(const YCHAR *str); ++void yaffs_link_fixup(struct yaffs_dev *dev, struct list_head *hard_list); ++void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no); ++int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, ++ int force, int is_shrink, int shadows, ++ struct yaffs_xattr_mod *xop); ++void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id, ++ int backward_scanning); ++int yaffs_check_alloc_available(struct yaffs_dev *dev, int n_chunks); ++struct yaffs_tnode *yaffs_get_tnode(struct yaffs_dev *dev); ++struct yaffs_tnode *yaffs_add_find_tnode_0(struct yaffs_dev *dev, ++ struct yaffs_file_var *file_struct, ++ u32 chunk_id, ++ struct yaffs_tnode *passed_tn); ++ ++int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset, ++ int n_bytes, int write_trhrough); ++void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size); ++void yaffs_skip_rest_of_block(struct yaffs_dev *dev); ++ ++int yaffs_count_free_chunks(struct yaffs_dev *dev); ++ ++struct yaffs_tnode *yaffs_find_tnode_0(struct yaffs_dev *dev, ++ struct yaffs_file_var *file_struct, ++ u32 chunk_id); ++ ++u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn, ++ unsigned pos); ++ ++int yaffs_is_non_empty_dir(struct yaffs_obj *obj); ++ ++int yaffs_guts_format_dev(struct yaffs_dev *dev); ++ ++void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr, ++ int *chunk_out, u32 *offset_out); ++/* ++ * Marshalling functions to get loff_t file sizes into and out of ++ * object headers. ++ */ ++void yaffs_oh_size_load(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh, ++ loff_t fsize, int do_endian); ++loff_t yaffs_oh_to_size(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh, ++ int do_endian); ++loff_t yaffs_max_file_size(struct yaffs_dev *dev); ++ ++/* ++ * Debug function to count number of blocks in each state ++ * NB Needs to be called with correct number of integers ++ */ ++ ++void yaffs_count_blocks_by_state(struct yaffs_dev *dev, int bs[10]); ++ ++int yaffs_find_chunk_in_file(struct yaffs_obj *in, int inode_chunk, ++ struct yaffs_ext_tags *tags); ++ ++/* ++ * Define LOFF_T_32_BIT if a 32-bit LOFF_T is being used. ++ * Not serious if you get this wrong - you might just get some warnings. ++*/ ++ ++#ifdef LOFF_T_32_BIT ++#define FSIZE_LOW(fsize) (fsize) ++#define FSIZE_HIGH(fsize) 0 ++#define FSIZE_COMBINE(high, low) (low) ++#else ++#define FSIZE_LOW(fsize) ((fsize) & 0xffffffff) ++#define FSIZE_HIGH(fsize)(((fsize) >> 32) & 0xffffffff) ++#define FSIZE_COMBINE(high, low) ((((loff_t) (high)) << 32) | \ ++ (((loff_t) (low)) & 0xFFFFFFFF)) ++#endif ++ ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_linux.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_linux.h.patch new file mode 100644 index 00000000..166b3a6d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_linux.h.patch @@ -0,0 +1,51 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_linux.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_linux.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,48 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_LINUX_H__ ++#define __YAFFS_LINUX_H__ ++ ++#include "yportenv.h" ++ ++struct yaffs_linux_context { ++ struct list_head context_list; /* List of these we have mounted */ ++ struct yaffs_dev *dev; ++ struct super_block *super; ++ struct task_struct *bg_thread; /* Background thread for this device */ ++ int bg_running; ++ struct mutex gross_lock; /* Gross locking mutex*/ ++ u8 *spare_buffer; /* For mtdif2 use. Don't know the buffer size ++ * at compile time so we have to allocate it. ++ */ ++ struct list_head search_contexts; ++ struct task_struct *readdir_process; ++ unsigned mount_id; ++ int dirty; ++}; ++ ++#define yaffs_dev_to_lc(dev) ((struct yaffs_linux_context *)((dev)->os_context)) ++#define yaffs_dev_to_mtd(dev) ((struct mtd_info *)((dev)->driver_context)) ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++#define WRITE_SIZE_STR "writesize" ++#define WRITE_SIZE(mtd) ((mtd)->writesize) ++#else ++#define WRITE_SIZE_STR "oobblock" ++#define WRITE_SIZE(mtd) ((mtd)->oobblock) ++#endif ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_mtdif.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_mtdif.c.patch new file mode 100644 index 00000000..fca0aa6b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_mtdif.c.patch @@ -0,0 +1,313 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_mtdif.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_mtdif.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,310 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yportenv.h" ++ ++#include "yaffs_mtdif.h" ++ ++#include "linux/mtd/mtd.h" ++#include "linux/types.h" ++#include "linux/time.h" ++#include "linux/mtd/nand.h" ++#include "linux/kernel.h" ++#include "linux/version.h" ++#include "linux/types.h" ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) ++#include "uapi/linux/major.h" ++#endif ++ ++#include "yaffs_trace.h" ++#include "yaffs_guts.h" ++#include "yaffs_linux.h" ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) ++#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO ++#endif ++ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) ++#define mtd_erase(m, ei) (m)->erase(m, ei) ++#define mtd_write_oob(m, addr, pops) (m)->write_oob(m, addr, pops) ++#define mtd_read_oob(m, addr, pops) (m)->read_oob(m, addr, pops) ++#define mtd_block_isbad(m, offs) (m)->block_isbad(m, offs) ++#define mtd_block_markbad(m, offs) (m)->block_markbad(m, offs) ++#endif ++ ++ ++ ++int nandmtd_erase_block(struct yaffs_dev *dev, int block_no) ++{ ++ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); ++ u32 addr = ++ ((loff_t) block_no) * dev->param.total_bytes_per_chunk * ++ dev->param.chunks_per_block; ++ struct erase_info ei; ++ int retval = 0; ++ ++ ei.mtd = mtd; ++ ei.addr = addr; ++ ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block; ++ ei.time = 1000; ++ ei.retries = 2; ++ ei.callback = NULL; ++ ei.priv = (u_long) dev; ++ ++ retval = mtd_erase(mtd, &ei); ++ ++ if (retval == 0) ++ return YAFFS_OK; ++ ++ return YAFFS_FAIL; ++} ++ ++ ++static int yaffs_mtd_write(struct yaffs_dev *dev, int nand_chunk, ++ const u8 *data, int data_len, ++ const u8 *oob, int oob_len) ++{ ++ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); ++ loff_t addr; ++ struct mtd_oob_ops ops; ++ int retval; ++ ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "yaffs_mtd_write(%p, %d, %p, %d, %p, %d)\n", ++ dev, nand_chunk, data, data_len, oob, oob_len); ++ ++ if (!data || !data_len) { ++ data = NULL; ++ data_len = 0; ++ } ++ ++ if (!oob || !oob_len) { ++ oob = NULL; ++ oob_len = 0; ++ } ++ ++ addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk; ++ memset(&ops, 0, sizeof(ops)); ++ ops.mode = MTD_OPS_AUTO_OOB; ++ ops.len = (data) ? data_len : 0; ++ ops.ooblen = oob_len; ++ ops.datbuf = (u8 *)data; ++ ops.oobbuf = (u8 *)oob; ++ ++ retval = mtd_write_oob(mtd, addr, &ops); ++ if (retval) { ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "write_oob failed, chunk %d, mtd error %d", ++ nand_chunk, retval); ++ } ++ return retval ? YAFFS_FAIL : YAFFS_OK; ++} ++ ++static int yaffs_mtd_read(struct yaffs_dev *dev, int nand_chunk, ++ u8 *data, int data_len, ++ u8 *oob, int oob_len, ++ enum yaffs_ecc_result *ecc_result) ++{ ++ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); ++ loff_t addr; ++ struct mtd_oob_ops ops; ++ int retval; ++ ++ addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk; ++ memset(&ops, 0, sizeof(ops)); ++ ops.mode = MTD_OPS_AUTO_OOB; ++ ops.len = (data) ? data_len : 0; ++ ops.ooblen = oob_len; ++ ops.datbuf = data; ++ ops.oobbuf = oob; ++ ++#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20)) ++ /* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug; ++ * help it out with ops.len = ops.ooblen when ops.datbuf == NULL. ++ */ ++ ops.len = (ops.datbuf) ? ops.len : ops.ooblen; ++#endif ++ /* Read page and oob using MTD. ++ * Check status and determine ECC result. ++ */ ++ retval = mtd_read_oob(mtd, addr, &ops); ++ if (retval) ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "read_oob failed, chunk %d, mtd error %d", ++ nand_chunk, retval); ++ ++ switch (retval) { ++ case 0: ++ /* no error */ ++ if(ecc_result) ++ *ecc_result = YAFFS_ECC_RESULT_NO_ERROR; ++ break; ++ ++ case -EUCLEAN: ++ /* MTD's ECC fixed the data */ ++ if(ecc_result) ++ *ecc_result = YAFFS_ECC_RESULT_FIXED; ++ dev->n_ecc_fixed++; ++ break; ++ ++ case -EBADMSG: ++ default: ++ /* MTD's ECC could not fix the data */ ++ dev->n_ecc_unfixed++; ++ if(ecc_result) ++ *ecc_result = YAFFS_ECC_RESULT_UNFIXED; ++ return YAFFS_FAIL; ++ } ++ ++ return YAFFS_OK; ++} ++ ++static int yaffs_mtd_erase(struct yaffs_dev *dev, int block_no) ++{ ++ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); ++ ++ loff_t addr; ++ struct erase_info ei; ++ int retval = 0; ++ u32 block_size; ++ ++ block_size = dev->param.total_bytes_per_chunk * ++ dev->param.chunks_per_block; ++ addr = ((loff_t) block_no) * block_size; ++ ++ ei.mtd = mtd; ++ ei.addr = addr; ++ ei.len = block_size; ++ ei.time = 1000; ++ ei.retries = 2; ++ ei.callback = NULL; ++ ei.priv = (u_long) dev; ++ ++ retval = mtd_erase(mtd, &ei); ++ ++ if (retval == 0) ++ return YAFFS_OK; ++ ++ return YAFFS_FAIL; ++} ++ ++static int yaffs_mtd_mark_bad(struct yaffs_dev *dev, int block_no) ++{ ++ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); ++ int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk; ++ int retval; ++ ++ yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no); ++ ++ retval = mtd_block_markbad(mtd, (loff_t) blocksize * block_no); ++ return (retval) ? YAFFS_FAIL : YAFFS_OK; ++} ++ ++static int yaffs_mtd_check_bad(struct yaffs_dev *dev, int block_no) ++{ ++ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); ++ int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk; ++ int retval; ++ ++ yaffs_trace(YAFFS_TRACE_MTD, "checking block %d bad", block_no); ++ ++ retval = mtd_block_isbad(mtd, (loff_t) blocksize * block_no); ++ return (retval) ? YAFFS_FAIL : YAFFS_OK; ++} ++ ++static int yaffs_mtd_initialise(struct yaffs_dev *dev) ++{ ++ return YAFFS_OK; ++} ++ ++static int yaffs_mtd_deinitialise(struct yaffs_dev *dev) ++{ ++ return YAFFS_OK; ++} ++ ++ ++void yaffs_mtd_drv_install(struct yaffs_dev *dev) ++{ ++ struct yaffs_driver *drv = &dev->drv; ++ ++ drv->drv_write_chunk_fn = yaffs_mtd_write; ++ drv->drv_read_chunk_fn = yaffs_mtd_read; ++ drv->drv_erase_fn = yaffs_mtd_erase; ++ drv->drv_mark_bad_fn = yaffs_mtd_mark_bad; ++ drv->drv_check_bad_fn = yaffs_mtd_check_bad; ++ drv->drv_initialise_fn = yaffs_mtd_initialise; ++ drv->drv_deinitialise_fn = yaffs_mtd_deinitialise; ++} ++ ++ ++struct mtd_info * yaffs_get_mtd_device(dev_t sdev) ++{ ++ struct mtd_info *mtd; ++ ++ mtd = yaffs_get_mtd_device(sdev); ++ ++ /* Check it's an mtd device..... */ ++ if (MAJOR(sdev) != MTD_BLOCK_MAJOR) ++ return NULL; /* This isn't an mtd device */ ++ ++ /* Check it's NAND */ ++ if (mtd->type != MTD_NANDFLASH) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs: MTD device is not NAND it's type %d", ++ mtd->type); ++ return NULL; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_OS, " %s %d", WRITE_SIZE_STR, WRITE_SIZE(mtd)); ++ yaffs_trace(YAFFS_TRACE_OS, " oobsize %d", mtd->oobsize); ++ yaffs_trace(YAFFS_TRACE_OS, " erasesize %d", mtd->erasesize); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) ++ yaffs_trace(YAFFS_TRACE_OS, " size %u", mtd->size); ++#else ++ yaffs_trace(YAFFS_TRACE_OS, " size %lld", mtd->size); ++#endif ++ ++ return mtd; ++} ++ ++int yaffs_verify_mtd(struct mtd_info *mtd, int yaffs_version, int inband_tags) ++{ ++ if (yaffs_version == 2) { ++ if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE || ++ mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) && ++ !inband_tags) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "MTD device does not have the right page sizes" ++ ); ++ return -1; ++ } ++ } else { ++ if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK || ++ mtd->oobsize != YAFFS_BYTES_PER_SPARE) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "MTD device does not support have the right page sizes" ++ ); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++void yaffs_put_mtd_device(struct mtd_info *mtd) ++{ ++ if(mtd) ++ put_mtd_device(mtd); ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_mtdif.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_mtdif.h.patch new file mode 100644 index 00000000..44999bca --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_mtdif.h.patch @@ -0,0 +1,28 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_mtdif.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_mtdif.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,25 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_MTDIF_H__ ++#define __YAFFS_MTDIF_H__ ++ ++#include "yaffs_guts.h" ++ ++void yaffs_mtd_drv_install(struct yaffs_dev *dev); ++struct mtd_info * yaffs_get_mtd_device(dev_t sdev); ++void yaffs_put_mtd_device(struct mtd_info *mtd); ++int yaffs_verify_mtd(struct mtd_info *mtd, int yaffs_version, int inband_tags); ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nameval.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nameval.c.patch new file mode 100644 index 00000000..9e64ad5f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nameval.c.patch @@ -0,0 +1,233 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_nameval.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_nameval.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,230 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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. ++ */ ++ ++/* ++ * This simple implementation of a name-value store assumes a small number of ++* values and fits into a small finite buffer. ++ * ++ * Each attribute is stored as a record: ++ * sizeof(size) bytes record size. ++ * strnlen+1 bytes name null terminated. ++ * nbytes value. ++ * ---------- ++ * total size stored in record size ++ * ++ * This code has not been tested with unicode yet. ++ */ ++ ++#include "yaffs_nameval.h" ++#include "yaffs_guts.h" ++#include "yportenv.h" ++#include "yaffs_endian.h" ++ ++static int nval_find(struct yaffs_dev *dev, ++ const char *xb, int xb_size, const YCHAR *name, ++ int *exist_size) ++{ ++ int pos = 0; ++ s32 size; ++ ++ memcpy(&size, xb, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ ++ while (size > 0 && (size < xb_size) && (pos + size < xb_size)) { ++ if (!strncmp((YCHAR *) (xb + pos + sizeof(size)), ++ name, size)) { ++ if (exist_size) ++ *exist_size = size; ++ return pos; ++ } ++ pos += size; ++ if (pos < (int)(xb_size - sizeof(size))) { ++ memcpy(&size, xb + pos, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ ++ } else ++ size = 0; ++ } ++ if (exist_size) ++ *exist_size = 0; ++ return -ENODATA; ++} ++ ++static int nval_used(struct yaffs_dev *dev, const char *xb, int xb_size) ++{ ++ int pos = 0; ++ s32 size; ++ ++ memcpy(&size, xb + pos, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ ++ while (size > 0 && (size < xb_size) && (pos + size < xb_size)) { ++ pos += size; ++ if (pos < (int)(xb_size - sizeof(size))) { ++ memcpy(&size, xb + pos, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ } else ++ size = 0; ++ } ++ return pos; ++} ++ ++int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR *name) ++{ ++ int pos = nval_find(dev, xb, xb_size, name, NULL); ++ s32 size; ++ ++ if (pos < 0 || pos >= xb_size) ++ return -ENODATA; ++ ++ /* Find size, shift rest over this record, ++ * then zero out the rest of buffer */ ++ memcpy(&size, xb + pos, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ ++ memcpy(xb + pos, xb + pos + size, xb_size - (pos + size)); ++ memset(xb + (xb_size - size), 0, size); ++ return 0; ++} ++ ++int nval_set(struct yaffs_dev *dev, ++ char *xb, int xb_size, const YCHAR *name, const char *buf, ++ int bsize, int flags) ++{ ++ int pos; ++ int namelen = strnlen(name, xb_size); ++ int size_exist = 0; ++ int space; ++ int start; ++ s32 reclen; ++ s32 reclen_endianised; ++ ++ pos = nval_find(dev, xb, xb_size, name, &size_exist); ++ ++ if (flags & XATTR_CREATE && pos >= 0) ++ return -EEXIST; ++ if (flags & XATTR_REPLACE && pos < 0) ++ return -ENODATA; ++ ++ start = nval_used(dev, xb, xb_size); ++ space = xb_size - start + size_exist; ++ ++ reclen = (sizeof(reclen) + namelen + 1 + bsize); ++ ++ if (reclen > space) ++ return -ENOSPC; ++ ++ if (pos >= 0) { ++ /* Exists, so delete it. */ ++ nval_del(dev, xb, xb_size, name); ++ start = nval_used(dev, xb, xb_size); ++ } ++ ++ pos = start; ++ ++ reclen_endianised = reclen; ++ yaffs_do_endian_s32(dev, &reclen_endianised); ++ memcpy(xb + pos, &reclen_endianised, sizeof(reclen_endianised)); ++ pos += sizeof(reclen_endianised); ++ strncpy((YCHAR *) (xb + pos), name, reclen); ++ pos += (namelen + 1); ++ memcpy(xb + pos, buf, bsize); ++ return 0; ++} ++ ++int nval_get(struct yaffs_dev *dev, ++ const char *xb, int xb_size, const YCHAR * name, char *buf, ++ int bsize) ++{ ++ int pos = nval_find(dev, xb, xb_size, name, NULL); ++ s32 size; ++ ++ if (pos >= 0 && pos < xb_size) { ++ ++ memcpy(&size, xb + pos, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ pos += sizeof(size); /* advance past record length */ ++ size -= sizeof(size); ++ ++ /* Advance over name string */ ++ while (xb[pos] && size > 0 && pos < xb_size) { ++ pos++; ++ size--; ++ } ++ /*Advance over NUL */ ++ pos++; ++ size--; ++ ++ /* If bsize is zero then this is a size query. ++ * Return the size, but don't copy. ++ */ ++ if (!bsize) ++ return size; ++ ++ if (size <= bsize) { ++ memcpy(buf, xb + pos, size); ++ return size; ++ } ++ } ++ if (pos >= 0) ++ return -ERANGE; ++ ++ return -ENODATA; ++} ++ ++int nval_list(struct yaffs_dev *dev, const char *xb, int xb_size, char *buf, int bsize) ++{ ++ int pos = 0; ++ s32 size; ++ int name_len; ++ int ncopied = 0; ++ int filled = 0; ++ ++ memcpy(&size, xb + pos, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ ++ while (size > (int)(sizeof(size)) && ++ size <= xb_size && ++ (pos + size) < xb_size && ++ !filled) { ++ pos += sizeof(size); ++ size -= sizeof(size); ++ name_len = strnlen((YCHAR *) (xb + pos), size); ++ if (ncopied + name_len + 1 < bsize) { ++ memcpy(buf, xb + pos, name_len * sizeof(YCHAR)); ++ buf += name_len; ++ *buf = '\0'; ++ buf++; ++ if (sizeof(YCHAR) > 1) { ++ *buf = '\0'; ++ buf++; ++ } ++ ncopied += (name_len + 1); ++ } else { ++ filled = 1; ++ } ++ pos += size; ++ if (pos < (int)(xb_size - sizeof(size))) { ++ memcpy(&size, xb + pos, sizeof(size)); ++ yaffs_do_endian_s32(dev, &size); ++ } ++ else ++ size = 0; ++ } ++ return ncopied; ++} ++ ++int nval_hasvalues(struct yaffs_dev *dev, const char *xb, int xb_size) ++{ ++ return nval_used(dev, xb, xb_size) > 0; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nameval.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nameval.h.patch new file mode 100644 index 00000000..b4c18062 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nameval.h.patch @@ -0,0 +1,36 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_nameval.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_nameval.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,33 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __NAMEVAL_H__ ++#define __NAMEVAL_H__ ++ ++#include "yportenv.h" ++ ++struct yaffs_dev; ++ ++int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR * name); ++int nval_set(struct yaffs_dev *dev, ++ char *xb, int xb_size, const YCHAR * name, const char *buf, ++ int bsize, int flags); ++int nval_get(struct yaffs_dev *dev, ++ const char *xb, int xb_size, const YCHAR * name, char *buf, ++ int bsize); ++int nval_list(struct yaffs_dev *dev, ++ const char *xb, int xb_size, char *buf, int bsize); ++int nval_hasvalues(struct yaffs_dev *dev, const char *xb, int xb_size); ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nand.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nand.c.patch new file mode 100644 index 00000000..01643f2d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nand.c.patch @@ -0,0 +1,125 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_nand.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_nand.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,122 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_nand.h" ++#include "yaffs_tagscompat.h" ++ ++#include "yaffs_getblockinfo.h" ++#include "yaffs_summary.h" ++ ++static int apply_chunk_offset(struct yaffs_dev *dev, int chunk) ++{ ++ return chunk - dev->chunk_offset; ++} ++ ++int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, ++ u8 *buffer, struct yaffs_ext_tags *tags) ++{ ++ int result; ++ struct yaffs_ext_tags local_tags; ++ int flash_chunk = apply_chunk_offset(dev, nand_chunk); ++ ++ dev->n_page_reads++; ++ ++ /* If there are no tags provided use local tags. */ ++ if (!tags) ++ tags = &local_tags; ++ ++ result = dev->tagger.read_chunk_tags_fn(dev, flash_chunk, buffer, tags); ++ if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) { ++ ++ struct yaffs_block_info *bi; ++ bi = yaffs_get_block_info(dev, ++ nand_chunk / ++ dev->param.chunks_per_block); ++ yaffs_handle_chunk_error(dev, bi); ++ } ++ return result; ++} ++ ++int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, ++ int nand_chunk, ++ const u8 *buffer, struct yaffs_ext_tags *tags) ++{ ++ int result; ++ int flash_chunk = apply_chunk_offset(dev, nand_chunk); ++ ++ dev->n_page_writes++; ++ ++ if (!tags) { ++ yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags"); ++ BUG(); ++ return YAFFS_FAIL; ++ } ++ ++ tags->seq_number = dev->seq_number; ++ tags->chunk_used = 1; ++ yaffs_trace(YAFFS_TRACE_WRITE, ++ "Writing chunk %d tags %d %d", ++ nand_chunk, tags->obj_id, tags->chunk_id); ++ ++ result = dev->tagger.write_chunk_tags_fn(dev, flash_chunk, ++ buffer, tags); ++ ++ yaffs_summary_add(dev, tags, nand_chunk); ++ ++ return result; ++} ++ ++int yaffs_mark_bad(struct yaffs_dev *dev, int block_no) ++{ ++ block_no -= dev->block_offset; ++ dev->n_bad_markings++; ++ ++ if (dev->param.disable_bad_block_marking) ++ return YAFFS_OK; ++ ++ return dev->tagger.mark_bad_fn(dev, block_no); ++} ++ ++ ++int yaffs_query_init_block_state(struct yaffs_dev *dev, ++ int block_no, ++ enum yaffs_block_state *state, ++ u32 *seq_number) ++{ ++ block_no -= dev->block_offset; ++ return dev->tagger.query_block_fn(dev, block_no, state, seq_number); ++} ++ ++int yaffs_erase_block(struct yaffs_dev *dev, int block_no) ++{ ++ int result; ++ ++ block_no -= dev->block_offset; ++ dev->n_erasures++; ++ result = dev->drv.drv_erase_fn(dev, block_no); ++ return result; ++} ++ ++int yaffs_init_nand(struct yaffs_dev *dev) ++{ ++ if (dev->drv.drv_initialise_fn) ++ return dev->drv.drv_initialise_fn(dev); ++ return YAFFS_OK; ++} ++ ++int yaffs_deinit_nand(struct yaffs_dev *dev) ++{ ++ if (dev->drv.drv_deinitialise_fn) ++ return dev->drv.drv_deinitialise_fn(dev); ++ return YAFFS_OK; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nand.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nand.h.patch new file mode 100644 index 00000000..b89015d4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_nand.h.patch @@ -0,0 +1,42 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_nand.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_nand.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,39 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_NAND_H__ ++#define __YAFFS_NAND_H__ ++#include "yaffs_guts.h" ++ ++int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, ++ u8 *buffer, struct yaffs_ext_tags *tags); ++ ++int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, ++ int nand_chunk, ++ const u8 *buffer, struct yaffs_ext_tags *tags); ++ ++int yaffs_mark_bad(struct yaffs_dev *dev, int block_no); ++ ++int yaffs_query_init_block_state(struct yaffs_dev *dev, ++ int block_no, ++ enum yaffs_block_state *state, ++ unsigned *seq_number); ++ ++int yaffs_erase_block(struct yaffs_dev *dev, int flash_block); ++ ++int yaffs_init_nand(struct yaffs_dev *dev); ++int yaffs_deinit_nand(struct yaffs_dev *dev); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags1.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags1.c.patch new file mode 100644 index 00000000..e715a817 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags1.c.patch @@ -0,0 +1,58 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_packedtags1.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_packedtags1.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,55 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_packedtags1.h" ++#include "yportenv.h" ++ ++static const u8 all_ff[20] = { ++ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff ++}; ++ ++void yaffs_pack_tags1(struct yaffs_packed_tags1 *pt, ++ const struct yaffs_ext_tags *t) ++{ ++ pt->chunk_id = t->chunk_id; ++ pt->serial_number = t->serial_number; ++ pt->n_bytes = t->n_bytes; ++ pt->obj_id = t->obj_id; ++ pt->ecc = 0; ++ pt->deleted = (t->is_deleted) ? 0 : 1; ++ pt->unused_stuff = 0; ++ pt->should_be_ff = 0xffffffff; ++} ++ ++void yaffs_unpack_tags1(struct yaffs_ext_tags *t, ++ const struct yaffs_packed_tags1 *pt) ++{ ++ if (memcmp(all_ff, pt, sizeof(struct yaffs_packed_tags1))) { ++ t->block_bad = 0; ++ if (pt->should_be_ff != 0xffffffff) ++ t->block_bad = 1; ++ t->chunk_used = 1; ++ t->obj_id = pt->obj_id; ++ t->chunk_id = pt->chunk_id; ++ t->n_bytes = pt->n_bytes; ++ t->ecc_result = YAFFS_ECC_RESULT_NO_ERROR; ++ t->is_deleted = (pt->deleted) ? 0 : 1; ++ t->serial_number = pt->serial_number; ++ } else { ++ memset(t, 0, sizeof(struct yaffs_ext_tags)); ++ } ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags1.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags1.h.patch new file mode 100644 index 00000000..c7b8867b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags1.h.patch @@ -0,0 +1,42 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_packedtags1.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_packedtags1.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,39 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++/* This is used to pack YAFFS1 tags, not YAFFS2 tags. */ ++ ++#ifndef __YAFFS_PACKEDTAGS1_H__ ++#define __YAFFS_PACKEDTAGS1_H__ ++ ++#include "yaffs_guts.h" ++ ++struct yaffs_packed_tags1 { ++ u32 chunk_id:20; ++ u32 serial_number:2; ++ u32 n_bytes:10; ++ u32 obj_id:18; ++ u32 ecc:12; ++ u32 deleted:1; ++ u32 unused_stuff:1; ++ unsigned should_be_ff; ++ ++}; ++ ++void yaffs_pack_tags1(struct yaffs_packed_tags1 *pt, ++ const struct yaffs_ext_tags *t); ++void yaffs_unpack_tags1(struct yaffs_ext_tags *t, ++ const struct yaffs_packed_tags1 *pt); ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags2.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags2.c.patch new file mode 100644 index 00000000..c70b8fb9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags2.c.patch @@ -0,0 +1,211 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_packedtags2.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_packedtags2.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,208 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_packedtags2.h" ++#include "yportenv.h" ++#include "yaffs_trace.h" ++#include "yaffs_endian.h" ++ ++/* This code packs a set of extended tags into a binary structure for ++ * NAND storage ++ */ ++ ++/* Some of the information is "extra" struff which can be packed in to ++ * speed scanning ++ * This is defined by having the EXTRA_HEADER_INFO_FLAG set. ++ */ ++ ++/* Extra flags applied to chunk_id */ ++ ++#define EXTRA_HEADER_INFO_FLAG 0x80000000 ++#define EXTRA_SHRINK_FLAG 0x40000000 ++#define EXTRA_SHADOWS_FLAG 0x20000000 ++#define EXTRA_SPARE_FLAGS 0x10000000 ++ ++#define ALL_EXTRA_FLAGS 0xf0000000 ++ ++/* Also, the top 4 bits of the object Id are set to the object type. */ ++#define EXTRA_OBJECT_TYPE_SHIFT (28) ++#define EXTRA_OBJECT_TYPE_MASK ((0x0f) << EXTRA_OBJECT_TYPE_SHIFT) ++ ++static void yaffs_dump_packed_tags2_tags_only( ++ const struct yaffs_packed_tags2_tags_only *ptt) ++{ ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "packed tags obj %d chunk %d byte %d seq %d", ++ ptt->obj_id, ptt->chunk_id, ptt->n_bytes, ptt->seq_number); ++} ++ ++static void yaffs_dump_packed_tags2(const struct yaffs_packed_tags2 *pt) ++{ ++ yaffs_dump_packed_tags2_tags_only(&pt->t); ++} ++ ++static void yaffs_dump_tags2(const struct yaffs_ext_tags *t) ++{ ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d", ++ t->ecc_result, t->block_bad, t->chunk_used, t->obj_id, ++ t->chunk_id, t->n_bytes, t->is_deleted, t->serial_number, ++ t->seq_number); ++ ++} ++ ++static int yaffs_check_tags_extra_packable(const struct yaffs_ext_tags *t) ++{ ++ if (t->chunk_id != 0 || !t->extra_available) ++ return 0; ++ ++ /* Check if the file size is too long to store */ ++ if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE && ++ (t->extra_file_size >> 31) != 0) ++ return 0; ++ return 1; ++} ++ ++void yaffs_pack_tags2_tags_only(struct yaffs_dev *dev, ++ struct yaffs_packed_tags2_tags_only *ptt, ++ const struct yaffs_ext_tags *t) ++{ ++ ptt->chunk_id = t->chunk_id; ++ ptt->seq_number = t->seq_number; ++ ptt->n_bytes = t->n_bytes; ++ ptt->obj_id = t->obj_id; ++ ++ /* Only store extra tags for object headers. ++ * If it is a file then only store if the file size is short\ ++ * enough to fit. ++ */ ++ if (yaffs_check_tags_extra_packable(t)) { ++ /* Store the extra header info instead */ ++ /* We save the parent object in the chunk_id */ ++ ptt->chunk_id = EXTRA_HEADER_INFO_FLAG | t->extra_parent_id; ++ if (t->extra_is_shrink) ++ ptt->chunk_id |= EXTRA_SHRINK_FLAG; ++ if (t->extra_shadows) ++ ptt->chunk_id |= EXTRA_SHADOWS_FLAG; ++ ++ ptt->obj_id &= ~EXTRA_OBJECT_TYPE_MASK; ++ ptt->obj_id |= (t->extra_obj_type << EXTRA_OBJECT_TYPE_SHIFT); ++ ++ if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK) ++ ptt->n_bytes = t->extra_equiv_id; ++ else if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE) ++ ptt->n_bytes = (unsigned) t->extra_file_size; ++ else ++ ptt->n_bytes = 0; ++ } ++ ++ yaffs_dump_packed_tags2_tags_only(ptt); ++ yaffs_dump_tags2(t); ++ yaffs_do_endian_packed_tags2(dev, ptt); ++} ++ ++void yaffs_pack_tags2(struct yaffs_dev *dev, ++ struct yaffs_packed_tags2 *pt, ++ const struct yaffs_ext_tags *t, int tags_ecc) ++{ ++ yaffs_pack_tags2_tags_only(dev, &pt->t, t); ++ ++ if (tags_ecc) ++ yaffs_ecc_calc_other((unsigned char *)&pt->t, ++ sizeof(struct yaffs_packed_tags2_tags_only), ++ &pt->ecc); ++} ++ ++void yaffs_unpack_tags2_tags_only(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *t, ++ struct yaffs_packed_tags2_tags_only *ptt_ptr) ++{ ++ struct yaffs_packed_tags2_tags_only ptt_copy = *ptt_ptr; ++ ++ memset(t, 0, sizeof(struct yaffs_ext_tags)); ++ ++ if (ptt_copy.seq_number == 0xffffffff) ++ return; ++ ++ yaffs_do_endian_packed_tags2(dev, &ptt_copy); ++ ++ t->block_bad = 0; ++ t->chunk_used = 1; ++ t->obj_id = ptt_copy.obj_id; ++ t->chunk_id = ptt_copy.chunk_id; ++ t->n_bytes = ptt_copy.n_bytes; ++ t->is_deleted = 0; ++ t->serial_number = 0; ++ t->seq_number = ptt_copy.seq_number; ++ ++ /* Do extra header info stuff */ ++ if (ptt_copy.chunk_id & EXTRA_HEADER_INFO_FLAG) { ++ t->chunk_id = 0; ++ t->n_bytes = 0; ++ ++ t->extra_available = 1; ++ t->extra_parent_id = ptt_copy.chunk_id & (~(ALL_EXTRA_FLAGS)); ++ t->extra_is_shrink = ptt_copy.chunk_id & EXTRA_SHRINK_FLAG ? 1 : 0; ++ t->extra_shadows = ptt_copy.chunk_id & EXTRA_SHADOWS_FLAG ? 1 : 0; ++ t->extra_obj_type = ptt_copy.obj_id >> EXTRA_OBJECT_TYPE_SHIFT; ++ t->obj_id &= ~EXTRA_OBJECT_TYPE_MASK; ++ ++ if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK) ++ t->extra_equiv_id = ptt_copy.n_bytes; ++ else ++ t->extra_file_size = ptt_copy.n_bytes; ++ } ++ yaffs_dump_packed_tags2_tags_only(ptt_ptr); ++ yaffs_dump_tags2(t); ++} ++ ++void yaffs_unpack_tags2(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *t, ++ struct yaffs_packed_tags2 *pt, ++ int tags_ecc) ++{ ++ enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_NO_ERROR; ++ ++ if (pt->t.seq_number != 0xffffffff && tags_ecc) { ++ /* Chunk is in use and we need to do ECC */ ++ ++ struct yaffs_ecc_other ecc; ++ int result; ++ yaffs_ecc_calc_other((unsigned char *)&pt->t, ++ sizeof(struct yaffs_packed_tags2_tags_only), ++ &ecc); ++ result = ++ yaffs_ecc_correct_other((unsigned char *)&pt->t, ++ sizeof(struct yaffs_packed_tags2_tags_only), ++ &pt->ecc, &ecc); ++ switch (result) { ++ case 0: ++ ecc_result = YAFFS_ECC_RESULT_NO_ERROR; ++ break; ++ case 1: ++ ecc_result = YAFFS_ECC_RESULT_FIXED; ++ break; ++ case -1: ++ ecc_result = YAFFS_ECC_RESULT_UNFIXED; ++ break; ++ default: ++ ecc_result = YAFFS_ECC_RESULT_UNKNOWN; ++ } ++ } ++ yaffs_unpack_tags2_tags_only(dev, t, &pt->t); ++ ++ t->ecc_result = ecc_result; ++ ++ yaffs_dump_packed_tags2(pt); ++ yaffs_dump_tags2(t); ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags2.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags2.h.patch new file mode 100644 index 00000000..fcb0f967 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_packedtags2.h.patch @@ -0,0 +1,54 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_packedtags2.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_packedtags2.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,51 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++/* This is used to pack YAFFS2 tags, not YAFFS1tags. */ ++ ++#ifndef __YAFFS_PACKEDTAGS2_H__ ++#define __YAFFS_PACKEDTAGS2_H__ ++ ++#include "yaffs_guts.h" ++#include "yaffs_ecc.h" ++ ++struct yaffs_packed_tags2_tags_only { ++ unsigned seq_number; ++ unsigned obj_id; ++ unsigned chunk_id; ++ unsigned n_bytes; ++}; ++ ++struct yaffs_packed_tags2 { ++ struct yaffs_packed_tags2_tags_only t; ++ struct yaffs_ecc_other ecc; ++}; ++ ++/* Full packed tags with ECC, used for oob tags */ ++void yaffs_pack_tags2(struct yaffs_dev *dev, ++ struct yaffs_packed_tags2 *pt, ++ const struct yaffs_ext_tags *t, int tags_ecc); ++void yaffs_unpack_tags2(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt, ++ int tags_ecc); ++ ++/* Only the tags part (no ECC for use with inband tags */ ++void yaffs_pack_tags2_tags_only(struct yaffs_dev *dev, ++ struct yaffs_packed_tags2_tags_only *pt, ++ const struct yaffs_ext_tags *t); ++void yaffs_unpack_tags2_tags_only(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *t, ++ struct yaffs_packed_tags2_tags_only *pt); ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_summary.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_summary.c.patch new file mode 100644 index 00000000..4d386b38 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_summary.c.patch @@ -0,0 +1,313 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_summary.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_summary.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,310 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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. ++ */ ++ ++/* Summaries write the useful part of the tags for the chunks in a block into an ++ * an array which is written to the last n chunks of the block. ++ * Reading the summaries gives all the tags for the block in one read. Much ++ * faster. ++ * ++ * Chunks holding summaries are marked with tags making it look like ++ * they are part of a fake file. ++ * ++ * The summary could also be used during gc. ++ * ++ */ ++ ++#include "yaffs_summary.h" ++#include "yaffs_packedtags2.h" ++#include "yaffs_nand.h" ++#include "yaffs_getblockinfo.h" ++#include "yaffs_bitmap.h" ++ ++/* ++ * The summary is built up in an array of summary tags. ++ * This gets written to the last one or two (maybe more) chunks in a block. ++ * A summary header is written as the first part of each chunk of summary data. ++ * The summary header must match or the summary is rejected. ++ */ ++ ++/* Summary tags don't need the sequence number because that is redundant. */ ++struct yaffs_summary_tags { ++ unsigned obj_id; ++ unsigned chunk_id; ++ unsigned n_bytes; ++}; ++ ++/* Summary header */ ++struct yaffs_summary_header { ++ unsigned version; /* Must match current version */ ++ unsigned block; /* Must be this block */ ++ unsigned seq; /* Must be this sequence number */ ++ unsigned sum; /* Just add up all the bytes in the tags */ ++}; ++ ++ ++static void yaffs_summary_clear(struct yaffs_dev *dev) ++{ ++ if (!dev->sum_tags) ++ return; ++ memset(dev->sum_tags, 0, dev->chunks_per_summary * ++ sizeof(struct yaffs_summary_tags)); ++} ++ ++ ++void yaffs_summary_deinit(struct yaffs_dev *dev) ++{ ++ kfree(dev->sum_tags); ++ dev->sum_tags = NULL; ++ kfree(dev->gc_sum_tags); ++ dev->gc_sum_tags = NULL; ++ dev->chunks_per_summary = 0; ++} ++ ++int yaffs_summary_init(struct yaffs_dev *dev) ++{ ++ int sum_bytes; ++ int chunks_used; /* Number of chunks used by summary */ ++ int sum_tags_bytes; ++ ++ sum_bytes = dev->param.chunks_per_block * ++ sizeof(struct yaffs_summary_tags); ++ ++ chunks_used = (sum_bytes + dev->data_bytes_per_chunk - 1)/ ++ (dev->data_bytes_per_chunk - ++ sizeof(struct yaffs_summary_header)); ++ ++ dev->chunks_per_summary = dev->param.chunks_per_block - chunks_used; ++ sum_tags_bytes = sizeof(struct yaffs_summary_tags) * ++ dev->chunks_per_summary; ++ dev->sum_tags = kmalloc(sum_tags_bytes, GFP_NOFS); ++ dev->gc_sum_tags = kmalloc(sum_tags_bytes, GFP_NOFS); ++ if (!dev->sum_tags || !dev->gc_sum_tags) { ++ yaffs_summary_deinit(dev); ++ return YAFFS_FAIL; ++ } ++ ++ yaffs_summary_clear(dev); ++ ++ return YAFFS_OK; ++} ++ ++static unsigned yaffs_summary_sum(struct yaffs_dev *dev) ++{ ++ u8 *sum_buffer = (u8 *)dev->sum_tags; ++ int i; ++ unsigned sum = 0; ++ ++ i = sizeof(struct yaffs_summary_tags) * ++ dev->chunks_per_summary; ++ while (i > 0) { ++ sum += *sum_buffer; ++ sum_buffer++; ++ i--; ++ } ++ ++ return sum; ++} ++ ++static int yaffs_summary_write(struct yaffs_dev *dev, int blk) ++{ ++ struct yaffs_ext_tags tags; ++ u8 *buffer; ++ u8 *sum_buffer = (u8 *)dev->sum_tags; ++ int n_bytes; ++ int chunk_in_nand; ++ int chunk_in_block; ++ int result; ++ int this_tx; ++ struct yaffs_summary_header hdr; ++ int sum_bytes_per_chunk = dev->data_bytes_per_chunk - sizeof(hdr); ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk); ++ ++ buffer = yaffs_get_temp_buffer(dev); ++ n_bytes = sizeof(struct yaffs_summary_tags) * ++ dev->chunks_per_summary; ++ memset(&tags, 0, sizeof(struct yaffs_ext_tags)); ++ tags.obj_id = YAFFS_OBJECTID_SUMMARY; ++ tags.chunk_id = 1; ++ chunk_in_block = dev->chunks_per_summary; ++ chunk_in_nand = dev->alloc_block * dev->param.chunks_per_block + ++ dev->chunks_per_summary; ++ hdr.version = YAFFS_SUMMARY_VERSION; ++ hdr.block = blk; ++ hdr.seq = bi->seq_number; ++ hdr.sum = yaffs_summary_sum(dev); ++ ++ do { ++ this_tx = n_bytes; ++ if (this_tx > sum_bytes_per_chunk) ++ this_tx = sum_bytes_per_chunk; ++ memcpy(buffer, &hdr, sizeof(hdr)); ++ memcpy(buffer + sizeof(hdr), sum_buffer, this_tx); ++ tags.n_bytes = this_tx + sizeof(hdr); ++ result = yaffs_wr_chunk_tags_nand(dev, chunk_in_nand, ++ buffer, &tags); ++ ++ if (result != YAFFS_OK) ++ break; ++ yaffs_set_chunk_bit(dev, blk, chunk_in_block); ++ bi->pages_in_use++; ++ dev->n_free_chunks--; ++ ++ n_bytes -= this_tx; ++ sum_buffer += this_tx; ++ chunk_in_nand++; ++ chunk_in_block++; ++ tags.chunk_id++; ++ } while (result == YAFFS_OK && n_bytes > 0); ++ yaffs_release_temp_buffer(dev, buffer); ++ ++ ++ if (result == YAFFS_OK) ++ bi->has_summary = 1; ++ ++ ++ return result; ++} ++ ++int yaffs_summary_read(struct yaffs_dev *dev, ++ struct yaffs_summary_tags *st, ++ int blk) ++{ ++ struct yaffs_ext_tags tags; ++ u8 *buffer; ++ u8 *sum_buffer = (u8 *)st; ++ int n_bytes; ++ u32 chunk_id; ++ int chunk_in_nand; ++ int chunk_in_block; ++ int result; ++ int this_tx; ++ struct yaffs_summary_header hdr; ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk); ++ int sum_bytes_per_chunk = dev->data_bytes_per_chunk - sizeof(hdr); ++ ++ buffer = yaffs_get_temp_buffer(dev); ++ n_bytes = sizeof(struct yaffs_summary_tags) * dev->chunks_per_summary; ++ chunk_in_block = dev->chunks_per_summary; ++ chunk_in_nand = blk * dev->param.chunks_per_block + ++ dev->chunks_per_summary; ++ chunk_id = 1; ++ do { ++ this_tx = n_bytes; ++ if (this_tx > sum_bytes_per_chunk) ++ this_tx = sum_bytes_per_chunk; ++ result = yaffs_rd_chunk_tags_nand(dev, chunk_in_nand, ++ buffer, &tags); ++ ++ if (tags.chunk_id != chunk_id || ++ tags.obj_id != YAFFS_OBJECTID_SUMMARY || ++ tags.chunk_used == 0 || ++ tags.ecc_result > YAFFS_ECC_RESULT_FIXED || ++ tags.n_bytes != (this_tx + sizeof(hdr))) ++ result = YAFFS_FAIL; ++ if (result != YAFFS_OK) ++ break; ++ ++ if (st == dev->sum_tags) { ++ /* If we're scanning then update the block info */ ++ yaffs_set_chunk_bit(dev, blk, chunk_in_block); ++ bi->pages_in_use++; ++ } ++ memcpy(&hdr, buffer, sizeof(hdr)); ++ memcpy(sum_buffer, buffer + sizeof(hdr), this_tx); ++ n_bytes -= this_tx; ++ sum_buffer += this_tx; ++ chunk_in_nand++; ++ chunk_in_block++; ++ chunk_id++; ++ } while (result == YAFFS_OK && n_bytes > 0); ++ yaffs_release_temp_buffer(dev, buffer); ++ ++ if (result == YAFFS_OK) { ++ /* Verify header */ ++ if (hdr.version != YAFFS_SUMMARY_VERSION || ++ hdr.seq != bi->seq_number || ++ hdr.sum != yaffs_summary_sum(dev)) ++ result = YAFFS_FAIL; ++ } ++ ++ if (st == dev->sum_tags && result == YAFFS_OK) ++ bi->has_summary = 1; ++ ++ return result; ++} ++ ++int yaffs_summary_add(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *tags, ++ int chunk_in_nand) ++{ ++ struct yaffs_packed_tags2_tags_only tags_only; ++ struct yaffs_summary_tags *sum_tags; ++ int block_in_nand = chunk_in_nand / dev->param.chunks_per_block; ++ int chunk_in_block = chunk_in_nand % dev->param.chunks_per_block; ++ ++ if (!dev->sum_tags) ++ return YAFFS_OK; ++ ++ if (chunk_in_block >= 0 && chunk_in_block < dev->chunks_per_summary) { ++ yaffs_pack_tags2_tags_only(dev, &tags_only, tags); ++ sum_tags = &dev->sum_tags[chunk_in_block]; ++ ++ sum_tags->chunk_id = tags_only.chunk_id; ++ sum_tags->n_bytes = tags_only.n_bytes; ++ sum_tags->obj_id = tags_only.obj_id; ++ ++ if (chunk_in_block == dev->chunks_per_summary - 1) { ++ /* Time to write out the summary */ ++ yaffs_summary_write(dev, block_in_nand); ++ yaffs_summary_clear(dev); ++ yaffs_skip_rest_of_block(dev); ++ } ++ } ++ return YAFFS_OK; ++} ++ ++int yaffs_summary_fetch(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *tags, ++ int chunk_in_block) ++{ ++ struct yaffs_packed_tags2_tags_only tags_only; ++ struct yaffs_summary_tags *sum_tags; ++ if (chunk_in_block >= 0 && chunk_in_block < dev->chunks_per_summary) { ++ sum_tags = &dev->sum_tags[chunk_in_block]; ++ tags_only.chunk_id = sum_tags->chunk_id; ++ tags_only.n_bytes = sum_tags->n_bytes; ++ tags_only.obj_id = sum_tags->obj_id; ++ yaffs_unpack_tags2_tags_only(dev, tags, &tags_only); ++ return YAFFS_OK; ++ } ++ return YAFFS_FAIL; ++} ++ ++void yaffs_summary_gc(struct yaffs_dev *dev, int blk) ++{ ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk); ++ u32 i; ++ ++ if (!bi->has_summary) ++ return; ++ ++ for (i = dev->chunks_per_summary; ++ i < dev->param.chunks_per_block; ++ i++) { ++ if (yaffs_check_chunk_bit(dev, blk, i)) { ++ yaffs_clear_chunk_bit(dev, blk, i); ++ bi->pages_in_use--; ++ dev->n_free_chunks++; ++ } ++ } ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_summary.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_summary.h.patch new file mode 100644 index 00000000..6832a7c8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_summary.h.patch @@ -0,0 +1,40 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_summary.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_summary.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,37 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_SUMMARY_H__ ++#define __YAFFS_SUMMARY_H__ ++ ++#include "yaffs_packedtags2.h" ++ ++ ++int yaffs_summary_init(struct yaffs_dev *dev); ++void yaffs_summary_deinit(struct yaffs_dev *dev); ++ ++int yaffs_summary_add(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *tags, ++ int chunk_in_block); ++int yaffs_summary_fetch(struct yaffs_dev *dev, ++ struct yaffs_ext_tags *tags, ++ int chunk_in_block); ++int yaffs_summary_read(struct yaffs_dev *dev, ++ struct yaffs_summary_tags *st, ++ int blk); ++void yaffs_summary_gc(struct yaffs_dev *dev, int blk); ++ ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagscompat.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagscompat.c.patch new file mode 100644 index 00000000..ed6fbbb1 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagscompat.c.patch @@ -0,0 +1,403 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_tagscompat.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_tagscompat.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,400 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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. ++ * ++ * This file handles yaffs1-style tags to allow compatibility with Yaffs1 style ++ * flash layouts. ++ */ ++ ++#include "yaffs_guts.h" ++#include "yaffs_tagscompat.h" ++#include "yaffs_ecc.h" ++#include "yaffs_getblockinfo.h" ++#include "yaffs_trace.h" ++#include "yaffs_endian.h" ++ ++static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk); ++ ++ ++/********** Tags ECC calculations *********/ ++ ++void yaffs_calc_tags_ecc(struct yaffs_tags *tags) ++{ ++ /* Calculate an ecc */ ++ unsigned char *b = ((union yaffs_tags_union *)tags)->as_bytes; ++ unsigned i, j; ++ unsigned ecc = 0; ++ unsigned bit = 0; ++ ++ tags->ecc = 0; ++ ++ for (i = 0; i < 8; i++) { ++ for (j = 1; j & 0xff; j <<= 1) { ++ bit++; ++ if (b[i] & j) ++ ecc ^= bit; ++ } ++ } ++ tags->ecc = ecc; ++} ++ ++int yaffs_check_tags_ecc(struct yaffs_tags *tags) ++{ ++ unsigned ecc = tags->ecc; ++ ++ yaffs_calc_tags_ecc(tags); ++ ++ ecc ^= tags->ecc; ++ ++ if (ecc && ecc <= 64) { ++ /* TODO: Handle the failure better. Retire? */ ++ unsigned char *b = ((union yaffs_tags_union *)tags)->as_bytes; ++ ++ ecc--; ++ ++ b[ecc / 8] ^= (1 << (ecc & 7)); ++ ++ /* Now recvalc the ecc */ ++ yaffs_calc_tags_ecc(tags); ++ ++ return 1; /* recovered error */ ++ } else if (ecc) { ++ /* Wierd ecc failure value */ ++ /* TODO Need to do somethiong here */ ++ return -1; /* unrecovered error */ ++ } ++ return 0; ++} ++ ++/********** Tags **********/ ++ ++/* ++ * During tags storing/retireval we use a copy of the tags so that ++ * we can modify the endian etc without damaging the previous structure. ++ */ ++static void yaffs_load_tags_to_spare(struct yaffs_dev *dev, ++ struct yaffs_spare *spare_ptr, ++ struct yaffs_tags *tags_ptr) ++{ ++ union yaffs_tags_union *tu_ptr = (union yaffs_tags_union *)tags_ptr; ++ union yaffs_tags_union tags_stored = *tu_ptr; ++ ++ yaffs_calc_tags_ecc(&tags_stored.as_tags); ++ ++ yaffs_do_endian_u32(dev, &tags_stored.as_u32[0]); ++ yaffs_do_endian_u32(dev, &tags_stored.as_u32[1]); ++ ++ spare_ptr->tb0 = tags_stored.as_bytes[0]; ++ spare_ptr->tb1 = tags_stored.as_bytes[1]; ++ spare_ptr->tb2 = tags_stored.as_bytes[2]; ++ spare_ptr->tb3 = tags_stored.as_bytes[3]; ++ spare_ptr->tb4 = tags_stored.as_bytes[4]; ++ spare_ptr->tb5 = tags_stored.as_bytes[5]; ++ spare_ptr->tb6 = tags_stored.as_bytes[6]; ++ spare_ptr->tb7 = tags_stored.as_bytes[7]; ++} ++ ++static void yaffs_get_tags_from_spare(struct yaffs_dev *dev, ++ struct yaffs_spare *spare_ptr, ++ struct yaffs_tags *tags_ptr) ++{ ++ union yaffs_tags_union *tu = (union yaffs_tags_union *)tags_ptr; ++ union yaffs_tags_union tags_stored; ++ int result; ++ ++ tags_stored.as_bytes[0] = spare_ptr->tb0; ++ tags_stored.as_bytes[1] = spare_ptr->tb1; ++ tags_stored.as_bytes[2] = spare_ptr->tb2; ++ tags_stored.as_bytes[3] = spare_ptr->tb3; ++ tags_stored.as_bytes[4] = spare_ptr->tb4; ++ tags_stored.as_bytes[5] = spare_ptr->tb5; ++ tags_stored.as_bytes[6] = spare_ptr->tb6; ++ tags_stored.as_bytes[7] = spare_ptr->tb7; ++ ++ yaffs_do_endian_u32(dev, &tags_stored.as_u32[0]); ++ yaffs_do_endian_u32(dev, &tags_stored.as_u32[1]); ++ ++ *tu = tags_stored; ++ ++ result = yaffs_check_tags_ecc(tags_ptr); ++ if (result > 0) ++ dev->n_tags_ecc_fixed++; ++ else if (result < 0) ++ dev->n_tags_ecc_unfixed++; ++} ++ ++static void yaffs_spare_init(struct yaffs_spare *spare) ++{ ++ memset(spare, 0xff, sizeof(struct yaffs_spare)); ++} ++ ++static int yaffs_wr_nand(struct yaffs_dev *dev, ++ int nand_chunk, const u8 *data, ++ struct yaffs_spare *spare) ++{ ++ int data_size = dev->data_bytes_per_chunk; ++ ++ return dev->drv.drv_write_chunk_fn(dev, nand_chunk, ++ data, data_size, ++ (u8 *) spare, sizeof(*spare)); ++} ++ ++static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, ++ int nand_chunk, ++ u8 *data, ++ struct yaffs_spare *spare, ++ enum yaffs_ecc_result *ecc_result, ++ int correct_errors) ++{ ++ int ret_val; ++ struct yaffs_spare local_spare; ++ int data_size; ++ int spare_size; ++ int ecc_result1, ecc_result2; ++ u8 calc_ecc[3]; ++ ++ if (!spare) { ++ /* If we don't have a real spare, then we use a local one. */ ++ /* Need this for the calculation of the ecc */ ++ spare = &local_spare; ++ } ++ data_size = dev->data_bytes_per_chunk; ++ spare_size = sizeof(struct yaffs_spare); ++ ++ if (dev->param.use_nand_ecc) ++ return dev->drv.drv_read_chunk_fn(dev, nand_chunk, ++ data, data_size, ++ (u8 *) spare, spare_size, ++ ecc_result); ++ ++ ++ /* Handle the ECC at this level. */ ++ ++ ret_val = dev->drv.drv_read_chunk_fn(dev, nand_chunk, ++ data, data_size, ++ (u8 *)spare, spare_size, ++ NULL); ++ if (!data || !correct_errors) ++ return ret_val; ++ ++ /* Do ECC correction if needed. */ ++ yaffs_ecc_calc(data, calc_ecc); ++ ecc_result1 = yaffs_ecc_correct(data, spare->ecc1, calc_ecc); ++ yaffs_ecc_calc(&data[256], calc_ecc); ++ ecc_result2 = yaffs_ecc_correct(&data[256], spare->ecc2, calc_ecc); ++ ++ if (ecc_result1 > 0) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "**>>yaffs ecc error fix performed on chunk %d:0", ++ nand_chunk); ++ dev->n_ecc_fixed++; ++ } else if (ecc_result1 < 0) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "**>>yaffs ecc error unfixed on chunk %d:0", ++ nand_chunk); ++ dev->n_ecc_unfixed++; ++ } ++ ++ if (ecc_result2 > 0) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "**>>yaffs ecc error fix performed on chunk %d:1", ++ nand_chunk); ++ dev->n_ecc_fixed++; ++ } else if (ecc_result2 < 0) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "**>>yaffs ecc error unfixed on chunk %d:1", ++ nand_chunk); ++ dev->n_ecc_unfixed++; ++ } ++ ++ if (ecc_result1 || ecc_result2) { ++ /* We had a data problem on this page */ ++ yaffs_handle_rd_data_error(dev, nand_chunk); ++ } ++ ++ if (ecc_result1 < 0 || ecc_result2 < 0) ++ *ecc_result = YAFFS_ECC_RESULT_UNFIXED; ++ else if (ecc_result1 > 0 || ecc_result2 > 0) ++ *ecc_result = YAFFS_ECC_RESULT_FIXED; ++ else ++ *ecc_result = YAFFS_ECC_RESULT_NO_ERROR; ++ ++ return ret_val; ++} ++ ++/* ++ * Functions for robustisizing ++ */ ++ ++static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk) ++{ ++ int flash_block = nand_chunk / dev->param.chunks_per_block; ++ ++ /* Mark the block for retirement */ ++ yaffs_get_block_info(dev, flash_block + dev->block_offset)-> ++ needs_retiring = 1; ++ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, ++ "**>>Block %d marked for retirement", ++ flash_block); ++ ++ /* TODO: ++ * Just do a garbage collection on the affected block ++ * then retire the block ++ * NB recursion ++ */ ++} ++ ++static int yaffs_tags_compat_wr(struct yaffs_dev *dev, ++ int nand_chunk, ++ const u8 *data, const struct yaffs_ext_tags *ext_tags) ++{ ++ struct yaffs_spare spare; ++ struct yaffs_tags tags; ++ ++ yaffs_spare_init(&spare); ++ ++ if (ext_tags->is_deleted) ++ spare.page_status = 0; ++ else { ++ tags.obj_id = ext_tags->obj_id; ++ tags.chunk_id = ext_tags->chunk_id; ++ ++ tags.n_bytes_lsb = ext_tags->n_bytes & (1024 - 1); ++ ++ if (dev->data_bytes_per_chunk >= 1024) ++ tags.n_bytes_msb = (ext_tags->n_bytes >> 10) & 3; ++ else ++ tags.n_bytes_msb = 3; ++ ++ tags.serial_number = ext_tags->serial_number; ++ ++ if (!dev->param.use_nand_ecc && data) { ++ yaffs_ecc_calc(data, spare.ecc1); ++ yaffs_ecc_calc(&data[256], spare.ecc2); ++ } ++ ++ yaffs_load_tags_to_spare(dev, &spare, &tags); ++ } ++ return yaffs_wr_nand(dev, nand_chunk, data, &spare); ++} ++ ++static int yaffs_tags_compat_rd(struct yaffs_dev *dev, ++ int nand_chunk, ++ u8 *data, struct yaffs_ext_tags *ext_tags) ++{ ++ struct yaffs_spare spare; ++ struct yaffs_tags tags; ++ enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_UNKNOWN; ++ static struct yaffs_spare spare_ff; ++ static int init; ++ int deleted; ++ ++ if (!init) { ++ memset(&spare_ff, 0xff, sizeof(spare_ff)); ++ init = 1; ++ } ++ ++ if (!yaffs_rd_chunk_nand(dev, nand_chunk, ++ data, &spare, &ecc_result, 1)) ++ return YAFFS_FAIL; ++ ++ /* ext_tags may be NULL */ ++ if (!ext_tags) ++ return YAFFS_OK; ++ ++ deleted = (hweight8(spare.page_status) < 7) ? 1 : 0; ++ ++ ext_tags->is_deleted = deleted; ++ ext_tags->ecc_result = ecc_result; ++ ext_tags->block_bad = 0; /* We're reading it */ ++ /* therefore it is not a bad block */ ++ ext_tags->chunk_used = ++ memcmp(&spare_ff, &spare, sizeof(spare_ff)) ? 1 : 0; ++ ++ if (ext_tags->chunk_used) { ++ yaffs_get_tags_from_spare(dev, &spare, &tags); ++ ++ ext_tags->obj_id = tags.obj_id; ++ ext_tags->chunk_id = tags.chunk_id; ++ ext_tags->n_bytes = tags.n_bytes_lsb; ++ ++ if (dev->data_bytes_per_chunk >= 1024) ++ ext_tags->n_bytes |= ++ (((unsigned)tags.n_bytes_msb) << 10); ++ ++ ext_tags->serial_number = tags.serial_number; ++ } ++ ++ return YAFFS_OK; ++} ++ ++static int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block) ++{ ++ struct yaffs_spare spare; ++ ++ memset(&spare, 0xff, sizeof(struct yaffs_spare)); ++ ++ spare.block_status = 'Y'; ++ ++ yaffs_wr_nand(dev, flash_block * dev->param.chunks_per_block, NULL, ++ &spare); ++ yaffs_wr_nand(dev, flash_block * dev->param.chunks_per_block + 1, ++ NULL, &spare); ++ ++ return YAFFS_OK; ++} ++ ++static int yaffs_tags_compat_query_block(struct yaffs_dev *dev, ++ int block_no, ++ enum yaffs_block_state *state, ++ u32 *seq_number) ++{ ++ struct yaffs_spare spare0, spare1; ++ static struct yaffs_spare spare_ff; ++ static int init; ++ enum yaffs_ecc_result dummy; ++ ++ if (!init) { ++ memset(&spare_ff, 0xff, sizeof(spare_ff)); ++ init = 1; ++ } ++ ++ *seq_number = 0; ++ ++ /* Look for bad block markers in the first two chunks */ ++ yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block, ++ NULL, &spare0, &dummy, 0); ++ yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block + 1, ++ NULL, &spare1, &dummy, 0); ++ ++ if (hweight8(spare0.block_status & spare1.block_status) < 7) ++ *state = YAFFS_BLOCK_STATE_DEAD; ++ else if (memcmp(&spare_ff, &spare0, sizeof(spare_ff)) == 0) ++ *state = YAFFS_BLOCK_STATE_EMPTY; ++ else ++ *state = YAFFS_BLOCK_STATE_NEEDS_SCAN; ++ ++ return YAFFS_OK; ++} ++ ++void yaffs_tags_compat_install(struct yaffs_dev *dev) ++{ ++ if(dev->param.is_yaffs2) ++ return; ++ if(!dev->tagger.write_chunk_tags_fn) ++ dev->tagger.write_chunk_tags_fn = yaffs_tags_compat_wr; ++ if(!dev->tagger.read_chunk_tags_fn) ++ dev->tagger.read_chunk_tags_fn = yaffs_tags_compat_rd; ++ if(!dev->tagger.query_block_fn) ++ dev->tagger.query_block_fn = yaffs_tags_compat_query_block; ++ if(!dev->tagger.mark_bad_fn) ++ dev->tagger.mark_bad_fn = yaffs_tags_compat_mark_bad; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagscompat.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagscompat.h.patch new file mode 100644 index 00000000..0599f4a9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagscompat.h.patch @@ -0,0 +1,47 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_tagscompat.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_tagscompat.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,44 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_TAGSCOMPAT_H__ ++#define __YAFFS_TAGSCOMPAT_H__ ++ ++ ++#include "yaffs_guts.h" ++ ++#if 0 ++ ++ ++int yaffs_tags_compat_wr(struct yaffs_dev *dev, ++ int nand_chunk, ++ const u8 *data, const struct yaffs_ext_tags *tags); ++int yaffs_tags_compat_rd(struct yaffs_dev *dev, ++ int nand_chunk, ++ u8 *data, struct yaffs_ext_tags *tags); ++int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int block_no); ++int yaffs_tags_compat_query_block(struct yaffs_dev *dev, ++ int block_no, ++ enum yaffs_block_state *state, ++ u32 *seq_number); ++ ++#endif ++ ++ ++void yaffs_tags_compat_install(struct yaffs_dev *dev); ++void yaffs_calc_tags_ecc(struct yaffs_tags *tags); ++int yaffs_check_tags_ecc(struct yaffs_tags *tags); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagsmarshall.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagsmarshall.c.patch new file mode 100644 index 00000000..346d9d7c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagsmarshall.c.patch @@ -0,0 +1,209 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_tagsmarshall.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_tagsmarshall.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,206 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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. ++ * ++ * This file handles the marshalling (ie internal<-->external structure ++ * translation between the internal tags and the stored tags in Yaffs2-style ++ * tags storage. ++ */ ++ ++#include "yaffs_guts.h" ++#include "yaffs_trace.h" ++#include "yaffs_packedtags2.h" ++ ++static int yaffs_tags_marshall_write(struct yaffs_dev *dev, ++ int nand_chunk, const u8 *data, ++ const struct yaffs_ext_tags *tags) ++{ ++ struct yaffs_packed_tags2 pt; ++ int retval; ++ ++ int packed_tags_size = ++ dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt); ++ void *packed_tags_ptr = ++ dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt; ++ ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "yaffs_tags_marshall_write chunk %d data %p tags %p", ++ nand_chunk, data, tags); ++ ++ /* For yaffs2 writing there must be both data and tags. ++ * If we're using inband tags, then the tags are stuffed into ++ * the end of the data buffer. ++ */ ++ if (!data || !tags) ++ BUG(); ++ else if (dev->param.inband_tags) { ++ struct yaffs_packed_tags2_tags_only *pt2tp; ++ pt2tp = ++ (struct yaffs_packed_tags2_tags_only *)(data + ++ dev-> ++ data_bytes_per_chunk); ++ yaffs_pack_tags2_tags_only(dev, pt2tp, tags); ++ } else { ++ yaffs_pack_tags2(dev, &pt, tags, !dev->param.no_tags_ecc); ++ } ++ ++ retval = dev->drv.drv_write_chunk_fn(dev, nand_chunk, ++ data, dev->param.total_bytes_per_chunk, ++ (dev->param.inband_tags) ? NULL : packed_tags_ptr, ++ (dev->param.inband_tags) ? 0 : packed_tags_size); ++ ++ return retval; ++} ++ ++static int yaffs_tags_marshall_read(struct yaffs_dev *dev, ++ int nand_chunk, u8 *data, ++ struct yaffs_ext_tags *tags) ++{ ++ int retval = 0; ++ int local_data = 0; ++ u8 spare_buffer[100]; ++ enum yaffs_ecc_result ecc_result; ++ ++ struct yaffs_packed_tags2 pt; ++ ++ int packed_tags_size = ++ dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt); ++ void *packed_tags_ptr = ++ dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt; ++ ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "yaffs_tags_marshall_read chunk %d data %p tags %p", ++ nand_chunk, data, tags); ++ ++ if (dev->param.inband_tags) { ++ if (!data) { ++ local_data = 1; ++ data = yaffs_get_temp_buffer(dev); ++ } ++ } ++ ++ if (dev->param.inband_tags || (data && !tags)) ++ retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk, ++ data, dev->param.total_bytes_per_chunk, ++ NULL, 0, ++ &ecc_result); ++ else if (tags) ++ retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk, ++ data, dev->param.total_bytes_per_chunk, ++ spare_buffer, packed_tags_size, ++ &ecc_result); ++ else ++ BUG(); ++ ++ ++ if (retval == YAFFS_FAIL) ++ return YAFFS_FAIL; ++ ++ if (dev->param.inband_tags) { ++ if (tags) { ++ struct yaffs_packed_tags2_tags_only *pt2tp; ++ pt2tp = ++ (struct yaffs_packed_tags2_tags_only *) ++ &data[dev->data_bytes_per_chunk]; ++ yaffs_unpack_tags2_tags_only(dev, tags, pt2tp); ++ } ++ } else if (tags) { ++ memcpy(packed_tags_ptr, spare_buffer, packed_tags_size); ++ yaffs_unpack_tags2(dev, tags, &pt, !dev->param.no_tags_ecc); ++ } ++ ++ if (local_data) ++ yaffs_release_temp_buffer(dev, data); ++ ++ if (tags && ecc_result == YAFFS_ECC_RESULT_UNFIXED) { ++ tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED; ++ dev->n_ecc_unfixed++; ++ } ++ ++ if (tags && ecc_result == YAFFS_ECC_RESULT_FIXED) { ++ if (tags->ecc_result <= YAFFS_ECC_RESULT_NO_ERROR) ++ tags->ecc_result = YAFFS_ECC_RESULT_FIXED; ++ dev->n_ecc_fixed++; ++ } ++ ++ if (ecc_result < YAFFS_ECC_RESULT_UNFIXED) ++ return YAFFS_OK; ++ else ++ return YAFFS_FAIL; ++} ++ ++static int yaffs_tags_marshall_query_block(struct yaffs_dev *dev, int block_no, ++ enum yaffs_block_state *state, ++ u32 *seq_number) ++{ ++ int retval; ++ ++ yaffs_trace(YAFFS_TRACE_MTD, "yaffs_tags_marshall_query_block %d", ++ block_no); ++ ++ retval = dev->drv.drv_check_bad_fn(dev, block_no); ++ ++ if (retval== YAFFS_FAIL) { ++ yaffs_trace(YAFFS_TRACE_MTD, "block is bad"); ++ ++ *state = YAFFS_BLOCK_STATE_DEAD; ++ *seq_number = 0; ++ } else { ++ struct yaffs_ext_tags t; ++ ++ yaffs_tags_marshall_read(dev, ++ block_no * dev->param.chunks_per_block, ++ NULL, &t); ++ ++ if (t.chunk_used) { ++ *seq_number = t.seq_number; ++ *state = YAFFS_BLOCK_STATE_NEEDS_SCAN; ++ } else { ++ *seq_number = 0; ++ *state = YAFFS_BLOCK_STATE_EMPTY; ++ } ++ } ++ ++ yaffs_trace(YAFFS_TRACE_MTD, ++ "block query returns seq %d state %d", ++ *seq_number, *state); ++ ++ if (retval == 0) ++ return YAFFS_OK; ++ else ++ return YAFFS_FAIL; ++} ++ ++static int yaffs_tags_marshall_mark_bad(struct yaffs_dev *dev, int block_no) ++{ ++ return dev->drv.drv_mark_bad_fn(dev, block_no); ++ ++} ++ ++ ++void yaffs_tags_marshall_install(struct yaffs_dev *dev) ++{ ++ if (!dev->param.is_yaffs2) ++ return; ++ ++ if (!dev->tagger.write_chunk_tags_fn) ++ dev->tagger.write_chunk_tags_fn = yaffs_tags_marshall_write; ++ ++ if (!dev->tagger.read_chunk_tags_fn) ++ dev->tagger.read_chunk_tags_fn = yaffs_tags_marshall_read; ++ ++ if (!dev->tagger.query_block_fn) ++ dev->tagger.query_block_fn = yaffs_tags_marshall_query_block; ++ ++ if (!dev->tagger.mark_bad_fn) ++ dev->tagger.mark_bad_fn = yaffs_tags_marshall_mark_bad; ++ ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagsmarshall.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagsmarshall.h.patch new file mode 100644 index 00000000..fa5df370 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_tagsmarshall.h.patch @@ -0,0 +1,25 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_tagsmarshall.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_tagsmarshall.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,22 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_TAGSMARSHALL_H__ ++#define __YAFFS_TAGSMARSHALL_H__ ++ ++#include "yaffs_guts.h" ++void yaffs_tags_marshall_install(struct yaffs_dev *dev); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_trace.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_trace.h.patch new file mode 100644 index 00000000..e3cf9d91 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_trace.h.patch @@ -0,0 +1,60 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_trace.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_trace.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,57 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YTRACE_H__ ++#define __YTRACE_H__ ++ ++extern unsigned int yaffs_trace_mask; ++extern unsigned int yaffs_wr_attempts; ++ ++/* ++ * Tracing flags. ++ * The flags masked in YAFFS_TRACE_ALWAYS are always traced. ++ */ ++ ++#define YAFFS_TRACE_OS 0x00000002 ++#define YAFFS_TRACE_ALLOCATE 0x00000004 ++#define YAFFS_TRACE_SCAN 0x00000008 ++#define YAFFS_TRACE_BAD_BLOCKS 0x00000010 ++#define YAFFS_TRACE_ERASE 0x00000020 ++#define YAFFS_TRACE_GC 0x00000040 ++#define YAFFS_TRACE_WRITE 0x00000080 ++#define YAFFS_TRACE_TRACING 0x00000100 ++#define YAFFS_TRACE_DELETION 0x00000200 ++#define YAFFS_TRACE_BUFFERS 0x00000400 ++#define YAFFS_TRACE_NANDACCESS 0x00000800 ++#define YAFFS_TRACE_GC_DETAIL 0x00001000 ++#define YAFFS_TRACE_SCAN_DEBUG 0x00002000 ++#define YAFFS_TRACE_MTD 0x00004000 ++#define YAFFS_TRACE_CHECKPOINT 0x00008000 ++ ++#define YAFFS_TRACE_VERIFY 0x00010000 ++#define YAFFS_TRACE_VERIFY_NAND 0x00020000 ++#define YAFFS_TRACE_VERIFY_FULL 0x00040000 ++#define YAFFS_TRACE_VERIFY_ALL 0x000f0000 ++ ++#define YAFFS_TRACE_SYNC 0x00100000 ++#define YAFFS_TRACE_BACKGROUND 0x00200000 ++#define YAFFS_TRACE_LOCK 0x00400000 ++#define YAFFS_TRACE_MOUNT 0x00800000 ++ ++#define YAFFS_TRACE_ERROR 0x40000000 ++#define YAFFS_TRACE_BUG 0x80000000 ++#define YAFFS_TRACE_ALWAYS 0xf0000000 ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_verify.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_verify.c.patch new file mode 100644 index 00000000..e9889bca --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_verify.c.patch @@ -0,0 +1,543 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_verify.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_verify.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,540 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_verify.h" ++#include "yaffs_trace.h" ++#include "yaffs_bitmap.h" ++#include "yaffs_getblockinfo.h" ++#include "yaffs_nand.h" ++ ++int yaffs_skip_verification(struct yaffs_dev *dev) ++{ ++ (void) dev; ++ return !(yaffs_trace_mask & ++ (YAFFS_TRACE_VERIFY | YAFFS_TRACE_VERIFY_FULL)); ++} ++ ++static int yaffs_skip_full_verification(struct yaffs_dev *dev) ++{ ++ (void) dev; ++ return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_FULL)); ++} ++ ++static int yaffs_skip_nand_verification(struct yaffs_dev *dev) ++{ ++ (void) dev; ++ return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_NAND)); ++} ++ ++static const char * const block_state_name[] = { ++ "Unknown", ++ "Needs scan", ++ "Scanning", ++ "Empty", ++ "Allocating", ++ "Full", ++ "Dirty", ++ "Checkpoint", ++ "Collecting", ++ "Dead" ++}; ++ ++void yaffs_verify_blk(struct yaffs_dev *dev, struct yaffs_block_info *bi, int n) ++{ ++ int actually_used; ++ int in_use; ++ ++ if (yaffs_skip_verification(dev)) ++ return; ++ ++ /* Report illegal runtime states */ ++ if (bi->block_state >= YAFFS_NUMBER_OF_BLOCK_STATES) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Block %d has undefined state %d", ++ n, bi->block_state); ++ ++ switch (bi->block_state) { ++ case YAFFS_BLOCK_STATE_UNKNOWN: ++ case YAFFS_BLOCK_STATE_SCANNING: ++ case YAFFS_BLOCK_STATE_NEEDS_SCAN: ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Block %d has bad run-state %s", ++ n, block_state_name[bi->block_state]); ++ } ++ ++ /* Check pages in use and soft deletions are legal */ ++ ++ actually_used = bi->pages_in_use - bi->soft_del_pages; ++ ++ if (bi->pages_in_use < 0 || ++ bi->pages_in_use > (int)dev->param.chunks_per_block || ++ bi->soft_del_pages < 0 || ++ bi->soft_del_pages > (int)dev->param.chunks_per_block || ++ actually_used < 0 || actually_used > (int)dev->param.chunks_per_block) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Block %d has illegal values pages_in_used %d soft_del_pages %d", ++ n, bi->pages_in_use, bi->soft_del_pages); ++ ++ /* Check chunk bitmap legal */ ++ in_use = yaffs_count_chunk_bits(dev, n); ++ if (in_use != bi->pages_in_use) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Block %d has inconsistent values pages_in_use %d counted chunk bits %d", ++ n, bi->pages_in_use, in_use); ++} ++ ++void yaffs_verify_collected_blk(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi, int n) ++{ ++ yaffs_verify_blk(dev, bi, n); ++ ++ /* After collection the block should be in the erased state */ ++ ++ if (bi->block_state != YAFFS_BLOCK_STATE_COLLECTING && ++ bi->block_state != YAFFS_BLOCK_STATE_EMPTY) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "Block %d is in state %d after gc, should be erased", ++ n, bi->block_state); ++ } ++} ++ ++void yaffs_verify_blocks(struct yaffs_dev *dev) ++{ ++ u32 i; ++ u32 state_count[YAFFS_NUMBER_OF_BLOCK_STATES]; ++ int illegal_states = 0; ++ ++ if (yaffs_skip_verification(dev)) ++ return; ++ ++ memset(state_count, 0, sizeof(state_count)); ++ ++ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { ++ struct yaffs_block_info *bi = yaffs_get_block_info(dev, i); ++ yaffs_verify_blk(dev, bi, i); ++ ++ if (bi->block_state < YAFFS_NUMBER_OF_BLOCK_STATES) ++ state_count[bi->block_state]++; ++ else ++ illegal_states++; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_VERIFY, "Block summary"); ++ ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "%d blocks have illegal states", ++ illegal_states); ++ if (state_count[YAFFS_BLOCK_STATE_ALLOCATING] > 1) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Too many allocating blocks"); ++ ++ for (i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "%s %d blocks", ++ block_state_name[i], state_count[i]); ++ ++ if (dev->blocks_in_checkpt != state_count[YAFFS_BLOCK_STATE_CHECKPOINT]) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Checkpoint block count wrong dev %d count %d", ++ dev->blocks_in_checkpt, ++ state_count[YAFFS_BLOCK_STATE_CHECKPOINT]); ++ ++ if (dev->n_erased_blocks != (int)state_count[YAFFS_BLOCK_STATE_EMPTY]) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Erased block count wrong dev %d count %d", ++ dev->n_erased_blocks, ++ state_count[YAFFS_BLOCK_STATE_EMPTY]); ++ ++ if (state_count[YAFFS_BLOCK_STATE_COLLECTING] > 1) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Too many collecting blocks %d (max is 1)", ++ state_count[YAFFS_BLOCK_STATE_COLLECTING]); ++} ++ ++/* ++ * Verify the object header. oh must be valid, but obj and tags may be NULL in ++ * which case those tests will not be performed. ++ */ ++void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh, ++ struct yaffs_ext_tags *tags, int parent_check) ++{ ++ if (obj && yaffs_skip_verification(obj->my_dev)) ++ return; ++ ++ if (!(tags && obj && oh)) { ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Verifying object header tags %p obj %p oh %p", ++ tags, obj, oh); ++ return; ++ } ++ ++ if (oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN || ++ oh->type > YAFFS_OBJECT_TYPE_MAX) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d header type is illegal value 0x%x", ++ tags->obj_id, oh->type); ++ ++ if (tags->obj_id != obj->obj_id) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d header mismatch obj_id %d", ++ tags->obj_id, obj->obj_id); ++ ++ /* ++ * Check that the object's parent ids match if parent_check requested. ++ * ++ * Tests do not apply to the root object. ++ */ ++ ++ if (parent_check && tags->obj_id > 1 && !obj->parent) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d header mismatch parent_id %d obj->parent is NULL", ++ tags->obj_id, oh->parent_obj_id); ++ ++ if (parent_check && obj->parent && ++ oh->parent_obj_id != obj->parent->obj_id && ++ (oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED || ++ obj->parent->obj_id != YAFFS_OBJECTID_DELETED)) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d header mismatch parent_id %d parent_obj_id %d", ++ tags->obj_id, oh->parent_obj_id, ++ obj->parent->obj_id); ++ ++ if (tags->obj_id > 1 && oh->name[0] == 0) /* Null name */ ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d header name is NULL", ++ obj->obj_id); ++ ++ if (tags->obj_id > 1 && ((u8) (oh->name[0])) == 0xff) /* Junk name */ ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d header name is 0xff", ++ obj->obj_id); ++} ++ ++void yaffs_verify_file(struct yaffs_obj *obj) ++{ ++ u32 x; ++ int required_depth; ++ int last_chunk; ++ u32 offset_in_chunk; ++ u32 the_chunk; ++ ++ int i; ++ struct yaffs_dev *dev; ++ struct yaffs_ext_tags tags; ++ struct yaffs_tnode *tn; ++ u32 obj_id; ++ ++ if (!obj) ++ return; ++ ++ if (yaffs_skip_verification(obj->my_dev)) ++ return; ++ ++ dev = obj->my_dev; ++ obj_id = obj->obj_id; ++ ++ ++ /* Check file size is consistent with tnode depth */ ++ yaffs_addr_to_chunk(dev, obj->variant.file_variant.file_size, ++ &last_chunk, &offset_in_chunk); ++ last_chunk++; ++ x = last_chunk >> YAFFS_TNODES_LEVEL0_BITS; ++ required_depth = 0; ++ while (x > 0) { ++ x >>= YAFFS_TNODES_INTERNAL_BITS; ++ required_depth++; ++ } ++ ++ /* Check that the chunks in the tnode tree are all correct. ++ * We do this by scanning through the tnode tree and ++ * checking the tags for every chunk match. ++ */ ++ ++ if (yaffs_skip_nand_verification(dev)) ++ return; ++ ++ for (i = 1; i <= last_chunk; i++) { ++ tn = yaffs_find_tnode_0(dev, &obj->variant.file_variant, i); ++ ++ if (!tn) ++ continue; ++ ++ the_chunk = yaffs_get_group_base(dev, tn, i); ++ if (the_chunk > 0) { ++ yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL, ++ &tags); ++ if (tags.obj_id != obj_id || tags.chunk_id != (u32)i) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Object %d chunk_id %d NAND mismatch chunk %d tags (%d:%d)", ++ obj_id, i, the_chunk, ++ tags.obj_id, tags.chunk_id); ++ } ++ } ++} ++ ++void yaffs_verify_link(struct yaffs_obj *obj) ++{ ++ if (obj && yaffs_skip_verification(obj->my_dev)) ++ return; ++ ++ /* Verify sane equivalent object */ ++} ++ ++void yaffs_verify_symlink(struct yaffs_obj *obj) ++{ ++ if (obj && yaffs_skip_verification(obj->my_dev)) ++ return; ++ ++ /* Verify symlink string */ ++} ++ ++void yaffs_verify_special(struct yaffs_obj *obj) ++{ ++ if (obj && yaffs_skip_verification(obj->my_dev)) ++ return; ++} ++ ++void yaffs_verify_obj(struct yaffs_obj *obj) ++{ ++ struct yaffs_dev *dev; ++ u32 chunk_min; ++ u32 chunk_max; ++ u32 chunk_id_ok; ++ u32 chunk_in_range; ++ u32 chunk_wrongly_deleted; ++ u32 chunk_valid; ++ ++ if (!obj) ++ return; ++ ++ if (obj->being_created) ++ return; ++ ++ dev = obj->my_dev; ++ ++ if (yaffs_skip_verification(dev)) ++ return; ++ ++ /* Check sane object header chunk */ ++ ++ chunk_min = dev->internal_start_block * dev->param.chunks_per_block; ++ chunk_max = ++ (dev->internal_end_block + 1) * dev->param.chunks_per_block - 1; ++ ++ chunk_in_range = (((unsigned)(obj->hdr_chunk)) >= chunk_min && ++ ((unsigned)(obj->hdr_chunk)) <= chunk_max); ++ chunk_id_ok = chunk_in_range || (obj->hdr_chunk == 0); ++ chunk_valid = chunk_in_range && ++ yaffs_check_chunk_bit(dev, ++ obj->hdr_chunk / dev->param.chunks_per_block, ++ obj->hdr_chunk % dev->param.chunks_per_block); ++ chunk_wrongly_deleted = chunk_in_range && !chunk_valid; ++ ++ if (!obj->fake && (!chunk_id_ok || chunk_wrongly_deleted)) ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d has chunk_id %d %s %s", ++ obj->obj_id, obj->hdr_chunk, ++ chunk_id_ok ? "" : ",out of range", ++ chunk_wrongly_deleted ? ",marked as deleted" : ""); ++ ++ if (chunk_valid && !yaffs_skip_nand_verification(dev)) { ++ struct yaffs_ext_tags tags; ++ struct yaffs_obj_hdr *oh; ++ u8 *buffer = yaffs_get_temp_buffer(dev); ++ ++ oh = (struct yaffs_obj_hdr *)buffer; ++ ++ yaffs_rd_chunk_tags_nand(dev, obj->hdr_chunk, buffer, &tags); ++ ++ yaffs_verify_oh(obj, oh, &tags, 1); ++ ++ yaffs_release_temp_buffer(dev, buffer); ++ } ++ ++ /* Verify it has a parent */ ++ if (obj && !obj->fake && (!obj->parent || obj->parent->my_dev != dev)) { ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d has parent pointer %p which does not look like an object", ++ obj->obj_id, obj->parent); ++ } ++ ++ /* Verify parent is a directory */ ++ if (obj->parent && ++ obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d's parent is not a directory (type %d)", ++ obj->obj_id, obj->parent->variant_type); ++ } ++ ++ switch (obj->variant_type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ yaffs_verify_file(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ yaffs_verify_symlink(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ yaffs_verify_dir(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ yaffs_verify_link(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ yaffs_verify_special(obj); ++ break; ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ default: ++ yaffs_trace(YAFFS_TRACE_VERIFY, ++ "Obj %d has illegaltype %d", ++ obj->obj_id, obj->variant_type); ++ break; ++ } ++} ++ ++void yaffs_verify_objects(struct yaffs_dev *dev) ++{ ++ struct yaffs_obj *obj; ++ int i; ++ struct list_head *lh; ++ ++ if (yaffs_skip_verification(dev)) ++ return; ++ ++ /* Iterate through the objects in each hash entry */ ++ ++ for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) { ++ list_for_each(lh, &dev->obj_bucket[i].list) { ++ obj = list_entry(lh, struct yaffs_obj, hash_link); ++ yaffs_verify_obj(obj); ++ } ++ } ++} ++ ++void yaffs_verify_obj_in_dir(struct yaffs_obj *obj) ++{ ++ struct list_head *lh; ++ struct yaffs_obj *list_obj; ++ int count = 0; ++ ++ if (!obj) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "No object to verify"); ++ BUG(); ++ return; ++ } ++ ++ if (yaffs_skip_verification(obj->my_dev)) ++ return; ++ ++ if (!obj->parent) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "Object does not have parent"); ++ BUG(); ++ return; ++ } ++ ++ if (obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "Parent is not directory"); ++ BUG(); ++ } ++ ++ /* Iterate through the objects in each hash entry */ ++ ++ list_for_each(lh, &obj->parent->variant.dir_variant.children) { ++ list_obj = list_entry(lh, struct yaffs_obj, siblings); ++ yaffs_verify_obj(list_obj); ++ if (obj == list_obj) ++ count++; ++ } ++ ++ if (count != 1) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "Object in directory %d times", ++ count); ++ BUG(); ++ } ++} ++ ++void yaffs_verify_dir(struct yaffs_obj *directory) ++{ ++ struct list_head *lh; ++ struct yaffs_obj *list_obj; ++ struct yaffs_dev *dev; ++ ++ if (!directory) { ++ BUG(); ++ return; ++ } ++ ++ dev = directory->my_dev; ++ ++ if (!dev) { ++ BUG(); ++ return; ++ } ++ ++ if (directory == dev->root_dir || ++ directory == dev->lost_n_found || ++ directory == dev->unlinked_dir || ++ directory == dev->del_dir) ++ return; ++ ++ if (yaffs_skip_full_verification(directory->my_dev)) ++ return; ++ ++ if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "Directory has wrong type: %d", ++ directory->variant_type); ++ BUG(); ++ } ++ ++ /* Iterate through the objects in each hash entry */ ++ ++ list_for_each(lh, &directory->variant.dir_variant.children) { ++ list_obj = list_entry(lh, struct yaffs_obj, siblings); ++ if (list_obj->parent != directory) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "Object in directory list has wrong parent %p", ++ list_obj->parent); ++ BUG(); ++ } ++ yaffs_verify_obj_in_dir(list_obj); ++ } ++} ++ ++static int yaffs_free_verification_failures; ++ ++void yaffs_verify_free_chunks(struct yaffs_dev *dev) ++{ ++ int counted; ++ int difference; ++ ++ if (yaffs_skip_verification(dev)) ++ return; ++ ++ counted = yaffs_count_free_chunks(dev); ++ ++ difference = dev->n_free_chunks - counted; ++ ++ if (difference) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "Freechunks verification failure %d %d %d", ++ dev->n_free_chunks, counted, difference); ++ yaffs_free_verification_failures++; ++ } ++} ++ ++int yaffs_verify_file_sane(struct yaffs_obj *in) ++{ ++ (void) in; ++ return YAFFS_OK; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_verify.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_verify.h.patch new file mode 100644 index 00000000..220317fa --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_verify.h.patch @@ -0,0 +1,46 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_verify.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_verify.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,43 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_VERIFY_H__ ++#define __YAFFS_VERIFY_H__ ++ ++#include "yaffs_guts.h" ++ ++void yaffs_verify_blk(struct yaffs_dev *dev, struct yaffs_block_info *bi, ++ int n); ++void yaffs_verify_collected_blk(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi, int n); ++void yaffs_verify_blocks(struct yaffs_dev *dev); ++ ++void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh, ++ struct yaffs_ext_tags *tags, int parent_check); ++void yaffs_verify_file(struct yaffs_obj *obj); ++void yaffs_verify_link(struct yaffs_obj *obj); ++void yaffs_verify_symlink(struct yaffs_obj *obj); ++void yaffs_verify_special(struct yaffs_obj *obj); ++void yaffs_verify_obj(struct yaffs_obj *obj); ++void yaffs_verify_objects(struct yaffs_dev *dev); ++void yaffs_verify_obj_in_dir(struct yaffs_obj *obj); ++void yaffs_verify_dir(struct yaffs_obj *directory); ++void yaffs_verify_free_chunks(struct yaffs_dev *dev); ++ ++int yaffs_verify_file_sane(struct yaffs_obj *obj); ++ ++int yaffs_skip_verification(struct yaffs_dev *dev); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_vfs.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_vfs.c.patch new file mode 100644 index 00000000..ba2cb1f2 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_vfs.c.patch @@ -0,0 +1,3754 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_vfs.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_vfs.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,3751 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * Acknowledgements: ++ * Luc van OostenRyck for numerous patches. ++ * Nick Bane for numerous patches. ++ * Nick Bane for 2.5/2.6 integration. ++ * Andras Toth for mknod rdev issue. ++ * Michael Fischer for finding the problem with inode inconsistency. ++ * Some code bodily lifted from JFFS ++ * ++ * 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. ++ */ ++ ++/* ++ * ++ * This is the file system front-end to YAFFS that hooks it up to ++ * the VFS. ++ * ++ * Special notes: ++ * >> 2.4: sb->u.generic_sbp points to the struct yaffs_dev associated with ++ * this superblock ++ * >> 2.6: sb->s_fs_info points to the struct yaffs_dev associated with this ++ * superblock ++ * >> inode->u.generic_ip points to the associated struct yaffs_obj. ++ */ ++ ++/* ++ * There are two variants of the VFS glue code. This variant should compile ++ * for any version of Linux. ++ */ ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)) ++#define YAFFS_COMPILE_BACKGROUND ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)) ++#define YAFFS_COMPILE_FREEZER ++#endif ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) ++#define YAFFS_COMPILE_EXPORTFS ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) ++#define YAFFS_USE_SETATTR_COPY ++#define YAFFS_USE_TRUNCATE_SETSIZE ++#endif ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) ++#define YAFFS_HAS_EVICT_INODE ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13)) && \ ++ (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)) ++#define YAFFS_NEW_FOLLOW_LINK 1 ++#else ++#define YAFFS_NEW_FOLLOW_LINK 0 ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) ++#define YAFFS_HAS_WRITE_SUPER ++#endif ++ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++ ++#if (YAFFS_NEW_FOLLOW_LINK == 1) ++#include ++#endif ++ ++#ifdef YAFFS_COMPILE_EXPORTFS ++#include ++#endif ++ ++#ifdef YAFFS_COMPILE_BACKGROUND ++#include ++#include ++#endif ++#ifdef YAFFS_COMPILE_FREEZER ++#include ++#endif ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++ ++#include ++ ++#define UnlockPage(p) unlock_page(p) ++#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) ++ ++/* FIXME: use sb->s_id instead ? */ ++#define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) ++ ++#else ++ ++#include ++#define BDEVNAME_SIZE 0 ++#define yaffs_devname(sb, buf) kdevname(sb->s_dev) ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)) ++/* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */ ++#define __user ++#endif ++ ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)) ++#define YPROC_ROOT (&proc_root) ++#else ++#define YPROC_ROOT NULL ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)) ++#define Y_INIT_TIMER(a) init_timer(a) ++#else ++#define Y_INIT_TIMER(a) init_timer_on_stack(a) ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)) ++#define YAFFS_USE_WRITE_BEGIN_END 1 ++#else ++#define YAFFS_USE_WRITE_BEGIN_END 0 ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) ++#define YAFFS_SUPER_HAS_DIRTY ++#endif ++ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) ++#define set_nlink(inode, count) do { (inode)->i_nlink = (count); } while(0) ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)) ++static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size) ++{ ++ uint64_t result = partition_size; ++ do_div(result, block_size); ++ return (uint32_t) result; ++} ++#else ++#define YCALCBLOCKS(s, b) ((s)/(b)) ++#endif ++ ++#include ++#include ++ ++#include "yportenv.h" ++#include "yaffs_trace.h" ++#include "yaffs_guts.h" ++#include "yaffs_attribs.h" ++ ++#include "yaffs_linux.h" ++ ++#include "yaffs_mtdif.h" ++#include "yaffs_packedtags2.h" ++#include "yaffs_getblockinfo.h" ++ ++unsigned int yaffs_trace_mask = ++ YAFFS_TRACE_BAD_BLOCKS | ++ YAFFS_TRACE_ALWAYS | ++ 0; ++ ++unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; ++unsigned int yaffs_auto_checkpoint = 1; ++unsigned int yaffs_gc_control = 1; ++unsigned int yaffs_bg_enable = 1; ++unsigned int yaffs_auto_select = 1; ++/* Module Parameters */ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++module_param(yaffs_trace_mask, uint, 0644); ++module_param(yaffs_wr_attempts, uint, 0644); ++module_param(yaffs_auto_checkpoint, uint, 0644); ++module_param(yaffs_gc_control, uint, 0644); ++module_param(yaffs_bg_enable, uint, 0644); ++#else ++MODULE_PARM(yaffs_trace_mask, "i"); ++MODULE_PARM(yaffs_wr_attempts, "i"); ++MODULE_PARM(yaffs_auto_checkpoint, "i"); ++MODULE_PARM(yaffs_gc_control, "i"); ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)) ++/* use iget and read_inode */ ++#define Y_IGET(sb, inum) iget((sb), (inum)) ++ ++#else ++/* Call local equivalent */ ++#define YAFFS_USE_OWN_IGET ++#define Y_IGET(sb, inum) yaffs_iget((sb), (inum)) ++ ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)) ++#define yaffs_inode_to_obj_lv(iptr) ((iptr)->i_private) ++#else ++#define yaffs_inode_to_obj_lv(iptr) ((iptr)->u.generic_ip) ++#endif ++ ++#define yaffs_inode_to_obj(iptr) \ ++ ((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr))) ++#define yaffs_dentry_to_obj(dptr) yaffs_inode_to_obj((dptr)->d_inode) ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++#define yaffs_super_to_dev(sb) ((struct yaffs_dev *)sb->s_fs_info) ++#else ++#define yaffs_super_to_dev(sb) ((struct yaffs_dev *)sb->u.generic_sbp) ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) ++#define Y_CLEAR_INODE(i) clear_inode(i) ++#else ++#define Y_CLEAR_INODE(i) end_writeback(i) ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) ++#define YAFFS_USE_DIR_ITERATE ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) ++#define YAFFS_USE_XATTR ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) ++#define YAFFS_NEW_PROCFS ++#include ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)) ++#define PAGE_CACHE_SIZE PAGE_SIZE ++#define PAGE_CACHE_SHIFT PAGE_SHIFT ++#define Y_GET_DENTRY(f) ((f)->f_path.dentry) ++#define page_cache_release put_page ++#define YAFFS_NEW_XATTR 1 ++#define YAFFS_NEW_GET_LINK 1 ++#else ++#define Y_GET_DENTRY(f) ((f)->f_dentry) ++#define YAFFS_NEW_XATTR 0 ++#define YAFFS_NEW_GET_LINK 0 ++#endif ++ ++#define update_dir_time(dir) do {\ ++ (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \ ++ } while (0) ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) ++static inline int setattr_prepare(struct dentry *dentry, struct iattr *attr) ++{ ++ return inode_change_ok(dentry->d_inode, attr); ++} ++#endif ++ ++static void yaffs_fill_inode_from_obj(struct inode *inode, ++ struct yaffs_obj *obj); ++ ++ ++static void yaffs_gross_lock(struct yaffs_dev *dev) ++{ ++ yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locking %p", current); ++ mutex_lock(&(yaffs_dev_to_lc(dev)->gross_lock)); ++ yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locked %p", current); ++} ++ ++static void yaffs_gross_unlock(struct yaffs_dev *dev) ++{ ++ yaffs_trace(YAFFS_TRACE_LOCK, "yaffs unlocking %p", current); ++ mutex_unlock(&(yaffs_dev_to_lc(dev)->gross_lock)); ++} ++ ++ ++static int yaffs_readpage_nolock(struct file *f, struct page *pg) ++{ ++ /* Lifted from jffs2 */ ++ ++ struct yaffs_obj *obj; ++ unsigned char *pg_buf; ++ int ret; ++ loff_t pos = ((loff_t) pg->index) << PAGE_SHIFT; ++ struct yaffs_dev *dev; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_readpage_nolock at %lld, size %08x", ++ (long long)pos, ++ (unsigned)PAGE_SIZE); ++ ++ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); ++ ++ dev = obj->my_dev; ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++ BUG_ON(!PageLocked(pg)); ++#else ++ if (!PageLocked(pg)) ++ PAGE_BUG(pg); ++#endif ++ ++ pg_buf = kmap(pg); ++ /* FIXME: Can kmap fail? */ ++ ++ yaffs_gross_lock(dev); ++ ++ ret = yaffs_file_rd(obj, pg_buf, pos, PAGE_CACHE_SIZE); ++ ++ yaffs_gross_unlock(dev); ++ ++ if (ret >= 0) ++ ret = 0; ++ ++ if (ret) { ++ ClearPageUptodate(pg); ++ SetPageError(pg); ++ } else { ++ SetPageUptodate(pg); ++ ClearPageError(pg); ++ } ++ ++ flush_dcache_page(pg); ++ kunmap(pg); ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage_nolock done"); ++ return ret; ++} ++ ++static int yaffs_readpage_unlock(struct file *f, struct page *pg) ++{ ++ int ret = yaffs_readpage_nolock(f, pg); ++ UnlockPage(pg); ++ return ret; ++} ++ ++static int yaffs_readpage(struct file *f, struct page *pg) ++{ ++ int ret; ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage"); ++ ret = yaffs_readpage_unlock(f, pg); ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage done"); ++ return ret; ++} ++ ++ ++static void yaffs_set_super_dirty_val(struct yaffs_dev *dev, int val) ++{ ++ struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev); ++ ++ if (lc) ++ lc->dirty = val; ++ ++# ifdef YAFFS_SUPER_HAS_DIRTY ++ { ++ struct super_block *sb = lc->super; ++ ++ if (sb) ++ sb->s_dirt = val; ++ } ++#endif ++ ++} ++ ++static void yaffs_set_super_dirty(struct yaffs_dev *dev) ++{ ++ yaffs_set_super_dirty_val(dev, 1); ++} ++ ++static void yaffs_clear_super_dirty(struct yaffs_dev *dev) ++{ ++ yaffs_set_super_dirty_val(dev, 0); ++} ++ ++static int yaffs_check_super_dirty(struct yaffs_dev *dev) ++{ ++ struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev); ++ ++ if (lc && lc->dirty) ++ return 1; ++ ++# ifdef YAFFS_SUPER_HAS_DIRTY ++ { ++ struct super_block *sb = lc->super; ++ ++ if (sb && sb->s_dirt) ++ return 1; ++ } ++#endif ++ return 0; ++ ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++static int yaffs_writepage(struct page *page, struct writeback_control *wbc) ++#else ++static int yaffs_writepage(struct page *page) ++#endif ++{ ++ struct yaffs_dev *dev; ++ struct address_space *mapping = page->mapping; ++ struct inode *inode; ++ unsigned long end_index; ++ char *buffer; ++ struct yaffs_obj *obj; ++ int n_written = 0; ++ unsigned n_bytes; ++ loff_t i_size; ++ ++ if (!mapping) ++ BUG(); ++ inode = mapping->host; ++ if (!inode) ++ BUG(); ++ i_size = i_size_read(inode); ++ ++ end_index = i_size >> PAGE_CACHE_SHIFT; ++ ++ if (page->index < end_index) ++ n_bytes = PAGE_CACHE_SIZE; ++ else { ++ n_bytes = i_size & (PAGE_CACHE_SIZE - 1); ++ ++ if (page->index > end_index || !n_bytes) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_writepage at %lld, inode size = %lld!!", ++ ((loff_t)page->index) << PAGE_CACHE_SHIFT, ++ inode->i_size); ++ yaffs_trace(YAFFS_TRACE_OS, ++ " -> don't care!!"); ++ ++ zero_user_segment(page, 0, PAGE_CACHE_SIZE); ++ set_page_writeback(page); ++ unlock_page(page); ++ end_page_writeback(page); ++ return 0; ++ } ++ } ++ ++ if (n_bytes != PAGE_CACHE_SIZE) ++ zero_user_segment(page, n_bytes, PAGE_CACHE_SIZE); ++ ++ get_page(page); ++ ++ buffer = kmap(page); ++ ++ obj = yaffs_inode_to_obj(inode); ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_writepage at %lld, size %08x", ++ ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes); ++ yaffs_trace(YAFFS_TRACE_OS, ++ "writepag0: obj = %lld, ino = %lld", ++ obj->variant.file_variant.file_size, inode->i_size); ++ ++ n_written = yaffs_wr_file(obj, buffer, ++ ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes, 0); ++ ++ yaffs_set_super_dirty(dev); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "writepag1: obj = %lld, ino = %lld", ++ obj->variant.file_variant.file_size, inode->i_size); ++ ++ yaffs_gross_unlock(dev); ++ ++ kunmap(page); ++ set_page_writeback(page); ++ unlock_page(page); ++ end_page_writeback(page); ++ put_page(page); ++ ++ return (n_written == n_bytes) ? 0 : -ENOSPC; ++} ++ ++/* Space holding and freeing is done to ensure we have space available for write_begin/end */ ++/* For now we just assume few parallel writes and check against a small number. */ ++/* Todo: need to do this with a counter to handle parallel reads better */ ++ ++static ssize_t yaffs_hold_space(struct file *f) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++ ++ int n_free_chunks; ++ ++ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); ++ ++ dev = obj->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ n_free_chunks = yaffs_get_n_free_chunks(dev); ++ ++ yaffs_gross_unlock(dev); ++ ++ return (n_free_chunks > 20) ? 1 : 0; ++} ++ ++static void yaffs_release_space(struct file *f) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++ ++ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); ++ ++ dev = obj->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ yaffs_gross_unlock(dev); ++} ++ ++#if (YAFFS_USE_WRITE_BEGIN_END > 0) ++static int yaffs_write_begin(struct file *filp, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned flags, ++ struct page **pagep, void **fsdata) ++{ ++ struct page *pg = NULL; ++ pgoff_t index = pos >> PAGE_CACHE_SHIFT; ++ ++ int ret = 0; ++ int space_held = 0; ++ ++ /* Get a page */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) ++ pg = grab_cache_page_write_begin(mapping, index, flags); ++#else ++ pg = __grab_cache_page(mapping, index); ++#endif ++ ++ *pagep = pg; ++ if (!pg) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ yaffs_trace(YAFFS_TRACE_OS, ++ "start yaffs_write_begin index %d(%x) uptodate %d", ++ (int)index, (int)index, Page_Uptodate(pg) ? 1 : 0); ++ ++ /* Get fs space */ ++ space_held = yaffs_hold_space(filp); ++ ++ if (!space_held) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ ++ /* Update page if required */ ++ ++ if (!Page_Uptodate(pg)) ++ ret = yaffs_readpage_nolock(filp, pg); ++ ++ if (ret) ++ goto out; ++ ++ /* Happy path return */ ++ yaffs_trace(YAFFS_TRACE_OS, "end yaffs_write_begin - ok"); ++ ++ return 0; ++ ++out: ++ yaffs_trace(YAFFS_TRACE_OS, ++ "end yaffs_write_begin fail returning %d", ret); ++ if (space_held) ++ yaffs_release_space(filp); ++ if (pg) { ++ unlock_page(pg); ++ page_cache_release(pg); ++ } ++ return ret; ++} ++ ++#else ++ ++static int yaffs_prepare_write(struct file *f, struct page *pg, ++ unsigned offset, unsigned to) ++{ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_prepair_write"); ++ ++ if (!Page_Uptodate(pg)) ++ return yaffs_readpage_nolock(f, pg); ++ return 0; ++} ++#endif ++ ++ ++static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, ++ loff_t * pos) ++{ ++ struct yaffs_obj *obj; ++ int n_written; ++ loff_t ipos; ++ struct inode *inode; ++ struct yaffs_dev *dev; ++ ++ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); ++ ++ if (!obj) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_file_write: hey obj is null!"); ++ return -EINVAL; ++ } ++ ++ dev = obj->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ inode = Y_GET_DENTRY(f)->d_inode; ++ ++ if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) ++ ipos = inode->i_size; ++ else ++ ipos = *pos; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_file_write about to write writing %u(%x) bytes to object %d at %lld", ++ (unsigned)n, (unsigned)n, obj->obj_id, ipos); ++ ++ n_written = yaffs_wr_file(obj, buf, ipos, n, 0); ++ ++ yaffs_set_super_dirty(dev); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_file_write: %d(%x) bytes written", ++ (unsigned)n, (unsigned)n); ++ ++ if (n_written > 0) { ++ ipos += n_written; ++ *pos = ipos; ++ if (ipos > inode->i_size) { ++ inode->i_size = ipos; ++ inode->i_blocks = (ipos + 511) >> 9; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_file_write size updated to %lld bytes, %d blocks", ++ ipos, (int)(inode->i_blocks)); ++ } ++ ++ } ++ yaffs_gross_unlock(dev); ++ return (n_written == 0) && (n > 0) ? -ENOSPC : n_written; ++} ++ ++ ++#if (YAFFS_USE_WRITE_BEGIN_END > 0) ++static int yaffs_write_end(struct file *filp, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned copied, ++ struct page *pg, void *fsdadata) ++{ ++ int ret = 0; ++ void *addr, *kva; ++ uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1); ++ ++ kva = kmap(pg); ++ addr = kva + offset_into_page; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_write_end addr %p pos %lld n_bytes %d", ++ addr, pos, copied); ++ ++ ret = yaffs_file_write(filp, addr, copied, &pos); ++ ++ if (ret != copied) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_write_end not same size ret %d copied %d", ++ ret, copied); ++ SetPageError(pg); ++ } ++ ++ kunmap(pg); ++ ++ yaffs_release_space(filp); ++ unlock_page(pg); ++ page_cache_release(pg); ++ return ret; ++} ++#else ++ ++static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, ++ unsigned to) ++{ ++ void *addr, *kva; ++ ++ loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset; ++ int n_bytes = to - offset; ++ int n_written; ++ ++ kva = kmap(pg); ++ addr = kva + offset; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_commit_write addr %p pos %lld n_bytes %d", ++ addr, pos, n_bytes); ++ ++ n_written = yaffs_file_write(f, addr, n_bytes, &pos); ++ ++ if (n_written != n_bytes) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_commit_write not same size n_written %d n_bytes %d", ++ n_written, n_bytes); ++ SetPageError(pg); ++ } ++ kunmap(pg); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_commit_write returning %d", ++ n_written == n_bytes ? 0 : n_written); ++ ++ return n_written == n_bytes ? 0 : n_written; ++} ++#endif ++ ++static struct address_space_operations yaffs_file_address_operations = { ++ .readpage = yaffs_readpage, ++ .writepage = yaffs_writepage, ++#if (YAFFS_USE_WRITE_BEGIN_END > 0) ++ .write_begin = yaffs_write_begin, ++ .write_end = yaffs_write_end, ++#else ++ .prepare_write = yaffs_prepare_write, ++ .commit_write = yaffs_commit_write, ++#endif ++}; ++ ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++static int yaffs_file_flush(struct file *file, fl_owner_t id) ++#else ++static int yaffs_file_flush(struct file *file) ++#endif ++{ ++ struct yaffs_obj *obj = yaffs_dentry_to_obj(Y_GET_DENTRY(file)); ++ ++ struct yaffs_dev *dev = obj->my_dev; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_file_flush object %d (%s)", ++ obj->obj_id, ++ obj->dirty ? "dirty" : "clean"); ++ ++ yaffs_gross_lock(dev); ++ ++ yaffs_flush_file(obj, 1, 0, 0); ++ ++ yaffs_gross_unlock(dev); ++ ++ return 0; ++} ++ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) ++static int yaffs_sync_object(struct file *file, loff_t start, loff_t end, int datasync) ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)) ++static int yaffs_sync_object(struct file *file, int datasync) ++#else ++static int yaffs_sync_object(struct file *file, struct dentry *dentry, ++ int datasync) ++#endif ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)) ++ struct dentry *dentry = file->f_path.dentry; ++#endif ++ ++ obj = yaffs_dentry_to_obj(dentry); ++ ++ dev = obj->my_dev; ++ ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC, ++ "yaffs_sync_object"); ++ yaffs_gross_lock(dev); ++ yaffs_flush_file(obj, 1, datasync, 0); ++ yaffs_gross_unlock(dev); ++ return 0; ++} ++ ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)) ++static const struct file_operations yaffs_file_operations = { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) ++ .read = new_sync_read, ++ .write = new_sync_write, ++#endif ++ .read_iter = generic_file_read_iter, ++ .write_iter = generic_file_write_iter, ++#else ++ .read = do_sync_read, ++ .write = do_sync_write, ++ .aio_read = generic_file_aio_read, ++ .aio_write = generic_file_aio_write, ++#endif ++ .mmap = generic_file_mmap, ++ .flush = yaffs_file_flush, ++ .fsync = yaffs_sync_object, ++ .splice_read = generic_file_splice_read, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) ++ .splice_write = iter_file_splice_write, ++#else ++ .splice_write = generic_file_splice_write, ++#endif ++ .llseek = generic_file_llseek, ++}; ++ ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)) ++ ++static const struct file_operations yaffs_file_operations = { ++ .read = do_sync_read, ++ .write = do_sync_write, ++ .aio_read = generic_file_aio_read, ++ .aio_write = generic_file_aio_write, ++ .mmap = generic_file_mmap, ++ .flush = yaffs_file_flush, ++ .fsync = yaffs_sync_object, ++ .sendfile = generic_file_sendfile, ++}; ++ ++#else ++ ++static const struct file_operations yaffs_file_operations = { ++ .read = generic_file_read, ++ .write = generic_file_write, ++ .mmap = generic_file_mmap, ++ .flush = yaffs_file_flush, ++ .fsync = yaffs_sync_object, ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++ .sendfile = generic_file_sendfile, ++#endif ++}; ++#endif ++ ++ ++ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)) ++static void zero_user_segment(struct page *page, unsigned start, unsigned end) ++{ ++ void *kaddr = kmap_atomic(page, KM_USER0); ++ memset(kaddr + start, 0, end - start); ++ kunmap_atomic(kaddr, KM_USER0); ++ flush_dcache_page(page); ++} ++#endif ++ ++ ++static int yaffs_vfs_setsize(struct inode *inode, loff_t newsize) ++{ ++#ifdef YAFFS_USE_TRUNCATE_SETSIZE ++ truncate_setsize(inode, newsize); ++ return 0; ++#else ++ truncate_inode_pages(&inode->i_data, newsize); ++ return 0; ++#endif ++ ++} ++ ++ ++static int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr) ++{ ++#ifdef YAFFS_USE_SETATTR_COPY ++ setattr_copy(inode, attr); ++ return 0; ++#else ++ return inode_setattr(inode, attr); ++#endif ++ ++} ++ ++static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) ++{ ++ struct inode *inode = dentry->d_inode; ++ int error = 0; ++ struct yaffs_dev *dev; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_setattr of object %d", ++ yaffs_inode_to_obj(inode)->obj_id); ++#if 0 ++ /* Fail if a requested resize >= 2GB */ ++ if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31)) ++ error = -EINVAL; ++#endif ++ ++ if (error == 0) ++ error = setattr_prepare(dentry, attr); ++ if (error == 0) { ++ int result; ++ if (!error) { ++ error = yaffs_vfs_setattr(inode, attr); ++ yaffs_trace(YAFFS_TRACE_OS, "inode_setattr called"); ++ if (attr->ia_valid & ATTR_SIZE) { ++ yaffs_vfs_setsize(inode, attr->ia_size); ++ inode->i_blocks = (inode->i_size + 511) >> 9; ++ } ++ } ++ dev = yaffs_inode_to_obj(inode)->my_dev; ++ if (attr->ia_valid & ATTR_SIZE) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "resize to %d(%x)", ++ (int)(attr->ia_size), ++ (int)(attr->ia_size)); ++ } ++ yaffs_gross_lock(dev); ++ result = yaffs_set_attribs(yaffs_inode_to_obj(inode), attr); ++ if (result == YAFFS_OK) { ++ error = 0; ++ } else { ++ error = -EPERM; ++ } ++ yaffs_gross_unlock(dev); ++ ++ } ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_setattr done returning %d", error); ++ ++ return error; ++} ++ ++#ifdef YAFFS_USE_XATTR ++#if (YAFFS_NEW_XATTR > 0) ++static int yaffs_setxattr(struct dentry *dentry, struct inode *inode, ++ const char *name, const void *value, size_t size, int flags) ++{ ++#else ++static int yaffs_setxattr(struct dentry *dentry, const char *name, ++ const void *value, size_t size, int flags) ++{ ++ struct inode *inode = dentry->d_inode; ++#endif ++ int error = 0; ++ struct yaffs_dev *dev; ++ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr of object %d", obj->obj_id); ++ ++ if (error == 0) { ++ int result; ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ result = yaffs_set_xattrib(obj, name, value, size, flags); ++ if (result == YAFFS_OK) ++ error = 0; ++ else if (result < 0) ++ error = result; ++ yaffs_gross_unlock(dev); ++ ++ } ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr done returning %d", error); ++ ++ return error; ++} ++ ++#ifdef YAFFS_NEW_XATTR ++static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode, ++ const char *name, void *buff, size_t size) ++{ ++#else ++static ssize_t yaffs_getxattr(struct dentry * dentry, const char *name, ++ void *buff, size_t size) ++{ ++ struct inode *inode = dentry->d_inode; ++#endif ++ int error = 0; ++ struct yaffs_dev *dev; ++ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_getxattr \"%s\" from object %d", ++ name, obj->obj_id); ++ ++ if (error == 0) { ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ error = yaffs_get_xattrib(obj, name, buff, size); ++ yaffs_gross_unlock(dev); ++ ++ } ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_getxattr done returning %d", error); ++ ++ return error; ++} ++ ++static int yaffs_removexattr(struct dentry *dentry, const char *name) ++{ ++ struct inode *inode = dentry->d_inode; ++ int error = 0; ++ struct yaffs_dev *dev; ++ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_removexattr of object %d", obj->obj_id); ++ ++ if (error == 0) { ++ int result; ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ result = yaffs_remove_xattrib(obj, name); ++ if (result == YAFFS_OK) ++ error = 0; ++ else if (result < 0) ++ error = result; ++ yaffs_gross_unlock(dev); ++ ++ } ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_removexattr done returning %d", error); ++ ++ return error; ++} ++#endif ++ ++static ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size) ++{ ++ struct inode *inode = dentry->d_inode; ++ int error = 0; ++ struct yaffs_dev *dev; ++ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_listxattr of object %d", obj->obj_id); ++ ++ if (error == 0) { ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ error = yaffs_list_xattrib(obj, buff, size); ++ yaffs_gross_unlock(dev); ++ ++ } ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_listxattr done returning %d", error); ++ ++ return error; ++} ++ ++ ++static const struct inode_operations yaffs_file_inode_operations = { ++ .setattr = yaffs_setattr, ++#ifdef YAFFS_USE_XATTR ++ .setxattr = yaffs_setxattr, ++ .getxattr = yaffs_getxattr, ++ .removexattr = yaffs_removexattr, ++#endif ++ .listxattr = yaffs_listxattr, ++}; ++ ++ ++static int yaffs_readlink(struct dentry *dentry, char __user * buffer, ++ int buflen) ++{ ++ unsigned char *alias; ++ int ret; ++ ++ struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry)); ++ ++ yaffs_gross_unlock(dev); ++ ++ if (!alias) ++ return -ENOMEM; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) ++ ret = vfs_readlink(dentry, buffer, buflen, alias); ++#else ++ ret = readlink_copy(buffer, buflen, alias); ++#endif ++ kfree(alias); ++ return ret; ++} ++ ++#if (YAFFS_NEW_GET_LINK == 0) ++#if (YAFFS_NEW_FOLLOW_LINK == 1) ++static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) ++{ ++ void *ret; ++#else ++static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) ++{ ++ int ret ++#endif ++ unsigned char *alias; ++ int ret_int = 0; ++ struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry)); ++ yaffs_gross_unlock(dev); ++ ++ if (!alias) { ++ ret_int = -ENOMEM; ++ goto out; ++ } ++#if (YAFFS_NEW_FOLLOW_LINK == 1) ++ nd_set_link(nd, alias); ++ ret = alias; ++out: ++ if (ret_int) ++ ret = ERR_PTR(ret_int); ++ return ret; ++#else ++ ret = vfs_follow_link(nd, alias); ++ kfree(alias); ++out: ++ if (ret_int) ++ ret = ret_int; ++ return ret; ++#endif ++} ++#else ++static const char *yaffs_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) ++{ ++ unsigned char *alias; ++ struct yaffs_dev *dev; ++ ++ if (!dentry) ++ return ERR_PTR(-ECHILD); ++ ++ dev = yaffs_dentry_to_obj(dentry)->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry)); ++ yaffs_gross_unlock(dev); ++ ++ if (!alias) ++ return ERR_PTR(-ENOMEM); ++ set_delayed_call(done, kfree_link, alias); ++ return alias; ++} ++#endif ++ ++#ifdef YAFFS_HAS_PUT_INODE ++ ++/* For now put inode is just for debugging ++ * Put inode is called when the inode **structure** is put. ++ */ ++static void yaffs_put_inode(struct inode *inode) ++{ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_put_inode: ino %d, count %d"), ++ (int)inode->i_ino, atomic_read(&inode->i_count); ++ ++} ++#endif ++ ++#if (YAFFS_NEW_FOLLOW_LINK == 1) ++void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias) ++{ ++ kfree(alias); ++} ++#endif ++ ++static const struct inode_operations yaffs_symlink_inode_operations = { ++ .readlink = yaffs_readlink, ++#if (YAFFS_NEW_GET_LINK == 1) ++ .get_link = yaffs_get_link, ++#else ++ .follow_link = yaffs_follow_link, ++#endif ++#if (YAFFS_NEW_FOLLOW_LINK == 1) ++ .put_link = yaffs_put_link, ++#endif ++ .setattr = yaffs_setattr, ++#ifdef YAFFS_USE_XATTR ++ .setxattr = yaffs_setxattr, ++ .getxattr = yaffs_getxattr, ++ .removexattr = yaffs_removexattr, ++#endif ++ .listxattr = yaffs_listxattr, ++}; ++ ++#ifdef YAFFS_USE_OWN_IGET ++ ++static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino) ++{ ++ struct inode *inode; ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev = yaffs_super_to_dev(sb); ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_iget for %lu", ino); ++ ++ inode = iget_locked(sb, ino); ++ if (!inode) ++ return ERR_PTR(-ENOMEM); ++ if (!(inode->i_state & I_NEW)) ++ return inode; ++ ++ /* NB This is called as a side effect of other functions, but ++ * we had to release the lock to prevent deadlocks, so ++ * need to lock again. ++ */ ++ ++ yaffs_gross_lock(dev); ++ ++ obj = yaffs_find_by_number(dev, inode->i_ino); ++ ++ yaffs_fill_inode_from_obj(inode, obj); ++ ++ yaffs_gross_unlock(dev); ++ ++ unlock_new_inode(inode); ++ return inode; ++} ++ ++#else ++ ++static void yaffs_read_inode(struct inode *inode) ++{ ++ /* NB This is called as a side effect of other functions, but ++ * we had to release the lock to prevent deadlocks, so ++ * need to lock again. ++ */ ++ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev = yaffs_super_to_dev(inode->i_sb); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_read_inode for %d", (int)inode->i_ino); ++ ++ if (current != yaffs_dev_to_lc(dev)->readdir_process) ++ yaffs_gross_lock(dev); ++ ++ obj = yaffs_find_by_number(dev, inode->i_ino); ++ ++ yaffs_fill_inode_from_obj(inode, obj); ++ ++ if (current != yaffs_dev_to_lc(dev)->readdir_process) ++ yaffs_gross_unlock(dev); ++} ++ ++#endif ++ ++ ++ ++struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, ++ struct yaffs_obj *obj) ++{ ++ struct inode *inode; ++ ++ if (!sb) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_get_inode for NULL super_block!!"); ++ return NULL; ++ ++ } ++ ++ if (!obj) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_get_inode for NULL object!!"); ++ return NULL; ++ ++ } ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_get_inode for object %d", obj->obj_id); ++ ++ inode = Y_IGET(sb, obj->obj_id); ++ if (IS_ERR(inode)) ++ return NULL; ++ ++ /* NB Side effect: iget calls back to yaffs_read_inode(). */ ++ /* iget also increments the inode's i_count */ ++ /* NB You can't be holding gross_lock or deadlock will happen! */ ++ ++ return inode; ++} ++ ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) ++#define YCRED(x) x ++#else ++#define YCRED(x) (x->cred) ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) ++#define YPROC_uid(p) (YCRED(p)->fsuid) ++#define YPROC_gid(p) (YCRED(p)->fsgid) ++#define EXTRACT_gid(x) x ++#define EXTRACT_uid(x) x ++#define MAKE_gid(x) x ++#define MAKE_uid(x) x ++#else ++#define YPROC_uid(p) from_kuid(&init_user_ns, YCRED(p)->fsuid) ++#define YPROC_gid(p) from_kgid(&init_user_ns, YCRED(p)->fsgid) ++#define EXTRACT_gid(x) from_kgid(&init_user_ns, x) ++#define EXTRACT_uid(x) from_kuid(&init_user_ns, x) ++#define MAKE_gid(x) make_kgid(&init_user_ns, x) ++#define MAKE_uid(x) make_kuid(&init_user_ns, x) ++#endif ++ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) ++static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t rdev) ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, ++ dev_t rdev) ++#else ++static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, ++ int rdev) ++#endif ++{ ++ struct inode *inode; ++ ++ struct yaffs_obj *obj = NULL; ++ struct yaffs_dev *dev; ++ ++ struct yaffs_obj *parent = yaffs_inode_to_obj(dir); ++ ++ int error = -ENOSPC; ++ uid_t uid = YPROC_uid(current); ++ gid_t gid = ++ (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current); ++ ++ if ((dir->i_mode & S_ISGID) && S_ISDIR(mode)) ++ mode |= S_ISGID; ++ ++ if (parent) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_mknod: parent object %d type %d", ++ parent->obj_id, parent->variant_type); ++ } else { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_mknod: could not get parent object"); ++ return -EPERM; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_mknod: making oject for %s, mode %x dev %x", ++ dentry->d_name.name, mode, rdev); ++ ++ dev = parent->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ switch (mode & S_IFMT) { ++ default: ++ /* Special (socket, fifo, device...) */ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making special"); ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++ obj = ++ yaffs_create_special(parent, dentry->d_name.name, mode, uid, ++ gid, old_encode_dev(rdev)); ++#else ++ obj = ++ yaffs_create_special(parent, dentry->d_name.name, mode, uid, ++ gid, rdev); ++#endif ++ break; ++ case S_IFREG: /* file */ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making file"); ++ obj = yaffs_create_file(parent, dentry->d_name.name, mode, uid, ++ gid); ++ break; ++ case S_IFDIR: /* directory */ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making directory"); ++ obj = yaffs_create_dir(parent, dentry->d_name.name, mode, ++ uid, gid); ++ break; ++ case S_IFLNK: /* symlink */ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making symlink"); ++ obj = NULL; /* Do we ever get here? */ ++ break; ++ } ++ ++ /* Can not call yaffs_get_inode() with gross lock held */ ++ yaffs_gross_unlock(dev); ++ ++ if (obj) { ++ inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); ++ d_instantiate(dentry, inode); ++ update_dir_time(dir); ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_mknod created object %d count = %d", ++ obj->obj_id, atomic_read(&inode->i_count)); ++ error = 0; ++ yaffs_fill_inode_from_obj(dir, parent); ++ } else { ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod failed making object"); ++ error = -ENOMEM; ++ } ++ ++ return error; ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) ++static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ++#else ++static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ++#endif ++{ ++ int ret_val; ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mkdir"); ++ ret_val = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0); ++ return ret_val; ++} ++ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool dummy) ++#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) ++static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ struct nameidata *n) ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, ++ struct nameidata *n) ++#else ++static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) ++#endif ++{ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_create"); ++ return yaffs_mknod(dir, dentry, mode | S_IFREG, 0); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) ++static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int dummy) ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, ++ struct nameidata *n) ++#else ++static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) ++#endif ++{ ++ struct yaffs_obj *obj; ++ struct inode *inode = NULL; /* NCB 2.5/2.6 needs NULL here */ ++ ++ struct yaffs_dev *dev = yaffs_inode_to_obj(dir)->my_dev; ++ ++ if (current != yaffs_dev_to_lc(dev)->readdir_process) ++ yaffs_gross_lock(dev); ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup for %d:%s", ++ yaffs_inode_to_obj(dir)->obj_id, dentry->d_name.name); ++ ++ obj = yaffs_find_by_name(yaffs_inode_to_obj(dir), dentry->d_name.name); ++ ++ obj = yaffs_get_equivalent_obj(obj); /* in case it was a hardlink */ ++ ++ /* Can't hold gross lock when calling yaffs_get_inode() */ ++ if (current != yaffs_dev_to_lc(dev)->readdir_process) ++ yaffs_gross_unlock(dev); ++ ++ if (obj) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_lookup found %d", obj->obj_id); ++ ++ inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); ++ } else { ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup not found"); ++ ++ } ++ ++/* added NCB for 2.5/6 compatability - forces add even if inode is ++ * NULL which creates dentry hash */ ++ d_add(dentry, inode); ++ ++ return NULL; ++} ++ ++/* ++ * Create a link... ++ */ ++static int yaffs_link(struct dentry *old_dentry, struct inode *dir, ++ struct dentry *dentry) ++{ ++ struct inode *inode = old_dentry->d_inode; ++ struct yaffs_obj *obj = NULL; ++ struct yaffs_obj *link = NULL; ++ struct yaffs_dev *dev; ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_link"); ++ ++ obj = yaffs_inode_to_obj(inode); ++ dev = obj->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ if (!S_ISDIR(inode->i_mode)) /* Don't link directories */ ++ link = ++ yaffs_link_obj(yaffs_inode_to_obj(dir), dentry->d_name.name, ++ obj); ++ ++ if (link) { ++ set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj)); ++ d_instantiate(dentry, old_dentry->d_inode); ++ atomic_inc(&old_dentry->d_inode->i_count); ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_link link count %d i_count %d", ++ old_dentry->d_inode->i_nlink, ++ atomic_read(&old_dentry->d_inode->i_count)); ++ } ++ ++ yaffs_gross_unlock(dev); ++ ++ if (link) { ++ update_dir_time(dir); ++ return 0; ++ } ++ ++ return -EPERM; ++} ++ ++static int yaffs_symlink(struct inode *dir, struct dentry *dentry, ++ const char *symname) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++ uid_t uid = YPROC_uid(current); ++ gid_t gid = ++ (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current); ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink"); ++ ++ if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) > ++ YAFFS_MAX_NAME_LENGTH) ++ return -ENAMETOOLONG; ++ ++ if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) > ++ YAFFS_MAX_ALIAS_LENGTH) ++ return -ENAMETOOLONG; ++ ++ dev = yaffs_inode_to_obj(dir)->my_dev; ++ yaffs_gross_lock(dev); ++ obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name, ++ S_IFLNK | S_IRWXUGO, uid, gid, symname); ++ yaffs_gross_unlock(dev); ++ ++ if (obj) { ++ struct inode *inode; ++ ++ inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); ++ d_instantiate(dentry, inode); ++ update_dir_time(dir); ++ yaffs_trace(YAFFS_TRACE_OS, "symlink created OK"); ++ return 0; ++ } else { ++ yaffs_trace(YAFFS_TRACE_OS, "symlink not created"); ++ } ++ ++ return -ENOMEM; ++} ++ ++/* ++ * The VFS layer already does all the dentry stuff for rename. ++ * ++ * NB: POSIX says you can rename an object over an old object of the same name ++ */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) ++static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry, unsigned int unused) ++#else ++static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, ++ struct inode *new_dir, struct dentry *new_dentry) ++#endif ++{ ++ struct yaffs_dev *dev; ++ int ret_val = YAFFS_FAIL; ++ struct yaffs_obj *target; ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_rename"); ++ dev = yaffs_inode_to_obj(old_dir)->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ /* Check if the target is an existing directory that is not empty. */ ++ target = yaffs_find_by_name(yaffs_inode_to_obj(new_dir), ++ new_dentry->d_name.name); ++ ++ if (target && target->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY && ++ !list_empty(&target->variant.dir_variant.children)) { ++ ++ yaffs_trace(YAFFS_TRACE_OS, "target is non-empty dir"); ++ ++ ret_val = YAFFS_FAIL; ++ } else { ++ /* Now does unlinking internally using shadowing mechanism */ ++ yaffs_trace(YAFFS_TRACE_OS, "calling yaffs_rename_obj"); ++ ++ ret_val = yaffs_rename_obj(yaffs_inode_to_obj(old_dir), ++ old_dentry->d_name.name, ++ yaffs_inode_to_obj(new_dir), ++ new_dentry->d_name.name); ++ } ++ yaffs_gross_unlock(dev); ++ ++ if (ret_val == YAFFS_OK) { ++ if (target) ++ inode_dec_link_count(new_dentry->d_inode); ++ ++ update_dir_time(old_dir); ++ if (old_dir != new_dir) ++ update_dir_time(new_dir); ++ return 0; ++ } else { ++ return -ENOTEMPTY; ++ } ++} ++ ++ ++ ++ ++static int yaffs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ int ret_val; ++ ++ struct yaffs_dev *dev; ++ struct yaffs_obj *obj; ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_unlink %d:%s", ++ (int)(dir->i_ino), dentry->d_name.name); ++ obj = yaffs_inode_to_obj(dir); ++ dev = obj->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ ret_val = yaffs_unlinker(obj, dentry->d_name.name); ++ ++ if (ret_val == YAFFS_OK) { ++ inode_dec_link_count(dentry->d_inode); ++ dir->i_version++; ++ yaffs_gross_unlock(dev); ++ update_dir_time(dir); ++ return 0; ++ } ++ yaffs_gross_unlock(dev); ++ return -ENOTEMPTY; ++} ++ ++ ++ ++static const struct inode_operations yaffs_dir_inode_operations = { ++ .create = yaffs_create, ++ .lookup = yaffs_lookup, ++ .link = yaffs_link, ++ .unlink = yaffs_unlink, ++ .symlink = yaffs_symlink, ++ .mkdir = yaffs_mkdir, ++ .rmdir = yaffs_unlink, ++ .mknod = yaffs_mknod, ++ .rename = yaffs_rename, ++ .setattr = yaffs_setattr, ++ .listxattr = yaffs_listxattr, ++#ifdef YAFFS_USE_XATTR ++ .setxattr = yaffs_setxattr, ++ .getxattr = yaffs_getxattr, ++ .removexattr = yaffs_removexattr, ++#endif ++}; ++ ++/*-----------------------------------------------------------------*/ ++/* Directory search context allows us to unlock access to yaffs during ++ * filldir without causing problems with the directory being modified. ++ * This is similar to the tried and tested mechanism used in yaffs direct. ++ * ++ * A search context iterates along a doubly linked list of siblings in the ++ * directory. If the iterating object is deleted then this would corrupt ++ * the list iteration, likely causing a crash. The search context avoids ++ * this by using the remove_obj_fn to move the search context to the ++ * next object before the object is deleted. ++ * ++ * Many readdirs (and thus seach conexts) may be alive simulateously so ++ * each struct yaffs_dev has a list of these. ++ * ++ * A seach context lives for the duration of a readdir. ++ * ++ * All these functions must be called while yaffs is locked. ++ */ ++ ++struct yaffs_search_context { ++ struct yaffs_dev *dev; ++ struct yaffs_obj *dir_obj; ++ struct yaffs_obj *next_return; ++ struct list_head others; ++}; ++ ++/* ++ * yaffs_new_search() creates a new search context, initialises it and ++ * adds it to the device's search context list. ++ * ++ * Called at start of readdir. ++ */ ++static struct yaffs_search_context *yaffs_new_search(struct yaffs_obj *dir) ++{ ++ struct yaffs_dev *dev = dir->my_dev; ++ struct yaffs_search_context *sc = ++ kmalloc(sizeof(struct yaffs_search_context), GFP_NOFS); ++ if (sc) { ++ sc->dir_obj = dir; ++ sc->dev = dev; ++ if (list_empty(&sc->dir_obj->variant.dir_variant.children)) ++ sc->next_return = NULL; ++ else ++ sc->next_return = ++ list_entry(dir->variant.dir_variant.children.next, ++ struct yaffs_obj, siblings); ++ INIT_LIST_HEAD(&sc->others); ++ list_add(&sc->others, &(yaffs_dev_to_lc(dev)->search_contexts)); ++ } ++ return sc; ++} ++ ++/* ++ * yaffs_search_end() disposes of a search context and cleans up. ++ */ ++static void yaffs_search_end(struct yaffs_search_context *sc) ++{ ++ if (sc) { ++ list_del(&sc->others); ++ kfree(sc); ++ } ++} ++ ++/* ++ * yaffs_search_advance() moves a search context to the next object. ++ * Called when the search iterates or when an object removal causes ++ * the search context to be moved to the next object. ++ */ ++static void yaffs_search_advance(struct yaffs_search_context *sc) ++{ ++ if (!sc) ++ return; ++ ++ if (sc->next_return == NULL || ++ list_empty(&sc->dir_obj->variant.dir_variant.children)) ++ sc->next_return = NULL; ++ else { ++ struct list_head *next = sc->next_return->siblings.next; ++ ++ if (next == &sc->dir_obj->variant.dir_variant.children) ++ sc->next_return = NULL; /* end of list */ ++ else ++ sc->next_return = ++ list_entry(next, struct yaffs_obj, siblings); ++ } ++} ++ ++/* ++ * yaffs_remove_obj_callback() is called when an object is unlinked. ++ * We check open search contexts and advance any which are currently ++ * on the object being iterated. ++ */ ++static void yaffs_remove_obj_callback(struct yaffs_obj *obj) ++{ ++ ++ struct list_head *i; ++ struct yaffs_search_context *sc; ++ struct list_head *search_contexts = ++ &(yaffs_dev_to_lc(obj->my_dev)->search_contexts); ++ ++ /* Iterate through the directory search contexts. ++ * If any are currently on the object being removed, then advance ++ * the search context to the next object to prevent a hanging pointer. ++ */ ++ list_for_each(i, search_contexts) { ++ sc = list_entry(i, struct yaffs_search_context, others); ++ if (sc->next_return == obj) ++ yaffs_search_advance(sc); ++ } ++ ++} ++ ++ ++/*-----------------------------------------------------------------*/ ++ ++#ifdef YAFFS_USE_DIR_ITERATE ++static int yaffs_iterate(struct file *f, struct dir_context *dc) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++ struct yaffs_search_context *sc; ++ unsigned long curoffs; ++ struct yaffs_obj *l; ++ int ret_val = 0; ++ ++ char name[YAFFS_MAX_NAME_LENGTH + 1]; ++ ++ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); ++ dev = obj->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ yaffs_dev_to_lc(dev)->readdir_process = current; ++ ++ sc = yaffs_new_search(obj); ++ if (!sc) { ++ ret_val = -ENOMEM; ++ goto out; ++ } ++ ++ if (!dir_emit_dots(f, dc)) ++ return 0; ++ ++ curoffs = 1; ++ ++ while (sc->next_return) { ++ curoffs++; ++ l = sc->next_return; ++ if (curoffs >= dc->pos) { ++ int this_inode = yaffs_get_obj_inode(l); ++ int this_type = yaffs_get_obj_type(l); ++ ++ yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1); ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_readdir: %s inode %d", ++ name, yaffs_get_obj_inode(l)); ++ ++ yaffs_gross_unlock(dev); ++ ++ if (!dir_emit(dc, ++ name, ++ strlen(name), ++ this_inode, ++ this_type)) { ++ yaffs_gross_lock(dev); ++ goto out; ++ } ++ ++ yaffs_gross_lock(dev); ++ ++ dc->pos++; ++ f->f_pos++; ++ } ++ yaffs_search_advance(sc); ++ } ++ ++out: ++ yaffs_search_end(sc); ++ yaffs_dev_to_lc(dev)->readdir_process = NULL; ++ yaffs_gross_unlock(dev); ++ ++ return ret_val; ++} ++ ++#else ++ ++static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++ struct yaffs_search_context *sc; ++ struct inode *inode = Y_GET_DENTRY(f)->d_inode; ++ unsigned long offset, curoffs; ++ struct yaffs_obj *l; ++ int ret_val = 0; ++ ++ char name[YAFFS_MAX_NAME_LENGTH + 1]; ++ ++ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); ++ dev = obj->my_dev; ++ ++ yaffs_gross_lock(dev); ++ ++ yaffs_dev_to_lc(dev)->readdir_process = current; ++ ++ offset = f->f_pos; ++ ++ sc = yaffs_new_search(obj); ++ if (!sc) { ++ ret_val = -ENOMEM; ++ goto out; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_readdir: starting at %d", (int)offset); ++ ++ if (offset == 0) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_readdir: entry . ino %d", ++ (int)inode->i_ino); ++ yaffs_gross_unlock(dev); ++ if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0) { ++ yaffs_gross_lock(dev); ++ goto out; ++ } ++ yaffs_gross_lock(dev); ++ offset++; ++ f->f_pos++; ++ } ++ if (offset == 1) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_readdir: entry .. ino %d", ++ (int)f->f_dentry->d_parent->d_inode->i_ino); ++ yaffs_gross_unlock(dev); ++ if (filldir(dirent, "..", 2, offset, ++ f->f_dentry->d_parent->d_inode->i_ino, ++ DT_DIR) < 0) { ++ yaffs_gross_lock(dev); ++ goto out; ++ } ++ yaffs_gross_lock(dev); ++ offset++; ++ f->f_pos++; ++ } ++ ++ curoffs = 1; ++ ++ /* If the directory has changed since the open or last call to ++ readdir, rewind to after the 2 canned entries. */ ++ if (f->f_version != inode->i_version) { ++ offset = 2; ++ f->f_pos = offset; ++ f->f_version = inode->i_version; ++ } ++ ++ while (sc->next_return) { ++ curoffs++; ++ l = sc->next_return; ++ if (curoffs >= offset) { ++ int this_inode = yaffs_get_obj_inode(l); ++ int this_type = yaffs_get_obj_type(l); ++ ++ yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1); ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_readdir: %s inode %d", ++ name, yaffs_get_obj_inode(l)); ++ ++ yaffs_gross_unlock(dev); ++ ++ if (filldir(dirent, ++ name, ++ strlen(name), ++ offset, this_inode, this_type) < 0) { ++ yaffs_gross_lock(dev); ++ goto out; ++ } ++ ++ yaffs_gross_lock(dev); ++ ++ offset++; ++ f->f_pos++; ++ } ++ yaffs_search_advance(sc); ++ } ++ ++out: ++ yaffs_search_end(sc); ++ yaffs_dev_to_lc(dev)->readdir_process = NULL; ++ yaffs_gross_unlock(dev); ++ ++ return ret_val; ++} ++ ++#endif ++ ++static const struct file_operations yaffs_dir_operations = { ++ .read = generic_read_dir, ++#ifdef YAFFS_USE_DIR_ITERATE ++ .iterate = yaffs_iterate, ++#else ++ .readdir = yaffs_readdir, ++#endif ++ .fsync = yaffs_sync_object, ++ .llseek = generic_file_llseek, ++}; ++ ++static void yaffs_fill_inode_from_obj(struct inode *inode, ++ struct yaffs_obj *obj) ++{ ++ if (inode && obj) { ++ ++ /* Check mode against the variant type and attempt to repair if broken. */ ++ u32 mode = obj->yst_mode; ++ switch (obj->variant_type) { ++ case YAFFS_OBJECT_TYPE_FILE: ++ if (!S_ISREG(mode)) { ++ obj->yst_mode &= ~S_IFMT; ++ obj->yst_mode |= S_IFREG; ++ } ++ ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ if (!S_ISLNK(mode)) { ++ obj->yst_mode &= ~S_IFMT; ++ obj->yst_mode |= S_IFLNK; ++ } ++ ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ if (!S_ISDIR(mode)) { ++ obj->yst_mode &= ~S_IFMT; ++ obj->yst_mode |= S_IFDIR; ++ } ++ ++ break; ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ default: ++ /* TODO? */ ++ break; ++ } ++ ++ inode->i_flags |= S_NOATIME; ++ ++ inode->i_ino = obj->obj_id; ++ inode->i_mode = obj->yst_mode; ++ inode->i_uid = MAKE_uid(obj->yst_uid); ++ inode->i_gid = MAKE_gid(obj->yst_gid); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) ++ inode->i_blksize = inode->i_sb->s_blocksize; ++#endif ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++ ++ inode->i_rdev = old_decode_dev(obj->yst_rdev); ++ inode->i_atime.tv_sec = (time_t) (obj->yst_atime); ++ inode->i_atime.tv_nsec = 0; ++ inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; ++ inode->i_mtime.tv_nsec = 0; ++ inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; ++ inode->i_ctime.tv_nsec = 0; ++#else ++ inode->i_rdev = obj->yst_rdev; ++ inode->i_atime = obj->yst_atime; ++ inode->i_mtime = obj->yst_mtime; ++ inode->i_ctime = obj->yst_ctime; ++#endif ++ inode->i_size = yaffs_get_obj_length(obj); ++ inode->i_blocks = (inode->i_size + 511) >> 9; ++ ++ set_nlink(inode, yaffs_get_obj_link_count(obj)); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d", ++ inode->i_mode, obj->yst_uid, obj->yst_gid, ++ inode->i_size, atomic_read(&inode->i_count)); ++ ++ switch (obj->yst_mode & S_IFMT) { ++ default: /* fifo, device or socket */ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++ init_special_inode(inode, obj->yst_mode, ++ old_decode_dev(obj->yst_rdev)); ++#else ++ init_special_inode(inode, obj->yst_mode, ++ (dev_t) (obj->yst_rdev)); ++#endif ++ break; ++ case S_IFREG: /* file */ ++ inode->i_op = &yaffs_file_inode_operations; ++ inode->i_fop = &yaffs_file_operations; ++ inode->i_mapping->a_ops = ++ &yaffs_file_address_operations; ++ break; ++ case S_IFDIR: /* directory */ ++ inode->i_op = &yaffs_dir_inode_operations; ++ inode->i_fop = &yaffs_dir_operations; ++ break; ++ case S_IFLNK: /* symlink */ ++ inode->i_op = &yaffs_symlink_inode_operations; ++ break; ++ } ++ ++ yaffs_inode_to_obj_lv(inode) = obj; ++ ++ obj->my_inode = inode; ++ ++ } else { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_fill_inode invalid parameters"); ++ } ++ ++} ++ ++ ++ ++/* ++ * yaffs background thread functions . ++ * yaffs_bg_thread_fn() the thread function ++ * yaffs_bg_start() launches the background thread. ++ * yaffs_bg_stop() cleans up the background thread. ++ * ++ * NB: ++ * The thread should only run after the yaffs is initialised ++ * The thread should be stopped before yaffs is unmounted. ++ * The thread should not do any writing while the fs is in read only. ++ */ ++ ++static unsigned yaffs_bg_gc_urgency(struct yaffs_dev *dev) ++{ ++ unsigned erased_chunks = ++ dev->n_erased_blocks * dev->param.chunks_per_block; ++ struct yaffs_linux_context *context = yaffs_dev_to_lc(dev); ++ unsigned scattered = 0; /* Free chunks not in an erased block */ ++ ++ if (erased_chunks < dev->n_free_chunks) ++ scattered = (dev->n_free_chunks - erased_chunks); ++ ++ if (!context->bg_running) ++ return 0; ++ else if (scattered < (dev->param.chunks_per_block * 2)) ++ return 0; ++ else if (erased_chunks > dev->n_free_chunks / 2) ++ return 0; ++ else if (erased_chunks > dev->n_free_chunks / 4) ++ return 1; ++ else ++ return 2; ++} ++ ++#ifdef YAFFS_COMPILE_BACKGROUND ++ ++void yaffs_background_waker(unsigned long data) ++{ ++ wake_up_process((struct task_struct *)data); ++} ++ ++static int yaffs_bg_thread_fn(void *data) ++{ ++ struct yaffs_dev *dev = (struct yaffs_dev *)data; ++ struct yaffs_linux_context *context = yaffs_dev_to_lc(dev); ++ unsigned long now = jiffies; ++ unsigned long next_dir_update = now; ++ unsigned long next_gc = now; ++ unsigned long expires; ++ unsigned int urgency; ++ ++ int gc_result; ++ struct timer_list timer; ++ ++ yaffs_trace(YAFFS_TRACE_BACKGROUND, ++ "yaffs_background starting for dev %p", (void *)dev); ++ ++#ifdef YAFFS_COMPILE_FREEZER ++ set_freezable(); ++#endif ++ while (context->bg_running) { ++ yaffs_trace(YAFFS_TRACE_BACKGROUND, "yaffs_background"); ++ ++ if (kthread_should_stop()) ++ break; ++ ++#ifdef YAFFS_COMPILE_FREEZER ++ if (try_to_freeze()) ++ continue; ++#endif ++ yaffs_gross_lock(dev); ++ ++ now = jiffies; ++ ++ if (time_after(now, next_dir_update) && yaffs_bg_enable) { ++ yaffs_update_dirty_dirs(dev); ++ next_dir_update = now + HZ; ++ } ++ ++ if (time_after(now, next_gc) && yaffs_bg_enable) { ++ if (!dev->is_checkpointed) { ++ urgency = yaffs_bg_gc_urgency(dev); ++ gc_result = yaffs_bg_gc(dev, urgency); ++ if (urgency > 1) ++ next_gc = now + HZ / 20 + 1; ++ else if (urgency > 0) ++ next_gc = now + HZ / 10 + 1; ++ else ++ next_gc = now + HZ * 2; ++ } else { ++ /* ++ * gc not running so set to next_dir_update ++ * to cut down on wake ups ++ */ ++ next_gc = next_dir_update; ++ } ++ } ++ yaffs_gross_unlock(dev); ++#if 1 ++ expires = next_dir_update; ++ if (time_before(next_gc, expires)) ++ expires = next_gc; ++ if (time_before(expires, now)) ++ expires = now + HZ; ++ ++ Y_INIT_TIMER(&timer); ++ timer.expires = expires + 1; ++ timer.data = (unsigned long)current; ++ timer.function = yaffs_background_waker; ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ add_timer(&timer); ++ schedule(); ++ del_timer_sync(&timer); ++#else ++ msleep(10); ++#endif ++ } ++ ++ return 0; ++} ++ ++static int yaffs_bg_start(struct yaffs_dev *dev) ++{ ++ int retval = 0; ++ struct yaffs_linux_context *context = yaffs_dev_to_lc(dev); ++ ++ if (dev->read_only) ++ return -1; ++ ++ context->bg_running = 1; ++ ++ context->bg_thread = kthread_run(yaffs_bg_thread_fn, ++ (void *)dev, "yaffs-bg-%d", ++ context->mount_id); ++ ++ if (IS_ERR(context->bg_thread)) { ++ retval = PTR_ERR(context->bg_thread); ++ context->bg_thread = NULL; ++ context->bg_running = 0; ++ } ++ return retval; ++} ++ ++static void yaffs_bg_stop(struct yaffs_dev *dev) ++{ ++ struct yaffs_linux_context *ctxt = yaffs_dev_to_lc(dev); ++ ++ ctxt->bg_running = 0; ++ ++ if (ctxt->bg_thread) { ++ kthread_stop(ctxt->bg_thread); ++ ctxt->bg_thread = NULL; ++ } ++} ++#else ++static int yaffs_bg_thread_fn(void *data) ++{ ++ return 0; ++} ++ ++static int yaffs_bg_start(struct yaffs_dev *dev) ++{ ++ return 0; ++} ++ ++static void yaffs_bg_stop(struct yaffs_dev *dev) ++{ ++} ++#endif ++ ++ ++static void yaffs_flush_inodes(struct super_block *sb) ++{ ++ struct inode *iptr; ++ struct yaffs_obj *obj; ++ ++ list_for_each_entry(iptr, &sb->s_inodes, i_sb_list) { ++ obj = yaffs_inode_to_obj(iptr); ++ if (obj) { ++ yaffs_trace(YAFFS_TRACE_OS, ++ "flushing obj %d", ++ obj->obj_id); ++ yaffs_flush_file(obj, 1, 0, 0); ++ } ++ } ++} ++ ++static void yaffs_flush_super(struct super_block *sb, int do_checkpoint) ++{ ++ struct yaffs_dev *dev = yaffs_super_to_dev(sb); ++ if (!dev) ++ return; ++ ++ yaffs_flush_inodes(sb); ++ yaffs_update_dirty_dirs(dev); ++ yaffs_flush_whole_cache(dev, 1); ++ if (do_checkpoint) ++ yaffs_checkpoint_save(dev); ++} ++ ++static LIST_HEAD(yaffs_context_list); ++struct mutex yaffs_context_lock; ++ ++static void yaffs_put_super(struct super_block *sb) ++{ ++ struct yaffs_dev *dev = yaffs_super_to_dev(sb); ++ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); ++ ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS, ++ "yaffs_put_super"); ++ ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND, ++ "Shutting down yaffs background thread"); ++ yaffs_bg_stop(dev); ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND, ++ "yaffs background thread shut down"); ++ ++ yaffs_gross_lock(dev); ++ ++ yaffs_flush_super(sb, 1); ++ ++ yaffs_deinitialise(dev); ++ ++ yaffs_gross_unlock(dev); ++ ++ mutex_lock(&yaffs_context_lock); ++ list_del_init(&(yaffs_dev_to_lc(dev)->context_list)); ++ mutex_unlock(&yaffs_context_lock); ++ ++ if (yaffs_dev_to_lc(dev)->spare_buffer) { ++ kfree(yaffs_dev_to_lc(dev)->spare_buffer); ++ yaffs_dev_to_lc(dev)->spare_buffer = NULL; ++ } ++ ++ kfree(dev); ++ ++ yaffs_put_mtd_device(mtd); ++ ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS, ++ "yaffs_put_super done"); ++} ++ ++ ++static unsigned yaffs_gc_control_callback(struct yaffs_dev *dev) ++{ ++ return yaffs_gc_control; ++} ++ ++ ++#ifdef YAFFS_COMPILE_EXPORTFS ++ ++static struct inode *yaffs2_nfs_get_inode(struct super_block *sb, uint64_t ino, ++ uint32_t generation) ++{ ++ return Y_IGET(sb, ino); ++} ++ ++static struct dentry *yaffs2_fh_to_dentry(struct super_block *sb, ++ struct fid *fid, int fh_len, ++ int fh_type) ++{ ++ return generic_fh_to_dentry(sb, fid, fh_len, fh_type, ++ yaffs2_nfs_get_inode); ++} ++ ++static struct dentry *yaffs2_fh_to_parent(struct super_block *sb, ++ struct fid *fid, int fh_len, ++ int fh_type) ++{ ++ return generic_fh_to_parent(sb, fid, fh_len, fh_type, ++ yaffs2_nfs_get_inode); ++} ++ ++struct dentry *yaffs2_get_parent(struct dentry *dentry) ++{ ++ ++ struct super_block *sb = dentry->d_inode->i_sb; ++ struct dentry *parent = ERR_PTR(-ENOENT); ++ struct inode *inode; ++ unsigned long parent_ino; ++ struct yaffs_obj *d_obj; ++ struct yaffs_obj *parent_obj; ++ ++ d_obj = yaffs_inode_to_obj(dentry->d_inode); ++ ++ if (d_obj) { ++ parent_obj = d_obj->parent; ++ if (parent_obj) { ++ parent_ino = yaffs_get_obj_inode(parent_obj); ++ inode = Y_IGET(sb, parent_ino); ++ ++ if (IS_ERR(inode)) { ++ parent = ERR_CAST(inode); ++ } else { ++ parent = d_obtain_alias(inode); ++ if (!IS_ERR(parent)) { ++ parent = ERR_PTR(-ENOMEM); ++ iput(inode); ++ } ++ } ++ } ++ } ++ ++ return parent; ++} ++ ++/* Just declare a zero structure as a NULL value implies ++ * using the default functions of exportfs. ++ */ ++ ++static struct export_operations yaffs_export_ops = { ++ .fh_to_dentry = yaffs2_fh_to_dentry, ++ .fh_to_parent = yaffs2_fh_to_parent, ++ .get_parent = yaffs2_get_parent, ++}; ++ ++#endif ++ ++static void yaffs_unstitch_obj(struct inode *inode, struct yaffs_obj *obj) ++{ ++ /* Clear the association between the inode and ++ * the struct yaffs_obj. ++ */ ++ obj->my_inode = NULL; ++ yaffs_inode_to_obj_lv(inode) = NULL; ++ ++ /* If the object freeing was deferred, then the real ++ * free happens now. ++ * This should fix the inode inconsistency problem. ++ */ ++ yaffs_handle_defered_free(obj); ++} ++ ++#ifdef YAFFS_HAS_EVICT_INODE ++/* yaffs_evict_inode combines into one operation what was previously done in ++ * yaffs_clear_inode() and yaffs_delete_inode() ++ * ++ */ ++static void yaffs_evict_inode(struct inode *inode) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++ int deleteme = 0; ++ ++ obj = yaffs_inode_to_obj(inode); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_evict_inode: ino %d, count %d %s", ++ (int)inode->i_ino, atomic_read(&inode->i_count), ++ obj ? "object exists" : "null object"); ++ ++ if (!inode->i_nlink && !is_bad_inode(inode)) ++ deleteme = 1; ++ truncate_inode_pages(&inode->i_data, 0); ++ Y_CLEAR_INODE(inode); ++ ++ if (deleteme && obj) { ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ yaffs_del_obj(obj); ++ yaffs_gross_unlock(dev); ++ } ++ if (obj) { ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ yaffs_unstitch_obj(inode, obj); ++ yaffs_gross_unlock(dev); ++ } ++} ++#else ++ ++/* clear is called to tell the fs to release any per-inode data it holds. ++ * The object might still exist on disk and is just being thrown out of the cache ++ * or else the object has actually been deleted and we're being called via ++ * the chain ++ * yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode() ++ */ ++ ++static void yaffs_clear_inode(struct inode *inode) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_dev *dev; ++ ++ obj = yaffs_inode_to_obj(inode); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_clear_inode: ino %d, count %d %s", ++ (int)inode->i_ino, atomic_read(&inode->i_count), ++ obj ? "object exists" : "null object"); ++ ++ if (obj) { ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ yaffs_unstitch_obj(inode, obj); ++ yaffs_gross_unlock(dev); ++ } ++ ++} ++ ++/* delete is called when the link count is zero and the inode ++ * is put (ie. nobody wants to know about it anymore, time to ++ * delete the file). ++ * NB Must call clear_inode() ++ */ ++static void yaffs_delete_inode(struct inode *inode) ++{ ++ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); ++ struct yaffs_dev *dev; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_delete_inode: ino %d, count %d %s", ++ (int)inode->i_ino, atomic_read(&inode->i_count), ++ obj ? "object exists" : "null object"); ++ ++ if (obj) { ++ dev = obj->my_dev; ++ yaffs_gross_lock(dev); ++ yaffs_del_obj(obj); ++ yaffs_gross_unlock(dev); ++ } ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13)) ++ truncate_inode_pages(&inode->i_data, 0); ++#endif ++ clear_inode(inode); ++} ++#endif ++ ++ ++ ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev; ++ struct super_block *sb = dentry->d_sb; ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf) ++{ ++ struct yaffs_dev *dev = yaffs_super_to_dev(sb); ++#else ++static int yaffs_statfs(struct super_block *sb, struct statfs *buf) ++{ ++ struct yaffs_dev *dev = yaffs_super_to_dev(sb); ++#endif ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_statfs"); ++ ++ yaffs_gross_lock(dev); ++ ++ buf->f_type = YAFFS_MAGIC; ++ buf->f_bsize = sb->s_blocksize; ++ buf->f_namelen = 255; ++ ++ if (dev->data_bytes_per_chunk & (dev->data_bytes_per_chunk - 1)) { ++ /* Do this if chunk size is not a power of 2 */ ++ ++ uint64_t bytes_in_dev; ++ uint64_t bytes_free; ++ ++ bytes_in_dev = ++ ((uint64_t) ++ ((dev->param.end_block - dev->param.start_block + ++ 1))) * ((uint64_t) (dev->param.chunks_per_block * ++ dev->data_bytes_per_chunk)); ++ ++ do_div(bytes_in_dev, sb->s_blocksize); /* bytes_in_dev becomes the number of blocks */ ++ buf->f_blocks = bytes_in_dev; ++ ++ bytes_free = ((uint64_t) (yaffs_get_n_free_chunks(dev))) * ++ ((uint64_t) (dev->data_bytes_per_chunk)); ++ ++ do_div(bytes_free, sb->s_blocksize); ++ ++ buf->f_bfree = bytes_free; ++ ++ } else if (sb->s_blocksize > dev->data_bytes_per_chunk) { ++ ++ buf->f_blocks = ++ (dev->param.end_block - dev->param.start_block + 1) * ++ dev->param.chunks_per_block / ++ (sb->s_blocksize / dev->data_bytes_per_chunk); ++ buf->f_bfree = ++ yaffs_get_n_free_chunks(dev) / ++ (sb->s_blocksize / dev->data_bytes_per_chunk); ++ } else { ++ buf->f_blocks = ++ (dev->param.end_block - dev->param.start_block + 1) * ++ dev->param.chunks_per_block * ++ (dev->data_bytes_per_chunk / sb->s_blocksize); ++ ++ buf->f_bfree = ++ yaffs_get_n_free_chunks(dev) * ++ (dev->data_bytes_per_chunk / sb->s_blocksize); ++ } ++ ++ buf->f_files = 0; ++ buf->f_ffree = 0; ++ buf->f_bavail = buf->f_bfree; ++ ++ yaffs_gross_unlock(dev); ++ return 0; ++} ++ ++ ++ ++static int yaffs_do_sync_fs(struct super_block *sb, int request_checkpoint) ++{ ++ ++ struct yaffs_dev *dev = yaffs_super_to_dev(sb); ++ unsigned int oneshot_checkpoint = (yaffs_auto_checkpoint & 4); ++ unsigned gc_urgent = yaffs_bg_gc_urgency(dev); ++ int do_checkpoint; ++ int dirty = yaffs_check_super_dirty(dev); ++ ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND, ++ "yaffs_do_sync_fs: gc-urgency %d %s %s%s", ++ gc_urgent, ++ dirty ? "dirty" : "clean", ++ request_checkpoint ? "checkpoint requested" : "no checkpoint", ++ oneshot_checkpoint ? " one-shot" : ""); ++ ++ yaffs_gross_lock(dev); ++ do_checkpoint = ((request_checkpoint && !gc_urgent) || ++ oneshot_checkpoint) && !dev->is_checkpointed; ++ ++ if (dirty || do_checkpoint) { ++ yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint); ++ yaffs_clear_super_dirty(dev); ++ if (oneshot_checkpoint) ++ yaffs_auto_checkpoint &= ~4; ++ } ++ yaffs_gross_unlock(dev); ++ ++ return 0; ++} ++ ++ ++#ifdef YAFFS_HAS_WRITE_SUPER ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++static void yaffs_write_super(struct super_block *sb) ++#else ++static int yaffs_write_super(struct super_block *sb) ++#endif ++{ ++ unsigned request_checkpoint = (yaffs_auto_checkpoint >= 2); ++ ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND, ++ "yaffs_write_super %s", ++ request_checkpoint ? " checkpt" : ""); ++ ++ yaffs_do_sync_fs(sb, request_checkpoint); ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) ++ return 0; ++#endif ++} ++#endif ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++static int yaffs_sync_fs(struct super_block *sb, int wait) ++#else ++static int yaffs_sync_fs(struct super_block *sb) ++#endif ++{ ++ unsigned request_checkpoint = (yaffs_auto_checkpoint >= 1); ++ ++ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC, ++ "yaffs_sync_fs%s", request_checkpoint ? " checkpt" : ""); ++ ++ yaffs_do_sync_fs(sb, request_checkpoint); ++ ++ return 0; ++} ++ ++/* the function only is used to change dev->read_only when this file system ++ * is remounted. ++ */ ++static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data) ++{ ++ int read_only = 0; ++ struct mtd_info *mtd; ++ struct yaffs_dev *dev = 0; ++ ++ /* Get the device */ ++ mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); ++ if (!mtd) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "MTD device #%u doesn't appear to exist", ++ MINOR(sb->s_dev)); ++ return 1; ++ } ++ ++ /* Check it's NAND */ ++ if (mtd->type != MTD_NANDFLASH) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "MTD device is not NAND it's type %d", ++ mtd->type); ++ return 1; ++ } ++ ++ read_only = ((*flags & MS_RDONLY) != 0); ++ if (!read_only && !(mtd->flags & MTD_WRITEABLE)) { ++ read_only = 1; ++ printk(KERN_INFO ++ "yaffs: mtd is read only, setting superblock read only"); ++ *flags |= MS_RDONLY; ++ } ++ ++ dev = sb->s_fs_info; ++ dev->read_only = read_only; ++ ++ return 0; ++} ++ ++static const struct super_operations yaffs_super_ops = { ++ .statfs = yaffs_statfs, ++ ++#ifndef YAFFS_USE_OWN_IGET ++ .read_inode = yaffs_read_inode, ++#endif ++#ifdef YAFFS_HAS_PUT_INODE ++ .put_inode = yaffs_put_inode, ++#endif ++ .put_super = yaffs_put_super, ++#ifdef YAFFS_HAS_EVICT_INODE ++ .evict_inode = yaffs_evict_inode, ++#else ++ .delete_inode = yaffs_delete_inode, ++ .clear_inode = yaffs_clear_inode, ++#endif ++ .sync_fs = yaffs_sync_fs, ++#ifdef YAFFS_HAS_WRITE_SUPER ++ .write_super = yaffs_write_super, ++#endif ++ .remount_fs = yaffs_remount_fs, ++}; ++ ++struct yaffs_options { ++ int inband_tags; ++ int skip_checkpoint_read; ++ int skip_checkpoint_write; ++ int no_cache; ++ int tags_ecc_on; ++ int tags_ecc_overridden; ++ int lazy_loading_enabled; ++ int lazy_loading_overridden; ++ int empty_lost_and_found; ++ int empty_lost_and_found_overridden; ++ int disable_summary; ++}; ++ ++#define MAX_OPT_LEN 30 ++static int yaffs_parse_options(struct yaffs_options *options, ++ const char *options_str) ++{ ++ char cur_opt[MAX_OPT_LEN + 1]; ++ int p; ++ int error = 0; ++ ++ /* Parse through the options which is a comma seperated list */ ++ ++ while (options_str && *options_str && !error) { ++ memset(cur_opt, 0, MAX_OPT_LEN + 1); ++ p = 0; ++ ++ while (*options_str == ',') ++ options_str++; ++ ++ while (*options_str && *options_str != ',') { ++ if (p < MAX_OPT_LEN) { ++ cur_opt[p] = *options_str; ++ p++; ++ } ++ options_str++; ++ } ++ ++ if (!strcmp(cur_opt, "inband-tags")) { ++ options->inband_tags = 1; ++ } else if (!strcmp(cur_opt, "tags-ecc-off")) { ++ options->tags_ecc_on = 0; ++ options->tags_ecc_overridden = 1; ++ } else if (!strcmp(cur_opt, "tags-ecc-on")) { ++ options->tags_ecc_on = 1; ++ options->tags_ecc_overridden = 1; ++ } else if (!strcmp(cur_opt, "lazy-loading-off")) { ++ options->lazy_loading_enabled = 0; ++ options->lazy_loading_overridden = 1; ++ } else if (!strcmp(cur_opt, "lazy-loading-on")) { ++ options->lazy_loading_enabled = 1; ++ options->lazy_loading_overridden = 1; ++ } else if (!strcmp(cur_opt, "disable-summary")) { ++ options->disable_summary = 1; ++ } else if (!strcmp(cur_opt, "empty-lost-and-found-off")) { ++ options->empty_lost_and_found = 0; ++ options->empty_lost_and_found_overridden = 1; ++ } else if (!strcmp(cur_opt, "empty-lost-and-found-on")) { ++ options->empty_lost_and_found = 1; ++ options->empty_lost_and_found_overridden = 1; ++ } else if (!strcmp(cur_opt, "no-cache")) { ++ options->no_cache = 1; ++ } else if (!strcmp(cur_opt, "no-checkpoint-read")) { ++ options->skip_checkpoint_read = 1; ++ } else if (!strcmp(cur_opt, "no-checkpoint-write")) { ++ options->skip_checkpoint_write = 1; ++ } else if (!strcmp(cur_opt, "no-checkpoint")) { ++ options->skip_checkpoint_read = 1; ++ options->skip_checkpoint_write = 1; ++ } else { ++ printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n", ++ cur_opt); ++ error = 1; ++ } ++ } ++ ++ return error; ++} ++ ++ ++static struct dentry *yaffs_make_root(struct inode *inode) ++{ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) ++ struct dentry *root = d_alloc_root(inode); ++ ++ if (!root) ++ iput(inode); ++ ++ return root; ++#else ++ return d_make_root(inode); ++#endif ++} ++ ++ ++ ++ ++static struct super_block *yaffs_internal_read_super(int yaffs_version, ++ struct super_block *sb, ++ void *data, int silent) ++{ ++ int n_blocks; ++ struct inode *inode = NULL; ++ struct dentry *root; ++ struct yaffs_dev *dev = 0; ++ char devname_buf[BDEVNAME_SIZE + 1]; ++ struct mtd_info *mtd; ++ int err; ++ char *data_str = (char *)data; ++ struct yaffs_linux_context *context = NULL; ++ struct yaffs_param *param; ++ ++ int read_only = 0; ++ int inband_tags = 0; ++ ++ struct yaffs_options options; ++ ++ unsigned mount_id; ++ int found; ++ struct yaffs_linux_context *context_iterator; ++ struct list_head *l; ++ ++ if (!sb) { ++ printk(KERN_INFO "yaffs: sb is NULL\n"); ++ return NULL; ++ } ++ ++ sb->s_magic = YAFFS_MAGIC; ++ sb->s_op = &yaffs_super_ops; ++ sb->s_flags |= MS_NOATIME; ++ ++ read_only = ((sb->s_flags & MS_RDONLY) != 0); ++ ++#ifdef YAFFS_COMPILE_EXPORTFS ++ sb->s_export_op = &yaffs_export_ops; ++#endif ++ ++ if (!sb->s_dev) ++ printk(KERN_INFO "yaffs: sb->s_dev is NULL\n"); ++ else if (!yaffs_devname(sb, devname_buf)) ++ printk(KERN_INFO "yaffs: devname is NULL\n"); ++ else ++ printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n", ++ sb->s_dev, ++ yaffs_devname(sb, devname_buf), read_only ? "ro" : "rw"); ++ ++ if (!data_str) ++ data_str = ""; ++ ++ printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str); ++ ++ memset(&options, 0, sizeof(options)); ++ ++ if (yaffs_parse_options(&options, data_str)) { ++ /* Option parsing failed */ ++ return NULL; ++ } ++ ++ sb->s_blocksize = PAGE_CACHE_SIZE; ++ sb->s_blocksize_bits = PAGE_CACHE_SHIFT; ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_read_super: Using yaffs%d", yaffs_version); ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_read_super: block size %d", (int)(sb->s_blocksize)); ++ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs: Attempting MTD mount of %u.%u,\"%s\"", ++ MAJOR(sb->s_dev), MINOR(sb->s_dev), ++ yaffs_devname(sb, devname_buf)); ++ ++ /* Get the device */ ++ mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); ++ if (IS_ERR(mtd)) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs: MTD device %u either not valid or unavailable", ++ MINOR(sb->s_dev)); ++ return NULL; ++ } ++ ++ if (yaffs_auto_select && yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs2"); ++ yaffs_version = 2; ++ } ++ ++ /* Added NCB 26/5/2006 for completeness */ ++ if (yaffs_version == 2 && !options.inband_tags ++ && WRITE_SIZE(mtd) == 512) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1"); ++ yaffs_version = 1; ++ } ++ ++ if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) || ++ options.inband_tags) ++ inband_tags = 1; ++ ++ if(yaffs_verify_mtd(mtd, yaffs_version, inband_tags) < 0) ++ return NULL; ++ ++ /* OK, so if we got here, we have an MTD that's NAND and looks ++ * like it has the right capabilities ++ * Set the struct yaffs_dev up for mtd ++ */ ++ ++ if (!read_only && !(mtd->flags & MTD_WRITEABLE)) { ++ read_only = 1; ++ printk(KERN_INFO ++ "yaffs: mtd is read only, setting superblock read only\n" ++ ); ++ sb->s_flags |= MS_RDONLY; ++ } ++ ++ dev = kmalloc(sizeof(struct yaffs_dev), GFP_KERNEL); ++ context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL); ++ ++ if (!dev || !context) { ++ kfree(dev); ++ kfree(context); ++ dev = NULL; ++ context = NULL; ++ ++ /* Deep shit could not allocate device structure */ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs_read_super: Failed trying to allocate struct yaffs_dev." ++ ); ++ return NULL; ++ } ++ memset(dev, 0, sizeof(struct yaffs_dev)); ++ param = &(dev->param); ++ ++ memset(context, 0, sizeof(struct yaffs_linux_context)); ++ dev->os_context = context; ++ INIT_LIST_HEAD(&(context->context_list)); ++ context->dev = dev; ++ context->super = sb; ++ ++ dev->read_only = read_only; ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++ sb->s_fs_info = dev; ++#else ++ sb->u.generic_sbp = dev; ++#endif ++ ++ ++ dev->driver_context = mtd; ++ param->name = mtd->name; ++ ++ /* Set up the memory size parameters.... */ ++ ++ ++ param->n_reserved_blocks = 5; ++ param->n_caches = (options.no_cache) ? 0 : 10; ++ param->inband_tags = inband_tags; ++ ++ param->enable_xattr = 1; ++ if (options.lazy_loading_overridden) ++ param->disable_lazy_load = !options.lazy_loading_enabled; ++ ++ param->defered_dir_update = 1; ++ ++ if (options.tags_ecc_overridden) ++ param->no_tags_ecc = !options.tags_ecc_on; ++ ++ param->empty_lost_n_found = 1; ++ param->refresh_period = 500; ++ param->disable_summary = options.disable_summary; ++ ++ ++#ifdef CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING ++ param->disable_bad_block_marking = 1; ++#endif ++ if (options.empty_lost_and_found_overridden) ++ param->empty_lost_n_found = options.empty_lost_and_found; ++ ++ /* ... and the functions. */ ++ if (yaffs_version == 2) { ++ param->is_yaffs2 = 1; ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++ param->total_bytes_per_chunk = mtd->writesize; ++ param->chunks_per_block = mtd->erasesize / mtd->writesize; ++#else ++ param->total_bytes_per_chunk = mtd->oobblock; ++ param->chunks_per_block = mtd->erasesize / mtd->oobblock; ++#endif ++ n_blocks = YCALCBLOCKS(mtd->size, mtd->erasesize); ++ ++ param->start_block = 0; ++ param->end_block = n_blocks - 1; ++ } else { ++ param->is_yaffs2 = 0; ++ n_blocks = YCALCBLOCKS(mtd->size, ++ YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); ++ ++ param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK; ++ param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK; ++ } ++ ++ param->start_block = 0; ++ param->end_block = n_blocks - 1; ++ ++ yaffs_mtd_drv_install(dev); ++ ++ param->sb_dirty_fn = yaffs_set_super_dirty; ++ param->gc_control_fn = yaffs_gc_control_callback; ++ ++ yaffs_dev_to_lc(dev)->super = sb; ++ ++ param->use_nand_ecc = 1; ++ ++ param->skip_checkpt_rd = options.skip_checkpoint_read; ++ param->skip_checkpt_wr = options.skip_checkpoint_write; ++ ++ mutex_lock(&yaffs_context_lock); ++ /* Get a mount id */ ++ found = 0; ++ for (mount_id = 0; !found; mount_id++) { ++ found = 1; ++ list_for_each(l, &yaffs_context_list) { ++ context_iterator = ++ list_entry(l, struct yaffs_linux_context, ++ context_list); ++ if (context_iterator->mount_id == mount_id) ++ found = 0; ++ } ++ } ++ context->mount_id = mount_id; ++ ++ list_add_tail(&(yaffs_dev_to_lc(dev)->context_list), ++ &yaffs_context_list); ++ mutex_unlock(&yaffs_context_lock); ++ ++ /* Directory search handling... */ ++ INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->search_contexts)); ++ param->remove_obj_fn = yaffs_remove_obj_callback; ++ ++ mutex_init(&(yaffs_dev_to_lc(dev)->gross_lock)); ++ ++ yaffs_gross_lock(dev); ++ ++ err = yaffs_guts_initialise(dev); ++ ++ yaffs_trace(YAFFS_TRACE_OS, ++ "yaffs_read_super: guts initialised %s", ++ (err == YAFFS_OK) ? "OK" : "FAILED"); ++ ++ if (err == YAFFS_OK) ++ yaffs_bg_start(dev); ++ ++ if (!context->bg_thread) ++ param->defered_dir_update = 0; ++ ++ sb->s_maxbytes = yaffs_max_file_size(dev); ++ ++ /* Release lock before yaffs_get_inode() */ ++ yaffs_gross_unlock(dev); ++ ++ /* Create root inode */ ++ if (err == YAFFS_OK) ++ inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_root(dev)); ++ ++ if (!inode) ++ return NULL; ++ ++ inode->i_op = &yaffs_dir_inode_operations; ++ inode->i_fop = &yaffs_dir_operations; ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode"); ++ ++ root = yaffs_make_root(inode); ++ ++ if (!root) ++ return NULL; ++ ++ sb->s_root = root; ++ if(!dev->is_checkpointed) ++ yaffs_set_super_dirty(dev); ++ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs_read_super: is_checkpointed %d", ++ dev->is_checkpointed); ++ ++ yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: done"); ++ return sb; ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data, ++ int silent) ++{ ++ return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL; ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) ++static struct dentry *yaffs_mount(struct file_system_type *fs_type, int flags, ++ const char *dev_name, void *data) ++{ ++ return mount_bdev(fs_type, flags, dev_name, data, yaffs_internal_read_super_mtd); ++} ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++static int yaffs_read_super(struct file_system_type *fs, ++ int flags, const char *dev_name, ++ void *data, struct vfsmount *mnt) ++{ ++ ++ return get_sb_bdev(fs, flags, dev_name, data, ++ yaffs_internal_read_super_mtd, mnt); ++} ++#else ++static struct super_block *yaffs_read_super(struct file_system_type *fs, ++ int flags, const char *dev_name, ++ void *data) ++{ ++ ++ return get_sb_bdev(fs, flags, dev_name, data, ++ yaffs_internal_read_super_mtd); ++} ++#endif ++ ++static struct file_system_type yaffs_fs_type = { ++ .owner = THIS_MODULE, ++ .name = "yaffs", ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) ++ .mount = yaffs_mount, ++#else ++ .get_sb = yaffs_read_super, ++#endif ++ .kill_sb = kill_block_super, ++ .fs_flags = FS_REQUIRES_DEV, ++}; ++#else ++static struct super_block *yaffs_read_super(struct super_block *sb, void *data, ++ int silent) ++{ ++ return yaffs_internal_read_super(1, sb, data, silent); ++} ++ ++static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, ++ FS_REQUIRES_DEV); ++#endif ++ ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data, ++ int silent) ++{ ++ return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL; ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) ++static struct dentry *yaffs2_mount(struct file_system_type *fs_type, int flags, ++ const char *dev_name, void *data) ++{ ++ return mount_bdev(fs_type, flags, dev_name, data, yaffs2_internal_read_super_mtd); ++} ++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) ++static int yaffs2_read_super(struct file_system_type *fs, ++ int flags, const char *dev_name, void *data, ++ struct vfsmount *mnt) ++{ ++ return get_sb_bdev(fs, flags, dev_name, data, ++ yaffs2_internal_read_super_mtd, mnt); ++} ++#else ++static struct super_block *yaffs2_read_super(struct file_system_type *fs, ++ int flags, const char *dev_name, ++ void *data) ++{ ++ ++ return get_sb_bdev(fs, flags, dev_name, data, ++ yaffs2_internal_read_super_mtd); ++} ++#endif ++ ++static struct file_system_type yaffs2_fs_type = { ++ .owner = THIS_MODULE, ++ .name = "yaffs2", ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) ++ .mount = yaffs2_mount, ++#else ++ .get_sb = yaffs2_read_super, ++#endif ++ .kill_sb = kill_block_super, ++ .fs_flags = FS_REQUIRES_DEV, ++}; ++#else ++static struct super_block *yaffs2_read_super(struct super_block *sb, ++ void *data, int silent) ++{ ++ return yaffs_internal_read_super(2, sb, data, silent); ++} ++ ++static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, ++ FS_REQUIRES_DEV); ++#endif ++ ++ ++static struct proc_dir_entry *my_proc_entry; ++ ++static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev) ++{ ++ struct yaffs_param *param = &dev->param; ++ int bs[10]; ++ ++ yaffs_count_blocks_by_state(dev,bs); ++ ++ buf += sprintf(buf, "start_block.......... %d\n", param->start_block); ++ buf += sprintf(buf, "end_block............ %d\n", param->end_block); ++ buf += sprintf(buf, "total_bytes_per_chunk %d\n", ++ param->total_bytes_per_chunk); ++ buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc); ++ buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc); ++ buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2); ++ buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags); ++ buf += sprintf(buf, "empty_lost_n_found... %d\n", ++ param->empty_lost_n_found); ++ buf += sprintf(buf, "disable_lazy_load.... %d\n", ++ param->disable_lazy_load); ++ buf += sprintf(buf, "disable_bad_block_mrk %d\n", ++ param->disable_bad_block_marking); ++ buf += sprintf(buf, "refresh_period....... %d\n", ++ param->refresh_period); ++ buf += sprintf(buf, "n_caches............. %d\n", param->n_caches); ++ buf += sprintf(buf, "n_reserved_blocks.... %d\n", ++ param->n_reserved_blocks); ++ buf += sprintf(buf, "always_check_erased.. %d\n", ++ param->always_check_erased); ++ buf += sprintf(buf, "\n"); ++ buf += sprintf(buf, "block count by state\n"); ++ buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n", ++ bs[0], bs[1], bs[2], bs[3], bs[4]); ++ buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n", ++ bs[5], bs[6], bs[7], bs[8], bs[9]); ++ ++ return buf; ++} ++ ++static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev) ++{ ++ buf += sprintf(buf, "max file size....... %lld\n", ++ (long long) yaffs_max_file_size(dev)); ++ buf += sprintf(buf, "data_bytes_per_chunk. %d\n", ++ dev->data_bytes_per_chunk); ++ buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits); ++ buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size); ++ buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks); ++ buf += sprintf(buf, "blocks_in_checkpt.... %d\n", ++ dev->blocks_in_checkpt); ++ buf += sprintf(buf, "\n"); ++ buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes); ++ buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj); ++ buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks); ++ buf += sprintf(buf, "\n"); ++ buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes); ++ buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads); ++ buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures); ++ buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies); ++ buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs); ++ buf += sprintf(buf, "passive_gc_count..... %u\n", ++ dev->passive_gc_count); ++ buf += sprintf(buf, "oldest_dirty_gc_count %u\n", ++ dev->oldest_dirty_gc_count); ++ buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks); ++ buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs); ++ buf += sprintf(buf, "n_retried_writes..... %u\n", ++ dev->n_retried_writes); ++ buf += sprintf(buf, "n_retired_blocks..... %u\n", ++ dev->n_retired_blocks); ++ buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed); ++ buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed); ++ buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n", ++ dev->n_tags_ecc_fixed); ++ buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n", ++ dev->n_tags_ecc_unfixed); ++ buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits); ++ buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files); ++ buf += sprintf(buf, "n_unlinked_files..... %u\n", ++ dev->n_unlinked_files); ++ buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count); ++ buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions); ++ buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used); ++ buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used); ++ ++ return buf; ++} ++ ++static int yaffs_proc_read(char *page, ++ char **start, ++ off_t offset, int count, int *eof, void *data) ++{ ++ struct list_head *item; ++ char *buf = page; ++ int step = offset; ++ int n = 0; ++ ++ /* Get proc_file_read() to step 'offset' by one on each sucessive call. ++ * We use 'offset' (*ppos) to indicate where we are in dev_list. ++ * This also assumes the user has posted a read buffer large ++ * enough to hold the complete output; but that's life in /proc. ++ */ ++ ++ *(int *)start = 1; ++ ++ /* Print header first */ ++ if (step == 0) ++ buf += ++ sprintf(buf, "Multi-version YAFFS\n"); ++ else if (step == 1) ++ buf += sprintf(buf, "\n"); ++ else { ++ step -= 2; ++ ++ mutex_lock(&yaffs_context_lock); ++ ++ /* Locate and print the Nth entry. Order N-squared but N is small. */ ++ list_for_each(item, &yaffs_context_list) { ++ struct yaffs_linux_context *dc = ++ list_entry(item, struct yaffs_linux_context, ++ context_list); ++ struct yaffs_dev *dev = dc->dev; ++ ++ if (n < (step & ~1)) { ++ n += 2; ++ continue; ++ } ++ if ((step & 1) == 0) { ++ buf += ++ sprintf(buf, "\nDevice %d \"%s\"\n", n, ++ dev->param.name); ++ buf = yaffs_dump_dev_part0(buf, dev); ++ } else { ++ buf = yaffs_dump_dev_part1(buf, dev); ++ } ++ ++ break; ++ } ++ mutex_unlock(&yaffs_context_lock); ++ } ++ ++ return buf - page < count ? buf - page : count; ++} ++ ++/** ++ * Set the verbosity of the warnings and error messages. ++ * ++ * Note that the names can only be a..z or _ with the current code. ++ */ ++ ++static struct { ++ char *mask_name; ++ unsigned mask_bitfield; ++} mask_flags[] = { ++ {"allocate", YAFFS_TRACE_ALLOCATE}, ++ {"always", YAFFS_TRACE_ALWAYS}, ++ {"background", YAFFS_TRACE_BACKGROUND}, ++ {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS}, ++ {"buffers", YAFFS_TRACE_BUFFERS}, ++ {"bug", YAFFS_TRACE_BUG}, ++ {"checkpt", YAFFS_TRACE_CHECKPOINT}, ++ {"deletion", YAFFS_TRACE_DELETION}, ++ {"erase", YAFFS_TRACE_ERASE}, ++ {"error", YAFFS_TRACE_ERROR}, ++ {"gc_detail", YAFFS_TRACE_GC_DETAIL}, ++ {"gc", YAFFS_TRACE_GC}, ++ {"lock", YAFFS_TRACE_LOCK}, ++ {"mtd", YAFFS_TRACE_MTD}, ++ {"nandaccess", YAFFS_TRACE_NANDACCESS}, ++ {"os", YAFFS_TRACE_OS}, ++ {"scan_debug", YAFFS_TRACE_SCAN_DEBUG}, ++ {"scan", YAFFS_TRACE_SCAN}, ++ {"mount", YAFFS_TRACE_MOUNT}, ++ {"tracing", YAFFS_TRACE_TRACING}, ++ {"sync", YAFFS_TRACE_SYNC}, ++ {"write", YAFFS_TRACE_WRITE}, ++ {"verify", YAFFS_TRACE_VERIFY}, ++ {"verify_nand", YAFFS_TRACE_VERIFY_NAND}, ++ {"verify_full", YAFFS_TRACE_VERIFY_FULL}, ++ {"verify_all", YAFFS_TRACE_VERIFY_ALL}, ++ {"all", 0xffffffff}, ++ {"none", 0}, ++ {NULL, 0}, ++}; ++ ++#define MAX_MASK_NAME_LENGTH 40 ++static int yaffs_proc_write_trace_options(struct file *file, const char *buf, ++ unsigned long count) ++{ ++ unsigned rg = 0, mask_bitfield; ++ char *end; ++ char *mask_name; ++ const char *x; ++ char substring[MAX_MASK_NAME_LENGTH + 1]; ++ int i; ++ int done = 0; ++ int add, len = 0; ++ int pos = 0; ++ ++ rg = yaffs_trace_mask; ++ ++ while (!done && (pos < count)) { ++ done = 1; ++ while ((pos < count) && isspace(buf[pos])) ++ pos++; ++ ++ switch (buf[pos]) { ++ case '+': ++ case '-': ++ case '=': ++ add = buf[pos]; ++ pos++; ++ break; ++ ++ default: ++ add = ' '; ++ break; ++ } ++ mask_name = NULL; ++ ++ mask_bitfield = simple_strtoul(buf + pos, &end, 0); ++ ++ if (end > buf + pos) { ++ mask_name = "numeral"; ++ len = end - (buf + pos); ++ pos += len; ++ done = 0; ++ } else { ++ for (x = buf + pos, i = 0; ++ (*x == '_' || (*x >= 'a' && *x <= 'z')) && ++ i < MAX_MASK_NAME_LENGTH; x++, i++, pos++) ++ substring[i] = *x; ++ substring[i] = '\0'; ++ ++ for (i = 0; mask_flags[i].mask_name != NULL; i++) { ++ if (strcmp(substring, mask_flags[i].mask_name) ++ == 0) { ++ mask_name = mask_flags[i].mask_name; ++ mask_bitfield = ++ mask_flags[i].mask_bitfield; ++ done = 0; ++ break; ++ } ++ } ++ } ++ ++ if (mask_name != NULL) { ++ done = 0; ++ switch (add) { ++ case '-': ++ rg &= ~mask_bitfield; ++ break; ++ case '+': ++ rg |= mask_bitfield; ++ break; ++ case '=': ++ rg = mask_bitfield; ++ break; ++ default: ++ rg |= mask_bitfield; ++ break; ++ } ++ } ++ } ++ ++ yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS; ++ ++ printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask); ++ ++ if (rg & YAFFS_TRACE_ALWAYS) { ++ for (i = 0; mask_flags[i].mask_name != NULL; i++) { ++ char flag; ++ flag = ((rg & mask_flags[i].mask_bitfield) == ++ mask_flags[i].mask_bitfield) ? '+' : '-'; ++ printk(KERN_DEBUG "%c%s\n", flag, ++ mask_flags[i].mask_name); ++ } ++ } ++ ++ return count; ++} ++ ++/* Debug strings are of the form: ++ * .bnnn print info on block n ++ * .cobjn,chunkn print nand chunk id for objn:chunkn ++ */ ++ ++static int yaffs_proc_debug_write(struct file *file, const char *buf, ++ unsigned long count) ++{ ++ ++ char str[100]; ++ char *p0; ++ char *p1; ++ long p1_val; ++ long p0_val; ++ char cmd; ++ struct list_head *item; ++ ++ memset(str, 0, sizeof(str)); ++ memcpy(str, buf, min((size_t)count, sizeof(str) -1)); ++ ++ cmd = str[1]; ++ ++ p0 = str + 2; ++ ++ p1 = p0; ++ ++ while (*p1 && *p1 != ',') { ++ p1++; ++ } ++ *p1 = '\0'; ++ p1++; ++ ++ p0_val = simple_strtol(p0, NULL, 0); ++ p1_val = simple_strtol(p1, NULL, 0); ++ ++ ++ mutex_lock(&yaffs_context_lock); ++ ++ /* Locate and print the Nth entry. Order N-squared but N is small. */ ++ list_for_each(item, &yaffs_context_list) { ++ struct yaffs_linux_context *dc = ++ list_entry(item, struct yaffs_linux_context, ++ context_list); ++ struct yaffs_dev *dev = dc->dev; ++ ++ if (cmd == 'b') { ++ struct yaffs_block_info *bi; ++ ++ bi = yaffs_get_block_info(dev,p0_val); ++ ++ if(bi) { ++ printk("Block %d: state %d, retire %d, use %d, seq %d\n", ++ (int)p0_val, bi->block_state, ++ bi->needs_retiring, bi->pages_in_use, ++ bi->seq_number); ++ } ++ } else if (cmd == 'c') { ++ struct yaffs_obj *obj; ++ int nand_chunk; ++ ++ obj = yaffs_find_by_number(dev, p0_val); ++ if (!obj) ++ printk("No obj %d\n", (int)p0_val); ++ else { ++ if(p1_val == 0) ++ nand_chunk = obj->hdr_chunk; ++ else ++ nand_chunk = ++ yaffs_find_chunk_in_file(obj, ++ p1_val, NULL); ++ printk("Nand chunk for %d:%d is %d\n", ++ (int)p0_val, (int)p1_val, nand_chunk); ++ } ++ } ++ } ++ ++ mutex_unlock(&yaffs_context_lock); ++ ++ return count; ++} ++ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) ++static int yaffs_proc_write(struct file *file, const char *buf, ++ unsigned long count, void *ppos) ++#else ++static ssize_t yaffs_proc_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++#endif ++{ ++ if (buf[0] == '.') ++ return yaffs_proc_debug_write(file, buf, count); ++ return yaffs_proc_write_trace_options(file, buf, count); ++} ++ ++/* Stuff to handle installation of file systems */ ++struct file_system_to_install { ++ struct file_system_type *fst; ++ int installed; ++}; ++ ++static struct file_system_to_install fs_to_install[] = { ++ {&yaffs_fs_type, 0}, ++ {&yaffs2_fs_type, 0}, ++ {NULL, 0} ++}; ++ ++ ++#ifdef YAFFS_NEW_PROCFS ++static int yaffs_proc_show(struct seq_file *m, void *v) ++{ ++ /* FIXME: Unify in a better way? */ ++ char buffer[512]; ++ char *start; ++ int len; ++ ++ len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL); ++ seq_puts(m, buffer); ++ return 0; ++} ++ ++static int yaffs_proc_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, yaffs_proc_show, NULL); ++} ++ ++static struct file_operations procfs_ops = { ++ .owner = THIS_MODULE, ++ .open = yaffs_proc_open, ++ .read = seq_read, ++ .write = yaffs_proc_write, ++}; ++ ++static int yaffs_procfs_init(void) ++{ ++ /* Install the proc_fs entries */ ++ my_proc_entry = proc_create("yaffs", ++ S_IRUGO | S_IFREG, ++ YPROC_ROOT, ++ &procfs_ops); ++ ++ if (my_proc_entry) { ++ return 0; ++ } else { ++ return -ENOMEM; ++ } ++} ++ ++#else ++ ++ ++static int yaffs_procfs_init(void) ++{ ++ /* Install the proc_fs entries */ ++ my_proc_entry = create_proc_entry("yaffs", ++ S_IRUGO | S_IFREG, YPROC_ROOT); ++ ++ if (my_proc_entry) { ++ my_proc_entry->write_proc = yaffs_proc_write; ++ my_proc_entry->read_proc = yaffs_proc_read; ++ my_proc_entry->data = NULL; ++ return 0; ++ } else { ++ return -ENOMEM; ++ } ++} ++ ++#endif ++ ++ ++static int __init init_yaffs_fs(void) ++{ ++ int error = 0; ++ struct file_system_to_install *fsinst; ++ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs Installing."); ++ ++ mutex_init(&yaffs_context_lock); ++ ++ error = yaffs_procfs_init(); ++ if (error) ++ return error; ++ ++ /* Now add the file system entries */ ++ ++ fsinst = fs_to_install; ++ ++ while (fsinst->fst && !error) { ++ error = register_filesystem(fsinst->fst); ++ if (!error) ++ fsinst->installed = 1; ++ fsinst++; ++ } ++ ++ /* Any errors? uninstall */ ++ if (error) { ++ fsinst = fs_to_install; ++ ++ while (fsinst->fst) { ++ if (fsinst->installed) { ++ unregister_filesystem(fsinst->fst); ++ fsinst->installed = 0; ++ } ++ fsinst++; ++ } ++ } ++ ++ return error; ++} ++ ++static void __exit exit_yaffs_fs(void) ++{ ++ ++ struct file_system_to_install *fsinst; ++ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "yaffs removing."); ++ ++ remove_proc_entry("yaffs", YPROC_ROOT); ++ ++ fsinst = fs_to_install; ++ ++ while (fsinst->fst) { ++ if (fsinst->installed) { ++ unregister_filesystem(fsinst->fst); ++ fsinst->installed = 0; ++ } ++ fsinst++; ++ } ++} ++ ++module_init(init_yaffs_fs) ++ module_exit(exit_yaffs_fs) ++ ++ MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system"); ++MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2011"); ++MODULE_LICENSE("GPL"); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs1.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs1.c.patch new file mode 100644 index 00000000..a9951835 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs1.c.patch @@ -0,0 +1,427 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_yaffs1.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_yaffs1.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,424 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_yaffs1.h" ++#include "yportenv.h" ++#include "yaffs_trace.h" ++#include "yaffs_bitmap.h" ++#include "yaffs_getblockinfo.h" ++#include "yaffs_nand.h" ++#include "yaffs_attribs.h" ++ ++int yaffs1_scan(struct yaffs_dev *dev) ++{ ++ struct yaffs_ext_tags tags; ++ u32 blk; ++ int result; ++ int chunk; ++ u32 c; ++ int deleted; ++ enum yaffs_block_state state; ++ LIST_HEAD(hard_list); ++ struct yaffs_block_info *bi; ++ u32 seq_number; ++ struct yaffs_obj_hdr *oh; ++ struct yaffs_obj *in; ++ struct yaffs_obj *parent; ++ int alloc_failed = 0; ++ struct yaffs_shadow_fixer *shadow_fixers = NULL; ++ u8 *chunk_data; ++ ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "yaffs1_scan starts intstartblk %d intendblk %d...", ++ dev->internal_start_block, dev->internal_end_block); ++ ++ chunk_data = yaffs_get_temp_buffer(dev); ++ ++ dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER; ++ ++ /* Scan all the blocks to determine their state */ ++ bi = dev->block_info; ++ for (blk = dev->internal_start_block; blk <= dev->internal_end_block; ++ blk++) { ++ yaffs_clear_chunk_bits(dev, blk); ++ bi->pages_in_use = 0; ++ bi->soft_del_pages = 0; ++ ++ yaffs_query_init_block_state(dev, blk, &state, &seq_number); ++ ++ bi->block_state = state; ++ bi->seq_number = seq_number; ++ ++ if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK) ++ bi->block_state = state = YAFFS_BLOCK_STATE_DEAD; ++ ++ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, ++ "Block scanning block %d state %d seq %d", ++ blk, state, seq_number); ++ ++ if (state == YAFFS_BLOCK_STATE_DEAD) { ++ yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, ++ "block %d is bad", blk); ++ } else if (state == YAFFS_BLOCK_STATE_EMPTY) { ++ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty "); ++ dev->n_erased_blocks++; ++ dev->n_free_chunks += dev->param.chunks_per_block; ++ } ++ bi++; ++ } ++ ++ /* For each block.... */ ++ for (blk = dev->internal_start_block; ++ !alloc_failed && blk <= dev->internal_end_block; blk++) { ++ ++ cond_resched(); ++ ++ bi = yaffs_get_block_info(dev, blk); ++ state = bi->block_state; ++ ++ deleted = 0; ++ ++ /* For each chunk in each block that needs scanning.... */ ++ for (c = 0; ++ !alloc_failed && c < dev->param.chunks_per_block && ++ state == YAFFS_BLOCK_STATE_NEEDS_SCAN; c++) { ++ /* Read the tags and decide what to do */ ++ chunk = blk * dev->param.chunks_per_block + c; ++ ++ result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, ++ &tags); ++ ++ if (result != YAFFS_OK) ++ continue; ++ /* Let's have a good look at this chunk... */ ++ ++ if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED || ++ tags.is_deleted) { ++ /* YAFFS1 only... ++ * A deleted chunk ++ */ ++ deleted++; ++ dev->n_free_chunks++; ++ } else if (!tags.chunk_used) { ++ /* An unassigned chunk in the block ++ * This means that either the block is empty or ++ * this is the one being allocated from ++ */ ++ ++ if (c == 0) { ++ /* We're looking at the first chunk in ++ *the block so the block is unused */ ++ state = YAFFS_BLOCK_STATE_EMPTY; ++ dev->n_erased_blocks++; ++ } else { ++ /* this is the block being allocated */ ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ " Allocating from %d %d", ++ blk, c); ++ state = YAFFS_BLOCK_STATE_ALLOCATING; ++ dev->alloc_block = blk; ++ dev->alloc_page = c; ++ dev->alloc_block_finder = blk; ++ ++ } ++ ++ dev->n_free_chunks += ++ (dev->param.chunks_per_block - c); ++ } else if (tags.chunk_id > 0) { ++ /* chunk_id > 0 so it is a data chunk... */ ++ unsigned int endpos; ++ ++ yaffs_set_chunk_bit(dev, blk, c); ++ bi->pages_in_use++; ++ ++ in = yaffs_find_or_create_by_number(dev, ++ tags.obj_id, ++ YAFFS_OBJECT_TYPE_FILE); ++ /* PutChunkIntoFile checks for a clash ++ * (two data chunks with the same chunk_id). ++ */ ++ ++ if (!in) ++ alloc_failed = 1; ++ ++ if (in) { ++ if (!yaffs_put_chunk_in_file ++ (in, tags.chunk_id, chunk, 1)) ++ alloc_failed = 1; ++ } ++ ++ endpos = ++ (tags.chunk_id - 1) * ++ dev->data_bytes_per_chunk + ++ tags.n_bytes; ++ if (in && ++ in->variant_type == ++ YAFFS_OBJECT_TYPE_FILE && ++ in->variant.file_variant.stored_size < ++ endpos) { ++ in->variant.file_variant.stored_size = ++ endpos; ++ if (!dev->param.use_header_file_size) { ++ in->variant. ++ file_variant.file_size = ++ in->variant. ++ file_variant.stored_size; ++ } ++ ++ } ++ } else { ++ /* chunk_id == 0, so it is an ObjectHeader. ++ * Make the object ++ */ ++ yaffs_set_chunk_bit(dev, blk, c); ++ bi->pages_in_use++; ++ ++ result = yaffs_rd_chunk_tags_nand(dev, chunk, ++ chunk_data, ++ NULL); ++ ++ oh = (struct yaffs_obj_hdr *)chunk_data; ++ ++ in = yaffs_find_by_number(dev, tags.obj_id); ++ if (in && in->variant_type != oh->type) { ++ /* This should not happen, but somehow ++ * Wev'e ended up with an obj_id that ++ * has been reused but not yet deleted, ++ * and worse still it has changed type. ++ * Delete the old object. ++ */ ++ ++ yaffs_del_obj(in); ++ in = NULL; ++ } ++ ++ in = yaffs_find_or_create_by_number(dev, ++ tags.obj_id, ++ oh->type); ++ ++ if (!in) ++ alloc_failed = 1; ++ ++ if (in && oh->shadows_obj > 0) { ++ ++ struct yaffs_shadow_fixer *fixer; ++ fixer = ++ kmalloc(sizeof ++ (struct yaffs_shadow_fixer), ++ GFP_NOFS); ++ if (fixer) { ++ fixer->next = shadow_fixers; ++ shadow_fixers = fixer; ++ fixer->obj_id = tags.obj_id; ++ fixer->shadowed_id = ++ oh->shadows_obj; ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ " Shadow fixer: %d shadows %d", ++ fixer->obj_id, ++ fixer->shadowed_id); ++ ++ } ++ ++ } ++ ++ if (in && in->valid) { ++ /* We have already filled this one. ++ * We have a duplicate and need to ++ * resolve it. */ ++ ++ unsigned existing_serial = in->serial; ++ unsigned new_serial = ++ tags.serial_number; ++ ++ if (((existing_serial + 1) & 3) == ++ new_serial) { ++ /* Use new one - destroy the ++ * exisiting one */ ++ yaffs_chunk_del(dev, ++ in->hdr_chunk, ++ 1, __LINE__); ++ in->valid = 0; ++ } else { ++ /* Use existing - destroy ++ * this one. */ ++ yaffs_chunk_del(dev, chunk, 1, ++ __LINE__); ++ } ++ } ++ ++ if (in && !in->valid && ++ (tags.obj_id == YAFFS_OBJECTID_ROOT || ++ tags.obj_id == ++ YAFFS_OBJECTID_LOSTNFOUND)) { ++ /* We only load some info, don't fiddle ++ * with directory structure */ ++ in->valid = 1; ++ in->variant_type = oh->type; ++ ++ in->yst_mode = oh->yst_mode; ++ yaffs_load_attribs(in, oh); ++ in->hdr_chunk = chunk; ++ in->serial = tags.serial_number; ++ ++ } else if (in && !in->valid) { ++ /* we need to load this info */ ++ ++ in->valid = 1; ++ in->variant_type = oh->type; ++ ++ in->yst_mode = oh->yst_mode; ++ yaffs_load_attribs(in, oh); ++ in->hdr_chunk = chunk; ++ in->serial = tags.serial_number; ++ ++ yaffs_set_obj_name_from_oh(in, oh); ++ in->dirty = 0; ++ ++ /* directory stuff... ++ * hook up to parent ++ */ ++ ++ parent = ++ yaffs_find_or_create_by_number ++ (dev, oh->parent_obj_id, ++ YAFFS_OBJECT_TYPE_DIRECTORY); ++ if (!parent) ++ alloc_failed = 1; ++ if (parent && parent->variant_type == ++ YAFFS_OBJECT_TYPE_UNKNOWN) { ++ /* Set up as a directory */ ++ parent->variant_type = ++ YAFFS_OBJECT_TYPE_DIRECTORY; ++ INIT_LIST_HEAD(&parent-> ++ variant.dir_variant. ++ children); ++ } else if (!parent || ++ parent->variant_type != ++ YAFFS_OBJECT_TYPE_DIRECTORY) { ++ /* Hoosterman, a problem.... ++ * We're trying to use a ++ * non-directory as a directory ++ */ ++ ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found." ++ ); ++ parent = dev->lost_n_found; ++ } ++ ++ yaffs_add_obj_to_dir(parent, in); ++ ++ switch (in->variant_type) { ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ /* Todo got a problem */ ++ break; ++ case YAFFS_OBJECT_TYPE_FILE: ++ if (dev->param. ++ use_header_file_size) ++ in->variant. ++ file_variant.file_size ++ = yaffs_oh_to_size(dev, oh, 0); ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ in->variant. ++ hardlink_variant.equiv_id = ++ oh->equiv_id; ++ list_add(&in->hard_links, ++ &hard_list); ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ /* Do nothing */ ++ break; ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ /* Do nothing */ ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ in->variant.symlink_variant. ++ alias = ++ yaffs_clone_str(oh->alias); ++ if (!in->variant. ++ symlink_variant.alias) ++ alloc_failed = 1; ++ break; ++ } ++ } ++ } ++ } ++ ++ if (state == YAFFS_BLOCK_STATE_NEEDS_SCAN) { ++ /* If we got this far while scanning, ++ * then the block is fully allocated. */ ++ state = YAFFS_BLOCK_STATE_FULL; ++ } ++ ++ if (state == YAFFS_BLOCK_STATE_ALLOCATING) { ++ /* If the block was partially allocated then ++ * treat it as fully allocated. */ ++ state = YAFFS_BLOCK_STATE_FULL; ++ dev->alloc_block = -1; ++ } ++ ++ bi->block_state = state; ++ ++ /* Now let's see if it was dirty */ ++ if (bi->pages_in_use == 0 && ++ !bi->has_shrink_hdr && ++ bi->block_state == YAFFS_BLOCK_STATE_FULL) ++ yaffs_block_became_dirty(dev, blk); ++ } ++ ++ /* Ok, we've done all the scanning. ++ * Fix up the hard link chains. ++ * We should now have scanned all the objects, now it's time to add ++ * these hardlinks. ++ */ ++ ++ yaffs_link_fixup(dev, &hard_list); ++ ++ /* ++ * Fix up any shadowed objects. ++ * There should not be more than one of these. ++ */ ++ { ++ struct yaffs_shadow_fixer *fixer; ++ struct yaffs_obj *obj; ++ ++ while (shadow_fixers) { ++ fixer = shadow_fixers; ++ shadow_fixers = fixer->next; ++ /* Complete the rename transaction by deleting the ++ * shadowed object then setting the object header ++ to unshadowed. ++ */ ++ obj = yaffs_find_by_number(dev, fixer->shadowed_id); ++ if (obj) ++ yaffs_del_obj(obj); ++ ++ obj = yaffs_find_by_number(dev, fixer->obj_id); ++ ++ if (obj) ++ yaffs_update_oh(obj, NULL, 1, 0, 0, NULL); ++ ++ kfree(fixer); ++ } ++ } ++ ++ yaffs_release_temp_buffer(dev, chunk_data); ++ ++ if (alloc_failed) ++ return YAFFS_FAIL; ++ ++ yaffs_trace(YAFFS_TRACE_SCAN, "yaffs1_scan ends"); ++ ++ return YAFFS_OK; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs1.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs1.h.patch new file mode 100644 index 00000000..c0db2ff9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs1.h.patch @@ -0,0 +1,25 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_yaffs1.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_yaffs1.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,22 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_YAFFS1_H__ ++#define __YAFFS_YAFFS1_H__ ++ ++#include "yaffs_guts.h" ++int yaffs1_scan(struct yaffs_dev *dev); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs2.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs2.c.patch new file mode 100644 index 00000000..c02d5cb4 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs2.c.patch @@ -0,0 +1,1715 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_yaffs2.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_yaffs2.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,1712 @@ ++/* ++ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * 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 "yaffs_guts.h" ++#include "yaffs_trace.h" ++#include "yaffs_yaffs2.h" ++#include "yaffs_checkptrw.h" ++#include "yaffs_bitmap.h" ++#include "yaffs_nand.h" ++#include "yaffs_getblockinfo.h" ++#include "yaffs_verify.h" ++#include "yaffs_attribs.h" ++#include "yaffs_summary.h" ++#include "yaffs_endian.h" ++ ++/* ++ * Checkpoints are really no benefit on very small partitions. ++ * ++ * To save space on small partitions don't bother with checkpoints unless ++ * the partition is at least this big. ++ */ ++#define YAFFS_CHECKPOINT_MIN_BLOCKS 60 ++#define YAFFS_SMALL_HOLE_THRESHOLD 4 ++ ++/* ++ * Oldest Dirty Sequence Number handling. ++ */ ++ ++/* yaffs_calc_oldest_dirty_seq() ++ * yaffs2_find_oldest_dirty_seq() ++ * Calculate the oldest dirty sequence number if we don't know it. ++ */ ++void yaffs_calc_oldest_dirty_seq(struct yaffs_dev *dev) ++{ ++ u32 i; ++ unsigned seq; ++ unsigned block_no = 0; ++ struct yaffs_block_info *b; ++ ++ if (!dev->param.is_yaffs2) ++ return; ++ ++ /* Find the oldest dirty sequence number. */ ++ seq = dev->seq_number + 1; ++ b = dev->block_info; ++ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { ++ if (b->block_state == YAFFS_BLOCK_STATE_FULL && ++ (u32)(b->pages_in_use - b->soft_del_pages) < ++ dev->param.chunks_per_block && ++ b->seq_number < seq) { ++ seq = b->seq_number; ++ block_no = i; ++ } ++ b++; ++ } ++ ++ if (block_no) { ++ dev->oldest_dirty_seq = seq; ++ dev->oldest_dirty_block = block_no; ++ } ++} ++ ++void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev) ++{ ++ if (!dev->param.is_yaffs2) ++ return; ++ ++ if (!dev->oldest_dirty_seq) ++ yaffs_calc_oldest_dirty_seq(dev); ++} ++ ++/* ++ * yaffs_clear_oldest_dirty_seq() ++ * Called when a block is erased or marked bad. (ie. when its seq_number ++ * becomes invalid). If the value matches the oldest then we clear ++ * dev->oldest_dirty_seq to force its recomputation. ++ */ ++void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi) ++{ ++ ++ if (!dev->param.is_yaffs2) ++ return; ++ ++ if (!bi || bi->seq_number == dev->oldest_dirty_seq) { ++ dev->oldest_dirty_seq = 0; ++ dev->oldest_dirty_block = 0; ++ } ++} ++ ++/* ++ * yaffs2_update_oldest_dirty_seq() ++ * Update the oldest dirty sequence number whenever we dirty a block. ++ * Only do this if the oldest_dirty_seq is actually being tracked. ++ */ ++void yaffs2_update_oldest_dirty_seq(struct yaffs_dev *dev, unsigned block_no, ++ struct yaffs_block_info *bi) ++{ ++ if (!dev->param.is_yaffs2) ++ return; ++ ++ if (dev->oldest_dirty_seq) { ++ if (dev->oldest_dirty_seq > bi->seq_number) { ++ dev->oldest_dirty_seq = bi->seq_number; ++ dev->oldest_dirty_block = block_no; ++ } ++ } ++} ++ ++int yaffs_block_ok_for_gc(struct yaffs_dev *dev, struct yaffs_block_info *bi) ++{ ++ ++ if (!dev->param.is_yaffs2) ++ return 1; /* disqualification only applies to yaffs2. */ ++ ++ if (!bi->has_shrink_hdr) ++ return 1; /* can gc */ ++ ++ yaffs2_find_oldest_dirty_seq(dev); ++ ++ /* Can't do gc of this block if there are any blocks older than this ++ * one that have discarded pages. ++ */ ++ return (bi->seq_number <= dev->oldest_dirty_seq); ++} ++ ++/* ++ * yaffs2_find_refresh_block() ++ * periodically finds the oldest full block by sequence number for refreshing. ++ * Only for yaffs2. ++ */ ++u32 yaffs2_find_refresh_block(struct yaffs_dev *dev) ++{ ++ u32 b; ++ u32 oldest = 0; ++ u32 oldest_seq = 0; ++ struct yaffs_block_info *bi; ++ ++ if (!dev->param.is_yaffs2) ++ return oldest; ++ ++ /* ++ * If refresh period < 10 then refreshing is disabled. ++ */ ++ if (dev->param.refresh_period < 10) ++ return oldest; ++ ++ /* ++ * Fix broken values. ++ */ ++ if (dev->refresh_skip > dev->param.refresh_period) ++ dev->refresh_skip = dev->param.refresh_period; ++ ++ if (dev->refresh_skip > 0) ++ return oldest; ++ ++ /* ++ * Refresh skip is now zero. ++ * We'll do a refresh this time around.... ++ * Update the refresh skip and find the oldest block. ++ */ ++ dev->refresh_skip = dev->param.refresh_period; ++ dev->refresh_count++; ++ bi = dev->block_info; ++ for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) { ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_FULL) { ++ ++ if (oldest < 1 || bi->seq_number < oldest_seq) { ++ oldest = b; ++ oldest_seq = bi->seq_number; ++ } ++ } ++ bi++; ++ } ++ ++ if (oldest > 0) { ++ yaffs_trace(YAFFS_TRACE_GC, ++ "GC refresh count %d selected block %d with seq_number %d", ++ dev->refresh_count, oldest, oldest_seq); ++ } ++ ++ return oldest; ++} ++ ++int yaffs2_checkpt_required(struct yaffs_dev *dev) ++{ ++ int nblocks; ++ ++ if (!dev->param.is_yaffs2) ++ return 0; ++ ++ nblocks = dev->internal_end_block - dev->internal_start_block + 1; ++ ++ return !dev->param.skip_checkpt_wr && ++ !dev->read_only && (nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS); ++} ++ ++int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev) ++{ ++ int retval; ++ int n_bytes = 0; ++ int n_blocks; ++ int dev_blocks; ++ ++ if (!dev->param.is_yaffs2) ++ return 0; ++ ++ if (!dev->checkpoint_blocks_required && yaffs2_checkpt_required(dev)) { ++ /* Not a valid value so recalculate */ ++ dev_blocks = dev->param.end_block - dev->param.start_block + 1; ++ n_bytes += sizeof(struct yaffs_checkpt_validity); ++ n_bytes += sizeof(struct yaffs_checkpt_dev); ++ n_bytes += dev_blocks * sizeof(struct yaffs_block_info); ++ n_bytes += dev_blocks * dev->chunk_bit_stride; ++ n_bytes += ++ (sizeof(struct yaffs_checkpt_obj) + sizeof(u32)) * ++ dev->n_obj; ++ n_bytes += (dev->tnode_size + sizeof(u32)) * dev->n_tnodes; ++ n_bytes += sizeof(struct yaffs_checkpt_validity); ++ n_bytes += sizeof(u32); /* checksum */ ++ ++ /* Round up and add 2 blocks to allow for some bad blocks, ++ * so add 3 */ ++ ++ n_blocks = ++ (n_bytes / ++ (dev->data_bytes_per_chunk * ++ dev->param.chunks_per_block)) + 3; ++ ++ dev->checkpoint_blocks_required = n_blocks; ++ } ++ ++ retval = dev->checkpoint_blocks_required - dev->blocks_in_checkpt; ++ if (retval < 0) ++ retval = 0; ++ return retval; ++} ++ ++/*--------------------- Checkpointing --------------------*/ ++ ++static void yaffs2_do_endian_validity_marker(struct yaffs_dev *dev, ++ struct yaffs_checkpt_validity *v) ++{ ++ ++ if (!dev->swap_endian) ++ return; ++ v->struct_type = swap_s32(v->struct_type); ++ v->magic = swap_u32(v->magic); ++ v->version = swap_u32(v->version); ++ v->head = swap_u32(v->head); ++} ++ ++static int yaffs2_wr_checkpt_validity_marker(struct yaffs_dev *dev, int head) ++{ ++ struct yaffs_checkpt_validity cp; ++ ++ memset(&cp, 0, sizeof(cp)); ++ ++ cp.struct_type = sizeof(cp); ++ cp.magic = YAFFS_MAGIC; ++ cp.version = YAFFS_CHECKPOINT_VERSION; ++ cp.head = (head) ? 1 : 0; ++ ++ yaffs2_do_endian_validity_marker(dev, &cp); ++ ++ return (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)) ? 1 : 0; ++} ++ ++static int yaffs2_rd_checkpt_validity_marker(struct yaffs_dev *dev, int head) ++{ ++ struct yaffs_checkpt_validity cp; ++ int ok; ++ ++ ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp)); ++ yaffs2_do_endian_validity_marker(dev, &cp); ++ ++ if (ok) ++ ok = (cp.struct_type == sizeof(cp)) && ++ (cp.magic == YAFFS_MAGIC) && ++ (cp.version == YAFFS_CHECKPOINT_VERSION) && ++ (cp.head == ((head) ? 1 : 0)); ++ return ok ? 1 : 0; ++} ++ ++static void yaffs2_dev_to_checkpt_dev(struct yaffs_checkpt_dev *cp, ++ struct yaffs_dev *dev) ++{ ++ cp->struct_type = sizeof(*cp); ++ ++ cp->n_erased_blocks = dev->n_erased_blocks; ++ cp->alloc_block = dev->alloc_block; ++ cp->alloc_page = dev->alloc_page; ++ cp->n_free_chunks = dev->n_free_chunks; ++ ++ cp->n_deleted_files = dev->n_deleted_files; ++ cp->n_unlinked_files = dev->n_unlinked_files; ++ cp->n_bg_deletions = dev->n_bg_deletions; ++ cp->seq_number = dev->seq_number; ++ ++} ++ ++static void yaffs_checkpt_dev_to_dev(struct yaffs_dev *dev, ++ struct yaffs_checkpt_dev *cp) ++{ ++ dev->n_erased_blocks = cp->n_erased_blocks; ++ dev->alloc_block = cp->alloc_block; ++ dev->alloc_page = cp->alloc_page; ++ dev->n_free_chunks = cp->n_free_chunks; ++ ++ dev->n_deleted_files = cp->n_deleted_files; ++ dev->n_unlinked_files = cp->n_unlinked_files; ++ dev->n_bg_deletions = cp->n_bg_deletions; ++ dev->seq_number = cp->seq_number; ++} ++ ++static void yaffs2_do_endian_checkpt_dev(struct yaffs_dev *dev, ++ struct yaffs_checkpt_dev *cp) ++{ ++ if (!dev->swap_endian) ++ return; ++ cp->struct_type = swap_s32(cp->struct_type); ++ cp->n_erased_blocks = swap_s32(cp->n_erased_blocks); ++ cp->alloc_block = swap_s32(cp->alloc_block); ++ cp->alloc_page = swap_u32(cp->alloc_page); ++ cp->n_free_chunks = swap_s32(cp->n_free_chunks); ++ cp->n_deleted_files = swap_s32(cp->n_deleted_files); ++ cp->n_unlinked_files = swap_s32(cp->n_unlinked_files); ++ cp->n_bg_deletions = swap_s32(cp->n_bg_deletions); ++} ++ ++static int yaffs2_wr_checkpt_dev(struct yaffs_dev *dev) ++{ ++ struct yaffs_checkpt_dev cp; ++ u32 n_bytes; ++ u32 n_blocks = dev->internal_end_block - dev->internal_start_block + 1; ++ int ok; ++ u32 i; ++ union yaffs_block_info_union bu; ++ ++ /* Write device runtime values */ ++ yaffs2_dev_to_checkpt_dev(&cp, dev); ++ yaffs2_do_endian_checkpt_dev(dev, &cp); ++ ++ ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)); ++ if (!ok) ++ return 0; ++ ++ /* Write block info. */ ++ if (!dev->swap_endian) { ++ n_bytes = n_blocks * sizeof(struct yaffs_block_info); ++ ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) == ++ (int)n_bytes); ++ } else { ++ /* ++ * Need to swap the endianisms. We can't do this in place ++ * since that would damage live data, ++ * so write one block info at a time using a copy. ++ */ ++ for (i = 0; i < n_blocks && ok; i++) { ++ bu.bi = dev->block_info[i]; ++ bu.as_u32[0] = swap_u32(bu.as_u32[0]); ++ bu.as_u32[1] = swap_u32(bu.as_u32[1]); ++ ok = (yaffs2_checkpt_wr(dev, &bu, sizeof(bu)) == sizeof(bu)); ++ } ++ } ++ ++ if (!ok) ++ return 0; ++ ++ /* ++ * Write chunk bits. Chunk bits are in bytes so ++ * no endian conversion is needed. ++ */ ++ n_bytes = n_blocks * dev->chunk_bit_stride; ++ ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) == ++ (int)n_bytes); ++ ++ return ok ? 1 : 0; ++} ++ ++static int yaffs2_rd_checkpt_dev(struct yaffs_dev *dev) ++{ ++ struct yaffs_checkpt_dev cp; ++ u32 n_bytes; ++ u32 n_blocks = ++ (dev->internal_end_block - dev->internal_start_block + 1); ++ int ok; ++ ++ ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp)); ++ if (!ok) ++ return 0; ++ yaffs2_do_endian_checkpt_dev(dev, &cp); ++ ++ if (cp.struct_type != sizeof(cp)) ++ return 0; ++ ++ yaffs_checkpt_dev_to_dev(dev, &cp); ++ ++ n_bytes = n_blocks * sizeof(struct yaffs_block_info); ++ ++ ok = (yaffs2_checkpt_rd(dev, dev->block_info, n_bytes) == ++ (int)n_bytes); ++ ++ if (!ok) ++ return 0; ++ ++ if (dev->swap_endian) { ++ /* The block info can just be handled as a list of u32s. */ ++ u32 *as_u32 = (u32 *) dev->block_info; ++ u32 n_u32s = n_bytes/sizeof(u32); ++ u32 i; ++ ++ for (i=0; i < n_u32s; i++) ++ as_u32[i] = swap_u32(as_u32[i]); ++ } ++ ++ n_bytes = n_blocks * dev->chunk_bit_stride; ++ ++ ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == ++ (int)n_bytes); ++ ++ ++ return ok ? 1 : 0; ++} ++ ++ ++static void yaffs2_checkpt_obj_bit_assign(struct yaffs_checkpt_obj *cp, ++ int bit_offset, ++ int bit_width, ++ u32 value) ++{ ++ u32 and_mask; ++ ++ and_mask = ((1<bit_field &= ~and_mask; ++ cp->bit_field |= ((value << bit_offset) & and_mask); ++} ++ ++static u32 yaffs2_checkpt_obj_bit_get(struct yaffs_checkpt_obj *cp, ++ int bit_offset, ++ int bit_width) ++{ ++ u32 and_mask; ++ ++ and_mask = ((1<bit_field >> bit_offset) & and_mask; ++} ++ ++static void yaffs2_obj_checkpt_obj(struct yaffs_checkpt_obj *cp, ++ struct yaffs_obj *obj) ++{ ++ cp->obj_id = obj->obj_id; ++ cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0; ++ cp->hdr_chunk = obj->hdr_chunk; ++ ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_VARIANT_BITS, obj->variant_type); ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_DELETED_BITS, obj->deleted); ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_SOFT_DEL_BITS, obj->soft_del); ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_UNLINKED_BITS, obj->unlinked); ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_FAKE_BITS, obj->fake); ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_RENAME_ALLOWED_BITS, obj->rename_allowed); ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_UNLINK_ALLOWED_BITS, obj->unlink_allowed); ++ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_SERIAL_BITS, obj->serial); ++ ++ cp->n_data_chunks = obj->n_data_chunks; ++ ++ if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) ++ cp->size_or_equiv_obj = obj->variant.file_variant.file_size; ++ else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) ++ cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id; ++} ++ ++static int yaffs2_checkpt_obj_to_obj(struct yaffs_obj *obj, ++ struct yaffs_checkpt_obj *cp) ++{ ++ struct yaffs_obj *parent; ++ u32 cp_variant_type = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_VARIANT_BITS); ++ ++ if (obj->variant_type != cp_variant_type) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "Checkpoint read object %d type %d chunk %d does not match existing object type %d", ++ cp->obj_id, cp_variant_type, cp->hdr_chunk, ++ obj->variant_type); ++ return 0; ++ } ++ ++ obj->obj_id = cp->obj_id; ++ ++ if (cp->parent_id) ++ parent = yaffs_find_or_create_by_number(obj->my_dev, ++ cp->parent_id, ++ YAFFS_OBJECT_TYPE_DIRECTORY); ++ else ++ parent = NULL; ++ ++ if (parent) { ++ if (parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { ++ yaffs_trace(YAFFS_TRACE_ALWAYS, ++ "Checkpoint read object %d parent %d type %d chunk %d Parent type, %d, not directory", ++ cp->obj_id, cp->parent_id, ++ cp_variant_type, cp->hdr_chunk, ++ parent->variant_type); ++ return 0; ++ } ++ yaffs_add_obj_to_dir(parent, obj); ++ } ++ ++ obj->hdr_chunk = cp->hdr_chunk; ++ ++ obj->variant_type = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_VARIANT_BITS); ++ obj->deleted = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_DELETED_BITS); ++ obj->soft_del = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_SOFT_DEL_BITS); ++ obj->unlinked = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_UNLINKED_BITS); ++ obj->fake = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_FAKE_BITS); ++ obj->rename_allowed = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_RENAME_ALLOWED_BITS); ++ obj->unlink_allowed = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_UNLINK_ALLOWED_BITS); ++ obj->serial = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_SERIAL_BITS); ++ ++ obj->n_data_chunks = cp->n_data_chunks; ++ ++ if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) { ++ obj->variant.file_variant.file_size = cp->size_or_equiv_obj; ++ obj->variant.file_variant.stored_size = cp->size_or_equiv_obj; ++ } else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) { ++ obj->variant.hardlink_variant.equiv_id = cp->size_or_equiv_obj; ++ } ++ if (obj->hdr_chunk > 0) ++ obj->lazy_loaded = 1; ++ return 1; ++} ++ ++static void yaffs2_do_endian_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn) ++{ ++ int i; ++ u32 *as_u32 = (u32 *)tn; ++ int tnode_size_u32 = dev->tnode_size / sizeof(u32); ++ ++ if (!dev->swap_endian) ++ return; ++ /* Swap all the tnode data as u32s to fix endianisms. */ ++ for (i = 0; iswap_endian) ++ return tn; ++ ++ memcpy(dev->tn_swap_buffer, tn, dev->tnode_size); ++ tn = dev->tn_swap_buffer; ++ ++ yaffs2_do_endian_tnode(dev, tn); ++ ++ return tn; ++} ++ ++static int yaffs2_checkpt_tnode_worker(struct yaffs_obj *in, ++ struct yaffs_tnode *tn, u32 level, ++ int chunk_offset) ++{ ++ int i; ++ struct yaffs_dev *dev = in->my_dev; ++ int ok = 1; ++ u32 base_offset; ++ ++ if (!tn) ++ return 1; ++ ++ if (level > 0) { ++ for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) { ++ if (!tn->internal[i]) ++ continue; ++ ok = yaffs2_checkpt_tnode_worker(in, ++ tn->internal[i], ++ level - 1, ++ (chunk_offset << ++ YAFFS_TNODES_INTERNAL_BITS) + i); ++ } ++ return ok; ++ } ++ ++ /* Level 0 tnode */ ++ base_offset = chunk_offset << YAFFS_TNODES_LEVEL0_BITS; ++ yaffs_do_endian_u32(dev, &base_offset); ++ ++ ok = (yaffs2_checkpt_wr(dev, &base_offset, sizeof(base_offset)) == ++ sizeof(base_offset)); ++ if (ok) { ++ /* ++ * NB Can't do an in-place endian swizzle since that would ++ * damage current tnode data. ++ * If a tnode endian conversion is required we do a copy. ++ */ ++ tn = yaffs2_do_endian_tnode_copy(dev, tn); ++ ok = (yaffs2_checkpt_wr(dev, tn, dev->tnode_size) == ++ (int)dev->tnode_size); ++ } ++ return ok; ++} ++ ++static int yaffs2_wr_checkpt_tnodes(struct yaffs_obj *obj) ++{ ++ u32 end_marker = ~0; ++ int ok = 1; ++ ++ if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE) ++ return ok; ++ ++ ok = yaffs2_checkpt_tnode_worker(obj, ++ obj->variant.file_variant.top, ++ obj->variant.file_variant. ++ top_level, 0); ++ if (ok) ++ ok = (yaffs2_checkpt_wr(obj->my_dev, &end_marker, ++ sizeof(end_marker)) == sizeof(end_marker)); ++ ++ return ok ? 1 : 0; ++} ++ ++static int yaffs2_rd_checkpt_tnodes(struct yaffs_obj *obj) ++{ ++ u32 base_chunk; ++ int ok = 1; ++ struct yaffs_dev *dev = obj->my_dev; ++ struct yaffs_file_var *file_stuct_ptr = &obj->variant.file_variant; ++ struct yaffs_tnode *tn; ++ int nread = 0; ++ ++ ok = (yaffs2_checkpt_rd(dev, &base_chunk, sizeof(base_chunk)) == ++ sizeof(base_chunk)); ++ ++ yaffs_do_endian_u32(dev, &base_chunk); ++ ++ while (ok && (~base_chunk)) { ++ nread++; ++ /* Read level 0 tnode */ ++ ++ tn = yaffs_get_tnode(dev); ++ if (tn) { ++ ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) == ++ (int)dev->tnode_size); ++ yaffs2_do_endian_tnode(dev, tn); ++ } ++ else ++ ok = 0; ++ ++ if (tn && ok) ++ ok = yaffs_add_find_tnode_0(dev, ++ file_stuct_ptr, ++ base_chunk, tn) ? 1 : 0; ++ ++ if (ok) { ++ ok = (yaffs2_checkpt_rd ++ (dev, &base_chunk, ++ sizeof(base_chunk)) == sizeof(base_chunk)); ++ yaffs_do_endian_u32(dev, &base_chunk); ++ } ++ ++ } ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "Checkpoint read tnodes %d records, last %d. ok %d", ++ nread, base_chunk, ok); ++ ++ return ok ? 1 : 0; ++} ++ ++ ++static void yaffs2_do_endian_checkpt_obj(struct yaffs_dev *dev, ++ struct yaffs_checkpt_obj *cp) ++{ ++ if (!dev->swap_endian) ++ return; ++ cp->struct_type = swap_s32(cp->struct_type); ++ cp->obj_id = swap_u32(cp->obj_id); ++ cp->parent_id = swap_u32(cp->parent_id); ++ cp->hdr_chunk = swap_s32(cp->hdr_chunk); ++ cp->bit_field = swap_u32(cp->bit_field); ++ cp->n_data_chunks = swap_s32(cp->n_data_chunks); ++ cp->size_or_equiv_obj = swap_loff_t(cp->size_or_equiv_obj); ++} ++ ++static int yaffs2_wr_checkpt_objs(struct yaffs_dev *dev) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_checkpt_obj cp; ++ int i; ++ int ok = 1; ++ struct list_head *lh; ++ u32 cp_variant_type; ++ ++ /* Iterate through the objects in each hash entry, ++ * dumping them to the checkpointing stream. ++ */ ++ ++ for (i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++) { ++ list_for_each(lh, &dev->obj_bucket[i].list) { ++ obj = list_entry(lh, struct yaffs_obj, hash_link); ++ if (!obj->defered_free) { ++ yaffs2_obj_checkpt_obj(&cp, obj); ++ cp.struct_type = sizeof(cp); ++ cp_variant_type = yaffs2_checkpt_obj_bit_get( ++ &cp, CHECKPOINT_VARIANT_BITS); ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "Checkpoint write object %d parent %d type %d chunk %d obj addr %p", ++ cp.obj_id, cp.parent_id, ++ cp_variant_type, cp.hdr_chunk, obj); ++ ++ yaffs2_do_endian_checkpt_obj (dev, &cp); ++ ok = (yaffs2_checkpt_wr(dev, &cp, ++ sizeof(cp)) == sizeof(cp)); ++ ++ if (ok && ++ obj->variant_type == ++ YAFFS_OBJECT_TYPE_FILE) ++ ok = yaffs2_wr_checkpt_tnodes(obj); ++ } ++ } ++ } ++ ++ /* Dump end of list */ ++ memset(&cp, 0xff, sizeof(struct yaffs_checkpt_obj)); ++ cp.struct_type = sizeof(cp); ++ yaffs2_do_endian_checkpt_obj (dev, &cp); ++ ++ if (ok) ++ ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)); ++ ++ return ok ? 1 : 0; ++} ++ ++static int yaffs2_rd_checkpt_objs(struct yaffs_dev *dev) ++{ ++ struct yaffs_obj *obj; ++ struct yaffs_checkpt_obj cp; ++ int ok = 1; ++ int done = 0; ++ u32 cp_variant_type; ++ LIST_HEAD(hard_list); ++ ++ ++ while (ok && !done) { ++ ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp)); ++ yaffs2_do_endian_checkpt_obj (dev, &cp); ++ ++ if (cp.struct_type != sizeof(cp)) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "struct size %d instead of %d ok %d", ++ cp.struct_type, (int)sizeof(cp), ok); ++ ok = 0; ++ } ++ ++ cp_variant_type = yaffs2_checkpt_obj_bit_get( ++ &cp, CHECKPOINT_VARIANT_BITS); ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "Checkpoint read object %d parent %d type %d chunk %d ", ++ cp.obj_id, cp.parent_id, cp_variant_type, ++ cp.hdr_chunk); ++ ++ if (ok && cp.obj_id == (u32)(~0)) { ++ done = 1; ++ } else if (ok) { ++ obj = ++ yaffs_find_or_create_by_number(dev, cp.obj_id, ++ cp_variant_type); ++ if (obj) { ++ ok = yaffs2_checkpt_obj_to_obj(obj, &cp); ++ if (!ok) ++ break; ++ if (obj->variant_type == ++ YAFFS_OBJECT_TYPE_FILE) { ++ ok = yaffs2_rd_checkpt_tnodes(obj); ++ } else if (obj->variant_type == ++ YAFFS_OBJECT_TYPE_HARDLINK) { ++ list_add(&obj->hard_links, &hard_list); ++ } ++ } else { ++ ok = 0; ++ } ++ } ++ } ++ ++ if (ok) ++ yaffs_link_fixup(dev, &hard_list); ++ ++ return ok ? 1 : 0; ++} ++ ++static int yaffs2_wr_checkpt_sum(struct yaffs_dev *dev) ++{ ++ u32 checkpt_sum; ++ int ok; ++ ++ yaffs2_get_checkpt_sum(dev, &checkpt_sum); ++ ++ yaffs_do_endian_u32(dev, &checkpt_sum); ++ ++ ok = (yaffs2_checkpt_wr(dev, &checkpt_sum, sizeof(checkpt_sum)) == ++ sizeof(checkpt_sum)); ++ ++ if (!ok) ++ return 0; ++ ++ return 1; ++} ++ ++static int yaffs2_rd_checkpt_sum(struct yaffs_dev *dev) ++{ ++ u32 checkpt_sum0; ++ u32 checkpt_sum1; ++ int ok; ++ ++ yaffs2_get_checkpt_sum(dev, &checkpt_sum0); ++ ++ ok = (yaffs2_checkpt_rd(dev, &checkpt_sum1, sizeof(checkpt_sum1)) == ++ sizeof(checkpt_sum1)); ++ ++ if (!ok) ++ return 0; ++ yaffs_do_endian_u32(dev, &checkpt_sum1); ++ ++ if (checkpt_sum0 != checkpt_sum1) ++ return 0; ++ ++ return 1; ++} ++ ++static int yaffs2_wr_checkpt_data(struct yaffs_dev *dev) ++{ ++ int ok = 1; ++ ++ if (!yaffs2_checkpt_required(dev)) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "skipping checkpoint write"); ++ ok = 0; ++ } ++ ++ if (ok) ++ ok = yaffs2_checkpt_open(dev, 1); ++ ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "write checkpoint validity"); ++ ok = yaffs2_wr_checkpt_validity_marker(dev, 1); ++ } ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "write checkpoint device"); ++ ok = yaffs2_wr_checkpt_dev(dev); ++ } ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "write checkpoint objects"); ++ ok = yaffs2_wr_checkpt_objs(dev); ++ } ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "write checkpoint validity"); ++ ok = yaffs2_wr_checkpt_validity_marker(dev, 0); ++ } ++ ++ if (ok) ++ ok = yaffs2_wr_checkpt_sum(dev); ++ ++ if (!yaffs_checkpt_close(dev)) ++ ok = 0; ++ ++ if (ok) ++ dev->is_checkpointed = 1; ++ else ++ dev->is_checkpointed = 0; ++ ++ return dev->is_checkpointed; ++} ++ ++static int yaffs2_rd_checkpt_data(struct yaffs_dev *dev) ++{ ++ int ok = 1; ++ ++ if (!dev->param.is_yaffs2) ++ ok = 0; ++ ++ if (ok && dev->param.skip_checkpt_rd) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "skipping checkpoint read"); ++ ok = 0; ++ } ++ ++ if (ok) ++ ok = yaffs2_checkpt_open(dev, 0); /* open for read */ ++ ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "read checkpoint validity"); ++ ok = yaffs2_rd_checkpt_validity_marker(dev, 1); ++ } ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "read checkpoint device"); ++ ok = yaffs2_rd_checkpt_dev(dev); ++ } ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "read checkpoint objects"); ++ ok = yaffs2_rd_checkpt_objs(dev); ++ } ++ if (ok) { ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "read checkpoint validity"); ++ ok = yaffs2_rd_checkpt_validity_marker(dev, 0); ++ } ++ ++ if (ok) { ++ ok = yaffs2_rd_checkpt_sum(dev); ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "read checkpoint checksum %d", ok); ++ } ++ ++ if (!yaffs_checkpt_close(dev)) ++ ok = 0; ++ ++ if (ok) ++ dev->is_checkpointed = 1; ++ else ++ dev->is_checkpointed = 0; ++ ++ return ok ? 1 : 0; ++} ++ ++void yaffs2_checkpt_invalidate(struct yaffs_dev *dev) ++{ ++ if (dev->is_checkpointed || dev->blocks_in_checkpt > 0) { ++ dev->is_checkpointed = 0; ++ yaffs2_checkpt_invalidate_stream(dev); ++ } ++ if (dev->param.sb_dirty_fn) ++ dev->param.sb_dirty_fn(dev); ++} ++ ++int yaffs_checkpoint_save(struct yaffs_dev *dev) ++{ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "save entry: is_checkpointed %d", ++ dev->is_checkpointed); ++ ++ yaffs_verify_objects(dev); ++ yaffs_verify_blocks(dev); ++ yaffs_verify_free_chunks(dev); ++ ++ if (!dev->is_checkpointed) { ++ yaffs2_checkpt_invalidate(dev); ++ yaffs2_wr_checkpt_data(dev); ++ } ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT | YAFFS_TRACE_MOUNT, ++ "save exit: is_checkpointed %d", ++ dev->is_checkpointed); ++ ++ return dev->is_checkpointed; ++} ++ ++int yaffs2_checkpt_restore(struct yaffs_dev *dev) ++{ ++ int retval; ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "restore entry: is_checkpointed %d", ++ dev->is_checkpointed); ++ ++ retval = yaffs2_rd_checkpt_data(dev); ++ ++ if (dev->is_checkpointed) { ++ yaffs_verify_objects(dev); ++ yaffs_verify_blocks(dev); ++ yaffs_verify_free_chunks(dev); ++ } ++ ++ yaffs_trace(YAFFS_TRACE_CHECKPOINT, ++ "restore exit: is_checkpointed %d", ++ dev->is_checkpointed); ++ ++ return retval; ++} ++ ++/* End of checkpointing */ ++ ++/* Hole handling logic for truncate past end of file */ ++ ++int yaffs2_handle_hole(struct yaffs_obj *obj, loff_t new_size) ++{ ++ /* if new_size > old_file_size. ++ * We're going to be writing a hole. ++ * If the hole is small then write zeros otherwise write a start ++ * of hole marker. ++ */ ++ loff_t old_file_size; ++ loff_t increase; ++ int small_hole; ++ int result = YAFFS_OK; ++ struct yaffs_dev *dev = NULL; ++ u8 *local_buffer = NULL; ++ int small_increase_ok = 0; ++ ++ if (!obj) ++ return YAFFS_FAIL; ++ ++ if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE) ++ return YAFFS_FAIL; ++ ++ dev = obj->my_dev; ++ ++ /* Bail out if not yaffs2 mode */ ++ if (!dev->param.is_yaffs2) ++ return YAFFS_OK; ++ ++ old_file_size = obj->variant.file_variant.file_size; ++ ++ if (new_size <= old_file_size) ++ return YAFFS_OK; ++ ++ increase = new_size - old_file_size; ++ ++ if (increase < YAFFS_SMALL_HOLE_THRESHOLD * dev->data_bytes_per_chunk && ++ yaffs_check_alloc_available(dev, YAFFS_SMALL_HOLE_THRESHOLD + 1)) ++ small_hole = 1; ++ else ++ small_hole = 0; ++ ++ if (small_hole) ++ local_buffer = yaffs_get_temp_buffer(dev); ++ ++ if (local_buffer) { ++ /* fill hole with zero bytes */ ++ loff_t pos = old_file_size; ++ int this_write; ++ int written; ++ memset(local_buffer, 0, dev->data_bytes_per_chunk); ++ small_increase_ok = 1; ++ ++ while (increase > 0 && small_increase_ok) { ++ this_write = increase; ++ if (this_write > (int)dev->data_bytes_per_chunk) ++ this_write = dev->data_bytes_per_chunk; ++ written = ++ yaffs_do_file_wr(obj, local_buffer, pos, this_write, ++ 0); ++ if (written == this_write) { ++ pos += this_write; ++ increase -= this_write; ++ } else { ++ small_increase_ok = 0; ++ } ++ } ++ ++ yaffs_release_temp_buffer(dev, local_buffer); ++ ++ /* If out of space then reverse any chunks we've added */ ++ if (!small_increase_ok) ++ yaffs_resize_file_down(obj, old_file_size); ++ } ++ ++ if (!small_increase_ok && ++ obj->parent && ++ obj->parent->obj_id != YAFFS_OBJECTID_UNLINKED && ++ obj->parent->obj_id != YAFFS_OBJECTID_DELETED) { ++ /* Write a hole start header with the old file size */ ++ yaffs_update_oh(obj, NULL, 0, 1, 0, NULL); ++ } ++ ++ return result; ++} ++ ++/* Yaffs2 scanning */ ++ ++struct yaffs_block_index { ++ int seq; ++ int block; ++}; ++ ++static int yaffs2_ybicmp(const void *a, const void *b) ++{ ++ int aseq = ((struct yaffs_block_index *)a)->seq; ++ int bseq = ((struct yaffs_block_index *)b)->seq; ++ int ablock = ((struct yaffs_block_index *)a)->block; ++ int bblock = ((struct yaffs_block_index *)b)->block; ++ ++ if (aseq == bseq) ++ return ablock - bblock; ++ ++ return aseq - bseq; ++} ++ ++static inline int yaffs2_scan_chunk(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi, ++ int blk, int chunk_in_block, ++ int *found_chunks, ++ u8 *chunk_data, ++ struct list_head *hard_list, ++ int summary_available) ++{ ++ struct yaffs_obj_hdr *oh; ++ struct yaffs_obj *in; ++ struct yaffs_obj *parent; ++ int equiv_id; ++ loff_t file_size; ++ int is_shrink; ++ int is_unlinked; ++ struct yaffs_ext_tags tags; ++ int result; ++ int alloc_failed = 0; ++ int chunk = blk * dev->param.chunks_per_block + chunk_in_block; ++ struct yaffs_file_var *file_var; ++ struct yaffs_hardlink_var *hl_var; ++ struct yaffs_symlink_var *sl_var; ++ ++ if (summary_available) { ++ result = yaffs_summary_fetch(dev, &tags, chunk_in_block); ++ tags.seq_number = bi->seq_number; ++ } ++ ++ if (!summary_available || tags.obj_id == 0) { ++ result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags); ++ dev->tags_used++; ++ } else { ++ dev->summary_used++; ++ } ++ ++ if (result == YAFFS_FAIL) ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "Could not get tags for chunk %d\n", chunk); ++ /* Let's have a good look at this chunk... */ ++ ++ if (!tags.chunk_used) { ++ /* An unassigned chunk in the block. ++ * If there are used chunks after this one, then ++ * it is a chunk that was skipped due to failing ++ * the erased check. Just skip it so that it can ++ * be deleted. ++ * But, more typically, We get here when this is ++ * an unallocated chunk and his means that ++ * either the block is empty or this is the one ++ * being allocated from ++ */ ++ ++ if (*found_chunks) { ++ /* This is a chunk that was skipped due ++ * to failing the erased check */ ++ } else if (chunk_in_block == 0) { ++ /* We're looking at the first chunk in ++ * the block so the block is unused */ ++ bi->block_state = YAFFS_BLOCK_STATE_EMPTY; ++ dev->n_erased_blocks++; ++ } else { ++ if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN || ++ bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) { ++ if (dev->seq_number == bi->seq_number) { ++ /* Allocating from this block*/ ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ " Allocating from %d %d", ++ blk, chunk_in_block); ++ ++ bi->block_state = ++ YAFFS_BLOCK_STATE_ALLOCATING; ++ dev->alloc_block = blk; ++ dev->alloc_page = chunk_in_block; ++ dev->alloc_block_finder = blk; ++ } else { ++ /* This is a partially written block ++ * that is not the current ++ * allocation block. ++ */ ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "Partially written block %d detected. gc will fix this.", ++ blk); ++ } ++ } ++ } ++ ++ dev->n_free_chunks++; ++ ++ } else if (tags.ecc_result == ++ YAFFS_ECC_RESULT_UNFIXED) { ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ " Unfixed ECC in chunk(%d:%d), chunk ignored", ++ blk, chunk_in_block); ++ dev->n_free_chunks++; ++ } else if (tags.obj_id > YAFFS_MAX_OBJECT_ID || ++ tags.chunk_id > YAFFS_MAX_CHUNK_ID || ++ tags.obj_id == YAFFS_OBJECTID_SUMMARY || ++ (tags.chunk_id > 0 && ++ tags.n_bytes > dev->data_bytes_per_chunk) || ++ tags.seq_number != bi->seq_number) { ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored", ++ blk, chunk_in_block, tags.obj_id, ++ tags.chunk_id, tags.n_bytes); ++ dev->n_free_chunks++; ++ } else if (tags.chunk_id > 0) { ++ /* chunk_id > 0 so it is a data chunk... */ ++ loff_t endpos; ++ loff_t chunk_base = (tags.chunk_id - 1) * ++ dev->data_bytes_per_chunk; ++ ++ *found_chunks = 1; ++ ++ yaffs_set_chunk_bit(dev, blk, chunk_in_block); ++ bi->pages_in_use++; ++ ++ in = yaffs_find_or_create_by_number(dev, ++ tags.obj_id, ++ YAFFS_OBJECT_TYPE_FILE); ++ if (!in) ++ /* Out of memory */ ++ alloc_failed = 1; ++ ++ if (in && ++ in->variant_type == YAFFS_OBJECT_TYPE_FILE && ++ chunk_base < in->variant.file_variant.shrink_size) { ++ /* This has not been invalidated by ++ * a resize */ ++ if (!yaffs_put_chunk_in_file(in, tags.chunk_id, ++ chunk, -1)) ++ alloc_failed = 1; ++ ++ /* File size is calculated by looking at ++ * the data chunks if we have not ++ * seen an object header yet. ++ * Stop this practice once we find an ++ * object header. ++ */ ++ endpos = chunk_base + tags.n_bytes; ++ ++ if (!in->valid && ++ in->variant.file_variant.stored_size < endpos) { ++ in->variant.file_variant. ++ stored_size = endpos; ++ in->variant.file_variant. ++ file_size = endpos; ++ } ++ } else if (in) { ++ /* This chunk has been invalidated by a ++ * resize, or a past file deletion ++ * so delete the chunk*/ ++ yaffs_chunk_del(dev, chunk, 1, __LINE__); ++ } ++ } else { ++ /* chunk_id == 0, so it is an ObjectHeader. ++ * Thus, we read in the object header and make ++ * the object ++ */ ++ *found_chunks = 1; ++ ++ yaffs_set_chunk_bit(dev, blk, chunk_in_block); ++ bi->pages_in_use++; ++ ++ oh = NULL; ++ in = NULL; ++ ++ if (tags.extra_available) { ++ in = yaffs_find_or_create_by_number(dev, ++ tags.obj_id, ++ tags.extra_obj_type); ++ if (!in) ++ alloc_failed = 1; ++ } ++ ++ if (!in || ++ (!in->valid && dev->param.disable_lazy_load) || ++ tags.extra_shadows || ++ (!in->valid && (tags.obj_id == YAFFS_OBJECTID_ROOT || ++ tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND))) { ++ ++ /* If we don't have valid info then we ++ * need to read the chunk ++ * TODO In future we can probably defer ++ * reading the chunk and living with ++ * invalid data until needed. ++ */ ++ ++ result = yaffs_rd_chunk_tags_nand(dev, ++ chunk, ++ chunk_data, ++ NULL); ++ ++ oh = (struct yaffs_obj_hdr *)chunk_data; ++ ++ yaffs_do_endian_oh(dev, oh); ++ ++ if (dev->param.inband_tags) { ++ /* Fix up the header if they got ++ * corrupted by inband tags */ ++ oh->shadows_obj = ++ oh->inband_shadowed_obj_id; ++ oh->is_shrink = ++ oh->inband_is_shrink; ++ } ++ ++ if (!in) { ++ in = yaffs_find_or_create_by_number(dev, ++ tags.obj_id, oh->type); ++ if (!in) ++ alloc_failed = 1; ++ } ++ } ++ ++ if (!in) { ++ /* TODO Hoosterman we have a problem! */ ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs tragedy: Could not make object for object %d at chunk %d during scan", ++ tags.obj_id, chunk); ++ return YAFFS_FAIL; ++ } ++ ++ if (in->valid) { ++ /* We have already filled this one. ++ * We have a duplicate that will be ++ * discarded, but we first have to suck ++ * out resize info if it is a file. ++ */ ++ if ((in->variant_type == YAFFS_OBJECT_TYPE_FILE) && ++ ((oh && oh->type == YAFFS_OBJECT_TYPE_FILE) || ++ (tags.extra_available && ++ tags.extra_obj_type == YAFFS_OBJECT_TYPE_FILE) ++ )) { ++ loff_t this_size = (oh) ? ++ yaffs_oh_to_size(dev, oh, 0) : ++ tags.extra_file_size; ++ u32 parent_obj_id = (oh) ? ++ (u32)oh->parent_obj_id : ++ tags.extra_parent_id; ++ ++ is_shrink = (oh) ? ++ oh->is_shrink : ++ tags.extra_is_shrink; ++ ++ /* If it is deleted (unlinked ++ * at start also means deleted) ++ * we treat the file size as ++ * being zeroed at this point. ++ */ ++ if (parent_obj_id == YAFFS_OBJECTID_DELETED || ++ parent_obj_id == YAFFS_OBJECTID_UNLINKED) { ++ this_size = 0; ++ is_shrink = 1; ++ } ++ ++ if (is_shrink && ++ in->variant.file_variant.shrink_size > ++ this_size) ++ in->variant.file_variant.shrink_size = ++ this_size; ++ ++ if (is_shrink) ++ bi->has_shrink_hdr = 1; ++ } ++ /* Use existing - destroy this one. */ ++ yaffs_chunk_del(dev, chunk, 1, __LINE__); ++ } ++ ++ if (!in->valid && in->variant_type != ++ (oh ? oh->type : tags.extra_obj_type)) { ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs tragedy: Bad type, %d != %d, for object %d at chunk %d during scan", ++ oh ? oh->type : tags.extra_obj_type, ++ in->variant_type, tags.obj_id, ++ chunk); ++ in = yaffs_retype_obj(in, oh ? oh->type : tags.extra_obj_type); ++ } ++ ++ if (!in->valid && ++ (tags.obj_id == YAFFS_OBJECTID_ROOT || ++ tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND)) { ++ /* We only load some info, don't fiddle ++ * with directory structure */ ++ in->valid = 1; ++ ++ if (oh) { ++ in->yst_mode = oh->yst_mode; ++ yaffs_load_attribs(in, oh); ++ in->lazy_loaded = 0; ++ } else { ++ in->lazy_loaded = 1; ++ } ++ in->hdr_chunk = chunk; ++ ++ } else if (!in->valid) { ++ /* we need to load this info */ ++ in->valid = 1; ++ in->hdr_chunk = chunk; ++ if (oh) { ++ in->variant_type = oh->type; ++ in->yst_mode = oh->yst_mode; ++ yaffs_load_attribs(in, oh); ++ ++ if (oh->shadows_obj > 0) ++ yaffs_handle_shadowed_obj(dev, ++ oh->shadows_obj, 1); ++ ++ yaffs_set_obj_name_from_oh(in, oh); ++ parent = yaffs_find_or_create_by_number(dev, ++ oh->parent_obj_id, ++ YAFFS_OBJECT_TYPE_DIRECTORY); ++ file_size = yaffs_oh_to_size(dev, oh, 0); ++ is_shrink = oh->is_shrink; ++ equiv_id = oh->equiv_id; ++ } else { ++ in->variant_type = tags.extra_obj_type; ++ parent = yaffs_find_or_create_by_number(dev, ++ tags.extra_parent_id, ++ YAFFS_OBJECT_TYPE_DIRECTORY); ++ file_size = tags.extra_file_size; ++ is_shrink = tags.extra_is_shrink; ++ equiv_id = tags.extra_equiv_id; ++ in->lazy_loaded = 1; ++ } ++ in->dirty = 0; ++ ++ if (!parent) ++ alloc_failed = 1; ++ ++ /* directory stuff... ++ * hook up to parent ++ */ ++ ++ if (parent && ++ parent->variant_type == YAFFS_OBJECT_TYPE_UNKNOWN) { ++ /* Set up as a directory */ ++ parent->variant_type = ++ YAFFS_OBJECT_TYPE_DIRECTORY; ++ INIT_LIST_HEAD(&parent-> ++ variant.dir_variant.children); ++ } else if (!parent || ++ parent->variant_type != ++ YAFFS_OBJECT_TYPE_DIRECTORY) { ++ /* Hoosterman, another problem.... ++ * Trying to use a non-directory as a directory ++ */ ++ ++ yaffs_trace(YAFFS_TRACE_ERROR, ++ "yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found." ++ ); ++ parent = dev->lost_n_found; ++ } ++ yaffs_add_obj_to_dir(parent, in); ++ ++ is_unlinked = (parent == dev->del_dir) || ++ (parent == dev->unlinked_dir); ++ ++ if (is_shrink) ++ /* Mark the block */ ++ bi->has_shrink_hdr = 1; ++ ++ /* Note re hardlinks. ++ * Since we might scan a hardlink before its equivalent ++ * object is scanned we put them all in a list. ++ * After scanning is complete, we should have all the ++ * objects, so we run through this list and fix up all ++ * the chains. ++ */ ++ ++ switch (in->variant_type) { ++ case YAFFS_OBJECT_TYPE_UNKNOWN: ++ /* Todo got a problem */ ++ break; ++ case YAFFS_OBJECT_TYPE_FILE: ++ file_var = &in->variant.file_variant; ++ if (file_var->stored_size < file_size) { ++ /* This covers the case where the file ++ * size is greater than the data held. ++ * This will happen if the file is ++ * resized to be larger than its ++ * current data extents. ++ */ ++ file_var->file_size = file_size; ++ file_var->stored_size = file_size; ++ } ++ ++ if (file_var->shrink_size > file_size) ++ file_var->shrink_size = file_size; ++ ++ break; ++ case YAFFS_OBJECT_TYPE_HARDLINK: ++ hl_var = &in->variant.hardlink_variant; ++ if (!is_unlinked) { ++ hl_var->equiv_id = equiv_id; ++ list_add(&in->hard_links, hard_list); ++ } ++ break; ++ case YAFFS_OBJECT_TYPE_DIRECTORY: ++ /* Do nothing */ ++ break; ++ case YAFFS_OBJECT_TYPE_SPECIAL: ++ /* Do nothing */ ++ break; ++ case YAFFS_OBJECT_TYPE_SYMLINK: ++ sl_var = &in->variant.symlink_variant; ++ if (oh) { ++ sl_var->alias = ++ yaffs_clone_str(oh->alias); ++ if (!sl_var->alias) ++ alloc_failed = 1; ++ } ++ break; ++ } ++ } ++ } ++ return alloc_failed ? YAFFS_FAIL : YAFFS_OK; ++} ++ ++int yaffs2_scan_backwards(struct yaffs_dev *dev) ++{ ++ u32 blk; ++ int block_iter; ++ int start_iter; ++ int end_iter; ++ int n_to_scan = 0; ++ enum yaffs_block_state state; ++ int c; ++ LIST_HEAD(hard_list); ++ struct yaffs_block_info *bi; ++ u32 seq_number; ++ int n_blocks = dev->internal_end_block - dev->internal_start_block + 1; ++ u8 *chunk_data; ++ int found_chunks; ++ int alloc_failed = 0; ++ struct yaffs_block_index *block_index = NULL; ++ int alt_block_index = 0; ++ int summary_available; ++ ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "yaffs2_scan_backwards starts intstartblk %d intendblk %d...", ++ dev->internal_start_block, dev->internal_end_block); ++ ++ dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER; ++ ++ block_index = ++ kmalloc(n_blocks * sizeof(struct yaffs_block_index), GFP_NOFS); ++ ++ if (!block_index) { ++ block_index = ++ vmalloc(n_blocks * sizeof(struct yaffs_block_index)); ++ alt_block_index = 1; ++ } ++ ++ if (!block_index) { ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "yaffs2_scan_backwards() could not allocate block index!" ++ ); ++ return YAFFS_FAIL; ++ } ++ ++ dev->blocks_in_checkpt = 0; ++ ++ chunk_data = yaffs_get_temp_buffer(dev); ++ ++ /* Scan all the blocks to determine their state */ ++ bi = dev->block_info; ++ for (blk = dev->internal_start_block; blk <= dev->internal_end_block; ++ blk++) { ++ yaffs_clear_chunk_bits(dev, blk); ++ bi->pages_in_use = 0; ++ bi->soft_del_pages = 0; ++ ++ yaffs_query_init_block_state(dev, blk, &state, &seq_number); ++ ++ bi->block_state = state; ++ bi->seq_number = seq_number; ++ ++ if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA) ++ bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT; ++ if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK) ++ bi->block_state = YAFFS_BLOCK_STATE_DEAD; ++ ++ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, ++ "Block scanning block %d state %d seq %d", ++ blk, bi->block_state, seq_number); ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) { ++ dev->blocks_in_checkpt++; ++ ++ } else if (bi->block_state == YAFFS_BLOCK_STATE_DEAD) { ++ yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, ++ "block %d is bad", blk); ++ } else if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) { ++ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty "); ++ dev->n_erased_blocks++; ++ dev->n_free_chunks += dev->param.chunks_per_block; ++ } else if (bi->block_state == ++ YAFFS_BLOCK_STATE_NEEDS_SCAN) { ++ /* Determine the highest sequence number */ ++ if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER && ++ seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) { ++ block_index[n_to_scan].seq = seq_number; ++ block_index[n_to_scan].block = blk; ++ n_to_scan++; ++ if (seq_number >= dev->seq_number) ++ dev->seq_number = seq_number; ++ } else { ++ /* TODO: Nasty sequence number! */ ++ yaffs_trace(YAFFS_TRACE_SCAN, ++ "Block scanning block %d has bad sequence number %d", ++ blk, seq_number); ++ } ++ } ++ bi++; ++ } ++ ++ yaffs_trace(YAFFS_TRACE_ALWAYS, "%d blocks to be sorted...", n_to_scan); ++ ++ cond_resched(); ++ ++ /* Sort the blocks by sequence number */ ++ sort(block_index, n_to_scan, sizeof(struct yaffs_block_index), ++ yaffs2_ybicmp, NULL); ++ ++ cond_resched(); ++ ++ yaffs_trace(YAFFS_TRACE_SCAN, "...done"); ++ ++ /* Now scan the blocks looking at the data. */ ++ start_iter = 0; ++ end_iter = n_to_scan - 1; ++ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "%d blocks to scan", n_to_scan); ++ ++ /* For each block.... backwards */ ++ for (block_iter = end_iter; ++ !alloc_failed && block_iter >= start_iter; ++ block_iter--) { ++ /* Cooperative multitasking! This loop can run for so ++ long that watchdog timers expire. */ ++ cond_resched(); ++ ++ /* get the block to scan in the correct order */ ++ blk = block_index[block_iter].block; ++ bi = yaffs_get_block_info(dev, blk); ++ ++ summary_available = yaffs_summary_read(dev, dev->sum_tags, blk); ++ ++ /* For each chunk in each block that needs scanning.... */ ++ found_chunks = 0; ++ if (summary_available) ++ c = dev->chunks_per_summary - 1; ++ else ++ c = dev->param.chunks_per_block - 1; ++ ++ for (/* c is already initialised */; ++ !alloc_failed && c >= 0 && ++ (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN || ++ bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING); ++ c--) { ++ /* Scan backwards... ++ * Read the tags and decide what to do ++ */ ++ if (yaffs2_scan_chunk(dev, bi, blk, c, ++ &found_chunks, chunk_data, ++ &hard_list, summary_available) == ++ YAFFS_FAIL) ++ alloc_failed = 1; ++ } ++ ++ if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN) { ++ /* If we got this far while scanning, then the block ++ * is fully allocated. */ ++ bi->block_state = YAFFS_BLOCK_STATE_FULL; ++ } ++ ++ /* Now let's see if it was dirty */ ++ if (bi->pages_in_use == 0 && ++ !bi->has_shrink_hdr && ++ bi->block_state == YAFFS_BLOCK_STATE_FULL) { ++ yaffs_block_became_dirty(dev, blk); ++ } ++ } ++ ++ yaffs_skip_rest_of_block(dev); ++ ++ if (alt_block_index) ++ vfree(block_index); ++ else ++ kfree(block_index); ++ ++ /* Ok, we've done all the scanning. ++ * Fix up the hard link chains. ++ * We have scanned all the objects, now it's time to add these ++ * hardlinks. ++ */ ++ yaffs_link_fixup(dev, &hard_list); ++ ++ yaffs_release_temp_buffer(dev, chunk_data); ++ ++ if (alloc_failed) ++ return YAFFS_FAIL; ++ ++ yaffs_trace(YAFFS_TRACE_SCAN, "yaffs2_scan_backwards ends"); ++ ++ return YAFFS_OK; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs2.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs2.h.patch new file mode 100644 index 00000000..d033ce48 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yaffs_yaffs2.h.patch @@ -0,0 +1,42 @@ +--- linux-4.9.37/fs/yaffs2/yaffs_yaffs2.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yaffs_yaffs2.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,39 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YAFFS_YAFFS2_H__ ++#define __YAFFS_YAFFS2_H__ ++ ++#include "yaffs_guts.h" ++ ++void yaffs_calc_oldest_dirty_seq(struct yaffs_dev *dev); ++void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev); ++void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev, ++ struct yaffs_block_info *bi); ++void yaffs2_update_oldest_dirty_seq(struct yaffs_dev *dev, unsigned block_no, ++ struct yaffs_block_info *bi); ++int yaffs_block_ok_for_gc(struct yaffs_dev *dev, struct yaffs_block_info *bi); ++u32 yaffs2_find_refresh_block(struct yaffs_dev *dev); ++int yaffs2_checkpt_required(struct yaffs_dev *dev); ++int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev); ++ ++void yaffs2_checkpt_invalidate(struct yaffs_dev *dev); ++int yaffs2_checkpt_save(struct yaffs_dev *dev); ++int yaffs2_checkpt_restore(struct yaffs_dev *dev); ++ ++int yaffs2_handle_hole(struct yaffs_obj *obj, loff_t new_size); ++int yaffs2_scan_backwards(struct yaffs_dev *dev); ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yportenv.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yportenv.h.patch new file mode 100644 index 00000000..7fc18bee --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_fs-yaffs2-yportenv.h.patch @@ -0,0 +1,88 @@ +--- linux-4.9.37/fs/yaffs2/yportenv.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/fs/yaffs2/yportenv.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,85 @@ ++/* ++ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. ++ * ++ * Copyright (C) 2002-2011 Aleph One Ltd. ++ * for Toby Churchill Ltd and Brightstar Engineering ++ * ++ * Created by Charles Manning ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License version 2.1 as ++ * published by the Free Software Foundation. ++ * ++ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. ++ */ ++ ++#ifndef __YPORTENV_H__ ++#define __YPORTENV_H__ ++ ++/* ++ * Define the MTD version in terms of Linux Kernel versions ++ * This allows yaffs to be used independantly of the kernel ++ * as well as with it. ++ */ ++ ++#define MTD_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) ++ ++#ifdef YAFFS_OUT_OF_TREE ++#include "moduleconfig.h" ++#endif ++ ++#include ++#define MTD_VERSION_CODE LINUX_VERSION_CODE ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* These type wrappings are used to support Unicode names in WinCE. */ ++#define YCHAR char ++#define YUCHAR unsigned char ++#define _Y(x) x ++ ++#define YAFFS_LOSTNFOUND_NAME "lost+found" ++#define YAFFS_LOSTNFOUND_PREFIX "obj" ++ ++ ++#define YAFFS_ROOT_MODE 0755 ++#define YAFFS_LOSTNFOUND_MODE 0700 ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) ++#define Y_CURRENT_TIME CURRENT_TIME.tv_sec ++#define Y_TIME_CONVERT(x) (x).tv_sec ++#else ++#define Y_CURRENT_TIME CURRENT_TIME ++#define Y_TIME_CONVERT(x) (x) ++#endif ++ ++#define compile_time_assertion(assertion) \ ++ ({ int x = __builtin_choose_expr(assertion, 0, (void)0); (void) x; }) ++ ++ ++#define yaffs_printf(msk, fmt, ...) \ ++ printk(KERN_DEBUG "yaffs: " fmt "\n", ##__VA_ARGS__) ++ ++#define yaffs_trace(msk, fmt, ...) do { \ ++ if (yaffs_trace_mask & (msk)) \ ++ printk(KERN_DEBUG "yaffs: " fmt "\n", ##__VA_ARGS__); \ ++} while (0) ++ ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_gk7205v200_kernel-4.9.37_sdk-V100R001C00SPC020.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_gk7205v200_kernel-4.9.37_sdk-V100R001C00SPC020.patch deleted file mode 100644 index a4fb322b..00000000 --- a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_gk7205v200_kernel-4.9.37_sdk-V100R001C00SPC020.patch +++ /dev/null @@ -1,98458 +0,0 @@ ---- linux-4.9.37/arch/arm/boot/compressed/head.S 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/compressed/head.S 2021-06-07 13:01:32.000000000 +0300 -@@ -218,6 +218,21 @@ - addcc r0, r0, pc - cmpcc r4, r0 - orrcc r4, r4, #1 @ remember we skipped cache_on -+ -+/*TODO all the Cortex-A7 Single Core must fix this bug */ -+#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) \ -+ || defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) -+/* -+ * This is a bug on Cortex-A7 MPCORE. see buglist of Cortex-A7 -+ * The D-caches are disabled when ACTLR.SMP is set to 0 regardless of the -+ * value of the cache enable bit. so we must set SMP bit of ACTLR register -+ * before enable D cache -+ */ -+ mrc p15, 0, r0, c1, c0, 1 -+ orr r0, #(1 << 6) -+ mcr p15, 0, r0, c1, c0, 1 -+#endif -+ - blcs cache_on - - restart: adr r0, LC0 ---- linux-4.9.37/arch/arm/boot/dts/gk7202v300-demb.dts 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7202v300-demb.dts 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+/dts-v1/; -+#include "gk7202v300.dtsi" -+ -+/ { -+ model = "Goke GK7202V300 DEMO Board"; -+ compatible = "goke,gk7202v300"; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x40000000 0x20000000>; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "disabled"; -+}; -+ -+&uart2 { -+ status = "disabled"; -+}; -+ -+&i2c_bus0 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus1 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus2 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&spi_bus0{ -+ status = "okay"; -+ num-cs = <1>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&spi_bus1{ -+ status = "okay"; -+ num-cs = <2>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+ spidev@1 { -+ compatible = "rohm,dh2228fv"; -+ reg = <1>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&dual_timer0 { -+ status = "okay"; -+}; -+ -+&mdio0 { -+ goke,phy-reset-delays-us = <10000 20000 150000>; -+ phy0: ethernet-phy@1 { -+ reg = <1>; -+ }; -+}; -+ -+&femac { -+ mac-address = [00 00 00 00 00 00]; -+ phy-mode = "mii"; -+ phy-handle = <&phy0>; -+ status = "okay"; -+}; -+ -+&sfc { -+ sfc { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&snfc { -+ nand { -+ compatible = "jedec,spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&mmc0 { -+ status = "okay"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+}; -+ -+&gpio_chip0 { -+ status = "okay"; -+}; -+ -+&gpio_chip1 { -+ status = "okay"; -+}; -+ -+&gpio_chip2 { -+ status = "okay"; -+}; -+ -+&gpio_chip4 { -+ status = "okay"; -+}; -+ -+&gpio_chip5 { -+ status = "okay"; -+}; -+ -+&gpio_chip6 { -+ status = "okay"; -+}; -+ -+&gpio_chip7 { -+ status = "okay"; -+}; -+ -+&gpio_chip8 { -+ status = "okay"; -+}; -+ ---- linux-4.9.37/arch/arm/boot/dts/gk7202v300.dtsi 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7202v300.dtsi 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,625 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include "skeleton.dtsi" -+#include -+/ { -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ serial2 = &uart2; -+ i2c0 = &i2c_bus0; -+ i2c1 = &i2c_bus1; -+ i2c2 = &i2c_bus2; -+ spi0 = &spi_bus0; -+ spi1 = &spi_bus1; -+ gpio0 = &gpio_chip0; -+ gpio1 = &gpio_chip1; -+ gpio2 = &gpio_chip2; -+ gpio4 = &gpio_chip4; -+ gpio5 = &gpio_chip5; -+ gpio6 = &gpio_chip6; -+ gpio7 = &gpio_chip7; -+ gpio8 = &gpio_chip8; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ enable-method = "goke,gk7202v300"; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ clock-frequency = ; -+ reg = <0>; -+ }; -+ }; -+ -+ pmu { -+ compatible = "arm,armv7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ clock: clock@12010000 { -+ compatible = "goke,gk7202v300-clock", "syscon"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ #clock-cells = <1>; -+ #reset-cells = <2>; -+ reg = <0x12010000 0x1000>; -+ }; -+ -+ gic: interrupt-controller@10300000 { -+ compatible = "arm,cortex-a7-gic"; -+ #interrupt-cells = <3>; -+ #address-cells = <0>; -+ interrupt-controller; -+ /* gic dist base, gic cpu base , no virtual support */ -+ reg = <0x10301000 0x1000>, <0x10302000 0x100>; -+ }; -+ -+ syscounter { -+ compatible = "arm,armv7-timer"; -+ interrupt-parent = <&gic>; -+ interrupts = <1 13 0xf08>, -+ <1 14 0xf08>; -+ clock-frequency = <50000000>; -+ }; -+ -+ soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ clk_3m: clk_3m { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <3000000>; -+ }; -+ -+ clk_apb: clk_apb { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <50000000>; -+ }; -+ -+ pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ sysctrl: system-controller@12020000 { -+ compatible = "goke,sysctrl"; -+ reg = <0x12020000 0x1000>; -+ reboot-offset = <0x4>; -+ #clock-cells = <1>; -+ }; -+ -+ iocfg_ctrl: iocfg-controller@100c0000 { -+ compatible = "syscon"; -+ reg = <0x100C0000 0x10000>; -+ }; -+ -+ iocfg_ctrl2: iocfg-controller2@112c0000 { -+ compatible = "syscon"; -+ reg = <0x112C0000 0x10000>; -+ }; -+ -+#ifdef CONFIG_EDMAC -+ edmac: edma-controller@100B0000 { -+ compatible = "goke,edmac"; -+ reg = <0x100B0000 0x1000>; -+ interrupts = <0 38 4>; -+ clocks = <&clock GK7202V300_EDMAC_CLK>, <&clock GK7202V300_EDMAC_AXICLK>; -+ clock-names = "apb_pclk", "axi_aclk"; -+ clock-cells = <2>; -+ resets = <&clock 0x194 0>; -+ reset-names = "dma-reset"; -+ dma-requests = <32>; -+ dma-channels = <4>; -+ devid = <0>; -+ #dma-cells = <2>; -+ status = "okay"; -+ }; -+#endif -+ amba { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "arm,amba-bus"; -+ ranges; -+ -+ dual_timer0: dual_timer@12000000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer0 & timer1 */ -+ interrupts = <0 5 4>; -+ reg = <0x12000000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer00", "timer01", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ dual_timer1: dual_timer@12001000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer2 & timer3 */ -+ interrupts = <0 6 4>; -+ reg = <0x12001000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer10", "timer11", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart0: uart@12040000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12040000 0x1000>; -+ interrupts = <0 7 4>; -+ clocks = <&clock GK7202V300_UART0_CLK>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart1: uart@12041000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12041000 0x1000>; -+ interrupts = <0 8 4>; -+ clocks = <&clock GK7202V300_UART1_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 19 19>, <&edmac 18 18>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ uart2: uart@12042000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12042000 0x1000>; -+ interrupts = <0 9 4>; -+ clocks = <&clock GK7202V300_UART2_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 21 21>, <&edmac 20 20>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ }; -+ -+ i2c_bus0: i2c@12060000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12060000 0x1000>; -+ clocks = <&clock GK7202V300_I2C0_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus1: i2c@12061000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12061000 0x1000>; -+ clocks = <&clock GK7202V300_I2C1_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus2: i2c@12062000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12062000 0x1000>; -+ clocks = <&clock GK7202V300_I2C2_CLK>; -+ status = "disabled"; -+ }; -+ -+ spi_bus0: spi@12070000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12070000 0x1000>; -+ interrupts = <0 14 4>; -+ clocks = <&clock GK7202V300_SPI0_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 27 27>, <&edmac 26 26>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ spi_bus1: spi@12071000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12071000 0x1000>, <0x12028000 0x4>; -+ interrupts = <0 15 4>; -+ clocks = <&clock GK7202V300_SPI1_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ num-cs = <2>; -+ spi_cs_sb = <2>; -+ spi_cs_mask_bit = <0x4>;//0100 -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 29 29>, <&edmac 28 28>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ mdio0: mdio@10041100 { -+ compatible = "goke,femac-mdio"; -+ reg = <0x10041100 0x10>,<0x12028024 0x4>; -+ clocks = <&clock GK7202V300_ETH0_CLK>; -+ clock-names = "mdio"; -+ resets = <&clock 0x16c 3>; -+ reset-names = "internal-phy"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ femac: ethernet@10040000 { -+ compatible = "goke,femac"; -+ reg = <0x10040000 0x1000>,<0x10041300 0x200>; -+ interrupts = <0 33 4>; -+ clocks = <&clock GK7202V300_ETH0_CLK>; -+ resets = <&clock 0x16c 0>; -+ reset-names = "mac"; -+ }; -+ -+ fmc: flash-memory-controller@10000000 { -+ compatible = "goke,fmc"; -+ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; -+ reg-names = "control", "memory"; -+ clocks = <&clock GK7202V300_FMC_CLK>; -+ max-dma-size = <0x2000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sfc:spi-nor@0 { -+ compatible = "goke,fmc-spi-nor"; -+ assigned-clocks = <&clock GK7202V300_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ snfc:spi-nand@0 { -+ compatible = "goke,fmc-spi-nand"; -+ assigned-clocks = <&clock GK7202V300_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ -+ mmc0: sdhci@0x10010000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10010000 0x1000>; -+ interrupts = <0 30 4>; -+ clocks = <&clock GK7202V300_MMC0_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <150000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl>; -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-mmc-hw-reset; -+ cap-sd-highspeed; -+ mmc-hs200-1_8v; -+ full-pwr-cycle; -+ devid = <0>; -+ status = "enable"; -+ }; -+ -+ mmc1: sdhci@0x10020000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10020000 0x1000>; -+ interrupts = <0 31 4>; -+ clocks = <&clock GK7202V300_MMC1_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <50000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl2>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ full-pwr-cycle; -+ devid = <2>; -+ status = "enable"; -+ }; -+ -+ usb2_phy0: phy2-0 { -+ compatible = "goke,usbp2-phy"; -+ reg = <0x100D0000 0x1000>, -+ <0x12010000 0x1000>, -+ <0x100c0000 0x1000>; -+ clocks = <&clock GK7202V300_USB2_PHY_APB_CLK>, -+ <&clock GK7202V300_USB2_PHY_PLL_CLK>, -+ <&clock GK7202V300_USB2_PHY_XO_CLK>; -+ clock-names = "clk_u2phy_apb_ref", -+ "clk_u2phy_pll_ref", -+ "clk_u2phy_xo_ref"; -+ resets = <&clock 0x140 0>, -+ <&clock 0x140 1>; -+ reset-names = "phy_por_reset", -+ "phy_tpor_reset"; -+ phy_pll_offset = <0x14>; -+ phy_pll_mask = <0x03>; -+ phy_pll_val = <0x00>; -+ crg_offset = <0x140>; -+ crg_defal_mask = <0x0c07>; -+ crg_defal_val = <0x0807>; -+ vbus_offset = <0x7c>; -+ vbus_val = <0x0531>; -+ pwren_offset = <0x80>; -+ pwren_val = <0x1>; -+ ana_cfg_0_eye_val = <0x0433cc23>; -+ ana_cfg_0_offset = <0x00>; -+ ana_cfg_2_eye_val = <0x00320f0f>; -+ ana_cfg_2_offset = <0x08>; -+ ana_cfg_4_eye_val = <0x655>; -+ ana_cfg_4_offset = <0x10>; -+ trim_otp_addr = <0x12028004>; -+ trim_otp_mask = <0x1f>; -+ trim_otp_bit_offset = <0x00>; -+ trim_otp_min = <0x09>; -+ trim_otp_max = <0x1d>; -+ #phy-cells = <0>; -+ }; -+ -+ usbdrd3_0: usb3-0{ -+ compatible = "goke,dwusb2"; -+ reg = <0x10030000 0x10000>, -+ <0x12010000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ crg_offset = <0x140>; -+ crg_ctrl_def_mask = <0x3308>; -+ crg_ctrl_def_val = <0x1308>; -+ clocks = <&clock GK7202V300_USB2_BUS_CLK>, -+ <&clock GK7202V300_USB2_REF_CLK>, -+ <&clock GK7202V300_USB2_UTMI_CLK>; -+ clock-names = "usb2_bus_clk", -+ "usb2_ref_clk", -+ "usb2_utmi_clk"; -+ resets = <&clock 0x140 3>; -+ reset-names = "vcc_reset"; -+ ranges; -+ -+ dwc3@0x100e0000 { -+ compatible = "snps,dwc3"; -+ reg = <0x10030000 0x10000>; -+ interrupts = <0 39 4>; -+ interrupt-names = "peripheral"; -+ phys = <&usb2_phy0>; -+ phy-names = "usb2-phy"; -+ maximum-speed = "high-speed"; -+ dr_mode = "peripheral"; -+ eps_directions = <0x6a>; -+ snps,eps_new_init; -+ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; -+ snps,usb2-lpm-disable; -+ }; -+ }; -+ -+ gpio_chip0: gpio_chip@120b0000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b0000 0x1000>; -+ interrupts = <0 16 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip1: gpio_chip@120b1000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b1000 0x1000>; -+ interrupts = <0 17 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip2: gpio_chip@120b2000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b2000 0x1000>; -+ interrupts = <0 18 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip4: gpio_chip@120b4000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b4000 0x1000>; -+ interrupts = <0 20 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip5: gpio_chip@120b5000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b5000 0x1000>; -+ interrupts = <0 21 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip6: gpio_chip@120b6000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b6000 0x1000>; -+ interrupts = <0 22 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip7: gpio_chip@120b7000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b7000 0x1000>; -+ interrupts = <0 23 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip8: gpio_chip@120b8000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b8000 0x1000>; -+ interrupts = <0 24 4>; -+ clocks = <&clock GK7202V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ rtc: rtc@120e0000 { -+ compatible = "goke,rtc"; -+ reg = <0x120e0000 0x1000>; -+ interrupts = <0 0 4>; -+ }; -+ -+ cipher: cipher@0x10050000 { -+ compatible = "goke,cipher"; -+ reg = <0x10050000 0x10000>; -+ reg-names = "cipher"; -+ interrupts = <0 34 4>, <0 34 4>; -+ interrupt-names = "cipher", "hash"; -+ }; -+ -+ adc: adc@120a0000 { -+ compatible = "goke,lsadc"; -+ reg = <0x120a0000 0x1000>; -+ interrupts = <0 4 4>; -+ interrupt-names = "adc"; -+ resets = <&clock 0x1bc 2>; -+ reset-names = "lsadc-crg"; -+ status = "okay"; -+ }; -+ -+ wdg: wdg@0x12030000 { -+ compatible = "goke,wdg"; -+ reg = <0x12030000 0x1000>; -+ reg-names = "wdg"; -+ interrupts = <0 2 4>; -+ interrupt-names = "wdg"; -+ }; -+ }; -+ -+ media { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ osal: osal { -+ compatible = "goke,osal"; -+ }; -+ -+ sys: sys@12010000 { -+ compatible = "goke,sys"; -+ }; -+ -+ mipi: mipi@0x11240000 { -+ compatible = "goke,mipi"; -+ reg = <0x11240000 0x10000>; -+ reg-names = "mipi_rx"; -+ interrupts = <0 45 4>; -+ interrupt-names = "mipi_rx"; -+ }; -+ -+ vi: vi@11000000 { -+ compatible = "goke,vi"; -+ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; -+ reg-names = "VI_CAP0", "VI_PROC0"; -+ interrupts = <0 43 4>, <0 44 4>; -+ interrupt-names = "VI_CAP0", "VI_PROC0"; -+ }; -+ -+ isp: isp@11220000 { -+ compatible = "goke,isp"; -+ reg = <0x11220000 0x20000>; -+ reg-names = "ISP"; -+ interrupts = <0 43 4>; -+ interrupt-names = "ISP"; -+ }; -+ -+ vpss: vpss@11400000 { -+ compatible = "goke,vpss"; -+ reg = <0x11400000 0x10000>; -+ reg-names = "vpss0"; -+ interrupts = <0 46 4>; -+ interrupt-names = "vpss0"; -+ }; -+ -+ vo: vo@11280000 { -+ compatible = "goke,vo"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "vo"; -+ interrupts = <0 40 4>; -+ interrupt-names = "vo"; -+ }; -+ -+ gfbg: gfbg@11280000 { -+ compatible = "goke,gfbg"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "gfbg"; -+ interrupts = <0 41 4>; -+ interrupt-names = "gfbg"; -+ }; -+ -+ vgs: vgs@11300000 { -+ compatible = "goke,vgs"; -+ reg = <0x11300000 0x10000>; -+ reg-names = "vgs0"; -+ interrupts = <0 49 4>; -+ interrupt-names = "vgs0"; -+ }; -+ -+ gzip: gzip@11310000 { -+ compatible = "goke,gzip"; -+ reg = <0x11310000 0x10000>; -+ reg-names = "gzip"; -+ interrupts = <0 50 4>; -+ interrupt-names = "gzip"; -+ }; -+ -+ vedu: vedu@11410000 { -+ compatible = "goke,vedu"; -+ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; -+ reg-names = "vedu0", "jpge"; -+ interrupts = <0 47 4>, <0 48 4>; -+ interrupt-names = "vedu0","jpge"; -+ }; -+ -+ venc: venc { -+ compatible = "goke,venc"; -+ }; -+ -+ aiao: aiao@100e0000 { -+ compatible = "goke,aiao"; -+ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; -+ reg-names = "aiao","acodec"; -+ interrupts = <0 42 4>; -+ interrupt-names = "AIO"; -+ }; -+ -+ ive: ive@11320000 { -+ compatible = "goke,ive"; -+ reg = <0x11320000 0x10000>; -+ reg-names = "ive"; -+ interrupts = <0 51 4>; -+ interrupt-names = "ive"; -+ }; -+ }; -+}; ---- linux-4.9.37/arch/arm/boot/dts/gk7205v200-demb.dts 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7205v200-demb.dts 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+/dts-v1/; -+#include "gk7205v200.dtsi" -+ -+/ { -+ model = "Goke GK7205V200 DEMO Board"; -+ compatible = "goke,gk7205v200"; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x40000000 0x20000000>; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "disabled"; -+}; -+ -+&uart2 { -+ status = "disabled"; -+}; -+ -+&i2c_bus0 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus1 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus2 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&spi_bus0{ -+ status = "okay"; -+ num-cs = <1>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&spi_bus1{ -+ status = "okay"; -+ num-cs = <2>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+ spidev@1 { -+ compatible = "rohm,dh2228fv"; -+ reg = <1>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&dual_timer0 { -+ status = "okay"; -+}; -+ -+&mdio0 { -+ goke,phy-reset-delays-us = <10000 20000 150000>; -+ phy0: ethernet-phy@1 { -+ reg = <1>; -+ }; -+}; -+ -+&femac { -+ mac-address = [00 00 00 00 00 00]; -+ phy-mode = "mii"; -+ phy-handle = <&phy0>; -+ status = "okay"; -+}; -+ -+&sfc { -+ sfc { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&snfc { -+ nand { -+ compatible = "jedec,spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&mmc0 { -+ status = "okay"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+}; -+ -+&gpio_chip0 { -+ status = "okay"; -+}; -+ -+&gpio_chip1 { -+ status = "okay"; -+}; -+ -+&gpio_chip2 { -+ status = "okay"; -+}; -+ -+&gpio_chip4 { -+ status = "okay"; -+}; -+ -+&gpio_chip5 { -+ status = "okay"; -+}; -+ -+&gpio_chip6 { -+ status = "okay"; -+}; -+ -+&gpio_chip7 { -+ status = "okay"; -+}; -+ -+&gpio_chip8 { -+ status = "okay"; -+}; -+ ---- linux-4.9.37/arch/arm/boot/dts/gk7205v200.dtsi 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7205v200.dtsi 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,625 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include "skeleton.dtsi" -+#include -+/ { -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ serial2 = &uart2; -+ i2c0 = &i2c_bus0; -+ i2c1 = &i2c_bus1; -+ i2c2 = &i2c_bus2; -+ spi0 = &spi_bus0; -+ spi1 = &spi_bus1; -+ gpio0 = &gpio_chip0; -+ gpio1 = &gpio_chip1; -+ gpio2 = &gpio_chip2; -+ gpio4 = &gpio_chip4; -+ gpio5 = &gpio_chip5; -+ gpio6 = &gpio_chip6; -+ gpio7 = &gpio_chip7; -+ gpio8 = &gpio_chip8; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ enable-method = "goke,gk7205v200"; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ clock-frequency = ; -+ reg = <0>; -+ }; -+ }; -+ -+ pmu { -+ compatible = "arm,armv7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ clock: clock@12010000 { -+ compatible = "goke,gk7205v200-clock", "syscon"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ #clock-cells = <1>; -+ #reset-cells = <2>; -+ reg = <0x12010000 0x1000>; -+ }; -+ -+ gic: interrupt-controller@10300000 { -+ compatible = "arm,cortex-a7-gic"; -+ #interrupt-cells = <3>; -+ #address-cells = <0>; -+ interrupt-controller; -+ /* gic dist base, gic cpu base , no virtual support */ -+ reg = <0x10301000 0x1000>, <0x10302000 0x100>; -+ }; -+ -+ syscounter { -+ compatible = "arm,armv7-timer"; -+ interrupt-parent = <&gic>; -+ interrupts = <1 13 0xf08>, -+ <1 14 0xf08>; -+ clock-frequency = <50000000>; -+ }; -+ -+ soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ clk_3m: clk_3m { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <3000000>; -+ }; -+ -+ clk_apb: clk_apb { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <50000000>; -+ }; -+ -+ pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ sysctrl: system-controller@12020000 { -+ compatible = "goke,sysctrl"; -+ reg = <0x12020000 0x1000>; -+ reboot-offset = <0x4>; -+ #clock-cells = <1>; -+ }; -+ -+ iocfg_ctrl: iocfg-controller@100c0000 { -+ compatible = "syscon"; -+ reg = <0x100C0000 0x10000>; -+ }; -+ -+ iocfg_ctrl2: iocfg-controller2@112c0000 { -+ compatible = "syscon"; -+ reg = <0x112C0000 0x10000>; -+ }; -+ -+#ifdef CONFIG_EDMAC -+ edmac: edma-controller@100B0000 { -+ compatible = "goke,edmac"; -+ reg = <0x100B0000 0x1000>; -+ interrupts = <0 38 4>; -+ clocks = <&clock GK7205V200_EDMAC_CLK>, <&clock GK7205V200_EDMAC_AXICLK>; -+ clock-names = "apb_pclk", "axi_aclk"; -+ clock-cells = <2>; -+ resets = <&clock 0x194 0>; -+ reset-names = "dma-reset"; -+ dma-requests = <32>; -+ dma-channels = <4>; -+ devid = <0>; -+ #dma-cells = <2>; -+ status = "okay"; -+ }; -+#endif -+ amba { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "arm,amba-bus"; -+ ranges; -+ -+ dual_timer0: dual_timer@12000000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer0 & timer1 */ -+ interrupts = <0 5 4>; -+ reg = <0x12000000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer00", "timer01", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ dual_timer1: dual_timer@12001000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer2 & timer3 */ -+ interrupts = <0 6 4>; -+ reg = <0x12001000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer10", "timer11", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart0: uart@12040000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12040000 0x1000>; -+ interrupts = <0 7 4>; -+ clocks = <&clock GK7205V200_UART0_CLK>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart1: uart@12041000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12041000 0x1000>; -+ interrupts = <0 8 4>; -+ clocks = <&clock GK7205V200_UART1_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 19 19>, <&edmac 18 18>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ uart2: uart@12042000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12042000 0x1000>; -+ interrupts = <0 9 4>; -+ clocks = <&clock GK7205V200_UART2_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 21 21>, <&edmac 20 20>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ }; -+ -+ i2c_bus0: i2c@12060000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12060000 0x1000>; -+ clocks = <&clock GK7205V200_I2C0_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus1: i2c@12061000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12061000 0x1000>; -+ clocks = <&clock GK7205V200_I2C1_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus2: i2c@12062000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12062000 0x1000>; -+ clocks = <&clock GK7205V200_I2C2_CLK>; -+ status = "disabled"; -+ }; -+ -+ spi_bus0: spi@12070000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12070000 0x1000>; -+ interrupts = <0 14 4>; -+ clocks = <&clock GK7205V200_SPI0_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 27 27>, <&edmac 26 26>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ spi_bus1: spi@12071000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12071000 0x1000>, <0x12028000 0x4>; -+ interrupts = <0 15 4>; -+ clocks = <&clock GK7205V200_SPI1_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ num-cs = <2>; -+ spi_cs_sb = <2>; -+ spi_cs_mask_bit = <0x4>;//0100 -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 29 29>, <&edmac 28 28>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ mdio0: mdio@10041100 { -+ compatible = "goke,femac-mdio"; -+ reg = <0x10041100 0x10>,<0x12028024 0x4>; -+ clocks = <&clock GK7205V200_ETH0_CLK>; -+ clock-names = "mdio"; -+ resets = <&clock 0x16c 3>; -+ reset-names = "internal-phy"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ femac: ethernet@10040000 { -+ compatible = "goke,femac"; -+ reg = <0x10040000 0x1000>,<0x10041300 0x200>; -+ interrupts = <0 33 4>; -+ clocks = <&clock GK7205V200_ETH0_CLK>; -+ resets = <&clock 0x16c 0>; -+ reset-names = "mac"; -+ }; -+ -+ fmc: flash-memory-controller@10000000 { -+ compatible = "goke,fmc"; -+ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; -+ reg-names = "control", "memory"; -+ clocks = <&clock GK7205V200_FMC_CLK>; -+ max-dma-size = <0x2000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sfc:spi-nor@0 { -+ compatible = "goke,fmc-spi-nor"; -+ assigned-clocks = <&clock GK7205V200_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ snfc:spi-nand@0 { -+ compatible = "goke,fmc-spi-nand"; -+ assigned-clocks = <&clock GK7205V200_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ -+ mmc0: sdhci@0x10010000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10010000 0x1000>; -+ interrupts = <0 30 4>; -+ clocks = <&clock GK7205V200_MMC0_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <150000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl>; -+ bus-width = <4>; -+ cap-mmc-highspeed; -+ cap-mmc-hw-reset; -+ cap-sd-highspeed; -+ mmc-hs200-1_8v; -+ full-pwr-cycle; -+ devid = <0>; -+ status = "enable"; -+ }; -+ -+ mmc1: sdhci@0x10020000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10020000 0x1000>; -+ interrupts = <0 31 4>; -+ clocks = <&clock GK7205V200_MMC1_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <50000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl2>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ full-pwr-cycle; -+ devid = <2>; -+ status = "enable"; -+ }; -+ -+ usb2_phy0: phy2-0 { -+ compatible = "goke,usbp2-phy"; -+ reg = <0x100D0000 0x1000>, -+ <0x12010000 0x1000>, -+ <0x100c0000 0x1000>; -+ clocks = <&clock GK7205V200_USB2_PHY_APB_CLK>, -+ <&clock GK7205V200_USB2_PHY_PLL_CLK>, -+ <&clock GK7205V200_USB2_PHY_XO_CLK>; -+ clock-names = "clk_u2phy_apb_ref", -+ "clk_u2phy_pll_ref", -+ "clk_u2phy_xo_ref"; -+ resets = <&clock 0x140 0>, -+ <&clock 0x140 1>; -+ reset-names = "phy_por_reset", -+ "phy_tpor_reset"; -+ phy_pll_offset = <0x14>; -+ phy_pll_mask = <0x03>; -+ phy_pll_val = <0x00>; -+ crg_offset = <0x140>; -+ crg_defal_mask = <0x0c07>; -+ crg_defal_val = <0x0807>; -+ vbus_offset = <0x7c>; -+ vbus_val = <0x0531>; -+ pwren_offset = <0x80>; -+ pwren_val = <0x01>; -+ ana_cfg_0_eye_val = <0x0433cc23>; -+ ana_cfg_0_offset = <0x00>; -+ ana_cfg_2_eye_val = <0x00320f0f>; -+ ana_cfg_2_offset = <0x08>; -+ ana_cfg_4_eye_val = <0x655>; -+ ana_cfg_4_offset = <0x10>; -+ trim_otp_addr = <0x12028004>; -+ trim_otp_mask = <0x1f>; -+ trim_otp_bit_offset = <0x00>; -+ trim_otp_min = <0x09>; -+ trim_otp_max = <0x1d>; -+ #phy-cells = <0>; -+ }; -+ -+ usbdrd3_0: usb3-0{ -+ compatible = "goke,dwusb2"; -+ reg = <0x10030000 0x10000>, -+ <0x12010000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ crg_offset = <0x140>; -+ crg_ctrl_def_mask = <0x3308>; -+ crg_ctrl_def_val = <0x1308>; -+ clocks = <&clock GK7205V200_USB2_BUS_CLK>, -+ <&clock GK7205V200_USB2_REF_CLK>, -+ <&clock GK7205V200_USB2_UTMI_CLK>; -+ clock-names = "usb2_bus_clk", -+ "usb2_ref_clk", -+ "usb2_utmi_clk"; -+ resets = <&clock 0x140 3>; -+ reset-names = "vcc_reset"; -+ ranges; -+ -+ dwc3@0x100e0000 { -+ compatible = "snps,dwc3"; -+ reg = <0x10030000 0x10000>; -+ interrupts = <0 39 4>; -+ interrupt-names = "peripheral"; -+ phys = <&usb2_phy0>; -+ phy-names = "usb2-phy"; -+ maximum-speed = "high-speed"; -+ dr_mode = "host"; -+ eps_directions = <0x6a>; -+ snps,eps_new_init; -+ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; -+ snps,usb2-lpm-disable; -+ }; -+ }; -+ -+ gpio_chip0: gpio_chip@120b0000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b0000 0x1000>; -+ interrupts = <0 16 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip1: gpio_chip@120b1000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b1000 0x1000>; -+ interrupts = <0 17 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip2: gpio_chip@120b2000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b2000 0x1000>; -+ interrupts = <0 18 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip4: gpio_chip@120b4000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b4000 0x1000>; -+ interrupts = <0 20 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip5: gpio_chip@120b5000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b5000 0x1000>; -+ interrupts = <0 21 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip6: gpio_chip@120b6000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b6000 0x1000>; -+ interrupts = <0 22 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip7: gpio_chip@120b7000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b7000 0x1000>; -+ interrupts = <0 23 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip8: gpio_chip@120b8000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b8000 0x1000>; -+ interrupts = <0 24 4>; -+ clocks = <&clock GK7205V200_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ rtc: rtc@120e0000 { -+ compatible = "goke,rtc"; -+ reg = <0x120e0000 0x1000>; -+ interrupts = <0 0 4>; -+ }; -+ -+ cipher: cipher@0x10050000 { -+ compatible = "goke,cipher"; -+ reg = <0x10050000 0x10000>; -+ reg-names = "cipher"; -+ interrupts = <0 34 4>, <0 34 4>; -+ interrupt-names = "cipher", "hash"; -+ }; -+ -+ adc: adc@120a0000 { -+ compatible = "goke,lsadc"; -+ reg = <0x120a0000 0x1000>; -+ interrupts = <0 4 4>; -+ interrupt-names = "adc"; -+ resets = <&clock 0x1bc 2>; -+ reset-names = "lsadc-crg"; -+ status = "okay"; -+ }; -+ -+ wdg: wdg@0x12030000 { -+ compatible = "goke,wdg"; -+ reg = <0x12030000 0x1000>; -+ reg-names = "wdg"; -+ interrupts = <0 2 4>; -+ interrupt-names = "wdg"; -+ }; -+ }; -+ -+ media { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ osal: osal { -+ compatible = "goke,osal"; -+ }; -+ -+ sys: sys@12010000 { -+ compatible = "goke,sys"; -+ }; -+ -+ mipi: mipi@0x11240000 { -+ compatible = "goke,mipi"; -+ reg = <0x11240000 0x10000>; -+ reg-names = "mipi_rx"; -+ interrupts = <0 45 4>; -+ interrupt-names = "mipi_rx"; -+ }; -+ -+ vi: vi@11000000 { -+ compatible = "goke,vi"; -+ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; -+ reg-names = "VI_CAP0", "VI_PROC0"; -+ interrupts = <0 43 4>, <0 44 4>; -+ interrupt-names = "VI_CAP0", "VI_PROC0"; -+ }; -+ -+ isp: isp@11220000 { -+ compatible = "goke,isp"; -+ reg = <0x11220000 0x20000>; -+ reg-names = "ISP"; -+ interrupts = <0 43 4>; -+ interrupt-names = "ISP"; -+ }; -+ -+ vpss: vpss@11400000 { -+ compatible = "goke,vpss"; -+ reg = <0x11400000 0x10000>; -+ reg-names = "vpss0"; -+ interrupts = <0 46 4>; -+ interrupt-names = "vpss0"; -+ }; -+ -+ vo: vo@11280000 { -+ compatible = "goke,vo"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "vo"; -+ interrupts = <0 40 4>; -+ interrupt-names = "vo"; -+ }; -+ -+ gfbg: gfbg@11280000 { -+ compatible = "goke,gfbg"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "gfbg"; -+ interrupts = <0 41 4>; -+ interrupt-names = "gfbg"; -+ }; -+ -+ vgs: vgs@11300000 { -+ compatible = "goke,vgs"; -+ reg = <0x11300000 0x10000>; -+ reg-names = "vgs0"; -+ interrupts = <0 49 4>; -+ interrupt-names = "vgs0"; -+ }; -+ -+ gzip: gzip@11310000 { -+ compatible = "goke,gzip"; -+ reg = <0x11310000 0x10000>; -+ reg-names = "gzip"; -+ interrupts = <0 50 4>; -+ interrupt-names = "gzip"; -+ }; -+ -+ vedu: vedu@11410000 { -+ compatible = "goke,vedu"; -+ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; -+ reg-names = "vedu0", "jpge"; -+ interrupts = <0 47 4>, <0 48 4>; -+ interrupt-names = "vedu0","jpge"; -+ }; -+ -+ venc: venc { -+ compatible = "goke,venc"; -+ }; -+ -+ aiao: aiao@100e0000 { -+ compatible = "goke,aiao"; -+ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; -+ reg-names = "aiao","acodec"; -+ interrupts = <0 42 4>; -+ interrupt-names = "AIO"; -+ }; -+ -+ ive: ive@11320000 { -+ compatible = "goke,ive"; -+ reg = <0x11320000 0x10000>; -+ reg-names = "ive"; -+ interrupts = <0 51 4>; -+ interrupt-names = "ive"; -+ }; -+ }; -+}; ---- linux-4.9.37/arch/arm/boot/dts/gk7205v300-demb.dts 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7205v300-demb.dts 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,159 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+/dts-v1/; -+#include "gk7205v300.dtsi" -+ -+/ { -+ model = "Goke GK7205V300 DEMO Board"; -+ compatible = "goke,gk7205v300"; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x40000000 0x20000000>; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "disabled"; -+}; -+ -+&uart2 { -+ status = "disabled"; -+}; -+ -+&i2c_bus0 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus1 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus2 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&spi_bus0{ -+ status = "okay"; -+ num-cs = <1>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&spi_bus1{ -+ status = "okay"; -+ num-cs = <2>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+ spidev@1 { -+ compatible = "rohm,dh2228fv"; -+ reg = <1>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&dual_timer0 { -+ status = "okay"; -+}; -+ -+&mdio0 { -+ goke,phy-reset-delays-us = <10000 20000 150000>; -+ phy0: ethernet-phy@1 { -+ reg = <1>; -+ }; -+}; -+ -+&femac { -+ mac-address = [00 00 00 00 00 00]; -+ phy-mode = "mii"; -+ phy-handle = <&phy0>; -+ status = "okay"; -+}; -+ -+&sfc { -+ sfc { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&snfc { -+ nand { -+ compatible = "jedec,spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&mmc0 { -+ status = "okay"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+}; -+ -+&gpio_chip0 { -+ status = "okay"; -+}; -+ -+&gpio_chip1 { -+ status = "okay"; -+}; -+ -+&gpio_chip2 { -+ status = "okay"; -+}; -+ -+&gpio_chip3 { -+ status = "okay"; -+}; -+ -+&gpio_chip4 { -+ status = "okay"; -+}; -+ -+&gpio_chip5 { -+ status = "okay"; -+}; -+ -+&gpio_chip6 { -+ status = "okay"; -+}; -+ -+&gpio_chip7 { -+ status = "okay"; -+}; -+ -+&gpio_chip8 { -+ status = "okay"; -+}; -+ -+&gpio_chip9 { -+ status = "okay"; -+}; -+ ---- linux-4.9.37/arch/arm/boot/dts/gk7205v300.dtsi 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7205v300.dtsi 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,644 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include "skeleton.dtsi" -+#include -+/ { -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ serial2 = &uart2; -+ i2c0 = &i2c_bus0; -+ i2c1 = &i2c_bus1; -+ i2c2 = &i2c_bus2; -+ spi0 = &spi_bus0; -+ spi1 = &spi_bus1; -+ gpio0 = &gpio_chip0; -+ gpio1 = &gpio_chip1; -+ gpio2 = &gpio_chip2; -+ gpio3 = &gpio_chip3; -+ gpio4 = &gpio_chip4; -+ gpio5 = &gpio_chip5; -+ gpio6 = &gpio_chip6; -+ gpio7 = &gpio_chip7; -+ gpio8 = &gpio_chip8; -+ gpio9 = &gpio_chip9; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ enable-method = "goke,gk7205v300"; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ clock-frequency = ; -+ reg = <0>; -+ }; -+ }; -+ -+ pmu { -+ compatible = "arm,armv7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ clock: clock@12010000 { -+ compatible = "goke,gk7205v300-clock", "syscon"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ #clock-cells = <1>; -+ #reset-cells = <2>; -+ reg = <0x12010000 0x1000>; -+ }; -+ -+ gic: interrupt-controller@10300000 { -+ compatible = "arm,cortex-a7-gic"; -+ #interrupt-cells = <3>; -+ #address-cells = <0>; -+ interrupt-controller; -+ /* gic dist base, gic cpu base , no virtual support */ -+ reg = <0x10301000 0x1000>, <0x10302000 0x100>; -+ }; -+ -+ syscounter { -+ compatible = "arm,armv7-timer"; -+ interrupt-parent = <&gic>; -+ interrupts = <1 13 0xf08>, -+ <1 14 0xf08>; -+ clock-frequency = <50000000>; -+ }; -+ -+ soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ clk_3m: clk_3m { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <3000000>; -+ }; -+ -+ clk_apb: clk_apb { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <50000000>; -+ }; -+ -+ pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ sysctrl: system-controller@12020000 { -+ compatible = "goke,sysctrl"; -+ reg = <0x12020000 0x1000>; -+ reboot-offset = <0x4>; -+ #clock-cells = <1>; -+ }; -+ -+ iocfg_ctrl: iocfg-controller@100c0000 { -+ compatible = "syscon"; -+ reg = <0x100C0000 0x10000>; -+ }; -+ -+#ifdef CONFIG_EDMAC -+ edmac: edma-controller@100B0000 { -+ compatible = "goke,edmac"; -+ reg = <0x100B0000 0x1000>; -+ interrupts = <0 38 4>; -+ clocks = <&clock GK7205V300_EDMAC_CLK>, <&clock GK7205V300_EDMAC_AXICLK>; -+ clock-names = "apb_pclk", "axi_aclk"; -+ clock-cells = <2>; -+ resets = <&clock 0x194 0>; -+ reset-names = "dma-reset"; -+ dma-requests = <32>; -+ dma-channels = <4>; -+ devid = <0>; -+ #dma-cells = <2>; -+ status = "okay"; -+ }; -+#endif -+ amba { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "arm,amba-bus"; -+ ranges; -+ -+ dual_timer0: dual_timer@12000000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer0 & timer1 */ -+ interrupts = <0 5 4>; -+ reg = <0x12000000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer00", "timer01", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ dual_timer1: dual_timer@12001000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer2 & timer3 */ -+ interrupts = <0 6 4>; -+ reg = <0x12001000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer10", "timer11", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart0: uart@12040000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12040000 0x1000>; -+ interrupts = <0 7 4>; -+ clocks = <&clock GK7205V300_UART0_CLK>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart1: uart@12041000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12041000 0x1000>; -+ interrupts = <0 8 4>; -+ clocks = <&clock GK7205V300_UART1_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 19 19>, <&edmac 18 18>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ uart2: uart@12042000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12042000 0x1000>; -+ interrupts = <0 9 4>; -+ clocks = <&clock GK7205V300_UART2_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 21 21>, <&edmac 20 20>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ }; -+ -+ i2c_bus0: i2c@12060000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12060000 0x1000>; -+ clocks = <&clock GK7205V300_I2C0_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus1: i2c@12061000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12061000 0x1000>; -+ clocks = <&clock GK7205V300_I2C1_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus2: i2c@12062000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12062000 0x1000>; -+ clocks = <&clock GK7205V300_I2C2_CLK>; -+ status = "disabled"; -+ }; -+ -+ spi_bus0: spi@12070000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12070000 0x1000>; -+ interrupts = <0 14 4>; -+ clocks = <&clock GK7205V300_SPI0_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 27 27>, <&edmac 26 26>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ spi_bus1: spi@12071000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12071000 0x1000>, <0x12028000 0x4>; -+ interrupts = <0 15 4>; -+ clocks = <&clock GK7205V300_SPI1_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ num-cs = <2>; -+ spi_cs_sb = <2>; -+ spi_cs_mask_bit = <0x4>;//0100 -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 29 29>, <&edmac 28 28>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ mdio0: mdio@10041100 { -+ compatible = "goke,femac-mdio"; -+ reg = <0x10041100 0x10>,<0x12028024 0x4>; -+ clocks = <&clock GK7205V300_ETH0_CLK>; -+ clock-names = "mdio"; -+ resets = <&clock 0x16c 3>; -+ reset-names = "internal-phy"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ femac: ethernet@10040000 { -+ compatible = "goke,femac"; -+ reg = <0x10040000 0x1000>,<0x10041300 0x200>; -+ interrupts = <0 33 4>; -+ clocks = <&clock GK7205V300_ETH0_CLK>; -+ resets = <&clock 0x16c 0>; -+ reset-names = "mac"; -+ }; -+ -+ fmc: flash-memory-controller@10000000 { -+ compatible = "goke,fmc"; -+ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; -+ reg-names = "control", "memory"; -+ clocks = <&clock GK7205V300_FMC_CLK>; -+ max-dma-size = <0x2000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sfc:spi-nor@0 { -+ compatible = "goke,fmc-spi-nor"; -+ assigned-clocks = <&clock GK7205V300_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ snfc:spi-nand@0 { -+ compatible = "goke,fmc-spi-nand"; -+ assigned-clocks = <&clock GK7205V300_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ -+ mmc0: sdhci@0x10010000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10010000 0x1000>; -+ interrupts = <0 30 4>; -+ clocks = <&clock GK7205V300_MMC0_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <90000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl>; -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ cap-mmc-hw-reset; -+ cap-sd-highspeed; -+ mmc-hs200-1_8v; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ full-pwr-cycle; -+ devid = <0>; -+ status = "enable"; -+ }; -+ -+ mmc1: sdhci@0x10020000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10020000 0x1000>; -+ interrupts = <0 31 4>; -+ clocks = <&clock GK7205V300_MMC1_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <50000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ full-pwr-cycle; -+ devid = <2>; -+ status = "enable"; -+ }; -+ -+ usb2_phy0: phy2-0 { -+ compatible = "goke,usbp2-phy"; -+ reg = <0x100D0000 0x1000>, -+ <0x12010000 0x1000>, -+ <0x100c0000 0x1000>; -+ clocks = <&clock GK7205V300_USB2_PHY_APB_CLK>, -+ <&clock GK7205V300_USB2_PHY_PLL_CLK>, -+ <&clock GK7205V300_USB2_PHY_XO_CLK>; -+ clock-names = "clk_u2phy_apb_ref", -+ "clk_u2phy_pll_ref", -+ "clk_u2phy_xo_ref"; -+ resets = <&clock 0x140 0>, -+ <&clock 0x140 1>; -+ reset-names = "phy_por_reset", -+ "phy_tpor_reset"; -+ phy_pll_offset = <0x14>; -+ phy_pll_mask = <0x03>; -+ phy_pll_val = <0x00>; -+ crg_offset = <0x140>; -+ crg_defal_mask = <0x0c07>; -+ crg_defal_val = <0x0807>; -+ vbus_offset = <0x7c>; -+ vbus_val = <0x0431>; -+ pwren_offset = <0x80>; -+ pwren_val = <0x1>; -+ ana_cfg_0_eye_val = <0x0433cc23>; -+ ana_cfg_0_offset = <0x00>; -+ ana_cfg_2_eye_val = <0x00320f0f>; -+ ana_cfg_2_offset = <0x08>; -+ ana_cfg_4_eye_val = <0x655>; -+ ana_cfg_4_offset = <0x10>; -+ trim_otp_addr = <0x12028004>; -+ trim_otp_mask = <0x1f>; -+ trim_otp_bit_offset = <0x00>; -+ trim_otp_min = <0x09>; -+ trim_otp_max = <0x1d>; -+ #phy-cells = <0>; -+ }; -+ -+ usbdrd3_0: usb3-0{ -+ compatible = "goke,dwusb2"; -+ reg = <0x10030000 0x10000>, -+ <0x12010000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ crg_offset = <0x140>; -+ crg_ctrl_def_mask = <0x3308>; -+ crg_ctrl_def_val = <0x1308>; -+ clocks = <&clock GK7205V300_USB2_BUS_CLK>, -+ <&clock GK7205V300_USB2_REF_CLK>, -+ <&clock GK7205V300_USB2_UTMI_CLK>; -+ clock-names = "usb2_bus_clk", -+ "usb2_ref_clk", -+ "usb2_utmi_clk"; -+ resets = <&clock 0x140 3>; -+ reset-names = "vcc_reset"; -+ ranges; -+ -+ dwc3@0x100e0000 { -+ compatible = "snps,dwc3"; -+ reg = <0x10030000 0x10000>; -+ interrupts = <0 39 4>; -+ interrupt-names = "peripheral"; -+ phys = <&usb2_phy0>; -+ phy-names = "usb2-phy"; -+ maximum-speed = "high-speed"; -+ dr_mode = "host"; -+ eps_directions = <0x6a>; -+ snps,eps_new_init; -+ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; -+ snps,usb2-lpm-disable; -+ }; -+ }; -+ -+ gpio_chip0: gpio_chip@120b0000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b0000 0x1000>; -+ interrupts = <0 16 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip1: gpio_chip@120b1000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b1000 0x1000>; -+ interrupts = <0 17 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip2: gpio_chip@120b2000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b2000 0x1000>; -+ interrupts = <0 18 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip3: gpio_chip@120b3000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b3000 0x1000>; -+ interrupts = <0 19 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip4: gpio_chip@120b4000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b4000 0x1000>; -+ interrupts = <0 20 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip5: gpio_chip@120b5000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b5000 0x1000>; -+ interrupts = <0 21 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip6: gpio_chip@120b6000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b6000 0x1000>; -+ interrupts = <0 22 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip7: gpio_chip@120b7000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b7000 0x1000>; -+ interrupts = <0 23 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip8: gpio_chip@120b8000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b8000 0x1000>; -+ interrupts = <0 24 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip9: gpio_chip@120b9000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b9000 0x1000>; -+ interrupts = <0 25 4>; -+ clocks = <&clock GK7205V300_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ rtc: rtc@120e0000 { -+ compatible = "goke,rtc"; -+ reg = <0x120e0000 0x1000>; -+ interrupts = <0 0 4>; -+ }; -+ -+ cipher: cipher@0x10050000 { -+ compatible = "goke,cipher"; -+ reg = <0x10050000 0x10000>; -+ reg-names = "cipher"; -+ interrupts = <0 34 4>, <0 34 4>; -+ interrupt-names = "cipher", "hash"; -+ }; -+ -+ adc: adc@120a0000 { -+ compatible = "goke,lsadc"; -+ reg = <0x120a0000 0x1000>; -+ interrupts = <0 4 4>; -+ interrupt-names = "adc"; -+ resets = <&clock 0x1bc 2>; -+ reset-names = "lsadc-crg"; -+ status = "okay"; -+ }; -+ -+ wdg: wdg@0x12030000 { -+ compatible = "goke,wdg"; -+ reg = <0x12030000 0x1000>; -+ reg-names = "wdg"; -+ interrupts = <0 2 4>; -+ interrupt-names = "wdg"; -+ }; -+ }; -+ -+ media { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ osal: osal { -+ compatible = "goke,osal"; -+ }; -+ -+ sys: sys@12010000 { -+ compatible = "goke,sys"; -+ }; -+ -+ mipi: mipi@0x11240000 { -+ compatible = "goke,mipi"; -+ reg = <0x11240000 0x10000>; -+ reg-names = "mipi_rx"; -+ interrupts = <0 45 4>; -+ interrupt-names = "mipi_rx"; -+ }; -+ -+ vi: vi@11000000 { -+ compatible = "goke,vi"; -+ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; -+ reg-names = "VI_CAP0", "VI_PROC0"; -+ interrupts = <0 43 4>, <0 44 4>; -+ interrupt-names = "VI_CAP0", "VI_PROC0"; -+ }; -+ -+ isp: isp@11220000 { -+ compatible = "goke,isp"; -+ reg = <0x11220000 0x20000>; -+ reg-names = "ISP"; -+ interrupts = <0 43 4>; -+ interrupt-names = "ISP"; -+ }; -+ -+ vpss: vpss@11400000 { -+ compatible = "goke,vpss"; -+ reg = <0x11400000 0x10000>; -+ reg-names = "vpss0"; -+ interrupts = <0 46 4>; -+ interrupt-names = "vpss0"; -+ }; -+ -+ vo: vo@11280000 { -+ compatible = "goke,vo"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "vo"; -+ interrupts = <0 40 4>; -+ interrupt-names = "vo"; -+ }; -+ -+ gfbg: gfbg@11280000 { -+ compatible = "goke,gfbg"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "gfbg"; -+ interrupts = <0 41 4>; -+ interrupt-names = "gfbg"; -+ }; -+ -+ vgs: vgs@11300000 { -+ compatible = "goke,vgs"; -+ reg = <0x11300000 0x10000>; -+ reg-names = "vgs0"; -+ interrupts = <0 49 4>; -+ interrupt-names = "vgs0"; -+ }; -+ -+ gzip: gzip@11310000 { -+ compatible = "goke,gzip"; -+ reg = <0x11310000 0x10000>; -+ reg-names = "gzip"; -+ interrupts = <0 50 4>; -+ interrupt-names = "gzip"; -+ }; -+ -+ vedu: vedu@11410000 { -+ compatible = "goke,vedu"; -+ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; -+ reg-names = "vedu0", "jpge"; -+ interrupts = <0 47 4>, <0 48 4>; -+ interrupt-names = "vedu0","jpge"; -+ }; -+ -+ venc: venc { -+ compatible = "goke,venc"; -+ }; -+ -+ aiao: aiao@100e0000 { -+ compatible = "goke,aiao"; -+ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; -+ reg-names = "aiao","acodec"; -+ interrupts = <0 42 4>; -+ interrupt-names = "AIO"; -+ }; -+ -+ ive: ive@11320000 { -+ compatible = "goke,ive"; -+ reg = <0x11320000 0x10000>; -+ reg-names = "ive"; -+ interrupts = <0 51 4>; -+ interrupt-names = "ive"; -+ }; -+ }; -+}; ---- linux-4.9.37/arch/arm/boot/dts/gk7605v100-demb.dts 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7605v100-demb.dts 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,159 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+/dts-v1/; -+#include "gk7605v100.dtsi" -+ -+/ { -+ model = "Goke GK7605V100 DEMO Board"; -+ compatible = "goke,gk7605v100"; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x40000000 0x20000000>; -+ }; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "disabled"; -+}; -+ -+&uart2 { -+ status = "disabled"; -+}; -+ -+&i2c_bus0 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus1 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&i2c_bus2 { -+ status = "okay"; -+ clock-frequency = <100000>; -+}; -+ -+&spi_bus0{ -+ status = "okay"; -+ num-cs = <1>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&spi_bus1{ -+ status = "okay"; -+ num-cs = <2>; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+ spidev@1 { -+ compatible = "rohm,dh2228fv"; -+ reg = <1>; -+ pl022,interface = <0>; -+ pl022,com-mode = <0>; -+ spi-max-frequency = <50000000>; -+ }; -+}; -+ -+&dual_timer0 { -+ status = "okay"; -+}; -+ -+&mdio0 { -+ goke,phy-reset-delays-us = <10000 20000 150000>; -+ phy0: ethernet-phy@1 { -+ reg = <1>; -+ }; -+}; -+ -+&femac { -+ mac-address = [00 00 00 00 00 00]; -+ phy-mode = "mii"; -+ phy-handle = <&phy0>; -+ status = "okay"; -+}; -+ -+&sfc { -+ sfc { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&snfc { -+ nand { -+ compatible = "jedec,spi-nand"; -+ reg = <0>; -+ spi-max-frequency = <160000000>; -+ }; -+}; -+ -+&mmc0 { -+ status = "okay"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+}; -+ -+&gpio_chip0 { -+ status = "okay"; -+}; -+ -+&gpio_chip1 { -+ status = "okay"; -+}; -+ -+&gpio_chip2 { -+ status = "okay"; -+}; -+ -+&gpio_chip3 { -+ status = "okay"; -+}; -+ -+&gpio_chip4 { -+ status = "okay"; -+}; -+ -+&gpio_chip5 { -+ status = "okay"; -+}; -+ -+&gpio_chip6 { -+ status = "okay"; -+}; -+ -+&gpio_chip7 { -+ status = "okay"; -+}; -+ -+&gpio_chip8 { -+ status = "okay"; -+}; -+ -+&gpio_chip9 { -+ status = "okay"; -+}; -+ ---- linux-4.9.37/arch/arm/boot/dts/gk7605v100.dtsi 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/gk7605v100.dtsi 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,644 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include "skeleton.dtsi" -+#include -+/ { -+ aliases { -+ serial0 = &uart0; -+ serial1 = &uart1; -+ serial2 = &uart2; -+ i2c0 = &i2c_bus0; -+ i2c1 = &i2c_bus1; -+ i2c2 = &i2c_bus2; -+ spi0 = &spi_bus0; -+ spi1 = &spi_bus1; -+ gpio0 = &gpio_chip0; -+ gpio1 = &gpio_chip1; -+ gpio2 = &gpio_chip2; -+ gpio3 = &gpio_chip3; -+ gpio4 = &gpio_chip4; -+ gpio5 = &gpio_chip5; -+ gpio6 = &gpio_chip6; -+ gpio7 = &gpio_chip7; -+ gpio8 = &gpio_chip8; -+ gpio9 = &gpio_chip9; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ enable-method = "goke,gk7605v100"; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ clock-frequency = ; -+ reg = <0>; -+ }; -+ }; -+ -+ pmu { -+ compatible = "arm,armv7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ clock: clock@12010000 { -+ compatible = "goke,gk7605v100-clock", "syscon"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ #clock-cells = <1>; -+ #reset-cells = <2>; -+ reg = <0x12010000 0x1000>; -+ }; -+ -+ gic: interrupt-controller@10300000 { -+ compatible = "arm,cortex-a7-gic"; -+ #interrupt-cells = <3>; -+ #address-cells = <0>; -+ interrupt-controller; -+ /* gic dist base, gic cpu base , no virtual support */ -+ reg = <0x10301000 0x1000>, <0x10302000 0x100>; -+ }; -+ -+ syscounter { -+ compatible = "arm,armv7-timer"; -+ interrupt-parent = <&gic>; -+ interrupts = <1 13 0xf08>, -+ <1 14 0xf08>; -+ clock-frequency = <50000000>; -+ }; -+ -+ soc { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ clk_3m: clk_3m { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <3000000>; -+ }; -+ -+ clk_apb: clk_apb { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <50000000>; -+ }; -+ -+ pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = <0 58 4>; -+ }; -+ -+ sysctrl: system-controller@12020000 { -+ compatible = "goke,sysctrl"; -+ reg = <0x12020000 0x1000>; -+ reboot-offset = <0x4>; -+ #clock-cells = <1>; -+ }; -+ -+ iocfg_ctrl: iocfg-controller@100c0000 { -+ compatible = "syscon"; -+ reg = <0x100C0000 0x10000>; -+ }; -+ -+#ifdef CONFIG_EDMAC -+ edmac: edma-controller@100B0000 { -+ compatible = "goke,edmac"; -+ reg = <0x100B0000 0x1000>; -+ interrupts = <0 38 4>; -+ clocks = <&clock GK7605V100_EDMAC_CLK>, <&clock GK7605V100_EDMAC_AXICLK>; -+ clock-names = "apb_pclk", "axi_aclk"; -+ clock-cells = <2>; -+ resets = <&clock 0x194 0>; -+ reset-names = "dma-reset"; -+ dma-requests = <32>; -+ dma-channels = <4>; -+ devid = <0>; -+ #dma-cells = <2>; -+ status = "okay"; -+ }; -+#endif -+ amba { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "arm,amba-bus"; -+ ranges; -+ -+ dual_timer0: dual_timer@12000000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer0 & timer1 */ -+ interrupts = <0 5 4>; -+ reg = <0x12000000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer00", "timer01", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ dual_timer1: dual_timer@12001000 { -+ compatible = "arm,sp804", "arm,primecell"; -+ /* timer2 & timer3 */ -+ interrupts = <0 6 4>; -+ reg = <0x12001000 0x1000>; -+ clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>; -+ clock-names = "timer10", "timer11", "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart0: uart@12040000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12040000 0x1000>; -+ interrupts = <0 7 4>; -+ clocks = <&clock GK7605V100_UART0_CLK>; -+ clock-names = "apb_pclk"; -+ status = "disabled"; -+ }; -+ -+ uart1: uart@12041000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12041000 0x1000>; -+ interrupts = <0 8 4>; -+ clocks = <&clock GK7605V100_UART1_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 19 19>, <&edmac 18 18>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ uart2: uart@12042000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x12042000 0x1000>; -+ interrupts = <0 9 4>; -+ clocks = <&clock GK7605V100_UART2_CLK>; -+ clock-names = "apb_pclk"; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 21 21>, <&edmac 20 20>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ }; -+ -+ i2c_bus0: i2c@12060000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12060000 0x1000>; -+ clocks = <&clock GK7605V100_I2C0_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus1: i2c@12061000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12061000 0x1000>; -+ clocks = <&clock GK7605V100_I2C1_CLK>; -+ status = "disabled"; -+ }; -+ -+ i2c_bus2: i2c@12062000 { -+ compatible = "goke,goke-i2c"; -+ reg = <0x12062000 0x1000>; -+ clocks = <&clock GK7605V100_I2C2_CLK>; -+ status = "disabled"; -+ }; -+ -+ spi_bus0: spi@12070000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12070000 0x1000>; -+ interrupts = <0 14 4>; -+ clocks = <&clock GK7605V100_SPI0_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 27 27>, <&edmac 26 26>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ spi_bus1: spi@12071000 { -+ compatible = "arm,pl022", "arm,primecell"; -+ arm,primecell-periphid = <0x00041022>; -+ reg = <0x12071000 0x1000>, <0x12028000 0x4>; -+ interrupts = <0 15 4>; -+ clocks = <&clock GK7605V100_SPI1_CLK>; -+ clock-names = "apb_pclk"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ num-cs = <2>; -+ spi_cs_sb = <2>; -+ spi_cs_mask_bit = <0x4>;//0100 -+#ifdef CONFIG_EDMAC -+ dmas = <&edmac 29 29>, <&edmac 28 28>; -+ dma-names = "tx","rx"; -+#endif -+ status = "disabled"; -+ }; -+ -+ mdio0: mdio@10041100 { -+ compatible = "goke,femac-mdio"; -+ reg = <0x10041100 0x10>,<0x12028024 0x4>; -+ clocks = <&clock GK7605V100_ETH0_CLK>; -+ clock-names = "mdio"; -+ resets = <&clock 0x16c 3>; -+ reset-names = "internal-phy"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ femac: ethernet@10040000 { -+ compatible = "goke,femac"; -+ reg = <0x10040000 0x1000>,<0x10041300 0x200>; -+ interrupts = <0 33 4>; -+ clocks = <&clock GK7605V100_ETH0_CLK>; -+ resets = <&clock 0x16c 0>; -+ reset-names = "mac"; -+ }; -+ -+ fmc: flash-memory-controller@10000000 { -+ compatible = "goke,fmc"; -+ reg = <0x10000000 0x1000>, <0x14000000 0x10000>; -+ reg-names = "control", "memory"; -+ clocks = <&clock GK7605V100_FMC_CLK>; -+ max-dma-size = <0x2000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sfc:spi-nor@0 { -+ compatible = "goke,fmc-spi-nor"; -+ assigned-clocks = <&clock GK7605V100_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ snfc:spi-nand@0 { -+ compatible = "goke,fmc-spi-nand"; -+ assigned-clocks = <&clock GK7605V100_FMC_CLK>; -+ assigned-clock-rates = <24000000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ -+ mmc0: sdhci@0x10010000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10010000 0x1000>; -+ interrupts = <0 30 4>; -+ clocks = <&clock GK7605V100_MMC0_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x1f4 27>, <&clock 0x1f4 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <90000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl>; -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ cap-mmc-hw-reset; -+ cap-sd-highspeed; -+ mmc-hs200-1_8v; -+ mmc-hs400-1_8v; -+ mmc-hs400-enhanced-strobe; -+ full-pwr-cycle; -+ devid = <0>; -+ status = "enable"; -+ }; -+ -+ mmc1: sdhci@0x10020000 { -+ compatible = "goke,sdhci"; -+ reg = <0x10020000 0x1000>; -+ interrupts = <0 31 4>; -+ clocks = <&clock GK7605V100_MMC1_CLK>; -+ clock-names = "mmc_clk"; -+ resets = <&clock 0x22c 27>, <&clock 0x22c 29>; -+ reset-names = "crg_reset", "dll_reset"; -+ max-frequency = <50000000>; -+ crg_regmap = <&clock>; -+ iocfg_regmap = <&iocfg_ctrl>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ full-pwr-cycle; -+ devid = <2>; -+ status = "enable"; -+ }; -+ -+ usb2_phy0: phy2-0 { -+ compatible = "goke,usbp2-phy"; -+ reg = <0x100D0000 0x1000>, -+ <0x12010000 0x1000>, -+ <0x100c0000 0x1000>; -+ clocks = <&clock GK7605V100_USB2_PHY_APB_CLK>, -+ <&clock GK7605V100_USB2_PHY_PLL_CLK>, -+ <&clock GK7605V100_USB2_PHY_XO_CLK>; -+ clock-names = "clk_u2phy_apb_ref", -+ "clk_u2phy_pll_ref", -+ "clk_u2phy_xo_ref"; -+ resets = <&clock 0x140 0>, -+ <&clock 0x140 1>; -+ reset-names = "phy_por_reset", -+ "phy_tpor_reset"; -+ phy_pll_offset = <0x14>; -+ phy_pll_mask = <0x03>; -+ phy_pll_val = <0x00>; -+ crg_offset = <0x140>; -+ crg_defal_mask = <0x0c07>; -+ crg_defal_val = <0x0807>; -+ vbus_offset = <0x7c>; -+ vbus_val = <0x0431>; -+ pwren_offset = <0x80>; -+ pwren_val = <0x1>; -+ ana_cfg_0_eye_val = <0x0433cc23>; -+ ana_cfg_0_offset = <0x00>; -+ ana_cfg_2_eye_val = <0x00320f0f>; -+ ana_cfg_2_offset = <0x08>; -+ ana_cfg_4_eye_val = <0x655>; -+ ana_cfg_4_offset = <0x10>; -+ trim_otp_addr = <0x12028004>; -+ trim_otp_mask = <0x1f>; -+ trim_otp_bit_offset = <0x00>; -+ trim_otp_min = <0x09>; -+ trim_otp_max = <0x1d>; -+ #phy-cells = <0>; -+ }; -+ -+ usbdrd3_0: usb3-0{ -+ compatible = "goke,dwusb2"; -+ reg = <0x10030000 0x10000>, -+ <0x12010000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ crg_offset = <0x140>; -+ crg_ctrl_def_mask = <0x3308>; -+ crg_ctrl_def_val = <0x1308>; -+ clocks = <&clock GK7605V100_USB2_BUS_CLK>, -+ <&clock GK7605V100_USB2_REF_CLK>, -+ <&clock GK7605V100_USB2_UTMI_CLK>; -+ clock-names = "usb2_bus_clk", -+ "usb2_ref_clk", -+ "usb2_utmi_clk"; -+ resets = <&clock 0x140 3>; -+ reset-names = "vcc_reset"; -+ ranges; -+ -+ dwc3@0x100e0000 { -+ compatible = "snps,dwc3"; -+ reg = <0x10030000 0x10000>; -+ interrupts = <0 39 4>; -+ interrupt-names = "peripheral"; -+ phys = <&usb2_phy0>; -+ phy-names = "usb2-phy"; -+ maximum-speed = "high-speed"; -+ dr_mode = "host"; -+ eps_directions = <0x6a>; -+ snps,eps_new_init; -+ eps_map=<0x0 0x1 0x2 0x3 0x4 0x5 0x7>; -+ snps,usb2-lpm-disable; -+ }; -+ }; -+ -+ gpio_chip0: gpio_chip@120b0000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b0000 0x1000>; -+ interrupts = <0 16 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip1: gpio_chip@120b1000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b1000 0x1000>; -+ interrupts = <0 17 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip2: gpio_chip@120b2000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b2000 0x1000>; -+ interrupts = <0 18 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip3: gpio_chip@120b3000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b3000 0x1000>; -+ interrupts = <0 19 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip4: gpio_chip@120b4000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b4000 0x1000>; -+ interrupts = <0 20 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip5: gpio_chip@120b5000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b5000 0x1000>; -+ interrupts = <0 21 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip6: gpio_chip@120b6000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b6000 0x1000>; -+ interrupts = <0 22 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip7: gpio_chip@120b7000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b7000 0x1000>; -+ interrupts = <0 23 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip8: gpio_chip@120b8000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b8000 0x1000>; -+ interrupts = <0 24 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ gpio_chip9: gpio_chip@120b9000 { -+ compatible = "arm,pl061", "arm,primecell"; -+ reg = <0x120b9000 0x1000>; -+ interrupts = <0 25 4>; -+ clocks = <&clock GK7605V100_SYSAPB_CLK>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <2>; -+ status = "disabled"; -+ }; -+ -+ rtc: rtc@120e0000 { -+ compatible = "goke,rtc"; -+ reg = <0x120e0000 0x1000>; -+ interrupts = <0 0 4>; -+ }; -+ -+ cipher: cipher@0x10050000 { -+ compatible = "goke,cipher"; -+ reg = <0x10050000 0x10000>; -+ reg-names = "cipher"; -+ interrupts = <0 34 4>, <0 34 4>; -+ interrupt-names = "cipher", "hash"; -+ }; -+ -+ adc: adc@120a0000 { -+ compatible = "goke,lsadc"; -+ reg = <0x120a0000 0x1000>; -+ interrupts = <0 4 4>; -+ interrupt-names = "adc"; -+ resets = <&clock 0x1bc 2>; -+ reset-names = "lsadc-crg"; -+ status = "okay"; -+ }; -+ -+ wdg: wdg@0x12030000 { -+ compatible = "goke,wdg"; -+ reg = <0x12030000 0x1000>; -+ reg-names = "wdg"; -+ interrupts = <0 2 4>; -+ interrupt-names = "wdg"; -+ }; -+ }; -+ -+ media { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "simple-bus"; -+ interrupt-parent = <&gic>; -+ ranges; -+ -+ osal: osal { -+ compatible = "goke,osal"; -+ }; -+ -+ sys: sys@12010000 { -+ compatible = "goke,sys"; -+ }; -+ -+ mipi: mipi@0x11240000 { -+ compatible = "goke,mipi"; -+ reg = <0x11240000 0x10000>; -+ reg-names = "mipi_rx"; -+ interrupts = <0 45 4>; -+ interrupt-names = "mipi_rx"; -+ }; -+ -+ vi: vi@11000000 { -+ compatible = "goke,vi"; -+ reg = <0x11000000 0x200000>, <0x11200000 0x40000>; -+ reg-names = "VI_CAP0", "VI_PROC0"; -+ interrupts = <0 43 4>, <0 44 4>; -+ interrupt-names = "VI_CAP0", "VI_PROC0"; -+ }; -+ -+ isp: isp@11220000 { -+ compatible = "goke,isp"; -+ reg = <0x11220000 0x20000>; -+ reg-names = "ISP"; -+ interrupts = <0 43 4>; -+ interrupt-names = "ISP"; -+ }; -+ -+ vpss: vpss@11400000 { -+ compatible = "goke,vpss"; -+ reg = <0x11400000 0x10000>; -+ reg-names = "vpss0"; -+ interrupts = <0 46 4>; -+ interrupt-names = "vpss0"; -+ }; -+ -+ vo: vo@11280000 { -+ compatible = "goke,vo"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "vo"; -+ interrupts = <0 40 4>; -+ interrupt-names = "vo"; -+ }; -+ -+ gfbg: gfbg@11280000 { -+ compatible = "goke,gfbg"; -+ reg = <0x11280000 0x40000>; -+ reg-names = "gfbg"; -+ interrupts = <0 41 4>; -+ interrupt-names = "gfbg"; -+ }; -+ -+ vgs: vgs@11300000 { -+ compatible = "goke,vgs"; -+ reg = <0x11300000 0x10000>; -+ reg-names = "vgs0"; -+ interrupts = <0 49 4>; -+ interrupt-names = "vgs0"; -+ }; -+ -+ gzip: gzip@11310000 { -+ compatible = "goke,gzip"; -+ reg = <0x11310000 0x10000>; -+ reg-names = "gzip"; -+ interrupts = <0 50 4>; -+ interrupt-names = "gzip"; -+ }; -+ -+ vedu: vedu@11410000 { -+ compatible = "goke,vedu"; -+ reg = <0x11410000 0x10000>, <0x11420000 0x10000>; -+ reg-names = "vedu0", "jpge"; -+ interrupts = <0 47 4>, <0 48 4>; -+ interrupt-names = "vedu0","jpge"; -+ }; -+ -+ venc: venc { -+ compatible = "goke,venc"; -+ }; -+ -+ aiao: aiao@100e0000 { -+ compatible = "goke,aiao"; -+ reg = <0x100e0000 0x10000>,<0x100f0000 0x10000>; -+ reg-names = "aiao","acodec"; -+ interrupts = <0 42 4>; -+ interrupt-names = "AIO"; -+ }; -+ -+ ive: ive@11320000 { -+ compatible = "goke,ive"; -+ reg = <0x11320000 0x10000>; -+ reg-names = "ive"; -+ interrupts = <0 51 4>; -+ interrupt-names = "ive"; -+ }; -+ }; -+}; ---- linux-4.9.37/arch/arm/boot/dts/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/dts/Makefile 2021-06-07 13:01:32.000000000 +0300 -@@ -174,6 +174,14 @@ - hi3519-demb.dtb - dtb-$(CONFIG_ARCH_HIX5HD2) += \ - hisi-x5hd2-dkb.dtb -+dtb-$(CONFIG_ARCH_GK7205V200) += \ -+ gk7205v200-demb.dtb -+dtb-$(CONFIG_ARCH_GK7205V300) += \ -+ gk7205v300-demb.dtb -+dtb-$(CONFIG_ARCH_GK7202V300) += \ -+ gk7202v300-demb.dtb -+dtb-$(CONFIG_ARCH_GK7605V100) += \ -+ gk7605v100-demb.dtb - dtb-$(CONFIG_ARCH_INTEGRATOR) += \ - integratorap.dtb \ - integratorcp.dtb ---- linux-4.9.37/arch/arm/boot/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/boot/Makefile 2021-06-07 13:01:32.000000000 +0300 -@@ -16,6 +16,8 @@ - ifneq ($(MACHINE),) - include $(MACHINE)/Makefile.boot - endif -+include $(srctree)/arch/arm/mach-goke/Makefile.boot -+include $(srctree)/arch/arm/boot/dts/Makefile - - # Note: the following conditions must always be true: - # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) -@@ -24,10 +26,12 @@ - ZRELADDR := $(zreladdr-y) - PARAMS_PHYS := $(params_phys-y) - INITRD_PHYS := $(initrd_phys-y) -+DTB_OBJS ?= $(dtb-y) -+DTB_OBJS_FULL := $(addprefix $(obj)/dts/,$(DTB_OBJS)) - - export ZRELADDR INITRD_PHYS PARAMS_PHYS - --targets := Image zImage xipImage bootpImage uImage -+targets := Image zImage xipImage bootpImage uImage zImage-dtb - - ifeq ($(CONFIG_XIP_KERNEL),y) - -@@ -55,6 +59,10 @@ - $(obj)/zImage: $(obj)/compressed/vmlinux FORCE - $(call if_changed,objcopy) - -+$(obj)/zImage-dtb: $(obj)/zImage $(DTB_OBJS_FULL) FORCE -+ @cat $(obj)/zImage $(DTB_OBJS_FULL) > $@ -+ @$(kecho) ' Kernel: $@ is ready' -+ - endif - - ifneq ($(LOADADDR),) -@@ -75,7 +83,7 @@ - false; \ - fi - --$(obj)/uImage: $(obj)/zImage FORCE -+$(obj)/uImage: $(obj)/zImage-dtb FORCE - @$(check_for_multiple_loadaddr) - $(call if_changed,uimage) - ---- linux-4.9.37/arch/arm/configs/gk7202v300_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7202v300_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2858 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+# CONFIG_ARCH_GK7205V200 is not set -+# CONFIG_ARCH_GK7205V300 is not set -+CONFIG_ARCH_GK7202V300=y -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+# CONFIG_NETDEVICES is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=y -+CONFIG_USB_U_ETHER=y -+CONFIG_USB_F_ECM=y -+CONFIG_USB_F_RNDIS=y -+CONFIG_USB_CONFIGFS=y -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+# CONFIG_USB_CONFIGFS_ACM is not set -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7202V300=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7202v300_full_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7202v300_full_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2858 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+# CONFIG_ARCH_GK7205V200 is not set -+# CONFIG_ARCH_GK7205V300 is not set -+CONFIG_ARCH_GK7202V300=y -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+# CONFIG_NETDEVICES is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=y -+CONFIG_USB_U_ETHER=y -+CONFIG_USB_F_ECM=y -+CONFIG_USB_F_RNDIS=y -+CONFIG_USB_CONFIGFS=y -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+# CONFIG_USB_CONFIGFS_ACM is not set -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7202V300=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7202v300_mini_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7202v300_mini_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,1791 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+# CONFIG_KERNEL_GZIP is not set -+# CONFIG_KERNEL_LZMA is not set -+CONFIG_KERNEL_XZ=y -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+# CONFIG_CGROUP_FREEZER is not set -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+# CONFIG_BLK_DEV_INITRD is not set -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+# CONFIG_ARCH_GK7205V200 is not set -+# CONFIG_ARCH_GK7205V300 is not set -+CONFIG_ARCH_GK7202V300=y -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+# CONFIG_ARM_THUMB is not set -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+# CONFIG_VDSO is not set -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+# CONFIG_ARM_PATCH_IDIV is not set -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+# CONFIG_PACKET is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+# CONFIG_NET_KEY is not set -+# CONFIG_INET is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_ATM is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_STREAM_PARSER is not set -+# CONFIG_WIRELESS is not set -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+# CONFIG_UEVENT_HELPER is not set -+# CONFIG_DEVTMPFS is not set -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+# CONFIG_FIRMWARE_IN_KERNEL is not set -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_MMIO=y -+# CONFIG_DMA_SHARED_BUFFER is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+CONFIG_CLOSE_SPI_8PIN_4IO=y -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+# CONFIG_MTD_UBI is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+ -+# -+# DRBD disabled because PROC_FS or INET not selected -+# -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_NETDEVICES is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+# CONFIG_INPUT_MOUSEDEV is not set -+# CONFIG_INPUT_JOYDEV is not set -+# CONFIG_INPUT_EVDEV is not set -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+# CONFIG_INPUT_MISC is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_TAOS_EVM is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_FSL_SPI is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_SINGLE is not set -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+# CONFIG_GPIOLIB is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+# CONFIG_MEDIA_SUPPORT is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+# CONFIG_HID is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_UWB is not set -+# CONFIG_MMC is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+# CONFIG_RTC_CLASS is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7202V300=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+# CONFIG_GENERIC_PHY is not set -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+# CONFIG_PHY_GOKE_USBP2 is not set -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4_FS is not set -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+# CONFIG_FS_POSIX_ACL is not set -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+# CONFIG_MANDATORY_FILE_LOCKING is not set -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+# CONFIG_ISO9660_FS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+# CONFIG_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_TMPFS_XATTR is not set -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+# CONFIG_YAFFS_FS is not set -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+# CONFIG_LOGFS is not set -+# CONFIG_CRAMFS is not set -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+# CONFIG_NLS_CODEPAGE_437 is not set -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_ASCII is not set -+# CONFIG_NLS_ISO8859_1 is not set -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+# CONFIG_NLS_UTF8 is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+# CONFIG_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_T10DIF is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+# CONFIG_SG_SPLIT is not set -+# CONFIG_SG_POOL is not set -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7205v200_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7205v200_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2975 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+CONFIG_ARCH_GK7205V200=y -+# CONFIG_ARCH_GK7205V300 is not set -+# CONFIG_ARCH_GK7202V300 is not set -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+CONFIG_HAVE_NET_DSA=y -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_NET=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+CONFIG_NETDEVICES=y -+CONFIG_NET_CORE=y -+# CONFIG_BONDING is not set -+# CONFIG_DUMMY is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_NET_TEAM is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_VXLAN is not set -+# CONFIG_MACSEC is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_TUN is not set -+# CONFIG_TUN_VNET_CROSS_LE is not set -+# CONFIG_VETH is not set -+# CONFIG_NLMON is not set -+ -+# -+# CAIF transport drivers -+# -+ -+# -+# Distributed Switch Architecture drivers -+# -+CONFIG_ETHERNET=y -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DNET is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+CONFIG_NET_VENDOR_GOKE=y -+CONFIG_GOKE_FEMAC=y -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+CONFIG_NET_VENDOR_MICROCHIP=y -+# CONFIG_ENC28J60 is not set -+# CONFIG_ENCX24J600 is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_ETHOC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_PHYLIB=y -+CONFIG_SWPHY=y -+ -+# -+# MDIO bus device drivers -+# -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_GPIO is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+CONFIG_MDIO_GOKE_FEMAC=y -+# CONFIG_MDIO_HISI_FEMAC is not set -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_AMD_PHY is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+CONFIG_FIXED_PHY=y -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_STE10XP is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_USB_NET_DRIVERS is not set -+# CONFIG_WLAN is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_ISDN is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=m -+CONFIG_USB_F_ACM=m -+CONFIG_USB_U_SERIAL=m -+CONFIG_USB_U_ETHER=m -+CONFIG_USB_F_ECM=m -+CONFIG_USB_F_RNDIS=m -+CONFIG_USB_F_MASS_STORAGE=m -+CONFIG_USB_CONFIGFS=m -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+CONFIG_USB_CONFIGFS_ACM=y -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7205V200=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7205v200_full_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7205v200_full_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2981 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+CONFIG_ARCH_GK7205V200=y -+# CONFIG_ARCH_GK7205V300 is not set -+# CONFIG_ARCH_GK7202V300 is not set -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+CONFIG_HAVE_NET_DSA=y -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_NET=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+CONFIG_NETDEVICES=y -+CONFIG_NET_CORE=y -+# CONFIG_BONDING is not set -+# CONFIG_DUMMY is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_NET_TEAM is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_VXLAN is not set -+# CONFIG_MACSEC is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_TUN is not set -+# CONFIG_TUN_VNET_CROSS_LE is not set -+# CONFIG_VETH is not set -+# CONFIG_NLMON is not set -+ -+# -+# CAIF transport drivers -+# -+ -+# -+# Distributed Switch Architecture drivers -+# -+CONFIG_ETHERNET=y -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DNET is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+CONFIG_NET_VENDOR_GOKE=y -+CONFIG_GOKE_FEMAC=y -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+CONFIG_NET_VENDOR_MICROCHIP=y -+# CONFIG_ENC28J60 is not set -+# CONFIG_ENCX24J600 is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_ETHOC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_PHYLIB=y -+CONFIG_SWPHY=y -+ -+# -+# MDIO bus device drivers -+# -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_GPIO is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+CONFIG_MDIO_GOKE_FEMAC=y -+# CONFIG_MDIO_HISI_FEMAC is not set -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_AMD_PHY is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+CONFIG_FIXED_PHY=y -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_STE10XP is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_USB_NET_DRIVERS is not set -+# CONFIG_WLAN is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_ISDN is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_PWM_BEEPER is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=m -+CONFIG_USB_F_ACM=m -+CONFIG_USB_U_SERIAL=m -+CONFIG_USB_U_ETHER=m -+CONFIG_USB_F_ECM=m -+CONFIG_USB_F_RNDIS=m -+CONFIG_USB_F_MASS_STORAGE=m -+CONFIG_USB_CONFIGFS=m -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+CONFIG_USB_CONFIGFS_ACM=y -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PWM is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7205V200=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+CONFIG_PWM=y -+CONFIG_PWM_SYSFS=y -+# CONFIG_PWM_FSL_FTM is not set -+CONFIG_PWM_GOKE=y -+# CONFIG_PWM_PCA9685 is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7205v200_mini_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7205v200_mini_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2050 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+# CONFIG_KERNEL_GZIP is not set -+# CONFIG_KERNEL_LZMA is not set -+CONFIG_KERNEL_XZ=y -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+# CONFIG_CGROUP_FREEZER is not set -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+# CONFIG_BLK_DEV_INITRD is not set -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+CONFIG_ARCH_GK7205V200=y -+# CONFIG_ARCH_GK7205V300 is not set -+# CONFIG_ARCH_GK7202V300 is not set -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+# CONFIG_ARM_THUMB is not set -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+# CONFIG_VDSO is not set -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+# CONFIG_ARM_PATCH_IDIV is not set -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+# CONFIG_PACKET is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+# CONFIG_XFRM_USER is not set -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# CONFIG_IP_ADVANCED_ROUTER is not set -+# CONFIG_IP_PNP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+# CONFIG_SYN_COOKIES is not set -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+CONFIG_HAVE_NET_DSA=y -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+# CONFIG_WIRELESS is not set -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+# CONFIG_UEVENT_HELPER is not set -+# CONFIG_DEVTMPFS is not set -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+# CONFIG_FIRMWARE_IN_KERNEL is not set -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_MMIO=y -+# CONFIG_DMA_SHARED_BUFFER is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+# CONFIG_SPI_GOKE_SFC is not set -+CONFIG_CLOSE_SPI_8PIN_4IO=y -+# CONFIG_MTD_UBI is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_NET=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NET_CORE is not set -+ -+# -+# CAIF transport drivers -+# -+ -+# -+# Distributed Switch Architecture drivers -+# -+CONFIG_ETHERNET=y -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DNET is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+CONFIG_NET_VENDOR_GOKE=y -+CONFIG_GOKE_FEMAC=y -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+# CONFIG_NET_VENDOR_MICROCHIP is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_ETHOC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_PHYLIB=y -+CONFIG_SWPHY=y -+ -+# -+# MDIO bus device drivers -+# -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+CONFIG_MDIO_GOKE_FEMAC=y -+# CONFIG_MDIO_HISI_FEMAC is not set -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_AMD_PHY is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+CONFIG_FIXED_PHY=y -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_STE10XP is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+ -+# -+# Host-side USB support is needed for USB Network Adapter support -+# -+# CONFIG_WLAN is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_ISDN is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+# CONFIG_INPUT_MOUSEDEV is not set -+# CONFIG_INPUT_JOYDEV is not set -+# CONFIG_INPUT_EVDEV is not set -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+# CONFIG_INPUT_MISC is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_TAOS_EVM is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_FSL_SPI is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_SINGLE is not set -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+# CONFIG_GPIOLIB is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_CORE is not set -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+# CONFIG_MFD_GOKE_FMC is not set -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+# CONFIG_MEDIA_SUPPORT is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+# CONFIG_HID is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_UWB is not set -+# CONFIG_MMC is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+# CONFIG_RTC_CLASS is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7205V200=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+# CONFIG_GENERIC_PHY is not set -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+# CONFIG_PHY_GOKE_USBP2 is not set -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4_FS is not set -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+# CONFIG_FS_POSIX_ACL is not set -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+# CONFIG_MANDATORY_FILE_LOCKING is not set -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+# CONFIG_ISO9660_FS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+# CONFIG_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_TMPFS_XATTR is not set -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+# CONFIG_YAFFS_FS is not set -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+# CONFIG_LOGFS is not set -+# CONFIG_CRAMFS is not set -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+# CONFIG_NFS_FS is not set -+# CONFIG_NFSD is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+# CONFIG_NLS_CODEPAGE_437 is not set -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_ASCII is not set -+# CONFIG_NLS_ISO8859_1 is not set -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+# CONFIG_NLS_UTF8 is not set -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+# CONFIG_CRYPTO_MANAGER is not set -+# CONFIG_CRYPTO_MANAGER2 is not set -+# CONFIG_CRYPTO_USER is not set -+# CONFIG_CRYPTO_GF128MUL is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+# CONFIG_CRYPTO_CCM is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+# CONFIG_CRYPTO_SEQIV is not set -+# CONFIG_CRYPTO_ECHAINIV is not set -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+# CONFIG_CRYPTO_GHASH is not set -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+# CONFIG_CRYPTO_MD5 is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+# CONFIG_CRYPTO_SHA1 is not set -+# CONFIG_CRYPTO_SHA256 is not set -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+# CONFIG_CRYPTO_ARC4 is not set -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_LZO is not set -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_DRBG_MENU is not set -+# CONFIG_CRYPTO_JITTERENTROPY is not set -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_T10DIF is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+# CONFIG_SG_SPLIT is not set -+# CONFIG_SG_POOL is not set -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7205v300_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7205v300_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2975 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+# CONFIG_ARCH_GK7205V200 is not set -+CONFIG_ARCH_GK7205V300=y -+# CONFIG_ARCH_GK7202V300 is not set -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+CONFIG_HAVE_NET_DSA=y -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_NET=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+CONFIG_NETDEVICES=y -+CONFIG_NET_CORE=y -+# CONFIG_BONDING is not set -+# CONFIG_DUMMY is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_NET_TEAM is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_VXLAN is not set -+# CONFIG_MACSEC is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_TUN is not set -+# CONFIG_TUN_VNET_CROSS_LE is not set -+# CONFIG_VETH is not set -+# CONFIG_NLMON is not set -+ -+# -+# CAIF transport drivers -+# -+ -+# -+# Distributed Switch Architecture drivers -+# -+CONFIG_ETHERNET=y -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DNET is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+CONFIG_NET_VENDOR_GOKE=y -+CONFIG_GOKE_FEMAC=y -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+CONFIG_NET_VENDOR_MICROCHIP=y -+# CONFIG_ENC28J60 is not set -+# CONFIG_ENCX24J600 is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_ETHOC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_PHYLIB=y -+CONFIG_SWPHY=y -+ -+# -+# MDIO bus device drivers -+# -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_GPIO is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+CONFIG_MDIO_GOKE_FEMAC=y -+# CONFIG_MDIO_HISI_FEMAC is not set -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_AMD_PHY is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+CONFIG_FIXED_PHY=y -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_STE10XP is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_USB_NET_DRIVERS is not set -+# CONFIG_WLAN is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_ISDN is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=m -+CONFIG_USB_F_ACM=m -+CONFIG_USB_U_SERIAL=m -+CONFIG_USB_U_ETHER=m -+CONFIG_USB_F_ECM=m -+CONFIG_USB_F_RNDIS=m -+CONFIG_USB_F_MASS_STORAGE=m -+CONFIG_USB_CONFIGFS=m -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+CONFIG_USB_CONFIGFS_ACM=y -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7205V300=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7205v300_full_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7205v300_full_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2975 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+# CONFIG_ARCH_GK7205V200 is not set -+CONFIG_ARCH_GK7205V300=y -+# CONFIG_ARCH_GK7202V300 is not set -+# CONFIG_ARCH_GK7605V100 is not set -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+CONFIG_HAVE_NET_DSA=y -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_NET=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+CONFIG_NETDEVICES=y -+CONFIG_NET_CORE=y -+# CONFIG_BONDING is not set -+# CONFIG_DUMMY is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_NET_TEAM is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_VXLAN is not set -+# CONFIG_MACSEC is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_TUN is not set -+# CONFIG_TUN_VNET_CROSS_LE is not set -+# CONFIG_VETH is not set -+# CONFIG_NLMON is not set -+ -+# -+# CAIF transport drivers -+# -+ -+# -+# Distributed Switch Architecture drivers -+# -+CONFIG_ETHERNET=y -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DNET is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+CONFIG_NET_VENDOR_GOKE=y -+CONFIG_GOKE_FEMAC=y -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+CONFIG_NET_VENDOR_MICROCHIP=y -+# CONFIG_ENC28J60 is not set -+# CONFIG_ENCX24J600 is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_ETHOC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_PHYLIB=y -+CONFIG_SWPHY=y -+ -+# -+# MDIO bus device drivers -+# -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_GPIO is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+CONFIG_MDIO_GOKE_FEMAC=y -+# CONFIG_MDIO_HISI_FEMAC is not set -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_AMD_PHY is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+CONFIG_FIXED_PHY=y -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_STE10XP is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_USB_NET_DRIVERS is not set -+# CONFIG_WLAN is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_ISDN is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=m -+CONFIG_USB_F_ACM=m -+CONFIG_USB_U_SERIAL=m -+CONFIG_USB_U_ETHER=m -+CONFIG_USB_F_ECM=m -+CONFIG_USB_F_RNDIS=m -+CONFIG_USB_F_MASS_STORAGE=m -+CONFIG_USB_CONFIGFS=m -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+CONFIG_USB_CONFIGFS_ACM=y -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7205V300=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7605v100_emmc_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7605v100_emmc_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2975 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+# CONFIG_ARCH_GK7205V200 is not set -+# CONFIG_ARCH_GK7205V300 is not set -+# CONFIG_ARCH_GK7202V300 is not set -+CONFIG_ARCH_GK7605V100=y -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+CONFIG_HAVE_NET_DSA=y -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_NET=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+CONFIG_NETDEVICES=y -+CONFIG_NET_CORE=y -+# CONFIG_BONDING is not set -+# CONFIG_DUMMY is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_NET_TEAM is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_VXLAN is not set -+# CONFIG_MACSEC is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_TUN is not set -+# CONFIG_TUN_VNET_CROSS_LE is not set -+# CONFIG_VETH is not set -+# CONFIG_NLMON is not set -+ -+# -+# CAIF transport drivers -+# -+ -+# -+# Distributed Switch Architecture drivers -+# -+CONFIG_ETHERNET=y -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DNET is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+CONFIG_NET_VENDOR_GOKE=y -+CONFIG_GOKE_FEMAC=y -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+CONFIG_NET_VENDOR_MICROCHIP=y -+# CONFIG_ENC28J60 is not set -+# CONFIG_ENCX24J600 is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_ETHOC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_PHYLIB=y -+CONFIG_SWPHY=y -+ -+# -+# MDIO bus device drivers -+# -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_GPIO is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+CONFIG_MDIO_GOKE_FEMAC=y -+# CONFIG_MDIO_HISI_FEMAC is not set -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_AMD_PHY is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+CONFIG_FIXED_PHY=y -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_STE10XP is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_USB_NET_DRIVERS is not set -+# CONFIG_WLAN is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_ISDN is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=m -+CONFIG_USB_F_ACM=m -+CONFIG_USB_U_SERIAL=m -+CONFIG_USB_U_ETHER=m -+CONFIG_USB_F_ECM=m -+CONFIG_USB_F_RNDIS=m -+CONFIG_USB_F_MASS_STORAGE=m -+CONFIG_USB_CONFIGFS=m -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+CONFIG_USB_CONFIGFS_ACM=y -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7605V100=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/configs/gk7605v100_full_defconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/configs/gk7605v100_full_defconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,2975 @@ -+# -+# Automatically generated file; DO NOT EDIT. -+# Linux/arm 4.9.37 Kernel Configuration -+# -+CONFIG_ARM=y -+CONFIG_ARM_HAS_SG_CHAIN=y -+CONFIG_MIGHT_HAVE_PCI=y -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_HAVE_PROC_CPU=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_FIX_EARLYCON_MEM=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_NEED_DMA_MAP_STATE=y -+CONFIG_ARCH_SUPPORTS_UPROBES=y -+CONFIG_VECTORS_BASE=0xffff0000 -+CONFIG_ARM_PATCH_PHYS_VIRT=y -+CONFIG_GENERIC_BUG=y -+CONFIG_PGTABLE_LEVELS=2 -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+CONFIG_IRQ_WORK=y -+CONFIG_BUILDTIME_EXTABLE_SORT=y -+ -+# -+# General setup -+# -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_CROSS_COMPILE="" -+# CONFIG_COMPILE_TEST is not set -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_HAVE_KERNEL_GZIP=y -+CONFIG_HAVE_KERNEL_LZMA=y -+CONFIG_HAVE_KERNEL_XZ=y -+CONFIG_HAVE_KERNEL_LZO=y -+CONFIG_HAVE_KERNEL_LZ4=y -+CONFIG_KERNEL_GZIP=y -+# CONFIG_KERNEL_LZMA is not set -+# CONFIG_KERNEL_XZ is not set -+# CONFIG_KERNEL_LZO is not set -+# CONFIG_KERNEL_LZ4 is not set -+CONFIG_DEFAULT_HOSTNAME="(none)" -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_CROSS_MEMORY_ATTACH=y -+CONFIG_FHANDLE=y -+CONFIG_USELIB=y -+# CONFIG_AUDIT is not set -+CONFIG_HAVE_ARCH_AUDITSYSCALL=y -+ -+# -+# IRQ subsystem -+# -+CONFIG_GENERIC_IRQ_PROBE=y -+CONFIG_GENERIC_IRQ_SHOW=y -+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -+CONFIG_HARDIRQS_SW_RESEND=y -+CONFIG_IRQ_DOMAIN=y -+CONFIG_IRQ_DOMAIN_HIERARCHY=y -+CONFIG_HANDLE_DOMAIN_IRQ=y -+CONFIG_IRQ_FORCED_THREADING=y -+CONFIG_SPARSE_IRQ=y -+CONFIG_ARCH_CLOCKSOURCE_DATA=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+ -+# -+# Timers subsystem -+# -+CONFIG_HZ_PERIODIC=y -+# CONFIG_NO_HZ_IDLE is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+ -+# -+# CPU/Task time and stats accounting -+# -+CONFIG_TICK_CPU_ACCOUNTING=y -+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -+# CONFIG_IRQ_TIME_ACCOUNTING is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_TINY_RCU=y -+# CONFIG_RCU_EXPERT is not set -+CONFIG_SRCU=y -+# CONFIG_TASKS_RCU is not set -+# CONFIG_RCU_STALL_COMMON is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_RCU_EXPEDITE_BOOT is not set -+# CONFIG_BUILD_BIN2C is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=17 -+CONFIG_NMI_LOG_BUF_SHIFT=13 -+CONFIG_GENERIC_SCHED_CLOCK=y -+CONFIG_CGROUPS=y -+# CONFIG_MEMCG is not set -+# CONFIG_BLK_CGROUP is not set -+# CONFIG_CGROUP_SCHED is not set -+# CONFIG_CGROUP_PIDS is not set -+CONFIG_CGROUP_FREEZER=y -+# CONFIG_CPUSETS is not set -+# CONFIG_CGROUP_DEVICE is not set -+# CONFIG_CGROUP_CPUACCT is not set -+# CONFIG_CGROUP_DEBUG is not set -+# CONFIG_CHECKPOINT_RESTORE is not set -+CONFIG_NAMESPACES=y -+CONFIG_UTS_NS=y -+CONFIG_IPC_NS=y -+# CONFIG_USER_NS is not set -+CONFIG_PID_NS=y -+CONFIG_NET_NS=y -+# CONFIG_SCHED_AUTOGROUP is not set -+# CONFIG_SYSFS_DEPRECATED is not set -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_RD_GZIP=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+CONFIG_RD_LZ4=y -+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_HAVE_UID16=y -+CONFIG_BPF=y -+# CONFIG_EXPERT is not set -+CONFIG_UID16=y -+CONFIG_MULTIUSER=y -+# CONFIG_SGETMASK_SYSCALL is not set -+CONFIG_SYSFS_SYSCALL=y -+# CONFIG_SYSCTL_SYSCALL is not set -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -+CONFIG_KALLSYMS_BASE_RELATIVE=y -+CONFIG_PRINTK=y -+CONFIG_PRINTK_NMI=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+# CONFIG_BPF_SYSCALL is not set -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+CONFIG_ADVISE_SYSCALLS=y -+# CONFIG_USERFAULTFD is not set -+CONFIG_MEMBARRIER=y -+# CONFIG_EMBEDDED is not set -+CONFIG_HAVE_PERF_EVENTS=y -+CONFIG_PERF_USE_VMALLOC=y -+ -+# -+# Kernel Performance Events And Counters -+# -+# CONFIG_PERF_EVENTS is not set -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLAB_FREELIST_RANDOM is not set -+# CONFIG_SYSTEM_DATA_VERIFICATION is not set -+# CONFIG_PROFILING is not set -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+# CONFIG_JUMP_LABEL is not set -+# CONFIG_UPROBES is not set -+# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -+CONFIG_ARCH_USE_BUILTIN_BSWAP=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+CONFIG_HAVE_OPTPROBES=y -+CONFIG_HAVE_NMI=y -+CONFIG_HAVE_ARCH_TRACEHOOK=y -+CONFIG_HAVE_DMA_CONTIGUOUS=y -+CONFIG_GENERIC_SMP_IDLE_THREAD=y -+CONFIG_GENERIC_IDLE_POLL_SETUP=y -+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -+CONFIG_HAVE_CLK=y -+CONFIG_HAVE_DMA_API_DEBUG=y -+CONFIG_HAVE_PERF_REGS=y -+CONFIG_HAVE_PERF_USER_STACK_DUMP=y -+CONFIG_HAVE_ARCH_JUMP_LABEL=y -+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_HAVE_GCC_PLUGINS=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_HAVE_CC_STACKPROTECTOR=y -+CONFIG_CC_STACKPROTECTOR=y -+# CONFIG_CC_STACKPROTECTOR_NONE is not set -+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -+CONFIG_CC_STACKPROTECTOR_STRONG=y -+CONFIG_HAVE_CONTEXT_TRACKING=y -+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -+CONFIG_MODULES_USE_ELF_REL=y -+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -+CONFIG_HAVE_EXIT_THREAD=y -+CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -+CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -+CONFIG_ARCH_MMAP_RND_BITS=8 -+# CONFIG_HAVE_ARCH_HASH is not set -+# CONFIG_ISA_BUS_API is not set -+CONFIG_CLONE_BACKWARDS=y -+CONFIG_OLD_SIGSUSPEND3=y -+CONFIG_OLD_SIGACTION=y -+# CONFIG_CPU_NO_EFFICIENT_FFS is not set -+# CONFIG_HAVE_ARCH_VMAP_STACK is not set -+ -+# -+# GCOV-based kernel profiling -+# -+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -+CONFIG_HAVE_GENERIC_DMA_COHERENT=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+# CONFIG_MODULE_SIG is not set -+# CONFIG_MODULE_COMPRESS is not set -+# CONFIG_TRIM_UNUSED_KSYMS is not set -+CONFIG_BLOCK=y -+CONFIG_LBDAF=y -+CONFIG_BLK_DEV_BSG=y -+# CONFIG_BLK_DEV_BSGLIB is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+CONFIG_BLK_CMDLINE_PARSER=y -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_AIX_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+CONFIG_EFI_PARTITION=y -+# CONFIG_SYSV68_PARTITION is not set -+CONFIG_CMDLINE_PARTITION=y -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -+CONFIG_INLINE_READ_UNLOCK=y -+CONFIG_INLINE_READ_UNLOCK_IRQ=y -+CONFIG_INLINE_WRITE_UNLOCK=y -+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -+CONFIG_FREEZER=y -+ -+# -+# System Type -+# -+CONFIG_MMU=y -+CONFIG_ARCH_MULTIPLATFORM=y -+# CONFIG_ARCH_GEMINI is not set -+# CONFIG_ARCH_EBSA110 is not set -+# CONFIG_ARCH_EP93XX is not set -+# CONFIG_ARCH_FOOTBRIDGE is not set -+# CONFIG_ARCH_NETX is not set -+# CONFIG_ARCH_IOP13XX is not set -+# CONFIG_ARCH_IOP32X is not set -+# CONFIG_ARCH_IOP33X is not set -+# CONFIG_ARCH_IXP4XX is not set -+# CONFIG_ARCH_DOVE is not set -+# CONFIG_ARCH_KS8695 is not set -+# CONFIG_ARCH_W90X900 is not set -+# CONFIG_ARCH_LPC32XX is not set -+# CONFIG_ARCH_PXA is not set -+# CONFIG_ARCH_RPC is not set -+# CONFIG_ARCH_SA1100 is not set -+# CONFIG_ARCH_S3C24XX is not set -+# CONFIG_ARCH_DAVINCI is not set -+# CONFIG_ARCH_OMAP1 is not set -+ -+# -+# Multiple platform selection -+# -+ -+# -+# CPU Core family selection -+# -+# CONFIG_ARCH_MULTI_V6 is not set -+CONFIG_ARCH_MULTI_V7=y -+CONFIG_ARCH_MULTI_V6_V7=y -+# CONFIG_ARCH_MULTI_CPU_AUTO is not set -+# CONFIG_ARCH_VIRT is not set -+# CONFIG_ARCH_MVEBU is not set -+# CONFIG_ARCH_ALPINE is not set -+# CONFIG_ARCH_ARTPEC is not set -+# CONFIG_ARCH_AT91 is not set -+# CONFIG_ARCH_BCM is not set -+# CONFIG_ARCH_BERLIN is not set -+# CONFIG_ARCH_DIGICOLOR is not set -+# CONFIG_ARCH_HIGHBANK is not set -+# CONFIG_ARCH_HISI is not set -+CONFIG_ARCH_GOKE=y -+ -+# -+# Goke platform type -+# -+# CONFIG_ARCH_GK7205V200 is not set -+# CONFIG_ARCH_GK7205V300 is not set -+# CONFIG_ARCH_GK7202V300 is not set -+CONFIG_ARCH_GK7605V100=y -+# CONFIG_GOKE_MC is not set -+CONFIG_BSP_ZRELADDR=0x40008000 -+CONFIG_BSP_PARAMS_PHYS=0x00000100 -+CONFIG_BSP_INITRD_PHYS=0x00800000 -+# CONFIG_ARCH_KEYSTONE is not set -+# CONFIG_ARCH_MESON is not set -+# CONFIG_ARCH_MXC is not set -+# CONFIG_ARCH_MEDIATEK is not set -+ -+# -+# TI OMAP/AM/DM/DRA Family -+# -+# CONFIG_ARCH_OMAP3 is not set -+# CONFIG_ARCH_OMAP4 is not set -+# CONFIG_SOC_OMAP5 is not set -+# CONFIG_SOC_AM33XX is not set -+# CONFIG_SOC_AM43XX is not set -+# CONFIG_SOC_DRA7XX is not set -+# CONFIG_ARCH_MMP is not set -+# CONFIG_ARCH_QCOM is not set -+# CONFIG_ARCH_REALVIEW is not set -+# CONFIG_ARCH_ROCKCHIP is not set -+# CONFIG_ARCH_SOCFPGA is not set -+# CONFIG_PLAT_SPEAR is not set -+# CONFIG_ARCH_STI is not set -+# CONFIG_ARCH_S5PV210 is not set -+# CONFIG_ARCH_EXYNOS is not set -+# CONFIG_ARCH_RENESAS is not set -+# CONFIG_ARCH_SUNXI is not set -+# CONFIG_ARCH_SIRF is not set -+# CONFIG_ARCH_TANGO is not set -+# CONFIG_ARCH_TEGRA is not set -+# CONFIG_ARCH_UNIPHIER is not set -+# CONFIG_ARCH_U8500 is not set -+# CONFIG_ARCH_VEXPRESS is not set -+# CONFIG_ARCH_WM8850 is not set -+# CONFIG_ARCH_ZX is not set -+# CONFIG_ARCH_ZYNQ is not set -+ -+# -+# Processor Type -+# -+CONFIG_CPU_V7=y -+CONFIG_CPU_32v6K=y -+CONFIG_CPU_32v7=y -+CONFIG_CPU_ABRT_EV7=y -+CONFIG_CPU_PABRT_V7=y -+CONFIG_CPU_CACHE_V7=y -+CONFIG_CPU_CACHE_VIPT=y -+CONFIG_CPU_COPY_V6=y -+CONFIG_CPU_TLB_V7=y -+CONFIG_CPU_HAS_ASID=y -+CONFIG_CPU_CP15=y -+CONFIG_CPU_CP15_MMU=y -+ -+# -+# Processor Features -+# -+# CONFIG_ARM_LPAE is not set -+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set -+CONFIG_ARM_THUMB=y -+# CONFIG_ARM_THUMBEE is not set -+CONFIG_ARM_VIRT_EXT=y -+# CONFIG_SWP_EMULATE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_BPREDICT_DISABLE is not set -+CONFIG_KUSER_HELPERS=y -+CONFIG_VDSO=y -+CONFIG_MIGHT_HAVE_CACHE_L2X0=y -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_ARM_L1_CACHE_SHIFT_6=y -+CONFIG_ARM_L1_CACHE_SHIFT=6 -+CONFIG_ARM_DMA_MEM_BUFFERABLE=y -+# CONFIG_DEBUG_RODATA is not set -+CONFIG_MULTI_IRQ_HANDLER=y -+# CONFIG_ARM_ERRATA_430973 is not set -+# CONFIG_ARM_ERRATA_720789 is not set -+# CONFIG_ARM_ERRATA_754322 is not set -+# CONFIG_ARM_ERRATA_775420 is not set -+# CONFIG_ARM_ERRATA_773022 is not set -+# CONFIG_ARM_ERRATA_818325_852422 is not set -+# CONFIG_ARM_ERRATA_821420 is not set -+# CONFIG_ARM_ERRATA_825619 is not set -+# CONFIG_ARM_ERRATA_852421 is not set -+# CONFIG_ARM_ERRATA_852423 is not set -+ -+# -+# Bus support -+# -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS_GENERIC is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Kernel Features -+# -+CONFIG_HAVE_SMP=y -+# CONFIG_SMP is not set -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_VMSPLIT_3G=y -+# CONFIG_VMSPLIT_3G_OPT is not set -+# CONFIG_VMSPLIT_2G is not set -+# CONFIG_VMSPLIT_1G is not set -+CONFIG_PAGE_OFFSET=0xC0000000 -+# CONFIG_ARM_PSCI is not set -+CONFIG_ARCH_NR_GPIO=0 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_HZ_FIXED=0 -+CONFIG_HZ_100=y -+# CONFIG_HZ_200 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_500 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+# CONFIG_THUMB2_KERNEL is not set -+CONFIG_ARM_PATCH_IDIV=y -+CONFIG_AEABI=y -+# CONFIG_OABI_COMPAT is not set -+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -+CONFIG_HAVE_ARCH_PFN_VALID=y -+# CONFIG_HIGHMEM is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_HAVE_MEMBLOCK=y -+CONFIG_NO_BOOTMEM=y -+# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_COMPACTION=y -+CONFIG_MIGRATION=y -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+# CONFIG_KSM is not set -+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -+CONFIG_NEED_PER_CPU_KM=y -+# CONFIG_CLEANCACHE is not set -+# CONFIG_CMA is not set -+# CONFIG_ZPOOL is not set -+# CONFIG_ZBUD is not set -+# CONFIG_ZSMALLOC is not set -+CONFIG_GENERIC_EARLY_IOREMAP=y -+# CONFIG_IDLE_PAGE_TRACKING is not set -+CONFIG_FRAME_VECTOR=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_ALIGNMENT_TRAP=y -+# CONFIG_UACCESS_WITH_MEMCPY is not set -+# CONFIG_SECCOMP is not set -+CONFIG_SWIOTLB=y -+CONFIG_IOMMU_HELPER=y -+# CONFIG_PARAVIRT is not set -+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -+# CONFIG_XEN is not set -+ -+# -+# Boot options -+# -+CONFIG_USE_OF=y -+CONFIG_ATAGS=y -+# CONFIG_DEPRECATED_PARAM_STRUCT is not set -+CONFIG_ZBOOT_ROM_TEXT=0 -+CONFIG_ZBOOT_ROM_BSS=0 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -+CONFIG_CMDLINE="" -+# CONFIG_KEXEC is not set -+# CONFIG_CRASH_DUMP is not set -+CONFIG_AUTO_ZRELADDR=y -+# CONFIG_EFI is not set -+ -+# -+# CPU Power Management -+# -+ -+# -+# CPU Frequency scaling -+# -+# CONFIG_CPU_FREQ is not set -+ -+# -+# CPU Idle -+# -+# CONFIG_CPU_IDLE is not set -+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -+ -+# -+# Floating point emulation -+# -+ -+# -+# At least one emulation must be selected -+# -+CONFIG_VFP=y -+CONFIG_VFPv3=y -+CONFIG_NEON=y -+# CONFIG_KERNEL_MODE_NEON is not set -+ -+# -+# Userspace binary formats -+# -+CONFIG_BINFMT_ELF=y -+CONFIG_ELFCORE=y -+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -+CONFIG_BINFMT_SCRIPT=y -+# CONFIG_BINFMT_FLAT is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_COREDUMP=y -+ -+# -+# Power management options -+# -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y -+CONFIG_PM_SLEEP=y -+# CONFIG_PM_AUTOSLEEP is not set -+# CONFIG_PM_WAKELOCKS is not set -+CONFIG_PM=y -+# CONFIG_PM_DEBUG is not set -+# CONFIG_APM_EMULATION is not set -+CONFIG_PM_CLK=y -+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -+CONFIG_CPU_PM=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_ARM_CPU_SUSPEND=y -+CONFIG_ARCH_HIBERNATION_POSSIBLE=y -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_DIAG is not set -+CONFIG_UNIX=y -+# CONFIG_UNIX_DIAG is not set -+CONFIG_XFRM=y -+CONFIG_XFRM_ALGO=y -+CONFIG_XFRM_USER=y -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+# CONFIG_IP_FIB_TRIE_STATS is not set -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+# CONFIG_IP_PNP_DHCP is not set -+# CONFIG_IP_PNP_BOOTP is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE_DEMUX is not set -+# CONFIG_NET_IP_TUNNEL is not set -+CONFIG_IP_MROUTE=y -+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+# CONFIG_NET_UDP_TUNNEL is not set -+# CONFIG_NET_FOU is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_INET_UDP_DIAG is not set -+# CONFIG_INET_DIAG_DESTROY is not set -+CONFIG_TCP_CONG_ADVANCED=y -+CONFIG_TCP_CONG_BIC=m -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_TCP_CONG_WESTWOOD=m -+CONFIG_TCP_CONG_HTCP=m -+# CONFIG_TCP_CONG_HSTCP is not set -+# CONFIG_TCP_CONG_HYBLA is not set -+# CONFIG_TCP_CONG_VEGAS is not set -+# CONFIG_TCP_CONG_NV is not set -+# CONFIG_TCP_CONG_SCALABLE is not set -+# CONFIG_TCP_CONG_LP is not set -+# CONFIG_TCP_CONG_VENO is not set -+# CONFIG_TCP_CONG_YEAH is not set -+# CONFIG_TCP_CONG_ILLINOIS is not set -+# CONFIG_TCP_CONG_DCTCP is not set -+# CONFIG_TCP_CONG_CDG is not set -+# CONFIG_TCP_CONG_BBR is not set -+CONFIG_DEFAULT_CUBIC=y -+# CONFIG_DEFAULT_RENO is not set -+CONFIG_DEFAULT_TCP_CONG="cubic" -+CONFIG_TCP_MD5SIG=y -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NET_PTP_CLASSIFY is not set -+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_RDS is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_L2TP is not set -+# CONFIG_BRIDGE is not set -+CONFIG_HAVE_NET_DSA=y -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_PHONET is not set -+# CONFIG_IEEE802154 is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+CONFIG_DNS_RESOLVER=y -+# CONFIG_BATMAN_ADV is not set -+# CONFIG_OPENVSWITCH is not set -+# CONFIG_VSOCKETS is not set -+# CONFIG_NETLINK_DIAG is not set -+# CONFIG_MPLS is not set -+# CONFIG_HSR is not set -+# CONFIG_NET_SWITCHDEV is not set -+# CONFIG_NET_L3_MASTER_DEV is not set -+# CONFIG_NET_NCSI is not set -+# CONFIG_SOCK_CGROUP_DATA is not set -+# CONFIG_CGROUP_NET_PRIO is not set -+# CONFIG_CGROUP_NET_CLASSID is not set -+CONFIG_NET_RX_BUSY_POLL=y -+CONFIG_BQL=y -+# CONFIG_BPF_JIT is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_AF_KCM is not set -+# CONFIG_STREAM_PARSER is not set -+CONFIG_FIB_RULES=y -+CONFIG_WIRELESS=y -+CONFIG_WEXT_CORE=y -+CONFIG_WEXT_PROC=y -+CONFIG_CFG80211=m -+# CONFIG_NL80211_TESTMODE is not set -+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -+CONFIG_CFG80211_DEFAULT_PS=y -+# CONFIG_CFG80211_INTERNAL_REGDB is not set -+CONFIG_CFG80211_CRDA_SUPPORT=y -+CONFIG_CFG80211_WEXT=y -+# CONFIG_LIB80211 is not set -+CONFIG_MAC80211=m -+CONFIG_MAC80211_HAS_RC=y -+CONFIG_MAC80211_RC_MINSTREL=y -+CONFIG_MAC80211_RC_MINSTREL_HT=y -+# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -+CONFIG_MAC80211_MESH=y -+# CONFIG_MAC80211_MESSAGE_TRACING is not set -+# CONFIG_MAC80211_DEBUG_MENU is not set -+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+# CONFIG_CAIF is not set -+# CONFIG_CEPH_LIB is not set -+# CONFIG_NFC is not set -+# CONFIG_LWTUNNEL is not set -+# CONFIG_DST_CACHE is not set -+# CONFIG_NET_DEVLINK is not set -+CONFIG_MAY_USE_DEVLINK=y -+CONFIG_HAVE_CBPF_JIT=y -+ -+# -+# Device Drivers -+# -+CONFIG_ARM_AMBA=y -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_STANDALONE=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=y -+CONFIG_FIRMWARE_IN_KERNEL=y -+CONFIG_EXTRA_FIRMWARE="" -+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -+CONFIG_ALLOW_DEV_COREDUMP=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_GENERIC_CPU_DEVICES is not set -+CONFIG_REGMAP=y -+CONFIG_REGMAP_I2C=y -+CONFIG_REGMAP_SPI=y -+CONFIG_REGMAP_MMIO=y -+CONFIG_DMA_SHARED_BUFFER=y -+# CONFIG_FENCE_TRACE is not set -+ -+# -+# Bus devices -+# -+# CONFIG_BRCMSTB_GISB_ARB is not set -+# CONFIG_VEXPRESS_CONFIG is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AFS_PARTS is not set -+CONFIG_MTD_OF_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_SM_FTL is not set -+# CONFIG_MTD_OOPS is not set -+# CONFIG_MTD_PARTITIONED_MASTER is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_DATAFLASH is not set -+# CONFIG_MTD_M25P80 is not set -+# CONFIG_MTD_SST25L is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOCG3 is not set -+CONFIG_MTD_NAND_ECC=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_ECC_BCH is not set -+# CONFIG_MTD_SM_COMMON is not set -+# CONFIG_MTD_NAND_DENALI_DT is not set -+# CONFIG_MTD_NAND_GPIO is not set -+# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_DOCG4 is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_BRCMNAND is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_NAND_HISI504 is not set -+# CONFIG_MTD_NAND_MTK is not set -+CONFIG_MTD_SPI_NAND_GOKE=y -+# CONFIG_GOKE_NAND_ECC_STATUS_REPORT is not set -+# CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 is not set -+CONFIG_MTD_SPI_NAND_FMC100=y -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR & LPDDR2 PCM memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+# CONFIG_MTD_LPDDR2_NVM is not set -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_MT81xx_NOR is not set -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+# CONFIG_SPI_CADENCE_QUADSPI is not set -+CONFIG_SPI_GOKE_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_GOKE_SPI_BLOCK_PROTECT=y -+CONFIG_MTD_UBI=y -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_LIMIT=20 -+# CONFIG_MTD_UBI_FASTMAP is not set -+# CONFIG_MTD_UBI_GLUEBI is not set -+# CONFIG_MTD_UBI_BLOCK is not set -+CONFIG_DTC=y -+CONFIG_OF=y -+# CONFIG_OF_UNITTEST is not set -+CONFIG_OF_FLATTREE=y -+CONFIG_OF_EARLY_FLATTREE=y -+CONFIG_OF_ADDRESS=y -+CONFIG_OF_IRQ=y -+CONFIG_OF_NET=y -+CONFIG_OF_MDIO=y -+CONFIG_OF_RESERVED_MEM=y -+# CONFIG_OF_OVERLAY is not set -+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_NULL_BLK is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_DRBD is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MG_DISK is not set -+# CONFIG_BLK_DEV_RBD is not set -+# CONFIG_NVME_TARGET is not set -+ -+# -+# Misc devices -+# -+# CONFIG_SENSORS_LIS3LV02D is not set -+# CONFIG_AD525X_DPOT is not set -+# CONFIG_DUMMY_IRQ is not set -+# CONFIG_ICS932S401 is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_APDS9802ALS is not set -+# CONFIG_ISL29003 is not set -+# CONFIG_ISL29020 is not set -+# CONFIG_SENSORS_TSL2550 is not set -+# CONFIG_SENSORS_BH1770 is not set -+# CONFIG_SENSORS_APDS990X is not set -+# CONFIG_HMC6352 is not set -+# CONFIG_DS1682 is not set -+# CONFIG_TI_DAC7512 is not set -+# CONFIG_USB_SWITCH_FSA9480 is not set -+# CONFIG_LATTICE_ECP3_CONFIG is not set -+# CONFIG_SRAM is not set -+# CONFIG_C2PORT is not set -+ -+# -+# EEPROM support -+# -+# CONFIG_EEPROM_AT24 is not set -+# CONFIG_EEPROM_AT25 is not set -+# CONFIG_EEPROM_LEGACY is not set -+# CONFIG_EEPROM_MAX6875 is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_EEPROM_93XX46 is not set -+ -+# -+# Texas Instruments shared transport line discipline -+# -+# CONFIG_TI_ST is not set -+# CONFIG_SENSORS_LIS3_SPI is not set -+# CONFIG_SENSORS_LIS3_I2C is not set -+ -+# -+# Altera FPGA firmware download module -+# -+# CONFIG_ALTERA_STAPL is not set -+ -+# -+# Intel MIC Bus Driver -+# -+ -+# -+# SCIF Bus Driver -+# -+ -+# -+# VOP Bus Driver -+# -+ -+# -+# Intel MIC Host Driver -+# -+ -+# -+# Intel MIC Card Driver -+# -+ -+# -+# SCIF Driver -+# -+ -+# -+# Intel MIC Coprocessor State Management (COSM) Drivers -+# -+ -+# -+# VOP Driver -+# -+# CONFIG_ECHO is not set -+# CONFIG_CXL_BASE is not set -+# CONFIG_CXL_AFU_DRIVER_OPS is not set -+ -+# -+# SCSI device support -+# -+CONFIG_SCSI_MOD=y -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_NETLINK=y -+# CONFIG_SCSI_MQ_DEFAULT is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+CONFIG_SCSI_FC_ATTRS=y -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_ISCSI_BOOT_SYSFS is not set -+# CONFIG_SCSI_UFSHCD is not set -+# CONFIG_LIBFC is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_DH is not set -+# CONFIG_SCSI_OSD_INITIATOR is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_TARGET_CORE is not set -+CONFIG_NETDEVICES=y -+CONFIG_NET_CORE=y -+# CONFIG_BONDING is not set -+# CONFIG_DUMMY is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_NET_TEAM is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_VXLAN is not set -+# CONFIG_MACSEC is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_TUN is not set -+# CONFIG_TUN_VNET_CROSS_LE is not set -+# CONFIG_VETH is not set -+# CONFIG_NLMON is not set -+ -+# -+# CAIF transport drivers -+# -+ -+# -+# Distributed Switch Architecture drivers -+# -+CONFIG_ETHERNET=y -+# CONFIG_ALTERA_TSE is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_DM9000 is not set -+# CONFIG_DNET is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+CONFIG_NET_VENDOR_GOKE=y -+CONFIG_GOKE_FEMAC=y -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+CONFIG_NET_VENDOR_MICROCHIP=y -+# CONFIG_ENC28J60 is not set -+# CONFIG_ENCX24J600 is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_ETHOC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_PHYLIB=y -+CONFIG_SWPHY=y -+ -+# -+# MDIO bus device drivers -+# -+# CONFIG_MDIO_BCM_UNIMAC is not set -+# CONFIG_MDIO_BITBANG is not set -+# CONFIG_MDIO_BUS_MUX_GPIO is not set -+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -+CONFIG_MDIO_GOKE_FEMAC=y -+# CONFIG_MDIO_HISI_FEMAC is not set -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_AMD_PHY is not set -+# CONFIG_AQUANTIA_PHY is not set -+# CONFIG_AT803X_PHY is not set -+# CONFIG_BCM7XXX_PHY is not set -+# CONFIG_BCM87XX_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_DP83848_PHY is not set -+# CONFIG_DP83867_PHY is not set -+CONFIG_FIXED_PHY=y -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_INTEL_XWAY_PHY is not set -+# CONFIG_LSI_ET1011C_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_MICREL_PHY is not set -+# CONFIG_MICROCHIP_PHY is not set -+# CONFIG_MICROSEMI_PHY is not set -+# CONFIG_NATIONAL_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_REALTEK_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_STE10XP is not set -+# CONFIG_TERANETICS_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_XILINX_GMII2RGMII is not set -+# CONFIG_MICREL_KS8995MA is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_USB_NET_DRIVERS is not set -+# CONFIG_WLAN is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_ISDN is not set -+# CONFIG_NVM is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+# CONFIG_INPUT_SPARSEKMAP is not set -+# CONFIG_INPUT_MATRIXKMAP is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+CONFIG_INPUT_KEYBOARD=y -+# CONFIG_KEYBOARD_ADP5588 is not set -+# CONFIG_KEYBOARD_ADP5589 is not set -+CONFIG_KEYBOARD_ATKBD=y -+# CONFIG_KEYBOARD_QT1070 is not set -+# CONFIG_KEYBOARD_QT2160 is not set -+# CONFIG_KEYBOARD_LKKBD is not set -+# CONFIG_KEYBOARD_GPIO is not set -+# CONFIG_KEYBOARD_GPIO_POLLED is not set -+# CONFIG_KEYBOARD_TCA6416 is not set -+# CONFIG_KEYBOARD_TCA8418 is not set -+# CONFIG_KEYBOARD_MATRIX is not set -+# CONFIG_KEYBOARD_LM8333 is not set -+# CONFIG_KEYBOARD_MAX7359 is not set -+# CONFIG_KEYBOARD_MCS is not set -+# CONFIG_KEYBOARD_MPR121 is not set -+# CONFIG_KEYBOARD_NEWTON is not set -+# CONFIG_KEYBOARD_OPENCORES is not set -+# CONFIG_KEYBOARD_SAMSUNG is not set -+# CONFIG_KEYBOARD_STOWAWAY is not set -+# CONFIG_KEYBOARD_SUNKBD is not set -+# CONFIG_KEYBOARD_OMAP4 is not set -+# CONFIG_KEYBOARD_XTKBD is not set -+# CONFIG_KEYBOARD_CAP11XX is not set -+# CONFIG_KEYBOARD_BCM is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_BYD=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_CYPRESS=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_ELANTECH is not set -+# CONFIG_MOUSE_PS2_SENTELIC is not set -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+CONFIG_MOUSE_PS2_FOCALTECH=y -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_APPLETOUCH is not set -+# CONFIG_MOUSE_BCM5974 is not set -+# CONFIG_MOUSE_CYAPA is not set -+# CONFIG_MOUSE_ELAN_I2C is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_MOUSE_GPIO is not set -+# CONFIG_MOUSE_SYNAPTICS_I2C is not set -+# CONFIG_MOUSE_SYNAPTICS_USB is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+CONFIG_INPUT_MISC=y -+# CONFIG_INPUT_AD714X is not set -+# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -+# CONFIG_INPUT_BMA150 is not set -+# CONFIG_INPUT_E3X0_BUTTON is not set -+# CONFIG_INPUT_MMA8450 is not set -+# CONFIG_INPUT_MPU3050 is not set -+# CONFIG_INPUT_GP2A is not set -+# CONFIG_INPUT_GPIO_BEEPER is not set -+# CONFIG_INPUT_GPIO_TILT_POLLED is not set -+# CONFIG_INPUT_GPIO_DECODER is not set -+# CONFIG_INPUT_ATI_REMOTE2 is not set -+# CONFIG_INPUT_KEYSPAN_REMOTE is not set -+# CONFIG_INPUT_KXTJ9 is not set -+# CONFIG_INPUT_POWERMATE is not set -+# CONFIG_INPUT_YEALINK is not set -+# CONFIG_INPUT_CM109 is not set -+CONFIG_INPUT_UINPUT=y -+# CONFIG_INPUT_PCF8574 is not set -+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -+# CONFIG_INPUT_ADXL34X is not set -+# CONFIG_INPUT_CMA3000 is not set -+# CONFIG_INPUT_DRV260X_HAPTICS is not set -+# CONFIG_INPUT_DRV2665_HAPTICS is not set -+# CONFIG_INPUT_DRV2667_HAPTICS is not set -+# CONFIG_RMI4_CORE is not set -+ -+# -+# Hardware I/O ports -+# -+CONFIG_SERIO=y -+CONFIG_SERIO_SERPORT=y -+# CONFIG_SERIO_AMBAKMI is not set -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_SERIO_ALTERA_PS2 is not set -+# CONFIG_SERIO_PS2MULT is not set -+# CONFIG_SERIO_ARC_PS2 is not set -+# CONFIG_SERIO_APBPS2 is not set -+# CONFIG_USERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_TTY=y -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_VT_CONSOLE_SLEEP=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+# CONFIG_N_GSM is not set -+# CONFIG_TRACE_SINK is not set -+CONFIG_DEVMEM=y -+# CONFIG_DEVKMEM is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_EARLYCON=y -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_AMBA_PL010 is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -+# CONFIG_SERIAL_MAX3100 is not set -+# CONFIG_SERIAL_MAX310X is not set -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_SCCNXP is not set -+# CONFIG_SERIAL_SC16IS7XX is not set -+# CONFIG_SERIAL_BCM63XX is not set -+# CONFIG_SERIAL_ALTERA_JTAGUART is not set -+# CONFIG_SERIAL_ALTERA_UART is not set -+# CONFIG_SERIAL_IFX6X60 is not set -+# CONFIG_SERIAL_XILINX_PS_UART is not set -+# CONFIG_SERIAL_ARC is not set -+# CONFIG_SERIAL_FSL_LPUART is not set -+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -+# CONFIG_SERIAL_ST_ASC is not set -+# CONFIG_SERIAL_STM32 is not set -+# CONFIG_HVC_DCC is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_XILLYBUS is not set -+ -+# -+# I2C support -+# -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+CONFIG_I2C_COMPAT=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_MUX=y -+ -+# -+# Multiplexer I2C Chip support -+# -+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -+# CONFIG_I2C_MUX_GPIO is not set -+# CONFIG_I2C_MUX_PCA9541 is not set -+# CONFIG_I2C_MUX_PCA954x is not set -+# CONFIG_I2C_MUX_PINCTRL is not set -+# CONFIG_I2C_MUX_REG is not set -+# CONFIG_I2C_DEMUX_PINCTRL is not set -+CONFIG_I2C_HELPER_AUTO=y -+ -+# -+# I2C Hardware Bus support -+# -+ -+# -+# I2C system bus drivers (mostly embedded / system-on-chip) -+# -+# CONFIG_I2C_CBUS_GPIO is not set -+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -+# CONFIG_I2C_EMEV2 is not set -+# CONFIG_I2C_GPIO is not set -+CONFIG_I2C_GOKE=y -+# CONFIG_I2C_NOMADIK is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PCA_PLATFORM is not set -+# CONFIG_I2C_PXA_PCI is not set -+# CONFIG_I2C_RK3X is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_XILINX is not set -+ -+# -+# External I2C/SMBus adapter drivers -+# -+# CONFIG_I2C_DIOLAN_U2C is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Other I2C/SMBus bus drivers -+# -+CONFIG_DMA_MSG_MIN_LEN=5 -+CONFIG_DMA_MSG_MAX_LEN=4090 -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_SLAVE is not set -+# CONFIG_I2C_DEBUG_CORE is not set -+# CONFIG_I2C_DEBUG_ALGO is not set -+# CONFIG_I2C_DEBUG_BUS is not set -+CONFIG_SPI=y -+# CONFIG_SPI_DEBUG is not set -+CONFIG_SPI_MASTER=y -+ -+# -+# SPI Master Controller Drivers -+# -+# CONFIG_SPI_ALTERA is not set -+# CONFIG_SPI_AXI_SPI_ENGINE is not set -+# CONFIG_SPI_BITBANG is not set -+# CONFIG_SPI_CADENCE is not set -+# CONFIG_SPI_DESIGNWARE is not set -+# CONFIG_SPI_GPIO is not set -+# CONFIG_SPI_FSL_SPI is not set -+# CONFIG_SPI_OC_TINY is not set -+CONFIG_SPI_PL022=y -+# CONFIG_SPI_PXA2XX_PCI is not set -+# CONFIG_SPI_ROCKCHIP is not set -+# CONFIG_SPI_SC18IS602 is not set -+# CONFIG_SPI_XCOMM is not set -+# CONFIG_SPI_XILINX is not set -+# CONFIG_SPI_ZYNQMP_GQSPI is not set -+ -+# -+# SPI Protocol Masters -+# -+CONFIG_SPI_SPIDEV=y -+# CONFIG_SPI_LOOPBACK_TEST is not set -+# CONFIG_SPI_TLE62X0 is not set -+# CONFIG_SPMI is not set -+# CONFIG_HSI is not set -+ -+# -+# PPS support -+# -+# CONFIG_PPS is not set -+ -+# -+# PPS generators support -+# -+ -+# -+# PTP clock support -+# -+# CONFIG_PTP_1588_CLOCK is not set -+ -+# -+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. -+# -+CONFIG_PINCTRL=y -+ -+# -+# Pin controllers -+# -+CONFIG_PINMUX=y -+CONFIG_PINCONF=y -+CONFIG_GENERIC_PINCONF=y -+# CONFIG_DEBUG_PINCTRL is not set -+# CONFIG_PINCTRL_AMD is not set -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -+CONFIG_GPIOLIB=y -+CONFIG_OF_GPIO=y -+CONFIG_GPIOLIB_IRQCHIP=y -+# CONFIG_DEBUG_GPIO is not set -+CONFIG_GPIO_SYSFS=y -+ -+# -+# Memory mapped GPIO drivers -+# -+# CONFIG_GPIO_74XX_MMIO is not set -+# CONFIG_GPIO_ALTERA is not set -+# CONFIG_GPIO_DWAPB is not set -+# CONFIG_GPIO_EM is not set -+# CONFIG_GPIO_GENERIC_PLATFORM is not set -+# CONFIG_GPIO_GRGPIO is not set -+# CONFIG_GPIO_MOCKUP is not set -+# CONFIG_GPIO_MPC8XXX is not set -+CONFIG_GPIO_PL061=y -+# CONFIG_GPIO_SYSCON is not set -+# CONFIG_GPIO_XILINX is not set -+# CONFIG_GPIO_ZEVIO is not set -+# CONFIG_GPIO_ZX is not set -+ -+# -+# I2C GPIO expanders -+# -+# CONFIG_GPIO_ADP5588 is not set -+# CONFIG_GPIO_ADNP is not set -+# CONFIG_GPIO_MAX7300 is not set -+# CONFIG_GPIO_MAX732X is not set -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+# CONFIG_GPIO_SX150X is not set -+# CONFIG_GPIO_TPIC2810 is not set -+# CONFIG_GPIO_TS4900 is not set -+ -+# -+# MFD GPIO expanders -+# -+# CONFIG_HTC_EGPIO is not set -+ -+# -+# SPI GPIO expanders -+# -+# CONFIG_GPIO_74X164 is not set -+# CONFIG_GPIO_MAX7301 is not set -+# CONFIG_GPIO_MC33880 is not set -+# CONFIG_GPIO_PISOSR is not set -+ -+# -+# SPI or I2C GPIO expanders -+# -+# CONFIG_GPIO_MCP23S08 is not set -+ -+# -+# USB GPIO expanders -+# -+# CONFIG_W1 is not set -+# CONFIG_POWER_AVS is not set -+CONFIG_POWER_RESET=y -+# CONFIG_POWER_RESET_BRCMKONA is not set -+# CONFIG_POWER_RESET_BRCMSTB is not set -+CONFIG_POWER_RESET_GOKE=y -+# CONFIG_POWER_RESET_GPIO is not set -+# CONFIG_POWER_RESET_GPIO_RESTART is not set -+# CONFIG_POWER_RESET_LTC2952 is not set -+# CONFIG_POWER_RESET_RESTART is not set -+# CONFIG_POWER_RESET_VERSATILE is not set -+# CONFIG_POWER_RESET_SYSCON is not set -+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -+# CONFIG_SYSCON_REBOOT_MODE is not set -+CONFIG_POWER_SUPPLY=y -+# CONFIG_POWER_SUPPLY_DEBUG is not set -+# CONFIG_PDA_POWER is not set -+# CONFIG_TEST_POWER is not set -+# CONFIG_BATTERY_DS2780 is not set -+# CONFIG_BATTERY_DS2781 is not set -+# CONFIG_BATTERY_DS2782 is not set -+# CONFIG_BATTERY_SBS is not set -+# CONFIG_BATTERY_BQ27XXX is not set -+# CONFIG_BATTERY_MAX17040 is not set -+# CONFIG_BATTERY_MAX17042 is not set -+# CONFIG_CHARGER_MAX8903 is not set -+# CONFIG_CHARGER_LP8727 is not set -+# CONFIG_CHARGER_GPIO is not set -+# CONFIG_CHARGER_BQ2415X is not set -+# CONFIG_CHARGER_BQ24190 is not set -+# CONFIG_CHARGER_BQ24257 is not set -+# CONFIG_CHARGER_BQ24735 is not set -+# CONFIG_CHARGER_BQ25890 is not set -+# CONFIG_CHARGER_SMB347 is not set -+# CONFIG_BATTERY_GAUGE_LTC2941 is not set -+# CONFIG_CHARGER_RT9455 is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+CONFIG_BCMA_POSSIBLE=y -+ -+# -+# Broadcom specific AMBA -+# -+# CONFIG_BCMA is not set -+ -+# -+# Multifunction device drivers -+# -+CONFIG_MFD_CORE=y -+# CONFIG_MFD_ACT8945A is not set -+# CONFIG_MFD_AS3711 is not set -+# CONFIG_MFD_AS3722 is not set -+# CONFIG_PMIC_ADP5520 is not set -+# CONFIG_MFD_AAT2870_CORE is not set -+# CONFIG_MFD_ATMEL_FLEXCOM is not set -+# CONFIG_MFD_ATMEL_HLCDC is not set -+# CONFIG_MFD_BCM590XX is not set -+# CONFIG_MFD_AXP20X_I2C is not set -+# CONFIG_MFD_CROS_EC is not set -+# CONFIG_MFD_ASIC3 is not set -+# CONFIG_PMIC_DA903X is not set -+# CONFIG_MFD_DA9052_SPI is not set -+# CONFIG_MFD_DA9052_I2C is not set -+# CONFIG_MFD_DA9055 is not set -+# CONFIG_MFD_DA9062 is not set -+# CONFIG_MFD_DA9063 is not set -+# CONFIG_MFD_DA9150 is not set -+# CONFIG_MFD_DLN2 is not set -+# CONFIG_MFD_EXYNOS_LPASS is not set -+# CONFIG_MFD_MC13XXX_SPI is not set -+# CONFIG_MFD_MC13XXX_I2C is not set -+# CONFIG_MFD_HI6421_PMIC is not set -+CONFIG_MFD_GOKE_FMC=y -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_HTC_I2CPLD is not set -+# CONFIG_INTEL_SOC_PMIC is not set -+# CONFIG_MFD_KEMPLD is not set -+# CONFIG_MFD_88PM800 is not set -+# CONFIG_MFD_88PM805 is not set -+# CONFIG_MFD_88PM860X is not set -+# CONFIG_MFD_MAX14577 is not set -+# CONFIG_MFD_MAX77620 is not set -+# CONFIG_MFD_MAX77686 is not set -+# CONFIG_MFD_MAX77693 is not set -+# CONFIG_MFD_MAX77843 is not set -+# CONFIG_MFD_MAX8907 is not set -+# CONFIG_MFD_MAX8925 is not set -+# CONFIG_MFD_MAX8997 is not set -+# CONFIG_MFD_MAX8998 is not set -+# CONFIG_MFD_MT6397 is not set -+# CONFIG_MFD_MENF21BMC is not set -+# CONFIG_EZX_PCAP is not set -+# CONFIG_MFD_VIPERBOARD is not set -+# CONFIG_MFD_RETU is not set -+# CONFIG_MFD_PCF50633 is not set -+# CONFIG_MFD_PM8921_CORE is not set -+# CONFIG_MFD_RT5033 is not set -+# CONFIG_MFD_RTSX_USB is not set -+# CONFIG_MFD_RC5T583 is not set -+# CONFIG_MFD_RK808 is not set -+# CONFIG_MFD_RN5T618 is not set -+# CONFIG_MFD_SEC_CORE is not set -+# CONFIG_MFD_SI476X_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_MFD_SKY81452 is not set -+# CONFIG_MFD_SMSC is not set -+# CONFIG_ABX500_CORE is not set -+# CONFIG_MFD_STMPE is not set -+CONFIG_MFD_SYSCON=y -+# CONFIG_MFD_TI_AM335X_TSCADC is not set -+# CONFIG_MFD_LP3943 is not set -+# CONFIG_MFD_LP8788 is not set -+# CONFIG_MFD_PALMAS is not set -+# CONFIG_TPS6105X is not set -+# CONFIG_TPS65010 is not set -+# CONFIG_TPS6507X is not set -+# CONFIG_MFD_TPS65086 is not set -+# CONFIG_MFD_TPS65090 is not set -+# CONFIG_MFD_TPS65217 is not set -+# CONFIG_MFD_TI_LP873X is not set -+# CONFIG_MFD_TPS65218 is not set -+# CONFIG_MFD_TPS6586X is not set -+# CONFIG_MFD_TPS65910 is not set -+# CONFIG_MFD_TPS65912_I2C is not set -+# CONFIG_MFD_TPS65912_SPI is not set -+# CONFIG_MFD_TPS80031 is not set -+# CONFIG_TWL4030_CORE is not set -+# CONFIG_TWL6040_CORE is not set -+# CONFIG_MFD_WL1273_CORE is not set -+# CONFIG_MFD_LM3533 is not set -+# CONFIG_MFD_TC3589X is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_MFD_T7L66XB is not set -+# CONFIG_MFD_TC6387XB is not set -+# CONFIG_MFD_TC6393XB is not set -+# CONFIG_MFD_ARIZONA_I2C is not set -+# CONFIG_MFD_ARIZONA_SPI is not set -+# CONFIG_MFD_WM8400 is not set -+# CONFIG_MFD_WM831X_I2C is not set -+# CONFIG_MFD_WM831X_SPI is not set -+# CONFIG_MFD_WM8350_I2C is not set -+# CONFIG_MFD_WM8994 is not set -+# CONFIG_REGULATOR is not set -+CONFIG_MEDIA_SUPPORT=y -+ -+# -+# Multimedia core support -+# -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -+# CONFIG_MEDIA_RADIO_SUPPORT is not set -+# CONFIG_MEDIA_SDR_SUPPORT is not set -+# CONFIG_MEDIA_RC_SUPPORT is not set -+# CONFIG_MEDIA_CONTROLLER is not set -+CONFIG_VIDEO_DEV=y -+CONFIG_VIDEO_V4L2=y -+# CONFIG_VIDEO_ADV_DEBUG is not set -+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -+CONFIG_VIDEOBUF2_CORE=y -+CONFIG_VIDEOBUF2_MEMOPS=y -+CONFIG_VIDEOBUF2_VMALLOC=y -+# CONFIG_TTPCI_EEPROM is not set -+ -+# -+# Media drivers -+# -+CONFIG_MEDIA_USB_SUPPORT=y -+ -+# -+# Webcam devices -+# -+CONFIG_USB_VIDEO_CLASS=y -+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -+CONFIG_USB_GSPCA=m -+# CONFIG_USB_M5602 is not set -+# CONFIG_USB_STV06XX is not set -+# CONFIG_USB_GL860 is not set -+# CONFIG_USB_GSPCA_BENQ is not set -+# CONFIG_USB_GSPCA_CONEX is not set -+# CONFIG_USB_GSPCA_CPIA1 is not set -+# CONFIG_USB_GSPCA_DTCS033 is not set -+# CONFIG_USB_GSPCA_ETOMS is not set -+# CONFIG_USB_GSPCA_FINEPIX is not set -+# CONFIG_USB_GSPCA_JEILINJ is not set -+# CONFIG_USB_GSPCA_JL2005BCD is not set -+# CONFIG_USB_GSPCA_KINECT is not set -+# CONFIG_USB_GSPCA_KONICA is not set -+# CONFIG_USB_GSPCA_MARS is not set -+# CONFIG_USB_GSPCA_MR97310A is not set -+# CONFIG_USB_GSPCA_NW80X is not set -+# CONFIG_USB_GSPCA_OV519 is not set -+# CONFIG_USB_GSPCA_OV534 is not set -+# CONFIG_USB_GSPCA_OV534_9 is not set -+# CONFIG_USB_GSPCA_PAC207 is not set -+# CONFIG_USB_GSPCA_PAC7302 is not set -+# CONFIG_USB_GSPCA_PAC7311 is not set -+# CONFIG_USB_GSPCA_SE401 is not set -+# CONFIG_USB_GSPCA_SN9C2028 is not set -+# CONFIG_USB_GSPCA_SN9C20X is not set -+# CONFIG_USB_GSPCA_SONIXB is not set -+# CONFIG_USB_GSPCA_SONIXJ is not set -+# CONFIG_USB_GSPCA_SPCA500 is not set -+# CONFIG_USB_GSPCA_SPCA501 is not set -+# CONFIG_USB_GSPCA_SPCA505 is not set -+# CONFIG_USB_GSPCA_SPCA506 is not set -+# CONFIG_USB_GSPCA_SPCA508 is not set -+# CONFIG_USB_GSPCA_SPCA561 is not set -+# CONFIG_USB_GSPCA_SPCA1528 is not set -+# CONFIG_USB_GSPCA_SQ905 is not set -+# CONFIG_USB_GSPCA_SQ905C is not set -+# CONFIG_USB_GSPCA_SQ930X is not set -+# CONFIG_USB_GSPCA_STK014 is not set -+# CONFIG_USB_GSPCA_STK1135 is not set -+# CONFIG_USB_GSPCA_STV0680 is not set -+# CONFIG_USB_GSPCA_SUNPLUS is not set -+# CONFIG_USB_GSPCA_T613 is not set -+# CONFIG_USB_GSPCA_TOPRO is not set -+# CONFIG_USB_GSPCA_TOUPTEK is not set -+# CONFIG_USB_GSPCA_TV8532 is not set -+# CONFIG_USB_GSPCA_VC032X is not set -+# CONFIG_USB_GSPCA_VICAM is not set -+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -+# CONFIG_USB_GSPCA_ZC3XX is not set -+# CONFIG_USB_PWC is not set -+# CONFIG_VIDEO_CPIA2 is not set -+# CONFIG_USB_ZR364XX is not set -+# CONFIG_USB_STKWEBCAM is not set -+# CONFIG_USB_S2255 is not set -+ -+# -+# Webcam, TV (analog/digital) USB devices -+# -+# CONFIG_VIDEO_EM28XX is not set -+# CONFIG_V4L_PLATFORM_DRIVERS is not set -+# CONFIG_V4L_MEM2MEM_DRIVERS is not set -+# CONFIG_V4L_TEST_DRIVERS is not set -+ -+# -+# Supported MMC/SDIO adapters -+# -+# CONFIG_CYPRESS_FIRMWARE is not set -+ -+# -+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -+# -+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -+ -+# -+# Audio decoders, processors and mixers -+# -+ -+# -+# RDS decoders -+# -+ -+# -+# Video decoders -+# -+ -+# -+# Video and audio decoders -+# -+ -+# -+# Video encoders -+# -+ -+# -+# Camera sensor devices -+# -+ -+# -+# Flash devices -+# -+ -+# -+# Video improvement chips -+# -+ -+# -+# Audio/Video compression chips -+# -+ -+# -+# Miscellaneous helper chips -+# -+ -+# -+# Sensors used on soc_camera driver -+# -+ -+# -+# Tools to develop new frontends -+# -+# CONFIG_DVB_DUMMY_FE is not set -+ -+# -+# Graphics support -+# -+# CONFIG_IMX_IPUV3_CORE is not set -+# CONFIG_DRM is not set -+ -+# -+# ACP (Audio CoProcessor) Configuration -+# -+ -+# -+# Frame buffer Devices -+# -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+CONFIG_FB_CMDLINE=y -+CONFIG_FB_NOTIFY=y -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+# CONFIG_FB_CFB_FILLRECT is not set -+# CONFIG_FB_CFB_COPYAREA is not set -+# CONFIG_FB_CFB_IMAGEBLIT is not set -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_ARMCLCD is not set -+# CONFIG_FB_OPENCORES is not set -+# CONFIG_FB_S1D13XXX is not set -+# CONFIG_FB_SMSCUFX is not set -+# CONFIG_FB_UDL is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_BROADSHEET is not set -+# CONFIG_FB_AUO_K190X is not set -+# CONFIG_FB_SIMPLE is not set -+# CONFIG_FB_SSD1307 is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+ -+# -+# Console display driver support -+# -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE is not set -+# CONFIG_LOGO is not set -+# CONFIG_SOUND is not set -+ -+# -+# HID support -+# -+CONFIG_HID=y -+# CONFIG_HID_BATTERY_STRENGTH is not set -+# CONFIG_HIDRAW is not set -+# CONFIG_UHID is not set -+CONFIG_HID_GENERIC=y -+ -+# -+# Special HID drivers -+# -+# CONFIG_HID_A4TECH is not set -+# CONFIG_HID_ACRUX is not set -+# CONFIG_HID_APPLE is not set -+# CONFIG_HID_APPLEIR is not set -+# CONFIG_HID_AUREAL is not set -+# CONFIG_HID_BELKIN is not set -+# CONFIG_HID_BETOP_FF is not set -+# CONFIG_HID_CHERRY is not set -+# CONFIG_HID_CHICONY is not set -+# CONFIG_HID_CMEDIA is not set -+# CONFIG_HID_CP2112 is not set -+# CONFIG_HID_CYPRESS is not set -+# CONFIG_HID_DRAGONRISE is not set -+# CONFIG_HID_EMS_FF is not set -+# CONFIG_HID_ELECOM is not set -+# CONFIG_HID_ELO is not set -+# CONFIG_HID_EZKEY is not set -+# CONFIG_HID_GEMBIRD is not set -+# CONFIG_HID_GFRM is not set -+# CONFIG_HID_HOLTEK is not set -+# CONFIG_HID_KEYTOUCH is not set -+# CONFIG_HID_KYE is not set -+# CONFIG_HID_UCLOGIC is not set -+# CONFIG_HID_WALTOP is not set -+# CONFIG_HID_GYRATION is not set -+# CONFIG_HID_ICADE is not set -+# CONFIG_HID_TWINHAN is not set -+# CONFIG_HID_KENSINGTON is not set -+# CONFIG_HID_LCPOWER is not set -+# CONFIG_HID_LENOVO is not set -+# CONFIG_HID_LOGITECH is not set -+# CONFIG_HID_MAGICMOUSE is not set -+CONFIG_HID_MICROSOFT=y -+# CONFIG_HID_MONTEREY is not set -+# CONFIG_HID_MULTITOUCH is not set -+# CONFIG_HID_NTRIG is not set -+# CONFIG_HID_ORTEK is not set -+# CONFIG_HID_PANTHERLORD is not set -+# CONFIG_HID_PENMOUNT is not set -+# CONFIG_HID_PETALYNX is not set -+# CONFIG_HID_PICOLCD is not set -+# CONFIG_HID_PLANTRONICS is not set -+# CONFIG_HID_PRIMAX is not set -+# CONFIG_HID_ROCCAT is not set -+# CONFIG_HID_SAITEK is not set -+# CONFIG_HID_SAMSUNG is not set -+# CONFIG_HID_SPEEDLINK is not set -+# CONFIG_HID_STEELSERIES is not set -+# CONFIG_HID_SUNPLUS is not set -+# CONFIG_HID_RMI is not set -+# CONFIG_HID_GREENASIA is not set -+# CONFIG_HID_SMARTJOYPLUS is not set -+# CONFIG_HID_TIVO is not set -+# CONFIG_HID_TOPSEED is not set -+# CONFIG_HID_THRUSTMASTER is not set -+# CONFIG_HID_WACOM is not set -+# CONFIG_HID_XINMO is not set -+# CONFIG_HID_ZEROPLUS is not set -+# CONFIG_HID_ZYDACRON is not set -+# CONFIG_HID_SENSOR_HUB is not set -+# CONFIG_HID_ALPS is not set -+ -+# -+# USB HID support -+# -+CONFIG_USB_HID=y -+# CONFIG_HID_PID is not set -+# CONFIG_USB_HIDDEV is not set -+ -+# -+# I2C HID support -+# -+# CONFIG_I2C_HID is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB=y -+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEFAULT_PERSIST=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+# CONFIG_USB_OTG_WHITELIST is not set -+# CONFIG_USB_MON is not set -+# CONFIG_USB_WUSB_CBAF is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_C67X00_HCD is not set -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_PLATFORM=y -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_OXU210HP_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+# CONFIG_USB_ISP1362_HCD is not set -+# CONFIG_USB_FOTG210_HCD is not set -+# CONFIG_USB_MAX3421_HCD is not set -+# CONFIG_USB_OHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+# CONFIG_USB_HCD_TEST_MODE is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+# CONFIG_USB_WDM is not set -+# CONFIG_USB_TMC is not set -+ -+# -+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may -+# -+ -+# -+# also be needed; see USB_STORAGE Help for more info -+# -+CONFIG_USB_STORAGE=y -+# CONFIG_USB_STORAGE_DEBUG is not set -+# CONFIG_USB_STORAGE_REALTEK is not set -+# CONFIG_USB_STORAGE_DATAFAB is not set -+# CONFIG_USB_STORAGE_FREECOM is not set -+# CONFIG_USB_STORAGE_ISD200 is not set -+# CONFIG_USB_STORAGE_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_ONETOUCH is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -+# CONFIG_USB_STORAGE_ENE_UB6250 is not set -+# CONFIG_USB_UAS is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USBIP_CORE is not set -+# CONFIG_USB_MUSB_HDRC is not set -+CONFIG_USB_DWC3=y -+# CONFIG_USB_DWC3_HOST is not set -+# CONFIG_USB_DWC3_GADGET is not set -+CONFIG_USB_DWC3_DUAL_ROLE=y -+ -+# -+# Platform Glue Driver Support -+# -+CONFIG_USB_DWC3_OF_SIMPLE=y -+# CONFIG_USB_DWC2 is not set -+# CONFIG_USB_CHIPIDEA is not set -+# CONFIG_USB_ISP1760 is not set -+ -+# -+# USB port drivers -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_SEVSEG is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+# CONFIG_USB_EHSET_TEST_FIXTURE is not set -+# CONFIG_USB_ISIGHTFW is not set -+# CONFIG_USB_YUREX is not set -+# CONFIG_USB_EZUSB_FX2 is not set -+# CONFIG_USB_HSIC_USB3503 is not set -+# CONFIG_USB_HSIC_USB4604 is not set -+# CONFIG_USB_LINK_LAYER_TEST is not set -+ -+# -+# USB Physical Layer drivers -+# -+# CONFIG_USB_PHY is not set -+# CONFIG_NOP_USB_XCEIV is not set -+# CONFIG_USB_GPIO_VBUS is not set -+# CONFIG_USB_ISP1301 is not set -+# CONFIG_USB_ULPI is not set -+CONFIG_USB_GADGET=y -+# CONFIG_USB_GADGET_DEBUG is not set -+# CONFIG_USB_GADGET_DEBUG_FILES is not set -+CONFIG_USB_GADGET_VBUS_DRAW=2 -+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -+ -+# -+# USB Peripheral Controller -+# -+# CONFIG_USB_FUSB300 is not set -+# CONFIG_USB_FOTG210_UDC is not set -+# CONFIG_USB_GR_UDC is not set -+# CONFIG_USB_R8A66597 is not set -+# CONFIG_USB_PXA27X is not set -+# CONFIG_USB_MV_UDC is not set -+# CONFIG_USB_MV_U3D is not set -+# CONFIG_USB_M66592 is not set -+# CONFIG_USB_BDC_UDC is not set -+# CONFIG_USB_NET2272 is not set -+# CONFIG_USB_GADGET_XILINX is not set -+# CONFIG_USB_DUMMY_HCD is not set -+CONFIG_USB_LIBCOMPOSITE=m -+CONFIG_USB_F_ACM=m -+CONFIG_USB_U_SERIAL=m -+CONFIG_USB_U_ETHER=m -+CONFIG_USB_F_ECM=m -+CONFIG_USB_F_RNDIS=m -+CONFIG_USB_F_MASS_STORAGE=m -+CONFIG_USB_CONFIGFS=m -+# CONFIG_USB_CONFIGFS_SERIAL is not set -+CONFIG_USB_CONFIGFS_ACM=y -+# CONFIG_USB_CONFIGFS_OBEX is not set -+# CONFIG_USB_CONFIGFS_NCM is not set -+CONFIG_USB_CONFIGFS_ECM=y -+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set -+CONFIG_USB_CONFIGFS_RNDIS=y -+# CONFIG_USB_CONFIGFS_EEM is not set -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+# CONFIG_USB_CONFIGFS_F_LB_SS is not set -+# CONFIG_USB_CONFIGFS_F_FS is not set -+# CONFIG_USB_CONFIGFS_F_HID is not set -+# CONFIG_USB_CONFIGFS_F_UVC is not set -+# CONFIG_USB_CONFIGFS_F_PRINTER is not set -+# CONFIG_USB_ULPI_BUS is not set -+# CONFIG_UWB is not set -+CONFIG_MMC=y -+# CONFIG_MMC_DEBUG is not set -+CONFIG_PWRSEQ_EMMC=y -+CONFIG_PWRSEQ_SIMPLE=y -+ -+# -+# MMC/SD/SDIO Card Drivers -+# -+CONFIG_MMC_BLOCK=y -+CONFIG_MMC_BLOCK_MINORS=8 -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+# CONFIG_MMC_TEST is not set -+ -+# -+# MMC/SD/SDIO Host Controller Drivers -+# -+# CONFIG_MMC_ARMMMCI is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_MMC_SDHCI_OF_ARASAN is not set -+# CONFIG_MMC_SDHCI_OF_AT91 is not set -+CONFIG_MMC_SDHCI_GOKE=y -+# CONFIG_MMC_SDHCI_F_SDH30 is not set -+# CONFIG_MMC_SPI is not set -+# CONFIG_MMC_DW is not set -+# CONFIG_MMC_VUB300 is not set -+# CONFIG_MMC_USHC is not set -+# CONFIG_MMC_USDHI6ROL0 is not set -+# CONFIG_MMC_MTK is not set -+# CONFIG_MMC_CQ_HCI is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_EDAC_ATOMIC_SCRUB=y -+CONFIG_EDAC_SUPPORT=y -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+CONFIG_RTC_SYSTOHC=y -+CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+# CONFIG_RTC_DRV_ABB5ZES3 is not set -+# CONFIG_RTC_DRV_ABX80X is not set -+# CONFIG_RTC_DRV_DS1307 is not set -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_HYM8563 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_ISL12022 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8523 is not set -+# CONFIG_RTC_DRV_PCF85063 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+# CONFIG_RTC_DRV_BQ32K is not set -+# CONFIG_RTC_DRV_S35390A is not set -+# CONFIG_RTC_DRV_FM3130 is not set -+# CONFIG_RTC_DRV_RX8010 is not set -+# CONFIG_RTC_DRV_RX8581 is not set -+# CONFIG_RTC_DRV_RX8025 is not set -+# CONFIG_RTC_DRV_EM3027 is not set -+# CONFIG_RTC_DRV_RV8803 is not set -+ -+# -+# SPI RTC drivers -+# -+# CONFIG_RTC_DRV_M41T93 is not set -+# CONFIG_RTC_DRV_M41T94 is not set -+# CONFIG_RTC_DRV_DS1302 is not set -+# CONFIG_RTC_DRV_DS1305 is not set -+# CONFIG_RTC_DRV_DS1343 is not set -+# CONFIG_RTC_DRV_DS1347 is not set -+# CONFIG_RTC_DRV_DS1390 is not set -+# CONFIG_RTC_DRV_MAX6916 is not set -+# CONFIG_RTC_DRV_R9701 is not set -+# CONFIG_RTC_DRV_RX4581 is not set -+# CONFIG_RTC_DRV_RX6110 is not set -+# CONFIG_RTC_DRV_RS5C348 is not set -+# CONFIG_RTC_DRV_MAX6902 is not set -+# CONFIG_RTC_DRV_PCF2123 is not set -+# CONFIG_RTC_DRV_MCP795 is not set -+CONFIG_RTC_I2C_AND_SPI=y -+ -+# -+# SPI and I2C RTC drivers -+# -+# CONFIG_RTC_DRV_DS3232 is not set -+# CONFIG_RTC_DRV_PCF2127 is not set -+# CONFIG_RTC_DRV_RV3029C2 is not set -+ -+# -+# Platform RTC drivers -+# -+CONFIG_RTC_DRV_GOKE=y -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1685_FAMILY is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_DS2404 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_MSM6242 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_RP5C01 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+# CONFIG_RTC_DRV_ZYNQMP is not set -+ -+# -+# on-CPU RTC drivers -+# -+# CONFIG_RTC_DRV_PL030 is not set -+# CONFIG_RTC_DRV_PL031 is not set -+# CONFIG_RTC_DRV_SNVS is not set -+ -+# -+# HID Sensor RTC drivers -+# -+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -+# CONFIG_DMADEVICES is not set -+ -+# -+# DMABUF options -+# -+# CONFIG_SYNC_FILE is not set -+# CONFIG_AUXDISPLAY is not set -+# CONFIG_UIO is not set -+# CONFIG_VIRT_DRIVERS is not set -+ -+# -+# Virtio drivers -+# -+# CONFIG_VIRTIO_MMIO is not set -+ -+# -+# Microsoft Hyper-V guest support -+# -+# CONFIG_STAGING is not set -+# CONFIG_GOLDFISH is not set -+# CONFIG_CHROME_PLATFORMS is not set -+CONFIG_CLKDEV_LOOKUP=y -+CONFIG_HAVE_CLK_PREPARE=y -+CONFIG_COMMON_CLK=y -+ -+# -+# Common Clock Framework -+# -+# CONFIG_COMMON_CLK_SI5351 is not set -+# CONFIG_COMMON_CLK_SI514 is not set -+# CONFIG_COMMON_CLK_SI570 is not set -+# CONFIG_COMMON_CLK_CDCE706 is not set -+# CONFIG_COMMON_CLK_CDCE925 is not set -+# CONFIG_COMMON_CLK_CS2000_CP is not set -+# CONFIG_CLK_QORIQ is not set -+# CONFIG_COMMON_CLK_NXP is not set -+# CONFIG_COMMON_CLK_PXA is not set -+# CONFIG_COMMON_CLK_PIC32 is not set -+CONFIG_COMMON_CLK_GK7605V100=y -+CONFIG_RESET_GOKE=y -+ -+# -+# Hardware Spinlock drivers -+# -+ -+# -+# Clock Source drivers -+# -+CONFIG_CLKSRC_OF=y -+CONFIG_CLKSRC_PROBE=y -+CONFIG_CLKSRC_MMIO=y -+CONFIG_ARM_ARCH_TIMER=y -+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set -+CONFIG_ARM_TIMER_SP804=y -+# CONFIG_ATMEL_PIT is not set -+# CONFIG_SH_TIMER_CMT is not set -+# CONFIG_SH_TIMER_MTU2 is not set -+# CONFIG_SH_TIMER_TMU is not set -+# CONFIG_EM_TIMER_STI is not set -+# CONFIG_MAILBOX is not set -+# CONFIG_IOMMU_SUPPORT is not set -+ -+# -+# Remoteproc drivers -+# -+# CONFIG_STE_MODEM_RPROC is not set -+ -+# -+# Rpmsg drivers -+# -+ -+# -+# SOC (System On Chip) specific Drivers -+# -+ -+# -+# Broadcom SoC drivers -+# -+# CONFIG_SOC_BRCMSTB is not set -+# CONFIG_SUNXI_SRAM is not set -+# CONFIG_SOC_TI is not set -+# CONFIG_PM_DEVFREQ is not set -+# CONFIG_EXTCON is not set -+# CONFIG_MEMORY is not set -+# CONFIG_IIO is not set -+# CONFIG_PWM is not set -+CONFIG_IRQCHIP=y -+CONFIG_ARM_GIC=y -+CONFIG_ARM_GIC_MAX_NR=1 -+# CONFIG_IPACK_BUS is not set -+CONFIG_RESET_CONTROLLER=y -+# CONFIG_RESET_ATH79 is not set -+# CONFIG_RESET_BERLIN is not set -+# CONFIG_RESET_LPC18XX is not set -+# CONFIG_RESET_MESON is not set -+# CONFIG_RESET_PISTACHIO is not set -+# CONFIG_RESET_SOCFPGA is not set -+# CONFIG_RESET_STM32 is not set -+# CONFIG_RESET_SUNXI is not set -+# CONFIG_TI_SYSCON_RESET is not set -+# CONFIG_RESET_ZYNQ is not set -+# CONFIG_FMC is not set -+ -+# -+# PHY Subsystem -+# -+CONFIG_GENERIC_PHY=y -+# CONFIG_PHY_PXA_28NM_HSIC is not set -+# CONFIG_PHY_PXA_28NM_USB2 is not set -+# CONFIG_BCM_KONA_USB2_PHY is not set -+CONFIG_PHY_GOKE_USBP2=y -+# CONFIG_USB_MODE_OPTION is not set -+# CONFIG_POWERCAP is not set -+# CONFIG_MCB is not set -+ -+# -+# Performance monitor support -+# -+# CONFIG_RAS is not set -+ -+# -+# Android -+# -+# CONFIG_ANDROID is not set -+# CONFIG_NVMEM is not set -+# CONFIG_STM is not set -+# CONFIG_INTEL_TH is not set -+ -+# -+# FPGA Configuration Support -+# -+# CONFIG_FPGA is not set -+ -+# -+# goke driver support -+# -+ -+# -+# Firmware Drivers -+# -+# CONFIG_FIRMWARE_MEMMAP is not set -+# CONFIG_FW_CFG_SYSFS is not set -+CONFIG_HAVE_ARM_SMCCC=y -+ -+# -+# File systems -+# -+CONFIG_DCACHE_WORD_ACCESS=y -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_USE_FOR_EXT2=y -+# CONFIG_EXT4_FS_POSIX_ACL is not set -+# CONFIG_EXT4_FS_SECURITY is not set -+# CONFIG_EXT4_ENCRYPTION is not set -+# CONFIG_EXT4_DEBUG is not set -+CONFIG_JBD2=y -+# CONFIG_JBD2_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_XFS_FS is not set -+# CONFIG_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+# CONFIG_NILFS2_FS is not set -+# CONFIG_F2FS_FS is not set -+CONFIG_FS_POSIX_ACL=y -+CONFIG_EXPORTFS=y -+# CONFIG_EXPORTFS_BLOCK_OPS is not set -+CONFIG_FILE_LOCKING=y -+CONFIG_MANDATORY_FILE_LOCKING=y -+# CONFIG_FS_ENCRYPTION is not set -+CONFIG_FSNOTIFY=y -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_FANOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_QUOTACTL is not set -+# CONFIG_AUTOFS4_FS is not set -+# CONFIG_FUSE_FS is not set -+# CONFIG_OVERLAY_FS is not set -+ -+# -+# Caches -+# -+# CONFIG_FSCACHE is not set -+ -+# -+# CD-ROM/DVD Filesystems -+# -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_FAT_DEFAULT_UTF8 is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_PROC_PAGE_MONITOR=y -+# CONFIG_PROC_CHILDREN is not set -+CONFIG_KERNFS=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_TMPFS_XATTR=y -+# CONFIG_HUGETLB_PAGE is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ORANGEFS_FS is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_ECRYPT_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_YAFFS_FS=y -+CONFIG_YAFFS_YAFFS1=y -+# CONFIG_YAFFS_9BYTE_TAGS is not set -+# CONFIG_YAFFS_DOES_ECC is not set -+CONFIG_YAFFS_YAFFS2=y -+CONFIG_YAFFS_AUTO_YAFFS2=y -+# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set -+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -+# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set -+# CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING is not set -+# CONFIG_YAFFS_DISABLE_BACKGROUND is not set -+# CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING is not set -+CONFIG_YAFFS_XATTR=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+# CONFIG_JFFS2_LZMA is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_UBIFS_FS=y -+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -+CONFIG_UBIFS_FS_LZO=y -+CONFIG_UBIFS_FS_ZLIB=y -+# CONFIG_UBIFS_ATIME_SUPPORT is not set -+# CONFIG_LOGFS is not set -+CONFIG_CRAMFS=y -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX6FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_PSTORE is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+# CONFIG_NFS_SWAP is not set -+# CONFIG_NFS_V4_1 is not set -+CONFIG_ROOT_NFS=y -+# CONFIG_NFS_USE_LEGACY_DNS is not set -+CONFIG_NFS_USE_KERNEL_DNS=y -+# CONFIG_NFSD is not set -+CONFIG_GRACE_PERIOD=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_ACL_SUPPORT=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+CONFIG_SUNRPC_GSS=y -+# CONFIG_SUNRPC_DEBUG is not set -+# CONFIG_CEPH_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=m -+CONFIG_NLS_CODEPAGE_775=m -+CONFIG_NLS_CODEPAGE_850=m -+CONFIG_NLS_CODEPAGE_852=m -+CONFIG_NLS_CODEPAGE_855=m -+CONFIG_NLS_CODEPAGE_857=m -+CONFIG_NLS_CODEPAGE_860=m -+CONFIG_NLS_CODEPAGE_861=m -+CONFIG_NLS_CODEPAGE_862=m -+CONFIG_NLS_CODEPAGE_863=m -+CONFIG_NLS_CODEPAGE_864=m -+CONFIG_NLS_CODEPAGE_865=m -+CONFIG_NLS_CODEPAGE_866=m -+CONFIG_NLS_CODEPAGE_869=m -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=m -+CONFIG_NLS_CODEPAGE_932=m -+CONFIG_NLS_CODEPAGE_949=m -+CONFIG_NLS_CODEPAGE_874=m -+CONFIG_NLS_ISO8859_8=m -+CONFIG_NLS_CODEPAGE_1250=m -+CONFIG_NLS_CODEPAGE_1251=m -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=m -+CONFIG_NLS_ISO8859_3=m -+CONFIG_NLS_ISO8859_4=m -+CONFIG_NLS_ISO8859_5=m -+CONFIG_NLS_ISO8859_6=m -+CONFIG_NLS_ISO8859_7=m -+CONFIG_NLS_ISO8859_9=m -+CONFIG_NLS_ISO8859_13=m -+CONFIG_NLS_ISO8859_14=m -+CONFIG_NLS_ISO8859_15=m -+CONFIG_NLS_KOI8_R=m -+CONFIG_NLS_KOI8_U=m -+# CONFIG_NLS_MAC_ROMAN is not set -+# CONFIG_NLS_MAC_CELTIC is not set -+# CONFIG_NLS_MAC_CENTEURO is not set -+# CONFIG_NLS_MAC_CROATIAN is not set -+# CONFIG_NLS_MAC_CYRILLIC is not set -+# CONFIG_NLS_MAC_GAELIC is not set -+# CONFIG_NLS_MAC_GREEK is not set -+# CONFIG_NLS_MAC_ICELAND is not set -+# CONFIG_NLS_MAC_INUIT is not set -+# CONFIG_NLS_MAC_ROMANIAN is not set -+# CONFIG_NLS_MAC_TURKISH is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+ -+# -+# printk and dmesg options -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -+# CONFIG_BOOT_PRINTK_DELAY is not set -+ -+# -+# Compile-time checks and compiler options -+# -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_STRIP_ASM_SYMS is not set -+# CONFIG_READABLE_ASM is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_PAGE_OWNER is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_SECTION_MISMATCH is not set -+CONFIG_SECTION_MISMATCH_WARN_ONLY=y -+CONFIG_FRAME_POINTER=y -+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -+# CONFIG_MAGIC_SYSRQ is not set -+CONFIG_DEBUG_KERNEL=y -+ -+# -+# Memory Debugging -+# -+# CONFIG_PAGE_EXTENSION is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_PAGE_POISONING is not set -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_HAVE_DEBUG_KMEMLEAK=y -+# CONFIG_DEBUG_KMEMLEAK is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_VM is not set -+CONFIG_DEBUG_MEMORY_INIT=y -+# CONFIG_DEBUG_SHIRQ is not set -+ -+# -+# Debug Lockups and Hangs -+# -+# CONFIG_LOCKUP_DETECTOR is not set -+# CONFIG_DETECT_HUNG_TASK is not set -+# CONFIG_WQ_WATCHDOG is not set -+# CONFIG_PANIC_ON_OOPS is not set -+CONFIG_PANIC_ON_OOPS_VALUE=0 -+CONFIG_PANIC_TIMEOUT=0 -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHED_INFO is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_SCHED_STACK_END_CHECK is not set -+# CONFIG_DEBUG_TIMEKEEPING is not set -+# CONFIG_TIMER_STATS is not set -+ -+# -+# Lock Debugging (spinlocks, mutexes, etc...) -+# -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+# CONFIG_DEBUG_ATOMIC_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_LOCK_TORTURE_TEST is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_PI_LIST is not set -+# CONFIG_DEBUG_SG is not set -+# CONFIG_DEBUG_NOTIFIERS is not set -+# CONFIG_DEBUG_CREDENTIALS is not set -+ -+# -+# RCU Debugging -+# -+# CONFIG_PROVE_RCU is not set -+# CONFIG_SPARSE_RCU_POINTER is not set -+# CONFIG_TORTURE_TEST is not set -+# CONFIG_RCU_PERF_TEST is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_TRACE is not set -+# CONFIG_RCU_EQS_DEBUG is not set -+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_NOTIFIER_ERROR_INJECTION is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_HAVE_FUNCTION_TRACER=y -+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -+CONFIG_HAVE_DYNAMIC_FTRACE=y -+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -+CONFIG_HAVE_C_RECORDMCOUNT=y -+CONFIG_TRACING_SUPPORT=y -+# CONFIG_FTRACE is not set -+ -+# -+# Runtime Testing -+# -+# CONFIG_TEST_LIST_SORT is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_RBTREE_TEST is not set -+# CONFIG_INTERVAL_TREE_TEST is not set -+# CONFIG_PERCPU_TEST is not set -+# CONFIG_ATOMIC64_SELFTEST is not set -+# CONFIG_TEST_HEXDUMP is not set -+# CONFIG_TEST_STRING_HELPERS is not set -+# CONFIG_TEST_KSTRTOX is not set -+# CONFIG_TEST_PRINTF is not set -+# CONFIG_TEST_BITMAP is not set -+# CONFIG_TEST_UUID is not set -+# CONFIG_TEST_RHASHTABLE is not set -+# CONFIG_TEST_HASH is not set -+# CONFIG_DMA_API_DEBUG is not set -+# CONFIG_TEST_LKM is not set -+# CONFIG_TEST_USER_COPY is not set -+# CONFIG_TEST_BPF is not set -+# CONFIG_TEST_FIRMWARE is not set -+# CONFIG_TEST_UDELAY is not set -+# CONFIG_MEMTEST is not set -+# CONFIG_TEST_STATIC_KEYS is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+# CONFIG_ARCH_WANTS_UBSAN_NO_NULL is not set -+# CONFIG_UBSAN is not set -+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -+CONFIG_STRICT_DEVMEM=y -+# CONFIG_IO_STRICT_DEVMEM is not set -+# CONFIG_ARM_PTDUMP is not set -+# CONFIG_ARM_UNWIND is not set -+# CONFIG_DEBUG_USER is not set -+# CONFIG_DEBUG_LL is not set -+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -+# CONFIG_DEBUG_UART_8250 is not set -+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -+# CONFIG_PID_IN_CONTEXTIDR is not set -+# CONFIG_DEBUG_SET_MODULE_RONX is not set -+# CONFIG_CORESIGHT is not set -+ -+# -+# Security options -+# -+CONFIG_KEYS=y -+# CONFIG_PERSISTENT_KEYRINGS is not set -+# CONFIG_ENCRYPTED_KEYS is not set -+# CONFIG_KEY_DH_OPERATIONS is not set -+# CONFIG_SECURITY_DMESG_RESTRICT is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -+CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -+# CONFIG_HARDENED_USERCOPY is not set -+CONFIG_DEFAULT_SECURITY_DAC=y -+CONFIG_DEFAULT_SECURITY="" -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_ALGAPI2=y -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_AEAD2=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_BLKCIPHER2=y -+CONFIG_CRYPTO_HASH=y -+CONFIG_CRYPTO_HASH2=y -+CONFIG_CRYPTO_RNG=m -+CONFIG_CRYPTO_RNG2=y -+CONFIG_CRYPTO_RNG_DEFAULT=m -+CONFIG_CRYPTO_AKCIPHER2=y -+CONFIG_CRYPTO_KPP2=y -+# CONFIG_CRYPTO_RSA is not set -+# CONFIG_CRYPTO_DH is not set -+# CONFIG_CRYPTO_ECDH is not set -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_MANAGER2=y -+# CONFIG_CRYPTO_USER is not set -+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -+CONFIG_CRYPTO_GF128MUL=m -+CONFIG_CRYPTO_NULL=m -+CONFIG_CRYPTO_NULL2=y -+CONFIG_CRYPTO_WORKQUEUE=y -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_MCRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -+CONFIG_CRYPTO_SEQIV=m -+CONFIG_CRYPTO_ECHAINIV=m -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+CONFIG_CRYPTO_CTR=m -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_KEYWRAP is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_CMAC is not set -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_VMAC is not set -+ -+# -+# Digest -+# -+CONFIG_CRYPTO_CRC32C=y -+# CONFIG_CRYPTO_CRC32 is not set -+CONFIG_CRYPTO_CRCT10DIF=y -+CONFIG_CRYPTO_GHASH=m -+# CONFIG_CRYPTO_POLY1305 is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+CONFIG_CRYPTO_SHA1=y -+CONFIG_CRYPTO_SHA256=y -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_SHA3 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+CONFIG_CRYPTO_AES=y -+# CONFIG_CRYPTO_ANUBIS is not set -+CONFIG_CRYPTO_ARC4=y -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_CHACHA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+# CONFIG_CRYPTO_842 is not set -+# CONFIG_CRYPTO_LZ4 is not set -+# CONFIG_CRYPTO_LZ4HC is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+CONFIG_CRYPTO_DRBG_MENU=m -+CONFIG_CRYPTO_DRBG_HMAC=y -+# CONFIG_CRYPTO_DRBG_HASH is not set -+# CONFIG_CRYPTO_DRBG_CTR is not set -+CONFIG_CRYPTO_DRBG=m -+CONFIG_CRYPTO_JITTERENTROPY=m -+# CONFIG_CRYPTO_USER_API_HASH is not set -+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -+# CONFIG_CRYPTO_USER_API_RNG is not set -+# CONFIG_CRYPTO_USER_API_AEAD is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_ASYMMETRIC_KEY_TYPE is not set -+ -+# -+# Certificates for signature checking -+# -+# CONFIG_ARM_CRYPTO is not set -+# CONFIG_BINARY_PRINTF is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_HAVE_ARCH_BITREVERSE=y -+CONFIG_RATIONAL=y -+CONFIG_GENERIC_STRNCPY_FROM_USER=y -+CONFIG_GENERIC_STRNLEN_USER=y -+CONFIG_GENERIC_NET_UTILS=y -+CONFIG_GENERIC_PCI_IOMAP=y -+CONFIG_GENERIC_IO=y -+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC16=y -+CONFIG_CRC_T10DIF=y -+CONFIG_CRC_ITU_T=y -+CONFIG_CRC32=y -+# CONFIG_CRC32_SELFTEST is not set -+CONFIG_CRC32_SLICEBY8=y -+# CONFIG_CRC32_SLICEBY4 is not set -+# CONFIG_CRC32_SARWATE is not set -+# CONFIG_CRC32_BIT is not set -+# CONFIG_CRC7 is not set -+CONFIG_LIBCRC32C=y -+# CONFIG_CRC8 is not set -+# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -+# CONFIG_RANDOM32_SELFTEST is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_LZO_COMPRESS=y -+CONFIG_LZO_DECOMPRESS=y -+CONFIG_LZ4_DECOMPRESS=y -+CONFIG_XZ_DEC=y -+CONFIG_XZ_DEC_X86=y -+CONFIG_XZ_DEC_POWERPC=y -+CONFIG_XZ_DEC_IA64=y -+CONFIG_XZ_DEC_ARM=y -+CONFIG_XZ_DEC_ARMTHUMB=y -+CONFIG_XZ_DEC_SPARC=y -+CONFIG_XZ_DEC_BCJ=y -+# CONFIG_XZ_DEC_TEST is not set -+CONFIG_DECOMPRESS_GZIP=y -+CONFIG_DECOMPRESS_LZ4=y -+CONFIG_GENERIC_ALLOCATOR=y -+CONFIG_ASSOCIATIVE_ARRAY=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT_MAP=y -+CONFIG_HAS_DMA=y -+CONFIG_DQL=y -+CONFIG_NLATTR=y -+# CONFIG_CORDIC is not set -+# CONFIG_DDR is not set -+# CONFIG_IRQ_POLL is not set -+CONFIG_LIBFDT=y -+CONFIG_OID_REGISTRY=y -+# CONFIG_SG_SPLIT is not set -+CONFIG_SG_POOL=y -+CONFIG_ARCH_HAS_SG_CHAIN=y -+CONFIG_SBITMAP=y -+# CONFIG_VIRTUALIZATION is not set ---- linux-4.9.37/arch/arm/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/Kconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -330,7 +330,7 @@ - depends on MMU - select ARM_HAS_SG_CHAIN - select ARM_PATCH_PHYS_VIRT -- select AUTO_ZRELADDR -+ #select AUTO_ZRELADDR - select CLKSRC_OF - select COMMON_CLK - select GENERIC_CLOCKEVENTS -@@ -747,6 +747,8 @@ - - source "arch/arm/mach-hisi/Kconfig" - -+source "arch/arm/mach-goke/Kconfig" -+ - source "arch/arm/mach-integrator/Kconfig" - - source "arch/arm/mach-iop32x/Kconfig" ---- linux-4.9.37/arch/arm/Kconfig.debug 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/Kconfig.debug 2021-06-07 13:01:32.000000000 +0300 -@@ -287,6 +287,38 @@ - Say Y here if you want kernel low-level debugging support - on HI3620 UART. - -+ config DEBUG_GK7205V200_UART -+ bool "Goke GK7205V200 Debug UART" -+ depends on ARCH_GK7205V200 -+ select DEBUG_UART_PL01X -+ help -+ Say Y here if you want kernel low-level debugging support -+ on GK7205V200 UART. -+ -+ config DEBUG_GK7205V300_UART -+ bool "Goke GK7205V300 Debug UART" -+ depends on ARCH_GK7205V300 -+ select DEBUG_UART_PL01X -+ help -+ Say Y here if you want kernel low-level debugging support -+ on GK7205V300 UART. -+ -+ config DEBUG_GK7202V300_UART -+ bool "Goke GK7202V300 Debug UART" -+ depends on ARCH_GK7202V300 -+ select DEBUG_UART_PL01X -+ help -+ Say Y here if you want kernel low-level debugging support -+ on GK7202V300 UART. -+ -+ config DEBUG_GK7605V100_UART -+ bool "Goke GK7605V100 Debug UART" -+ depends on ARCH_GK7605V100 -+ select DEBUG_UART_PL01X -+ help -+ Say Y here if you want kernel low-level debugging support -+ on GK7605V100 UART. -+ - config DEBUG_HIGHBANK_UART - bool "Kernel low-level debugging messages via Highbank UART" - depends on ARCH_HIGHBANK -@@ -1530,6 +1562,9 @@ - default 0xf991e000 if DEBUG_QCOM_UARTDM - default 0xfc00c000 if DEBUG_AT91_SAMA5D4_USART3 - default 0xfcb00000 if DEBUG_HI3620_UART -+ default 0x12040000 if DEBUG_GK7205V200_UART -+ default 0x12040000 if DEBUG_GK7205V300_UART -+ default 0x12040000 if DEBUG_GK7202V300_UART - default 0xfd883000 if DEBUG_ALPINE_UART0 - default 0xfe800000 if ARCH_IOP32X - default 0xff690000 if DEBUG_RK32_UART2 -@@ -1619,6 +1654,9 @@ - default 0xfe300000 if DEBUG_BCM_KONA_UART - default 0xfe800000 if ARCH_IOP32X - default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HIX5HD2_UART -+ default 0xfe440000 if DEBUG_GK7205V200_UART -+ default 0xfe440000 if DEBUG_GK7205V300_UART -+ default 0xfe440000 if DEBUG_GK7202V300_UART - default 0xfeb24000 if DEBUG_RK3X_UART0 - default 0xfeb26000 if DEBUG_RK3X_UART1 - default 0xfeb30c00 if DEBUG_KEYSTONE_UART0 ---- linux-4.9.37/arch/arm/kvm/handle_exit.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/kvm/handle_exit.c 2021-06-07 13:01:32.000000000 +0300 -@@ -21,7 +21,7 @@ - #include - #include - #include --#include -+#include - #include - - #include "trace.h" ---- linux-4.9.37/arch/arm/mach-goke/include/mach/io.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/include/mach/io.h 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,6 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#ifndef __ASM_ARM_ARCH_IO_H -+#define __ASM_ARM_ARCH_IO_H -+#endif ---- linux-4.9.37/arch/arm/mach-goke/include/mach/platform.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/include/mach/platform.h 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,6 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#ifndef __GOKE_PLATFORM_H__ -+#define __GOKE_PLATFORM_H__ -+#endif /* End of __GOKE_PLATFORM_H__ */ ---- linux-4.9.37/arch/arm/mach-goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/Kconfig 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,71 @@ -+config ARCH_GOKE -+ bool "Goke SoC Support" -+ select ARM_AMBA -+ select ARM_GIC if ARCH_MULTI_V7 -+ select ARM_VIC if ARCH_MULTI_V5 -+ select ARM_TIMER_SP804 -+ select POWER_RESET -+ select POWER_RESET_GOKE -+ select POWER_SUPPLY -+ -+if ARCH_GOKE -+ -+menu "Goke platform type" -+ -+config ARCH_GK7205V200 -+ bool "Goke GK7205V200 Cortex-A7 family" -+ depends on ARCH_MULTI_V7 -+ select HAVE_ARM_ARCH_TIMER -+ select PINCTRL -+ select POWER_RESET_GOKE -+ help -+ Support for Goke GK7205V200 Soc family. -+ -+config ARCH_GK7205V300 -+ bool "Goke GK7205V300 Cortex-A7 family" -+ depends on ARCH_MULTI_V7 -+ select HAVE_ARM_ARCH_TIMER -+ select PINCTRL -+ select POWER_RESET_GOKE -+ help -+ Support for Goke GK7205V300 Soc family. -+ -+config ARCH_GK7202V300 -+ bool "Goke GK7202V300 Cortex-A7 family" -+ depends on ARCH_MULTI_V7 -+ select HAVE_ARM_ARCH_TIMER -+ select PINCTRL -+ select POWER_RESET_GOKE -+ help -+ Support for Goke GK7202V300 Soc family. -+ -+config ARCH_GK7605V100 -+ bool "Goke GK7605V100 Cortex-A7 family" -+ depends on ARCH_MULTI_V7 -+ select HAVE_ARM_ARCH_TIMER -+ select PINCTRL -+ select POWER_RESET_GOKE -+ help -+ Support for Goke GK7605V100 Soc family. -+ -+config GOKE_MC -+ bool "Goke mc platform solution" -+ default n -+ help -+ support for Goke mc platform solution -+ -+config BSP_ZRELADDR -+ hex 'zreladdr' -+ default "0x40008000" if ARCH_GK7205V200 || ARCH_GK7205V300 || ARCH_GK7202V300 || ARCH_GK7605V100 -+ -+config BSP_PARAMS_PHYS -+ hex 'params_phys' -+ default "0x00000100" -+ -+config BSP_INITRD_PHYS -+ hex 'initrd_phys' -+ default "0x00800000" -+ -+endmenu -+ -+endif ---- linux-4.9.37/arch/arm/mach-goke/mach-common.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/mach-common.h 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,12 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#ifndef __SMP_COMMON_H -+#define __SMP_COMMON_H -+ -+#ifdef CONFIG_SMP -+void bsp_set_cpu(unsigned int cpu, bool enable); -+void __init bsp_smp_prepare_cpus(unsigned int max_cpus); -+int bsp_boot_secondary(unsigned int cpu, struct task_struct *idle); -+#endif /* CONFIG_SMP */ -+#endif /* __SMP_COMMON_H */ ---- linux-4.9.37/arch/arm/mach-goke/mach-gk7202v300.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/mach-gk7202v300.c 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+ -+#include "mach-common.h" -+ -+#ifdef CONFIG_SMP -+ -+#define REG_CPU_SRST_CRG 0x78 -+#define CPU1_SRST_REQ BIT(2) -+#define DBG1_SRST_REQ BIT(4) -+ -+void bsp_set_cpu(unsigned int cpu, bool enable) -+{ -+ struct device_node *np = NULL; -+ unsigned int regval; -+ void __iomem *crg_base; -+ -+ np = of_find_compatible_node(NULL, NULL, "goke,gk7202v300-clock"); -+ if (!np) { -+ pr_err("failed to find goke clock node\n"); -+ return; -+ } -+ -+ crg_base = of_iomap(np, 0); -+ if (!crg_base) { -+ pr_err("failed to map address\n"); -+ return; -+ } -+ -+ if (enable) { -+ /* clear the slave cpu reset */ -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval &= ~CPU1_SRST_REQ; -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } else { -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } -+} -+ -+static const struct smp_operations bsp_smp_ops __initconst = { -+ .smp_prepare_cpus = bsp_smp_prepare_cpus, -+ .smp_boot_secondary = bsp_boot_secondary, -+}; -+ -+CPU_METHOD_OF_DECLARE(gk7202v300_smp, "goke,gk7202v300-smp", &bsp_smp_ops); -+#endif /* CONFIG_SMP */ ---- linux-4.9.37/arch/arm/mach-goke/mach-gk7205v200.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/mach-gk7205v200.c 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+ -+#include "mach-common.h" -+ -+#ifdef CONFIG_SMP -+ -+#define REG_CPU_SRST_CRG 0x78 -+#define CPU1_SRST_REQ BIT(2) -+#define DBG1_SRST_REQ BIT(4) -+ -+void bsp_set_cpu(unsigned int cpu, bool enable) -+{ -+ struct device_node *np = NULL; -+ unsigned int regval; -+ void __iomem *crg_base; -+ -+ np = of_find_compatible_node(NULL, NULL, "goke,gk7205v200-clock"); -+ if (!np) { -+ pr_err("failed to find goke clock node\n"); -+ return; -+ } -+ -+ crg_base = of_iomap(np, 0); -+ if (!crg_base) { -+ pr_err("failed to map address\n"); -+ return; -+ } -+ -+ if (enable) { -+ /* clear the slave cpu reset */ -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval &= ~CPU1_SRST_REQ; -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } else { -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } -+} -+ -+static const struct smp_operations bsp_smp_ops __initconst = { -+ .smp_prepare_cpus = bsp_smp_prepare_cpus, -+ .smp_boot_secondary = bsp_boot_secondary, -+}; -+ -+CPU_METHOD_OF_DECLARE(gk7205v200_smp, "goke,gk7205v200-smp", &bsp_smp_ops); -+#endif /* CONFIG_SMP */ ---- linux-4.9.37/arch/arm/mach-goke/mach-gk7205v300.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/mach-gk7205v300.c 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+ -+#include "mach-common.h" -+ -+#ifdef CONFIG_SMP -+ -+#define REG_CPU_SRST_CRG 0x78 -+#define CPU1_SRST_REQ BIT(2) -+#define DBG1_SRST_REQ BIT(4) -+ -+void bsp_set_cpu(unsigned int cpu, bool enable) -+{ -+ struct device_node *np = NULL; -+ unsigned int regval; -+ void __iomem *crg_base; -+ -+ np = of_find_compatible_node(NULL, NULL, "goke,gk7205v300-clock"); -+ if (!np) { -+ pr_err("failed to find goke clock node\n"); -+ return; -+ } -+ -+ crg_base = of_iomap(np, 0); -+ if (!crg_base) { -+ pr_err("failed to map address\n"); -+ return; -+ } -+ -+ if (enable) { -+ /* clear the slave cpu reset */ -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval &= ~CPU1_SRST_REQ; -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } else { -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } -+} -+ -+static const struct smp_operations bsp_smp_ops __initconst = { -+ .smp_prepare_cpus = bsp_smp_prepare_cpus, -+ .smp_boot_secondary = bsp_boot_secondary, -+}; -+ -+CPU_METHOD_OF_DECLARE(gk7205v300_smp, "goke,gk7205v300-smp", &bsp_smp_ops); -+#endif /* CONFIG_SMP */ ---- linux-4.9.37/arch/arm/mach-goke/mach-gk7605v100.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/mach-gk7605v100.c 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+ -+#include "mach-common.h" -+ -+#ifdef CONFIG_SMP -+ -+#define REG_CPU_SRST_CRG 0x78 -+#define CPU1_SRST_REQ BIT(2) -+#define DBG1_SRST_REQ BIT(4) -+ -+void bsp_set_cpu(unsigned int cpu, bool enable) -+{ -+ struct device_node *np = NULL; -+ unsigned int regval; -+ void __iomem *crg_base; -+ -+ np = of_find_compatible_node(NULL, NULL, "goke,gk7605v100-clock"); -+ if (!np) { -+ pr_err("failed to find goke clock node\n"); -+ return; -+ } -+ -+ crg_base = of_iomap(np, 0); -+ if (!crg_base) { -+ pr_err("failed to map address\n"); -+ return; -+ } -+ -+ if (enable) { -+ /* clear the slave cpu reset */ -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval &= ~CPU1_SRST_REQ; -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } else { -+ regval = readl(crg_base + REG_CPU_SRST_CRG); -+ regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ); -+ writel(regval, (crg_base + REG_CPU_SRST_CRG)); -+ } -+} -+ -+static const struct smp_operations bsp_smp_ops __initconst = { -+ .smp_prepare_cpus = bsp_smp_prepare_cpus, -+ .smp_boot_secondary = bsp_boot_secondary, -+}; -+ -+CPU_METHOD_OF_DECLARE(gk7605v100_smp, "goke,gk7605v100-smp", &bsp_smp_ops); -+#endif /* CONFIG_SMP */ ---- linux-4.9.37/arch/arm/mach-goke/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/Makefile 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,8 @@ -+# -+# Makefile for Goke processors family -+# -+ -+obj-$(CONFIG_ARCH_GK7205V200) += mach-gk7205v200.o -+obj-$(CONFIG_ARCH_GK7205V300) += mach-gk7205v300.o -+obj-$(CONFIG_ARCH_GK7202V300) += mach-gk7202v300.o -+obj-$(CONFIG_ARCH_GK7605V100) += mach-gk7605v100.o ---- linux-4.9.37/arch/arm/mach-goke/Makefile.boot 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/arch/arm/mach-goke/Makefile.boot 2021-06-07 13:01:32.000000000 +0300 -@@ -0,0 +1,3 @@ -+zreladdr-$(CONFIG_ARCH_GOKE) := $(CONFIG_BSP_ZRELADDR) -+params_phys-$(CONFIG_ARCH_GOKE) := $(CONFIG_BSP_PARAMS_PHYS) -+initrd_phys-$(CONFIG_ARCH_GOKE) := $(CONFIG_BSP_INITRD_PHYS) ---- linux-4.9.37/arch/arm/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/Makefile 2021-06-07 13:01:32.000000000 +0300 -@@ -170,6 +170,7 @@ - machine-$(CONFIG_ARCH_GEMINI) += gemini - machine-$(CONFIG_ARCH_HIGHBANK) += highbank - machine-$(CONFIG_ARCH_HISI) += hisi -+machine-$(CONFIG_ARCH_GOKE) += goke - machine-$(CONFIG_ARCH_INTEGRATOR) += integrator - machine-$(CONFIG_ARCH_IOP13XX) += iop13xx - machine-$(CONFIG_ARCH_IOP32X) += iop32x -@@ -268,6 +269,10 @@ - endif - endif - -+ifeq ($(CONFIG_ARCH_GOKE),y) -+KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs)) -+endif -+ - export TEXT_OFFSET GZFLAGS MMUEXT - - # Do we have FASTFPE? ---- linux-4.9.37/arch/arm/mm/dma-mapping.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/mm/dma-mapping.c 2021-06-07 13:01:32.000000000 +0300 -@@ -275,7 +275,7 @@ - return mask; - } - --static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) -+void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) - { - /* - * Ensure that the allocated pages are zeroed, and that any data -@@ -304,6 +304,7 @@ - } - } - } -+EXPORT_SYMBOL(__dma_clear_buffer); - - /* - * Allocate a DMA buffer for 'dev' of size 'size' using the -@@ -528,6 +529,12 @@ - flush_tlb_kernel_range(start, end); - } - -+void bsp_flush_tlb_kernel_range(unsigned long start, unsigned long end) -+{ -+ flush_tlb_kernel_range(start, end); -+} -+EXPORT_SYMBOL(bsp_flush_tlb_kernel_range); -+ - static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, - pgprot_t prot, struct page **ret_page, - const void *caller, bool want_vaddr) -@@ -2397,3 +2404,10 @@ - { - arm_teardown_iommu_dma_ops(dev); - } -+ -+void bsp_dmac_map_area(const void *kaddr, size_t size, -+ enum dma_data_direction dir) -+{ -+ dmac_map_area(kaddr, size, dir); -+} -+EXPORT_SYMBOL(bsp_dmac_map_area); ---- linux-4.9.37/arch/arm/mm/init.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/mm/init.c 2021-06-07 13:01:32.000000000 +0300 -@@ -268,6 +268,12 @@ - /* reserve any platform specific memblock areas */ - if (mdesc->reserve) - mdesc->reserve(); -+#if defined CONFIG_CMA && defined CONFIG_ARCH_GOKE -+ else { -+ extern int goke_declare_heap_memory(void); -+ goke_declare_heap_memory(); -+ } -+#endif - - early_init_fdt_reserve_self(); - early_init_fdt_scan_reserved_mem(); ---- linux-4.9.37/arch/arm/vdso/vgettimeofday.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/arm/vdso/vgettimeofday.c 2021-06-07 13:01:32.000000000 +0300 -@@ -115,7 +115,7 @@ - return 0; - } - --#ifdef CONFIG_ARM_ARCH_TIMER -+#if defined (CONFIG_ARM_ARCH_TIMER) && defined(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS) - - static notrace u64 get_ns(struct vdso_data *vdata) - { ---- linux-4.9.37/arch/sh/boot/compressed/vmlinux.scr 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/sh/boot/compressed/vmlinux.scr 1970-01-01 03:00:00.000000000 +0300 -@@ -1,10 +0,0 @@ --SECTIONS --{ -- .rodata..compressed : { -- input_len = .; -- LONG(input_data_end - input_data) input_data = .; -- *(.data) -- output_len = . - 4; -- input_data_end = .; -- } --} ---- linux-4.9.37/arch/sh/boot/romimage/vmlinux.scr 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/arch/sh/boot/romimage/vmlinux.scr 1970-01-01 03:00:00.000000000 +0300 -@@ -1,8 +0,0 @@ --SECTIONS --{ -- .text : { -- zero_page_pos = .; -- *(.data) -- end_data = .; -- } --} ---- linux-4.9.37/drivers/base/dma-contiguous.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/base/dma-contiguous.c 2021-06-07 13:01:33.000000000 +0300 -@@ -195,6 +195,7 @@ - - return cma_alloc(dev_get_cma_area(dev), count, align); - } -+EXPORT_SYMBOL(dma_alloc_from_contiguous); - - /** - * dma_release_from_contiguous() - release allocated pages -@@ -211,6 +212,7 @@ - { - return cma_release(dev_get_cma_area(dev), pages, count); - } -+EXPORT_SYMBOL(dma_release_from_contiguous); - - /* - * Support for reserved memory regions defined in device tree ---- linux-4.9.37/drivers/char/random.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/char/random.c 2021-06-07 13:01:33.000000000 +0300 -@@ -812,7 +812,7 @@ - if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { - crng_init = 1; - wake_up_interruptible(&crng_init_wait); -- pr_notice("random: fast init done\n"); -+ printk_once("random: fast init done\n"); - } - spin_unlock_irqrestore(&primary_crng.lock, flags); - return 1; -@@ -850,7 +850,7 @@ - crng_init = 2; - process_random_ready_list(); - wake_up_interruptible(&crng_init_wait); -- pr_notice("random: crng init done\n"); -+ printk_once("random: crng init done\n"); - } - spin_unlock_irqrestore(&primary_crng.lock, flags); - } -@@ -1744,7 +1744,7 @@ - - if (!crng_ready() && maxwarn > 0) { - maxwarn--; -- printk(KERN_NOTICE "random: %s: uninitialized urandom read " -+ printk_once(KERN_NOTICE "random: %s: uninitialized urandom read " - "(%zd bytes read)\n", - current->comm, nbytes); - spin_lock_irqsave(&primary_crng.lock, flags); ---- linux-4.9.37/drivers/clk/goke/clk.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/clk.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,188 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "clk.h" -+ -+static DEFINE_SPINLOCK(gk_clk_lock); -+ -+struct gk_clock_data *gk_clk_init(struct device_node *np, -+ int nr_clks) -+{ -+ struct gk_clock_data *clk_data; -+ struct clk **clk_table; -+ void __iomem *base; -+ -+ base = of_iomap(np, 0); -+ if (!base) { -+ pr_err("%s: failed to map clock registers\n", __func__); -+ goto err; -+ } -+ -+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); -+ if (!clk_data) { -+ pr_err("%s: could not allocate clock data\n", __func__); -+ goto err; -+ } -+ clk_data->base = base; -+ -+ clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); -+ if (!clk_table) { -+ pr_err("%s: could not allocate clock lookup table\n", __func__); -+ goto err_data; -+ } -+ clk_data->clk_data.clks = clk_table; -+ clk_data->clk_data.clk_num = nr_clks; -+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data); -+ return clk_data; -+err_data: -+ kfree(clk_data); -+err: -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(gk_clk_init); -+ -+int gk_clk_register_fixed_rate(const struct gk_fixed_rate_clock *clks, -+ int nums, struct gk_clock_data *data) -+{ -+ struct clk *clk; -+ int i; -+ -+ for (i = 0; i < nums; i++) { -+ clk = clk_register_fixed_rate(NULL, clks[i].name, -+ clks[i].parent_name, -+ clks[i].flags, -+ clks[i].fixed_rate); -+ if (IS_ERR(clk)) { -+ pr_err("%s: failed to register clock %s\n", -+ __func__, clks[i].name); -+ goto err; -+ } -+ data->clk_data.clks[clks[i].id] = clk; -+ } -+ -+ return 0; -+ -+err: -+ while (i--) -+ clk_unregister_fixed_rate(data->clk_data.clks[clks[i].id]); -+ -+ return PTR_ERR(clk); -+} -+EXPORT_SYMBOL_GPL(gk_clk_register_fixed_rate); -+ -+int gk_clk_register_fixed_factor(const struct gk_fixed_factor_clock *clks, -+ int nums, -+ struct gk_clock_data *data) -+{ -+ struct clk *clk; -+ int i; -+ -+ for (i = 0; i < nums; i++) { -+ clk = clk_register_fixed_factor(NULL, clks[i].name, -+ clks[i].parent_name, -+ clks[i].flags, clks[i].mult, -+ clks[i].div); -+ if (IS_ERR(clk)) { -+ pr_err("%s: failed to register clock %s\n", -+ __func__, clks[i].name); -+ goto err; -+ } -+ data->clk_data.clks[clks[i].id] = clk; -+ } -+ -+ return 0; -+ -+err: -+ while (i--) -+ clk_unregister_fixed_factor(data->clk_data.clks[clks[i].id]); -+ -+ return PTR_ERR(clk); -+} -+EXPORT_SYMBOL_GPL(gk_clk_register_fixed_factor); -+ -+int gk_clk_register_mux(const struct gk_mux_clock *clks, -+ int nums, struct gk_clock_data *data) -+{ -+ struct clk *clk; -+ void __iomem *base = data->base; -+ int i; -+ -+ for (i = 0; i < nums; i++) { -+ u32 mask = BIT(clks[i].width) - 1; -+ -+ clk = clk_register_mux_table(NULL, clks[i].name, -+ clks[i].parent_names, -+ clks[i].num_parents, clks[i].flags, -+ base + clks[i].offset, clks[i].shift, -+ mask, clks[i].mux_flags, -+ clks[i].table, &gk_clk_lock); -+ if (IS_ERR(clk)) { -+ pr_err("%s: failed to register clock %s\n", -+ __func__, clks[i].name); -+ goto err; -+ } -+ -+ if (clks[i].alias) -+ clk_register_clkdev(clk, clks[i].alias, NULL); -+ -+ data->clk_data.clks[clks[i].id] = clk; -+ } -+ -+ return 0; -+ -+err: -+ while (i--) -+ clk_unregister_mux(data->clk_data.clks[clks[i].id]); -+ -+ return PTR_ERR(clk); -+} -+EXPORT_SYMBOL_GPL(gk_clk_register_mux); -+ -+ -+int gk_clk_register_gate(const struct gk_gate_clock *clks, -+ int nums, struct gk_clock_data *data) -+{ -+ struct clk *clk; -+ void __iomem *base = data->base; -+ int i; -+ -+ for (i = 0; i < nums; i++) { -+ clk = clk_register_gate(NULL, clks[i].name, -+ clks[i].parent_name, -+ clks[i].flags, -+ base + clks[i].offset, -+ clks[i].bit_idx, -+ clks[i].gate_flags, -+ &gk_clk_lock); -+ if (IS_ERR(clk)) { -+ pr_err("%s: failed to register clock %s\n", -+ __func__, clks[i].name); -+ goto err; -+ } -+ -+ if (clks[i].alias) -+ clk_register_clkdev(clk, clks[i].alias, NULL); -+ -+ data->clk_data.clks[clks[i].id] = clk; -+ } -+ -+ return 0; -+ -+err: -+ while (i--) -+ clk_unregister_gate(data->clk_data.clks[clks[i].id]); -+ -+ return PTR_ERR(clk); -+} -+EXPORT_SYMBOL_GPL(gk_clk_register_gate); -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/clk/goke/clk-gk7202v300.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/clk-gk7202v300.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,233 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "clk.h" -+#include "reset.h" -+ -+static struct gk_fixed_rate_clock gk7202v300_fixed_rate_clks[] __initdata = { -+ { GK7202V300_FIXED_100K, "100k", NULL, 0, 100000, }, -+ { GK7202V300_FIXED_400K, "400k", NULL, 0, 400000, }, -+ { GK7202V300_FIXED_3M, "3m", NULL, 0, 3000000, }, -+ { GK7202V300_FIXED_6M, "6m", NULL, 0, 6000000, }, -+ { GK7202V300_FIXED_12M, "12m", NULL, 0, 12000000, }, -+ { GK7202V300_FIXED_24M, "24m", NULL, 0, 24000000, }, -+ { GK7202V300_FIXED_25M, "25m", NULL, 0, 25000000, }, -+ { GK7202V300_FIXED_50M, "50m", NULL, 0, 50000000, }, -+ { GK7202V300_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, -+ { GK7202V300_FIXED_90M, "90m", NULL, 0, 90000000, }, -+ { GK7202V300_FIXED_100M, "100m", NULL, 0, 100000000, }, -+ { GK7202V300_FIXED_112M, "112m", NULL, 0, 112000000, }, -+ { GK7202V300_FIXED_125M, "125m", NULL, 0, 125000000, }, -+ { GK7202V300_FIXED_150M, "150m", NULL, 0, 150000000, }, -+ { GK7202V300_FIXED_200M, "200m", NULL, 0, 200000000, }, -+ { GK7202V300_FIXED_250M, "250m", NULL, 0, 250000000, }, -+ { GK7202V300_FIXED_300M, "300m", NULL, 0, 300000000, }, -+ { GK7202V300_FIXED_324M, "324m", NULL, 0, 324000000, }, -+ { GK7202V300_FIXED_342M, "342m", NULL, 0, 342000000, }, -+ { GK7202V300_FIXED_342M, "375m", NULL, 0, 375000000, }, -+ { GK7202V300_FIXED_400M, "400m", NULL, 0, 400000000, }, -+ { GK7202V300_FIXED_448M, "448m", NULL, 0, 448000000, }, -+ { GK7202V300_FIXED_500M, "500m", NULL, 0, 500000000, }, -+ { GK7202V300_FIXED_540M, "540m", NULL, 0, 540000000, }, -+ { GK7202V300_FIXED_600M, "600m", NULL, 0, 600000000, }, -+ { GK7202V300_FIXED_750M, "750m", NULL, 0, 750000000, }, -+ { GK7202V300_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, -+ { GK7202V300_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, -+}; -+ -+static const char *sysaxi_mux_p[] __initconst = { -+ "24m", "200m" -+}; -+static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; -+static const char *uart_mux_p[] __initconst = {"24m", "6m"}; -+static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "200m", "300m", "360m"}; -+static const char *mmc_mux_p[] __initdata = { -+ "100k", "400k", "25m", "50m", "90m", "112m", "150m" -+}; -+static const char *eth_mux_p[] __initconst = {"100m", "54m"}; -+static const char *usb_mux_p[] __initdata = {"phy", "crg",}; -+ -+static u32 sysaxi_mux_table[] = {0, 1}; -+static u32 sysapb_mux_table[] = {0, 1}; -+static u32 uart_mux_table[] = {0, 1}; -+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -+static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; -+static u32 eth_mux_table[] = {0, 1}; -+static u32 usb_mux_table[] = {0, 1}; -+ -+static struct gk_mux_clock gk7202v300_mux_clks[] __initdata = { -+ { -+ GK7202V300_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, -+ ARRAY_SIZE(sysaxi_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, -+ }, -+ { -+ GK7202V300_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, -+ ARRAY_SIZE(sysapb_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, -+ }, -+ { -+ GK7202V300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, -+ }, -+ { -+ GK7202V300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7202V300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7202V300_UART_MUX, "uart_mux0", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7202V300_UART_MUX, "uart_mux1", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7202V300_UART_MUX, "uart_mux2", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7202V300_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), -+ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, -+ }, -+ { -+ GK7202V300_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), -+ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table -+ }, -+}; -+ -+static struct gk_fixed_factor_clock gk7202v300_fixed_factor_clks[] __initdata = { -+ { -+ GK7202V300_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, -+ CLK_SET_RATE_PARENT -+ }, -+}; -+ -+static struct gk_gate_clock gk7202v300_gate_clks[] __initdata = { -+ /* fmc */ -+ { -+ GK7202V300_FMC_CLK, "clk_fmc", "fmc_mux", -+ CLK_SET_RATE_PARENT, 0x144, 1, 0, -+ }, -+ /* mmc */ -+ { -+ GK7202V300_MMC0_CLK, "clk_mmc0", "mmc0_mux", -+ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, -+ }, -+ { -+ GK7202V300_MMC1_CLK, "clk_mmc1", "mmc1_mux", -+ CLK_SET_RATE_PARENT, 0x22c, 28, 0, -+ }, -+ /* uart */ -+ { -+ GK7202V300_UART0_CLK, "clk_uart0", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, -+ }, -+ { -+ GK7202V300_UART1_CLK, "clk_uart1", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, -+ }, -+ { -+ GK7202V300_UART2_CLK, "clk_uart2", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, -+ }, -+ /* spi */ -+ { -+ GK7202V300_SPI0_CLK, "clk_spi0", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, -+ }, -+ { -+ GK7202V300_SPI1_CLK, "clk_spi1", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, -+ }, -+ /* i2c */ -+ { -+ GK7202V300_I2C0_CLK, "clk_i2c0", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, -+ }, -+ { -+ GK7202V300_I2C1_CLK, "clk_i2c1", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, -+ }, -+ { -+ GK7202V300_I2C2_CLK, "clk_i2c2", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, -+ }, -+ /* ethernet mac */ -+ { -+ GK7202V300_ETH0_CLK, "clk_eth0", "eth_mux", -+ CLK_SET_RATE_PARENT, 0x16c, 1, 0, -+ }, -+ /* edmac */ -+ { -+ GK7202V300_EDMAC_AXICLK, "axi_clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 2, 0, -+ }, -+ { -+ GK7202V300_EDMAC_CLK, "clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 1, 0, -+ }, -+ /* usb */ -+ { -+ GK7202V300_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 8, 0, -+ }, -+ { -+ GK7202V300_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 9, 0, -+ }, -+ { -+ GK7202V300_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 12, 0, -+ }, -+ { -+ GK7202V300_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 11, 0, -+ }, -+ { -+ GK7202V300_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 4, 0, -+ }, -+ { -+ GK7202V300_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 2, 0, -+ }, -+}; -+ -+static void __init gk7202v300_clk_init(struct device_node *np) -+{ -+ struct gk_clock_data *clk_data; -+ -+ clk_data = gk_clk_init(np, GK7202V300_NR_CLKS); -+ if (!clk_data) -+ return; -+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) -+ gk_reset_init(np, GK7202V300_NR_RSTS); -+ -+ gk_clk_register_fixed_rate(gk7202v300_fixed_rate_clks, -+ ARRAY_SIZE(gk7202v300_fixed_rate_clks), -+ clk_data); -+ gk_clk_register_mux(gk7202v300_mux_clks, ARRAY_SIZE(gk7202v300_mux_clks), -+ clk_data); -+ gk_clk_register_fixed_factor(gk7202v300_fixed_factor_clks, -+ ARRAY_SIZE(gk7202v300_fixed_factor_clks), clk_data); -+ gk_clk_register_gate(gk7202v300_gate_clks, -+ ARRAY_SIZE(gk7202v300_gate_clks), clk_data); -+ -+} -+ -+CLK_OF_DECLARE(gk7202v300_clk, "goke,gk7202v300-clock", gk7202v300_clk_init); -+ ---- linux-4.9.37/drivers/clk/goke/clk-gk7205v200.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/clk-gk7205v200.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,235 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "clk.h" -+#include "reset.h" -+ -+static struct gk_fixed_rate_clock gk7205v200_fixed_rate_clks[] __initdata = { -+ { GK7205V200_FIXED_100K, "100k", NULL, 0, 100000, }, -+ { GK7205V200_FIXED_400K, "400k", NULL, 0, 400000, }, -+ { GK7205V200_FIXED_3M, "3m", NULL, 0, 3000000, }, -+ { GK7205V200_FIXED_6M, "6m", NULL, 0, 6000000, }, -+ { GK7205V200_FIXED_12M, "12m", NULL, 0, 12000000, }, -+ { GK7205V200_FIXED_24M, "24m", NULL, 0, 24000000, }, -+ { GK7205V200_FIXED_25M, "25m", NULL, 0, 25000000, }, -+ { GK7205V200_FIXED_50M, "50m", NULL, 0, 50000000, }, -+ { GK7205V200_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, -+ { GK7205V200_FIXED_90M, "90m", NULL, 0, 90000000, }, -+ { GK7205V200_FIXED_100M, "100m", NULL, 0, 100000000, }, -+ { GK7205V200_FIXED_112M, "112m", NULL, 0, 112000000, }, -+ { GK7205V200_FIXED_125M, "125m", NULL, 0, 125000000, }, -+ { GK7205V200_FIXED_150M, "150m", NULL, 0, 150000000, }, -+ { GK7205V200_FIXED_200M, "200m", NULL, 0, 200000000, }, -+ { GK7205V200_FIXED_250M, "250m", NULL, 0, 250000000, }, -+ { GK7205V200_FIXED_300M, "300m", NULL, 0, 300000000, }, -+ { GK7205V200_FIXED_324M, "324m", NULL, 0, 324000000, }, -+ { GK7205V200_FIXED_342M, "342m", NULL, 0, 342000000, }, -+ { GK7205V200_FIXED_342M, "375m", NULL, 0, 375000000, }, -+ { GK7205V200_FIXED_400M, "400m", NULL, 0, 400000000, }, -+ { GK7205V200_FIXED_448M, "448m", NULL, 0, 448000000, }, -+ { GK7205V200_FIXED_500M, "500m", NULL, 0, 500000000, }, -+ { GK7205V200_FIXED_540M, "540m", NULL, 0, 540000000, }, -+ { GK7205V200_FIXED_600M, "600m", NULL, 0, 600000000, }, -+ { GK7205V200_FIXED_750M, "750m", NULL, 0, 750000000, }, -+ { GK7205V200_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, -+ { GK7205V200_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, -+}; -+ -+static const char *sysaxi_mux_p[] __initconst = { -+ "24m", "200m" -+}; -+static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; -+static const char *uart_mux_p[] __initconst = {"24m", "6m"}; -+static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "200m", "300m", "360m"}; -+static const char *mmc_mux_p[] __initdata = { -+ "100k", "400k", "25m", "50m", "90m", "112m", "150m" -+}; -+static const char *eth_mux_p[] __initconst = {"100m", "54m"}; -+static const char *usb_mux_p[] __initdata = {"phy", "crg",}; -+ -+static u32 sysaxi_mux_table[] = {0, 1}; -+static u32 sysapb_mux_table[] = {0, 1}; -+static u32 uart_mux_table[] = {0, 1}; -+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -+static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; -+static u32 eth_mux_table[] = {0, 1}; -+static u32 usb_mux_table[] = {0, 1}; -+ -+static struct gk_mux_clock gk7205v200_mux_clks[] __initdata = { -+ { -+ GK7205V200_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, -+ ARRAY_SIZE(sysaxi_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, -+ }, -+ { -+ GK7205V200_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, -+ ARRAY_SIZE(sysapb_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, -+ }, -+ { -+ GK7205V200_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, -+ }, -+ { -+ GK7205V200_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7205V200_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7205V200_UART_MUX, "uart_mux0", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7205V200_UART_MUX, "uart_mux1", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7205V200_UART_MUX, "uart_mux2", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7205V200_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), -+ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, -+ }, -+ { -+ GK7205V200_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), -+ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table -+ }, -+}; -+ -+#if 1 -+static struct gk_fixed_factor_clock gk7205v200_fixed_factor_clks[] __initdata = { -+ { -+ GK7205V200_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, -+ CLK_SET_RATE_PARENT -+ }, -+}; -+#endif -+ -+static struct gk_gate_clock gk7205v200_gate_clks[] __initdata = { -+ /* fmc */ -+ { -+ GK7205V200_FMC_CLK, "clk_fmc", "fmc_mux", -+ CLK_SET_RATE_PARENT, 0x144, 1, 0, -+ }, -+ /* mmc */ -+ { -+ GK7205V200_MMC0_CLK, "clk_mmc0", "mmc0_mux", -+ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, -+ }, -+ { -+ GK7205V200_MMC1_CLK, "clk_mmc1", "mmc1_mux", -+ CLK_SET_RATE_PARENT, 0x22c, 28, 0, -+ }, -+ /* uart */ -+ { -+ GK7205V200_UART0_CLK, "clk_uart0", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, -+ }, -+ { -+ GK7205V200_UART1_CLK, "clk_uart1", "uart_mux1", -+ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, -+ }, -+ { -+ GK7205V200_UART2_CLK, "clk_uart2", "uart_mux2", -+ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, -+ }, -+ /* spi */ -+ { -+ GK7205V200_SPI0_CLK, "clk_spi0", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, -+ }, -+ { -+ GK7205V200_SPI1_CLK, "clk_spi1", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, -+ }, -+ /* i2c */ -+ { -+ GK7205V200_I2C0_CLK, "clk_i2c0", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, -+ }, -+ { -+ GK7205V200_I2C1_CLK, "clk_i2c1", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, -+ }, -+ { -+ GK7205V200_I2C2_CLK, "clk_i2c2", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, -+ }, -+ /* ethernet mac */ -+ { -+ GK7205V200_ETH0_CLK, "clk_eth0", "eth_mux", -+ CLK_SET_RATE_PARENT, 0x16c, 1, 0, -+ }, -+ /* edmac */ -+ { -+ GK7205V200_EDMAC_AXICLK, "axi_clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 2, 0, -+ }, -+ { -+ GK7205V200_EDMAC_CLK, "clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 1, 0, -+ }, -+ /* usb */ -+ { -+ GK7205V200_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 8, 0, -+ }, -+ { -+ GK7205V200_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 9, 0, -+ }, -+ { -+ GK7205V200_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 12, 0, -+ }, -+ { -+ GK7205V200_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 11, 0, -+ }, -+ { -+ GK7205V200_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 4, 0, -+ }, -+ { -+ GK7205V200_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 2, 0, -+ }, -+}; -+ -+static void __init gk7205v200_clk_init(struct device_node *np) -+{ -+ struct gk_clock_data *clk_data; -+ -+ clk_data = gk_clk_init(np, GK7205V200_NR_CLKS); -+ if (!clk_data) -+ return; -+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) -+ gk_reset_init(np, GK7205V200_NR_RSTS); -+ -+ gk_clk_register_fixed_rate(gk7205v200_fixed_rate_clks, -+ ARRAY_SIZE(gk7205v200_fixed_rate_clks), -+ clk_data); -+ gk_clk_register_mux(gk7205v200_mux_clks, ARRAY_SIZE(gk7205v200_mux_clks), -+ clk_data); -+ gk_clk_register_fixed_factor(gk7205v200_fixed_factor_clks, -+ ARRAY_SIZE(gk7205v200_fixed_factor_clks), clk_data); -+ gk_clk_register_gate(gk7205v200_gate_clks, -+ ARRAY_SIZE(gk7205v200_gate_clks), clk_data); -+ -+} -+ -+CLK_OF_DECLARE(gk7205v200_clk, "goke,gk7205v200-clock", gk7205v200_clk_init); -+ ---- linux-4.9.37/drivers/clk/goke/clk-gk7205v300.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/clk-gk7205v300.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,233 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "clk.h" -+#include "reset.h" -+ -+static struct gk_fixed_rate_clock gk7205v300_fixed_rate_clks[] __initdata = { -+ { GK7205V300_FIXED_100K, "100k", NULL, 0, 100000, }, -+ { GK7205V300_FIXED_400K, "400k", NULL, 0, 400000, }, -+ { GK7205V300_FIXED_3M, "3m", NULL, 0, 3000000, }, -+ { GK7205V300_FIXED_6M, "6m", NULL, 0, 6000000, }, -+ { GK7205V300_FIXED_12M, "12m", NULL, 0, 12000000, }, -+ { GK7205V300_FIXED_24M, "24m", NULL, 0, 24000000, }, -+ { GK7205V300_FIXED_25M, "25m", NULL, 0, 25000000, }, -+ { GK7205V300_FIXED_50M, "50m", NULL, 0, 50000000, }, -+ { GK7205V300_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, -+ { GK7205V300_FIXED_90M, "90m", NULL, 0, 90000000, }, -+ { GK7205V300_FIXED_100M, "100m", NULL, 0, 100000000, }, -+ { GK7205V300_FIXED_112M, "112m", NULL, 0, 112000000, }, -+ { GK7205V300_FIXED_125M, "125m", NULL, 0, 125000000, }, -+ { GK7205V300_FIXED_150M, "150m", NULL, 0, 150000000, }, -+ { GK7205V300_FIXED_200M, "200m", NULL, 0, 200000000, }, -+ { GK7205V300_FIXED_250M, "250m", NULL, 0, 250000000, }, -+ { GK7205V300_FIXED_300M, "300m", NULL, 0, 300000000, }, -+ { GK7205V300_FIXED_324M, "324m", NULL, 0, 324000000, }, -+ { GK7205V300_FIXED_342M, "342m", NULL, 0, 342000000, }, -+ { GK7205V300_FIXED_342M, "375m", NULL, 0, 375000000, }, -+ { GK7205V300_FIXED_400M, "400m", NULL, 0, 400000000, }, -+ { GK7205V300_FIXED_448M, "448m", NULL, 0, 448000000, }, -+ { GK7205V300_FIXED_500M, "500m", NULL, 0, 500000000, }, -+ { GK7205V300_FIXED_540M, "540m", NULL, 0, 540000000, }, -+ { GK7205V300_FIXED_600M, "600m", NULL, 0, 600000000, }, -+ { GK7205V300_FIXED_750M, "750m", NULL, 0, 750000000, }, -+ { GK7205V300_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, -+ { GK7205V300_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, -+}; -+ -+static const char *sysaxi_mux_p[] __initconst = { -+ "24m", "200m" -+}; -+static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; -+static const char *uart_mux_p[] __initconst = {"24m", "6m"}; -+static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "200m", "300m", "360m"}; -+static const char *mmc_mux_p[] __initdata = { -+ "100k", "400k", "25m", "50m", "90m", "112m", "150m" -+}; -+static const char *eth_mux_p[] __initconst = {"100m", "54m"}; -+static const char *usb_mux_p[] __initdata = {"phy", "crg",}; -+ -+static u32 sysaxi_mux_table[] = {0, 1}; -+static u32 sysapb_mux_table[] = {0, 1}; -+static u32 uart_mux_table[] = {0, 1}; -+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -+static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; -+static u32 eth_mux_table[] = {0, 1}; -+static u32 usb_mux_table[] = {0, 1}; -+ -+static struct gk_mux_clock gk7205v300_mux_clks[] __initdata = { -+ { -+ GK7205V300_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, -+ ARRAY_SIZE(sysaxi_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, -+ }, -+ { -+ GK7205V300_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, -+ ARRAY_SIZE(sysapb_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, -+ }, -+ { -+ GK7205V300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, -+ }, -+ { -+ GK7205V300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7205V300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7205V300_UART_MUX, "uart_mux0", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7205V300_UART_MUX, "uart_mux1", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7205V300_UART_MUX, "uart_mux2", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7205V300_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), -+ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, -+ }, -+ { -+ GK7205V300_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), -+ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table -+ }, -+}; -+ -+static struct gk_fixed_factor_clock gk7205v300_fixed_factor_clks[] __initdata = { -+ { -+ GK7205V300_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, -+ CLK_SET_RATE_PARENT -+ }, -+}; -+ -+static struct gk_gate_clock gk7205v300_gate_clks[] __initdata = { -+ /* fmc */ -+ { -+ GK7205V300_FMC_CLK, "clk_fmc", "fmc_mux", -+ CLK_SET_RATE_PARENT, 0x144, 1, 0, -+ }, -+ /* mmc */ -+ { -+ GK7205V300_MMC0_CLK, "clk_mmc0", "mmc0_mux", -+ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, -+ }, -+ { -+ GK7205V300_MMC1_CLK, "clk_mmc1", "mmc1_mux", -+ CLK_SET_RATE_PARENT, 0x22c, 28, 0, -+ }, -+ /* uart */ -+ { -+ GK7205V300_UART0_CLK, "clk_uart0", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, -+ }, -+ { -+ GK7205V300_UART1_CLK, "clk_uart1", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, -+ }, -+ { -+ GK7205V300_UART2_CLK, "clk_uart2", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, -+ }, -+ /* spi */ -+ { -+ GK7205V300_SPI0_CLK, "clk_spi0", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, -+ }, -+ { -+ GK7205V300_SPI1_CLK, "clk_spi1", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, -+ }, -+ /* i2c */ -+ { -+ GK7205V300_I2C0_CLK, "clk_i2c0", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, -+ }, -+ { -+ GK7205V300_I2C1_CLK, "clk_i2c1", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, -+ }, -+ { -+ GK7205V300_I2C2_CLK, "clk_i2c2", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, -+ }, -+ /* ethernet mac */ -+ { -+ GK7205V300_ETH0_CLK, "clk_eth0", "eth_mux", -+ CLK_SET_RATE_PARENT, 0x16c, 1, 0, -+ }, -+ /* edmac */ -+ { -+ GK7205V300_EDMAC_AXICLK, "axi_clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 2, 0, -+ }, -+ { -+ GK7205V300_EDMAC_CLK, "clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 1, 0, -+ }, -+ /* usb */ -+ { -+ GK7205V300_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 8, 0, -+ }, -+ { -+ GK7205V300_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 9, 0, -+ }, -+ { -+ GK7205V300_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 12, 0, -+ }, -+ { -+ GK7205V300_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 11, 0, -+ }, -+ { -+ GK7205V300_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 4, 0, -+ }, -+ { -+ GK7205V300_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 2, 0, -+ }, -+}; -+ -+static void __init gk7205v300_clk_init(struct device_node *np) -+{ -+ struct gk_clock_data *clk_data; -+ -+ clk_data = gk_clk_init(np, GK7205V300_NR_CLKS); -+ if (!clk_data) -+ return; -+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) -+ gk_reset_init(np, GK7205V300_NR_RSTS); -+ -+ gk_clk_register_fixed_rate(gk7205v300_fixed_rate_clks, -+ ARRAY_SIZE(gk7205v300_fixed_rate_clks), -+ clk_data); -+ gk_clk_register_mux(gk7205v300_mux_clks, ARRAY_SIZE(gk7205v300_mux_clks), -+ clk_data); -+ gk_clk_register_fixed_factor(gk7205v300_fixed_factor_clks, -+ ARRAY_SIZE(gk7205v300_fixed_factor_clks), clk_data); -+ gk_clk_register_gate(gk7205v300_gate_clks, -+ ARRAY_SIZE(gk7205v300_gate_clks), clk_data); -+ -+} -+ -+CLK_OF_DECLARE(gk7205v300_clk, "goke,gk7205v300-clock", gk7205v300_clk_init); -+ ---- linux-4.9.37/drivers/clk/goke/clk-gk7605v100.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/clk-gk7605v100.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,233 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "clk.h" -+#include "reset.h" -+ -+static struct gk_fixed_rate_clock gk7605v100_fixed_rate_clks[] __initdata = { -+ { GK7605V100_FIXED_100K, "100k", NULL, 0, 100000, }, -+ { GK7605V100_FIXED_400K, "400k", NULL, 0, 400000, }, -+ { GK7605V100_FIXED_3M, "3m", NULL, 0, 3000000, }, -+ { GK7605V100_FIXED_6M, "6m", NULL, 0, 6000000, }, -+ { GK7605V100_FIXED_12M, "12m", NULL, 0, 12000000, }, -+ { GK7605V100_FIXED_24M, "24m", NULL, 0, 24000000, }, -+ { GK7605V100_FIXED_25M, "25m", NULL, 0, 25000000, }, -+ { GK7605V100_FIXED_50M, "50m", NULL, 0, 50000000, }, -+ { GK7605V100_FIXED_83P3M, "83.3m",NULL, 0, 83300000, }, -+ { GK7605V100_FIXED_90M, "90m", NULL, 0, 90000000, }, -+ { GK7605V100_FIXED_100M, "100m", NULL, 0, 100000000, }, -+ { GK7605V100_FIXED_112M, "112m", NULL, 0, 112000000, }, -+ { GK7605V100_FIXED_125M, "125m", NULL, 0, 125000000, }, -+ { GK7605V100_FIXED_150M, "150m", NULL, 0, 150000000, }, -+ { GK7605V100_FIXED_200M, "200m", NULL, 0, 200000000, }, -+ { GK7605V100_FIXED_250M, "250m", NULL, 0, 250000000, }, -+ { GK7605V100_FIXED_300M, "300m", NULL, 0, 300000000, }, -+ { GK7605V100_FIXED_324M, "324m", NULL, 0, 324000000, }, -+ { GK7605V100_FIXED_342M, "342m", NULL, 0, 342000000, }, -+ { GK7605V100_FIXED_342M, "375m", NULL, 0, 375000000, }, -+ { GK7605V100_FIXED_400M, "400m", NULL, 0, 400000000, }, -+ { GK7605V100_FIXED_448M, "448m", NULL, 0, 448000000, }, -+ { GK7605V100_FIXED_500M, "500m", NULL, 0, 500000000, }, -+ { GK7605V100_FIXED_540M, "540m", NULL, 0, 540000000, }, -+ { GK7605V100_FIXED_600M, "600m", NULL, 0, 600000000, }, -+ { GK7605V100_FIXED_750M, "750m", NULL, 0, 750000000, }, -+ { GK7605V100_FIXED_1000M, "1000m",NULL, 0, 1000000000, }, -+ { GK7605V100_FIXED_1500M, "1500m",NULL, 0, 1500000000UL, }, -+}; -+ -+static const char *sysaxi_mux_p[] __initconst = { -+ "24m", "200m" -+}; -+static const char *sysapb_mux_p[] __initconst = {"24m", "50m"}; -+static const char *uart_mux_p[] __initconst = {"24m", "6m"}; -+static const char *fmc_mux_p[] __initconst = {"24m", "100", "150m", "200m", "300m", "360m"}; -+static const char *mmc_mux_p[] __initdata = { -+ "100k", "400k", "25m", "50m", "90m", "112m", "150m" -+}; -+static const char *eth_mux_p[] __initconst = {"100m", "54m"}; -+static const char *usb_mux_p[] __initdata = {"phy", "crg",}; -+ -+static u32 sysaxi_mux_table[] = {0, 1}; -+static u32 sysapb_mux_table[] = {0, 1}; -+static u32 uart_mux_table[] = {0, 1}; -+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -+static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; -+static u32 eth_mux_table[] = {0, 1}; -+static u32 usb_mux_table[] = {0, 1}; -+ -+static struct gk_mux_clock gk7605v100_mux_clks[] __initdata = { -+ { -+ GK7605V100_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p, -+ ARRAY_SIZE(sysaxi_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 6, 1, 0, sysaxi_mux_table, -+ }, -+ { -+ GK7605V100_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p, -+ ARRAY_SIZE(sysapb_mux_p), -+ CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table, -+ }, -+ { -+ GK7605V100_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table, -+ }, -+ { -+ GK7605V100_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x1f4, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7605V100_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -+ CLK_SET_RATE_PARENT, 0x22c, 24, 3, 0, mmc_mux_table, -+ }, -+ { -+ GK7605V100_UART_MUX, "uart_mux0", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7605V100_UART_MUX, "uart_mux1", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7605V100_UART_MUX, "uart_mux2", uart_mux_p, -+ ARRAY_SIZE(uart_mux_p), -+ CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table, -+ }, -+ { -+ GK7605V100_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), -+ CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table, -+ }, -+ { -+ GK7605V100_USB2_MUX, "usb2_mux", usb_mux_p, ARRAY_SIZE(usb_mux_p), -+ CLK_SET_RATE_PARENT, 0x140, 13, 0, 0, usb_mux_table -+ }, -+}; -+ -+static struct gk_fixed_factor_clock gk7605v100_fixed_factor_clks[] __initdata = { -+ { -+ GK7605V100_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4, -+ CLK_SET_RATE_PARENT -+ }, -+}; -+ -+static struct gk_gate_clock gk7605v100_gate_clks[] __initdata = { -+ /* fmc */ -+ { -+ GK7605V100_FMC_CLK, "clk_fmc", "fmc_mux", -+ CLK_SET_RATE_PARENT, 0x144, 1, 0, -+ }, -+ /* mmc */ -+ { -+ GK7605V100_MMC0_CLK, "clk_mmc0", "mmc0_mux", -+ CLK_SET_RATE_PARENT, 0x1f4, 28, 0, -+ }, -+ { -+ GK7605V100_MMC1_CLK, "clk_mmc1", "mmc1_mux", -+ CLK_SET_RATE_PARENT, 0x22c, 28, 0, -+ }, -+ /* uart */ -+ { -+ GK7605V100_UART0_CLK, "clk_uart0", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 0, 0, -+ }, -+ { -+ GK7605V100_UART1_CLK, "clk_uart1", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 1, 0, -+ }, -+ { -+ GK7605V100_UART2_CLK, "clk_uart2", "24m", -+ CLK_SET_RATE_PARENT, 0x1b8, 2, 0, -+ }, -+ /* spi */ -+ { -+ GK7605V100_SPI0_CLK, "clk_spi0", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 12, 0, -+ }, -+ { -+ GK7605V100_SPI1_CLK, "clk_spi1", "100m", -+ CLK_SET_RATE_PARENT, 0x1bc, 13, 0, -+ }, -+ /* i2c */ -+ { -+ GK7605V100_I2C0_CLK, "clk_i2c0", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 11, 0, -+ }, -+ { -+ GK7605V100_I2C1_CLK, "clk_i2c1", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 12, 0, -+ }, -+ { -+ GK7605V100_I2C2_CLK, "clk_i2c2", "50m", -+ CLK_SET_RATE_PARENT, 0x1b8, 13, 0, -+ }, -+ /* ethernet mac */ -+ { -+ GK7605V100_ETH0_CLK, "clk_eth0", "eth_mux", -+ CLK_SET_RATE_PARENT, 0x16c, 1, 0, -+ }, -+ /* edmac */ -+ { -+ GK7605V100_EDMAC_AXICLK, "axi_clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 2, 0, -+ }, -+ { -+ GK7605V100_EDMAC_CLK, "clk_edmac", NULL, -+ CLK_SET_RATE_PARENT, 0x194, 1, 0, -+ }, -+ /* usb */ -+ { -+ GK7605V100_USB2_BUS_CLK, "clk_usb2_bus", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 8, 0, -+ }, -+ { -+ GK7605V100_USB2_REF_CLK, "clk_usb2_ref", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 9, 0, -+ }, -+ { -+ GK7605V100_USB2_UTMI_CLK, "clk_usb2_utmi", "usb2_mux", -+ CLK_SET_RATE_PARENT, 0x140, 12, 0, -+ }, -+ { -+ GK7605V100_USB2_PHY_APB_CLK, "clk_u2phy_apb_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 11, 0, -+ }, -+ { -+ GK7605V100_USB2_PHY_PLL_CLK, "clk_u2phy_pll_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 4, 0, -+ }, -+ { -+ GK7605V100_USB2_PHY_XO_CLK, "clk_u2phy_xo_ref",NULL, -+ CLK_SET_RATE_PARENT, 0x140, 2, 0, -+ }, -+}; -+ -+static void __init gk7605v100_clk_init(struct device_node *np) -+{ -+ struct gk_clock_data *clk_data; -+ -+ clk_data = gk_clk_init(np, GK7605V100_NR_CLKS); -+ if (!clk_data) -+ return; -+ if (IS_ENABLED(CONFIG_RESET_CONTROLLER)) -+ gk_reset_init(np, GK7605V100_NR_RSTS); -+ -+ gk_clk_register_fixed_rate(gk7605v100_fixed_rate_clks, -+ ARRAY_SIZE(gk7605v100_fixed_rate_clks), -+ clk_data); -+ gk_clk_register_mux(gk7605v100_mux_clks, ARRAY_SIZE(gk7605v100_mux_clks), -+ clk_data); -+ gk_clk_register_fixed_factor(gk7605v100_fixed_factor_clks, -+ ARRAY_SIZE(gk7605v100_fixed_factor_clks), clk_data); -+ gk_clk_register_gate(gk7605v100_gate_clks, -+ ARRAY_SIZE(gk7605v100_gate_clks), clk_data); -+ -+} -+ -+CLK_OF_DECLARE(gk7605v100_clk, "goke,gk7605v100-clock", gk7605v100_clk_init); -+ ---- linux-4.9.37/drivers/clk/goke/clk.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/clk.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,90 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __GOKE_CLK_H -+#define __GOKE_CLK_H -+ -+#include -+#include -+#include -+ -+struct platform_device; -+ -+struct gk_clock_data { -+ struct clk_onecell_data clk_data; -+ void __iomem *base; -+}; -+ -+struct gk_fixed_rate_clock { -+ unsigned int id; -+ char *name; -+ const char *parent_name; -+ unsigned long flags; -+ unsigned long fixed_rate; -+}; -+ -+struct gk_fixed_factor_clock { -+ unsigned int id; -+ char *name; -+ const char *parent_name; -+ unsigned long mult; -+ unsigned long div; -+ unsigned long flags; -+}; -+ -+struct gk_mux_clock { -+ unsigned int id; -+ const char *name; -+ const char *const *parent_names; -+ u8 num_parents; -+ unsigned long flags; -+ unsigned long offset; -+ u8 shift; -+ u8 width; -+ u8 mux_flags; -+ u32 *table; -+ const char *alias; -+}; -+ -+struct gk_gate_clock { -+ unsigned int id; -+ const char *name; -+ const char *parent_name; -+ unsigned long flags; -+ unsigned long offset; -+ u8 bit_idx; -+ u8 gate_flags; -+ const char *alias; -+}; -+ -+struct gk_clock_data *gk_clk_init(struct device_node *, int); -+int gk_clk_register_fixed_rate(const struct gk_fixed_rate_clock *, -+ int, struct gk_clock_data *); -+int gk_clk_register_fixed_factor(const struct gk_fixed_factor_clock *, -+ int, struct gk_clock_data *); -+int gk_clk_register_mux(const struct gk_mux_clock *, int, -+ struct gk_clock_data *); -+int gk_clk_register_gate(const struct gk_gate_clock *, -+ int, struct gk_clock_data *); -+ -+#define gk_clk_unregister(type) \ -+static inline \ -+void gk_clk_unregister_##type(const struct gk_##type##_clock *clks, \ -+ int nums, struct gk_clock_data *data) \ -+{ \ -+ struct clk **clocks = data->clk_data.clks; \ -+ int i; \ -+ for (i = 0; i < nums; i++) { \ -+ int id = clks[i].id; \ -+ if (clocks[id]) \ -+ clk_unregister_##type(clocks[id]); \ -+ } \ -+} -+ -+gk_clk_unregister(fixed_rate) -+gk_clk_unregister(fixed_factor) -+gk_clk_unregister(mux) -+gk_clk_unregister(gate) -+ -+#endif /* __GOKE_CLK_H */ ---- linux-4.9.37/drivers/clk/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,39 @@ -+config COMMON_CLK_GK7205V200 -+ tristate "GK7205V200 Clock Driver" -+ depends on ARCH_GK7205V200 || COMPILE_TEST -+ select RESET_GOKE -+ default ARCH_GOKE -+ help -+ Build the clock driver for GK7205V200. -+ -+config COMMON_CLK_GK7205V300 -+ tristate "GK7205V300 Clock Driver" -+ depends on ARCH_GK7205V300 || COMPILE_TEST -+ select RESET_GOKE -+ default ARCH_GOKE -+ help -+ Build the clock driver for GK7205V300. -+ -+config COMMON_CLK_GK7202V300 -+ tristate "GK7202V300 Clock Driver" -+ depends on ARCH_GK7202V300 || COMPILE_TEST -+ select RESET_GOKE -+ default ARCH_GOKE -+ help -+ Build the clock driver for GK7202V300. -+ -+config COMMON_CLK_GK7605V100 -+ tristate "GK7605V100 Clock Driver" -+ depends on ARCH_GK7605V100 || COMPILE_TEST -+ select RESET_GOKE -+ default ARCH_GOKE -+ help -+ Build the clock driver for GK7605V100. -+ -+config RESET_GOKE -+ bool "Goke Reset Controller Driver" -+ depends on ARCH_GOKE || COMPILE_TEST || ARCH_GOKE -+ select RESET_CONTROLLER -+ help -+ Build reset controller driver for Goke device chipsets. -+ ---- linux-4.9.37/drivers/clk/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,10 @@ -+# -+# Goke Clock specific Makefile -+# -+ -+obj-y += clk.o -+obj-$(CONFIG_COMMON_CLK_GK7205V200) += clk-gk7205v200.o -+obj-$(CONFIG_COMMON_CLK_GK7205V300) += clk-gk7205v300.o -+obj-$(CONFIG_COMMON_CLK_GK7202V300) += clk-gk7202v300.o -+obj-$(CONFIG_COMMON_CLK_GK7605V100) += clk-gk7605v100.o -+obj-$(CONFIG_RESET_GOKE) += reset.o ---- linux-4.9.37/drivers/clk/goke/reset.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/reset.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,113 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "reset.h" -+ -+#define GOKE_RESET_BIT_MASK 0x1f -+#define GOKE_RESET_OFFSET_SHIFT 8 -+#define GOKE_RESET_OFFSET_MASK 0xffff00 -+ -+struct gk_reset_controller { -+ spinlock_t lock; -+ void __iomem *membase; -+ struct reset_controller_dev rcdev; -+}; -+ -+ -+#define to_gk_reset_controller(rcdev) \ -+ container_of(rcdev, struct gk_reset_controller, rcdev) -+ -+static int gk_reset_of_xlate(struct reset_controller_dev *rcdev, -+ const struct of_phandle_args *reset_spec) -+{ -+ u32 offset; -+ u8 bit; -+ -+ offset = (reset_spec->args[0] << GOKE_RESET_OFFSET_SHIFT) -+ & GOKE_RESET_OFFSET_MASK; -+ bit = reset_spec->args[1] & GOKE_RESET_BIT_MASK; -+ -+ return (offset | bit); -+} -+ -+static int gk_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct gk_reset_controller *rstc = to_gk_reset_controller(rcdev); -+ unsigned long flags; -+ u32 offset, reg; -+ u8 bit; -+ -+ offset = (id & GOKE_RESET_OFFSET_MASK) >> GOKE_RESET_OFFSET_SHIFT; -+ bit = id & GOKE_RESET_BIT_MASK; -+ -+ spin_lock_irqsave(&rstc->lock, flags); -+ -+ reg = readl(rstc->membase + offset); -+ writel(reg | BIT(bit), rstc->membase + offset); -+ -+ spin_unlock_irqrestore(&rstc->lock, flags); -+ -+ return 0; -+} -+ -+static int gk_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct gk_reset_controller *rstc = to_gk_reset_controller(rcdev); -+ unsigned long flags; -+ u32 offset, reg; -+ u8 bit; -+ -+ offset = (id & GOKE_RESET_OFFSET_MASK) >> GOKE_RESET_OFFSET_SHIFT; -+ bit = id & GOKE_RESET_BIT_MASK; -+ -+ spin_lock_irqsave(&rstc->lock, flags); -+ -+ reg = readl(rstc->membase + offset); -+ writel(reg & ~BIT(bit), rstc->membase + offset); -+ -+ spin_unlock_irqrestore(&rstc->lock, flags); -+ -+ return 0; -+} -+ -+static const struct reset_control_ops gk_reset_ops = { -+ .assert = gk_reset_assert, -+ .deassert = gk_reset_deassert, -+}; -+ -+int __init gk_reset_init(struct device_node *np, -+ int nr_rsts) -+{ -+ struct gk_reset_controller *rstc; -+ -+ rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); -+ if (!rstc) -+ return -ENOMEM; -+ -+ rstc->membase = of_iomap(np, 0); -+ if (!rstc->membase){ -+ kfree(rstc); -+ return -EINVAL; -+ } -+ -+ spin_lock_init(&rstc->lock); -+ -+ rstc->rcdev.owner = THIS_MODULE; -+ rstc->rcdev.nr_resets = nr_rsts; -+ rstc->rcdev.ops = &gk_reset_ops; -+ rstc->rcdev.of_node = np; -+ rstc->rcdev.of_reset_n_cells = 2; -+ rstc->rcdev.of_xlate = gk_reset_of_xlate; -+ -+ return reset_controller_register(&rstc->rcdev); -+} -+EXPORT_SYMBOL_GPL(gk_reset_init); ---- linux-4.9.37/drivers/clk/goke/reset.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/clk/goke/reset.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,15 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __GOKE_RESET_H -+#define __GOKE_RESET_H -+ -+struct device_node; -+struct gk_reset_controller; -+ -+#ifdef CONFIG_RESET_CONTROLLER -+int __init gk_reset_init(struct device_node *np, int nr_rsts); -+#endif -+ -+#endif /* __GOKE_RESET_H */ ---- linux-4.9.37/drivers/clk/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/clk/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -210,5 +210,6 @@ - source "drivers/clk/tegra/Kconfig" - source "drivers/clk/ti/Kconfig" - source "drivers/clk/uniphier/Kconfig" -+source "drivers/clk/goke/Kconfig" - - endmenu ---- linux-4.9.37/drivers/clk/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/clk/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -92,3 +92,4 @@ - endif - obj-$(CONFIG_ARCH_ZX) += zte/ - obj-$(CONFIG_ARCH_ZYNQ) += zynq/ -+obj-$(CONFIG_ARCH_GOKE) += goke/ -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/clocksource/arm_arch_timer.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/clocksource/arm_arch_timer.c 2021-06-07 13:01:33.000000000 +0300 -@@ -449,7 +449,10 @@ - | ARCH_TIMER_USR_PCT_ACCESS_EN); - - /* Enable user access to the virtual counter */ -- cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; -+ if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)) -+ cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; -+ else -+ cntkctl &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; - - arch_timer_set_cntkctl(cntkctl); - } ---- linux-4.9.37/drivers/clocksource/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/clocksource/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -305,6 +305,14 @@ - This must be disabled for hardware validation purposes to detect any - hardware anomalies of missing events. - -+config ARM_ARCH_TIMER_VCT_ACCESS -+ bool "Support for ARM architected timer virtual counter access in userspace" -+ default n -+ depends on ARM_ARCH_TIMER -+ help -+ This option enables support for reading the ARM architected timer's -+ virtual counter in userspace. -+ - config FSL_ERRATUM_A008585 - bool "Workaround for Freescale/NXP Erratum A-008585" - default y ---- linux-4.9.37/drivers/clocksource/timer-sp804.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/clocksource/timer-sp804.c 2021-06-07 13:01:33.000000000 +0300 -@@ -235,6 +235,10 @@ - writel(0, base + TIMER_CTRL); - writel(0, base + TIMER_2_BASE + TIMER_CTRL); - -+ /* Ensure timer interrupts are clear */ -+ writel(1, base + TIMER_INTCLR); -+ writel(1, base + TIMER_2_BASE + TIMER_INTCLR); -+ - if (initialized || !of_device_is_available(np)) { - ret = -EINVAL; - goto err; ---- linux-4.9.37/drivers/dma/edmac_goke.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/dma/edmac_goke.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,1286 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "edmac_goke.h" -+#include "dmaengine.h" -+#include "virt-dma.h" -+ -+#define DRIVER_NAME "edmac-goke" -+ -+int edmac_trace_level = EDMAC_TRACE_LEVEL; -+ -+typedef struct edmac_lli { -+ u64 next_lli; -+ u32 reserved[5]; -+ u32 count; -+ u64 src_addr; -+ u64 dest_addr; -+ u32 config; -+ u32 pad[3]; -+} edmac_lli; -+ -+struct edmac_sg { -+ dma_addr_t src_addr; -+ dma_addr_t dst_addr; -+ size_t len; -+ struct list_head node; -+}; -+ -+struct transfer_desc { -+ struct virt_dma_desc virt_desc; -+ -+ dma_addr_t llis_busaddr; -+ u64 *llis_vaddr; -+ u32 ccfg; -+ size_t size; -+ bool done; -+ bool cyclic; -+}; -+ -+enum edmac_dma_chan_state { -+ EDMAC_CHAN_IDLE, -+ EDMAC_CHAN_RUNNING, -+ EDMAC_CHAN_PAUSED, -+ EDMAC_CHAN_WAITING, -+}; -+ -+struct edmac_dma_chan { -+ bool slave; -+ int signal; -+ int id; -+ struct virt_dma_chan virt_chan; -+ struct edmac_phy_chan *phychan; -+ struct dma_slave_config cfg; -+ struct transfer_desc *at; -+ struct edmac_driver_data *host; -+ enum edmac_dma_chan_state state; -+}; -+ -+struct edmac_phy_chan { -+ unsigned int id; -+ void __iomem *base; -+ spinlock_t lock; -+ struct edmac_dma_chan *serving; -+}; -+ -+struct edmac_driver_data { -+ struct platform_device *dev; -+ struct dma_device slave; -+ struct dma_device memcpy; -+ void __iomem *base; -+ struct regmap *misc_regmap; -+ void __iomem *crg_ctrl; -+ struct edmac_phy_chan *phy_chans; -+ struct dma_pool *pool; -+ unsigned int misc_ctrl_base; -+ int irq; -+ unsigned int id; -+ struct clk *clk; -+ struct clk *axi_clk; -+ struct reset_control *rstc; -+ unsigned int channels; -+ unsigned int slave_requests; -+ unsigned int max_transfer_size; -+}; -+ -+#ifdef DEBUG_EDMAC -+void dump_lli(u64 *llis_vaddr, unsigned int num) -+{ -+ -+ edmac_lli *plli = (edmac_lli *)llis_vaddr; -+ unsigned int i; -+ -+ edmac_trace(3, "lli num = 0%d\n", num); -+ for (i = 0; i < num; i++) { -+ printk("lli%d:lli_L: 0x%llx\n", i, plli[i].next_lli & 0xffffffff); -+ printk("lli%d:lli_H: 0x%llx\n", i, plli[i].next_lli >> 32 & 0xffffffff); -+ printk("lli%d:count: 0x%llx\n", i, plli[i].count); -+ printk("lli%d:src_addr_L: 0x%llx\n", i, plli[i].src_addr & 0xffffffff); -+ printk("lli%d:src_addr_H: 0x%llx\n", i, plli[i].src_addr >> 32 & 0xffffffff); -+ printk("lli%d:dst_addr_L: 0x%llx\n", i, plli[i].dest_addr & 0xffffffff); -+ printk("lli%d:dst_addr_H: 0x%llx\n", i, plli[i].dest_addr >> 32 & 0xffffffff); -+ printk("lli%d:CONFIG: 0x%llx\n", i, plli[i].config); -+ } -+} -+ -+#else -+void dump_lli(u64 *llis_vaddr, unsigned int num) -+{ -+} -+#endif -+ -+static inline struct edmac_dma_chan *to_edamc_chan(struct dma_chan *chan) -+{ -+ return container_of(chan, struct edmac_dma_chan, virt_chan.chan); -+} -+ -+static inline struct transfer_desc *to_edmac_transfer_desc(struct dma_async_tx_descriptor *tx) -+{ -+ return container_of(tx, struct transfer_desc, virt_desc.tx); -+} -+ -+static struct dma_chan *edmac_find_chan_id(struct edmac_driver_data *edmac, -+ int request_num) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = NULL; -+ -+ list_for_each_entry(edmac_dma_chan, &edmac->slave.channels, virt_chan.chan.device_node) { -+ if (edmac_dma_chan->id == request_num) { -+ return &edmac_dma_chan->virt_chan.chan; -+ } -+ } -+ return NULL; -+} -+ -+static struct dma_chan *edma_of_xlate(struct of_phandle_args *dma_spec, -+ struct of_dma *ofdma) -+{ -+ struct edmac_driver_data *edmac = ofdma->of_dma_data; -+ struct edmac_dma_chan *edmac_dma_chan = NULL; -+ struct dma_chan *dma_chan = NULL; -+ struct regmap *misc = NULL; -+ unsigned int signal = 0, request_num = 0; -+ unsigned int reg = 0, offset = 0; -+ -+ if (!edmac) { -+ return NULL; -+ } -+ -+ misc = edmac->misc_regmap; -+ -+ if (dma_spec->args_count != 2) { -+ edmac_error("args count not true!\n"); -+ return NULL; -+ } -+ -+ request_num = dma_spec->args[0]; -+ signal = dma_spec->args[1]; -+ -+ edmac_trace(3, "host->id = %d,signal = %d, request_num = %d\n", edmac->id, signal, request_num); -+ -+ if (misc != NULL) { -+#ifdef CONFIG_ACCESS_M7_DEV -+ offset = edmac->misc_ctrl_base; -+ reg = 0xc0; -+ regmap_write(misc, offset, reg); -+#else -+ offset = edmac->misc_ctrl_base + (request_num & (~0x3)); -+ regmap_read(misc, offset, ®); -+ reg &= ~(0x3f << ((request_num & 0x3) << 3)); -+ reg |= signal << ((request_num & 0x3) << 3); -+ regmap_write(misc, offset, reg); -+#endif -+ } -+ -+ edmac_trace(3, "offset = 0x%x, reg = 0x%x\n", offset, reg); -+ -+ dma_chan = edmac_find_chan_id(edmac, request_num); -+ if (!dma_chan) { -+ edmac_error("DMA slave channel is not found!\n"); -+ return NULL; -+ } -+ -+ edmac_dma_chan = to_edamc_chan(dma_chan); -+ edmac_dma_chan->signal = request_num; -+ -+ return dma_get_slave_channel(dma_chan); -+} -+ -+ -+static int get_of_probe(struct edmac_driver_data *edmac) -+{ -+ struct resource *res = NULL; -+ struct platform_device *platdev = edmac->dev; -+ struct device_node *np = platdev->dev.of_node; -+ int ret; -+ -+ ret = of_property_read_u32((&platdev->dev)->of_node, -+ "devid", &(edmac->id)); -+ if (ret) { -+ edmac_error("get edmac id fail\n"); -+ return -ENODEV; -+ } -+ -+ edmac->clk = devm_clk_get(&(platdev->dev), "apb_pclk"); -+ if (IS_ERR(edmac->clk)) { -+ return PTR_ERR(edmac->clk); -+ } -+ -+ edmac->axi_clk = devm_clk_get(&(platdev->dev), "axi_aclk"); -+ if (IS_ERR(edmac->axi_clk)) { -+ return PTR_ERR(edmac->axi_clk); -+ } -+ -+ edmac->rstc = devm_reset_control_get(&(platdev->dev), "dma-reset"); -+ if (IS_ERR(edmac->rstc)) { -+ return PTR_ERR(edmac->rstc); -+ } -+ -+ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ edmac_error("no reg resource\n"); -+ return -ENODEV; -+ } -+ -+ edmac->base = devm_ioremap_resource(&(platdev->dev), res); -+ if (IS_ERR(edmac->base)) { -+ return PTR_ERR(edmac->base); -+ } -+#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) || \ -+ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) -+ edmac->misc_regmap = 0; -+ (void)np; -+#else -+ edmac->misc_regmap = syscon_regmap_lookup_by_phandle(np, "misc_regmap"); -+ if (IS_ERR(edmac->misc_regmap)) { -+ return PTR_ERR(edmac->misc_regmap); -+ } -+ -+ ret = of_property_read_u32((&platdev->dev)->of_node, -+ "misc_ctrl_base", &(edmac->misc_ctrl_base)); -+ if (ret) { -+ edmac_error( "get dma-misc_ctrl_base fail\n"); -+ return -ENODEV; -+ } -+#endif -+ edmac->irq = platform_get_irq(platdev, 0); -+ if (unlikely(edmac->irq < 0)) { -+ return -ENODEV; -+ } -+ -+ ret = of_property_read_u32((&platdev->dev)->of_node, -+ "dma-channels", &(edmac->channels)); -+ if (ret) { -+ edmac_error( "get dma-channels fail\n"); -+ return -ENODEV; -+ } -+ ret = of_property_read_u32((&platdev->dev)->of_node, -+ "dma-requests", &(edmac->slave_requests)); -+ if (ret) { -+ edmac_error( "get dma-requests fail\n"); -+ return -ENODEV; -+ } -+ edmac_trace(2, "dma-channels = %d, dma-requests = %d\n", -+ edmac->channels, edmac->slave_requests); -+ return of_dma_controller_register(platdev->dev.of_node, edma_of_xlate, edmac); -+} -+ -+static void edmac_free_chan_resources(struct dma_chan *chan) -+{ -+ vchan_free_chan_resources(to_virt_chan(chan)); -+} -+ -+static enum dma_status edmac_tx_status(struct dma_chan *chan, -+ dma_cookie_t cookie, struct dma_tx_state *txstate) -+{ -+ enum dma_status ret = DMA_COMPLETE; -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct virt_dma_desc *vd = NULL; -+ struct transfer_desc *tsf_desc = NULL; -+ unsigned long flags; -+ size_t bytes = 0; -+ u64 curr_lli = 0, curr_residue_bytes = 0, temp = 0; -+ edmac_lli *plli = NULL; -+ unsigned int i = 0, index = 0; -+ -+ ret = dma_cookie_status(chan, cookie, txstate); -+ if (ret == DMA_COMPLETE) { -+ return ret; -+ } -+ -+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); -+ vd = vchan_find_desc(&edmac_dma_chan->virt_chan, cookie); -+ if (vd) { -+ /* no been trasfer */ -+ tsf_desc = to_edmac_transfer_desc(&vd->tx); -+ bytes = tsf_desc->size; -+ } else { -+ /* trasfering */ -+ tsf_desc = edmac_dma_chan->at; -+ -+ if (!phychan || !tsf_desc) { -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ goto out; -+ } -+ curr_lli = (edmac_readl(edmac->base + EDMAC_Cx_LLI_L(phychan->id)) & (~(EDMAC_LLI_ALIGN - 1))); -+ curr_lli |= ((u64)(edmac_readl(edmac->base + EDMAC_Cx_LLI_H(phychan->id)) & 0xffffffff) << 32); -+ curr_residue_bytes = edmac_readl(edmac->base + EDMAC_Cx_CURR_CNT0(phychan->id)); -+ if (curr_lli == 0) { -+ /* It means non-lli mode */ -+ bytes = curr_residue_bytes; -+ } else { -+ /* It means lli mode */ -+ index = (curr_lli - tsf_desc->llis_busaddr) / sizeof(edmac_lli) - 1; -+ plli = (edmac_lli *)(tsf_desc->llis_vaddr); -+ for (i = 0; i < index; i++) { -+ temp += plli[i].count; -+ } -+ temp += plli[i].count - curr_residue_bytes; -+ bytes = tsf_desc->size - temp; -+ } -+ } -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ -+ dma_set_residue(txstate, bytes); -+ -+ if (edmac_dma_chan->state == EDMAC_CHAN_PAUSED && ret == DMA_IN_PROGRESS) { -+ ret = DMA_PAUSED; -+ return ret; -+ } -+ -+out: -+ return ret; -+} -+ -+static struct edmac_phy_chan *edmac_get_phy_channel( -+ struct edmac_driver_data *edmac, -+ struct edmac_dma_chan *edmac_dma_chan) -+{ -+ struct edmac_phy_chan *ch = NULL; -+ unsigned long flags; -+ int i; -+ -+ for (i = 0; i < edmac->channels; i++) { -+ ch = &edmac->phy_chans[i]; -+ -+ spin_lock_irqsave(&ch->lock, flags); -+ -+ if (!ch->serving) { -+ ch->serving = edmac_dma_chan; -+ spin_unlock_irqrestore(&ch->lock, flags); -+ break; -+ } -+ spin_unlock_irqrestore(&ch->lock, flags); -+ } -+ -+ if (i == edmac->channels) { -+ return NULL; -+ } -+ -+ return ch; -+} -+ -+static void edmac_write_lli(struct edmac_driver_data *edmac, -+ struct edmac_phy_chan *phychan, -+ struct transfer_desc *tsf_desc) -+{ -+ -+ edmac_lli *plli = (edmac_lli *)tsf_desc->llis_vaddr; -+ -+ if (plli->next_lli != 0x0) { -+ edmac_writel((plli->next_lli & 0xffffffff) | EDMAC_LLI_ENABLE, edmac->base + EDMAC_Cx_LLI_L(phychan->id)); -+ } else { -+ edmac_writel((plli->next_lli & 0xffffffff), edmac->base + EDMAC_Cx_LLI_L(phychan->id)); -+ } -+ -+ edmac_writel(((plli->next_lli >> 32) & 0xffffffff), edmac->base + EDMAC_Cx_LLI_H(phychan->id)); -+ edmac_writel(plli->count, edmac->base + EDMAC_Cx_CNT0(phychan->id)); -+ edmac_writel(plli->src_addr & 0xffffffff, edmac->base + EDMAC_Cx_SRC_ADDR_L(phychan->id)); -+ edmac_writel((plli->src_addr >> 32) & 0xffffffff, edmac->base + EDMAC_Cx_SRC_ADDR_H(phychan->id)); -+ edmac_writel(plli->dest_addr & 0xffffffff, edmac->base + EDMAC_Cx_DEST_ADDR_L(phychan->id)); -+ edmac_writel((plli->dest_addr >> 32) & 0xffffffff, edmac->base + EDMAC_Cx_DEST_ADDR_H(phychan->id)); -+ edmac_writel(plli->config, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+} -+ -+static void edmac_start_next_txd(struct edmac_dma_chan *edmac_dma_chan) -+{ -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; -+ struct virt_dma_desc *vd = vchan_next_desc(&edmac_dma_chan->virt_chan); -+ struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx); -+ unsigned int val = 0; -+ -+ list_del(&tsf_desc->virt_desc.node); -+ -+ edmac_dma_chan->at = tsf_desc; -+ -+ edmac_write_lli(edmac, phychan, tsf_desc); -+ -+ val = edmac_readl(edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+ -+ edmac_trace(2, " EDMAC_Cx_CONFIG = 0x%x\n", val); -+ edmac_writel(val | EDMAC_CxCONFIG_LLI_START, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+} -+ -+static void edmac_start(struct edmac_dma_chan * edmac_dma_chan) -+{ -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct edmac_phy_chan *ch; -+ -+ ch = edmac_get_phy_channel(edmac, edmac_dma_chan); -+ if (!ch) { -+ edmac_error("no phy channel available !\n"); -+ edmac_dma_chan->state = EDMAC_CHAN_WAITING; -+ return; -+ } -+ -+ edmac_dma_chan->phychan = ch; -+ edmac_dma_chan->state = EDMAC_CHAN_RUNNING; -+ -+ edmac_start_next_txd(edmac_dma_chan); -+} -+ -+static void edmac_issue_pending(struct dma_chan *chan) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); -+ if (vchan_issue_pending(&edmac_dma_chan->virt_chan)) { -+ if (!edmac_dma_chan->phychan && edmac_dma_chan->state != EDMAC_CHAN_WAITING) { -+ edmac_start(edmac_dma_chan); -+ } -+ } -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+} -+ -+static void edmac_free_txd_list(struct edmac_dma_chan *edmac_dma_chan) -+{ -+ LIST_HEAD(head); -+ -+ vchan_get_all_descriptors(&edmac_dma_chan->virt_chan, &head); -+ vchan_dma_desc_free_list(&edmac_dma_chan->virt_chan, &head); -+} -+ -+static int edmac_config(struct dma_chan *chan, -+ struct dma_slave_config *config) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ -+ if (!edmac_dma_chan->slave) { -+ edmac_error("slave is null!"); -+ return -EINVAL; -+ } -+ -+ edmac_dma_chan->cfg = *config; -+ -+ return 0; -+} -+ -+static void edmac_pause_phy_chan(struct edmac_dma_chan *edmac_dma_chan) -+{ -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; -+ unsigned int val; -+ int timeout; -+ -+ -+ val = edmac_readl(edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+ val &= ~CCFG_EN; -+ edmac_writel(val, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+ -+ /* Wait for channel inactive */ -+ for (timeout = 2000; timeout > 0; timeout--) { -+ if (!(0x1 << phychan->id & edmac_readl(edmac->base + EDMAC_CH_STAT))) { -+ break; -+ } -+ edmac_writel(val, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+ udelay(1); -+ } -+ -+ if (timeout == 0) { -+ edmac_error(":channel%u timeout waiting for pause, timeout:%d\n", -+ phychan->id, timeout); -+ } -+} -+ -+static int edmac_pause(struct dma_chan *chan) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); -+ -+ if (!edmac_dma_chan->phychan) { -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ return 0; -+ } -+ -+ edmac_pause_phy_chan(edmac_dma_chan); -+ edmac_dma_chan->state = EDMAC_CHAN_PAUSED; -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ -+ return 0; -+} -+ -+static void edmac_resume_phy_chan(struct edmac_dma_chan *edmac_dma_chan) -+{ -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; -+ unsigned int val; -+ -+ val = edmac_readl(edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+ val |= CCFG_EN; -+ edmac_writel(val, edmac->base + EDMAC_Cx_CONFIG(phychan->id)); -+} -+ -+static int edmac_resume(struct dma_chan *chan) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); -+ -+ if (!edmac_dma_chan->phychan) { -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ return 0; -+ } -+ -+ edmac_resume_phy_chan(edmac_dma_chan); -+ edmac_dma_chan->state = EDMAC_CHAN_RUNNING; -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ -+ return 0; -+} -+ -+void edmac_phy_free(struct edmac_dma_chan *chan); -+static void edmac_desc_free(struct virt_dma_desc *vd); -+static int edmac_terminate_all(struct dma_chan *chan) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags); -+ if (!edmac_dma_chan->phychan && !edmac_dma_chan->at) { -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ return 0; -+ } -+ -+ edmac_dma_chan->state = EDMAC_CHAN_IDLE; -+ -+ if (edmac_dma_chan->phychan) { -+ edmac_phy_free(edmac_dma_chan); -+ } -+ -+ if (edmac_dma_chan->at) { -+ edmac_desc_free(&edmac_dma_chan->at->virt_desc); -+ edmac_dma_chan->at = NULL; -+ } -+ edmac_free_txd_list(edmac_dma_chan); -+ -+ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -+ -+ return 0; -+} -+ -+static struct transfer_desc *edmac_get_tsf_desc(struct edmac_driver_data *plchan) -+{ -+ struct transfer_desc *tsf_desc = kzalloc(sizeof(struct transfer_desc), GFP_NOWAIT); -+ -+ if (tsf_desc) { -+ tsf_desc->ccfg = 0; -+ } -+ -+ return tsf_desc; -+} -+ -+static void edmac_free_tsf_desc(struct edmac_driver_data *edmac, -+ struct transfer_desc *tsf_desc) -+{ -+ if (tsf_desc->llis_vaddr) { -+ dma_pool_free(edmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); -+ } -+ -+ kfree(tsf_desc); -+} -+ -+static u32 get_width(enum dma_slave_buswidth width) -+{ -+ switch (width) { -+ case DMA_SLAVE_BUSWIDTH_1_BYTE: -+ return EDMAC_WIDTH_8BIT; -+ case DMA_SLAVE_BUSWIDTH_2_BYTES: -+ return EDMAC_WIDTH_16BIT; -+ case DMA_SLAVE_BUSWIDTH_4_BYTES: -+ return EDMAC_WIDTH_32BIT; -+ case DMA_SLAVE_BUSWIDTH_8_BYTES: -+ return EDMAC_WIDTH_64BIT; -+ default: -+ edmac_error("check here, width warning!\n"); -+ return ~0; -+ } -+} -+ -+struct transfer_desc *edmac_init_tsf_desc ( -+ struct dma_chan *chan, -+ enum dma_transfer_direction direction, -+ dma_addr_t *slave_addr) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct transfer_desc *tsf_desc; -+ unsigned int config = 0, burst = 0; -+ unsigned int addr_width = 0, maxburst = 0; -+ unsigned int width = 0; -+ -+ tsf_desc = edmac_get_tsf_desc(edmac); -+ if (!tsf_desc) { -+ edmac_error("get tsf desc fail!\n"); -+ return NULL; -+ } -+ -+ if (direction == DMA_MEM_TO_DEV) { -+ config = EDMAC_CONFIG_SRC_INC; -+ *slave_addr = edmac_dma_chan->cfg.dst_addr; -+ addr_width = edmac_dma_chan->cfg.dst_addr_width; -+ maxburst = edmac_dma_chan->cfg.dst_maxburst; -+ } else if (direction == DMA_DEV_TO_MEM) { -+ config = EDMAC_CONFIG_DST_INC; -+ *slave_addr = edmac_dma_chan->cfg.src_addr; -+ addr_width = edmac_dma_chan->cfg.src_addr_width; -+ maxburst = edmac_dma_chan->cfg.src_maxburst; -+ } else { -+ edmac_free_tsf_desc(edmac, tsf_desc); -+ edmac_error("direction unsupported!\n"); -+ return NULL; -+ } -+ -+ edmac_trace(3, "addr_width = 0x%x\n", addr_width); -+ width = get_width(addr_width); -+ edmac_trace(3, "width = 0x%x\n", width); -+ config |= width << EDMAC_CONFIG_SRC_WIDTH_SHIFT; -+ config |= width << EDMAC_CONFIG_DST_WIDTH_SHIFT; -+ edmac_trace(2, "tsf_desc->ccfg = 0x%x\n", config); -+ -+ edmac_trace(3, "maxburst = 0x%x\n", maxburst); -+ if (maxburst > (EDMAC_MAX_BURST_WIDTH)) { -+ burst |= (EDMAC_MAX_BURST_WIDTH - 1); -+ } else if (maxburst == 0) { -+ burst |= EDMAC_MIN_BURST_WIDTH; -+ } else { -+ burst |= (maxburst - 1); -+ } -+ edmac_trace(3, "burst = 0x%x\n", burst); -+ config |= burst << EDMAC_CONFIG_SRC_BURST_SHIFT; -+ config |= burst << EDMAC_CONFIG_DST_BURST_SHIFT; -+ -+ if (edmac_dma_chan->signal >= 0) { -+ edmac_trace(2, "edmac_dma_chan->signal = %d\n", edmac_dma_chan->signal); -+ config |= (unsigned int)edmac_dma_chan->signal << EDMAC_CXCONFIG_SIGNAL_SHIFT; -+ } -+ -+ config |= EDMAC_CXCONFIG_DEV_MEM_TYPE << EDMAC_CXCONFIG_TSF_TYPE_SHIFT; -+ tsf_desc->ccfg = config; -+ edmac_trace(2, "tsf_desc->ccfg = 0x%x\n", tsf_desc->ccfg); -+ -+ return tsf_desc; -+} -+ -+static void edmac_fill_desc(struct transfer_desc *tsf_desc, dma_addr_t src, -+ dma_addr_t dst, unsigned int length, unsigned int num) -+{ -+ edmac_lli *plli; -+ -+ plli = (edmac_lli *)(tsf_desc->llis_vaddr); -+ memset(&plli[num], 0x0, sizeof(edmac_lli)); -+ -+ plli[num].src_addr = src; -+ plli[num].dest_addr = dst; -+ plli[num].config = tsf_desc->ccfg; -+ plli[num].count = length; -+ tsf_desc->size += length; -+ -+ if (num > 0) { -+ plli[num - 1].next_lli = (tsf_desc->llis_busaddr + (num) * sizeof(edmac_lli)) & (~(EDMAC_LLI_ALIGN - 1)); -+ plli[num - 1].next_lli |= EDMAC_LLI_ENABLE; -+ } -+} -+ -+static struct dma_async_tx_descriptor *edmac_perp_slave_sg( -+ struct dma_chan *chan, struct scatterlist *sgl, -+ unsigned int sg_len, enum dma_transfer_direction direction, -+ unsigned long flags, void *context) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct transfer_desc *tsf_desc = NULL; -+ struct scatterlist *sg = NULL; -+ int tmp = 0; -+ dma_addr_t src = 0, dst = 0, addr = 0, slave_addr = 0; -+ unsigned int length = 0, num = 0; -+ -+ edmac_lli *last_plli = NULL; -+ -+ if (sgl == NULL) { -+ edmac_error("sgl is null!\n"); -+ return NULL; -+ } -+ -+ tsf_desc = edmac_init_tsf_desc(chan, direction, &slave_addr); -+ if (!tsf_desc) { -+ edmac_error("desc init fail\n"); -+ return NULL; -+ } -+ -+ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, &tsf_desc->llis_busaddr); -+ if (!tsf_desc->llis_vaddr) { -+ edmac_free_tsf_desc(edmac, tsf_desc); -+ edmac_error("malloc memory from pool fail !\n"); -+ return 0; -+ } -+ -+ for_each_sg(sgl, sg, sg_len, tmp) { -+ addr = sg_dma_address(sg); -+ length = sg_dma_len(sg); -+ if (direction == DMA_MEM_TO_DEV) { -+ src = addr; -+ dst = slave_addr; -+ } else if (direction == DMA_DEV_TO_MEM) { -+ src = slave_addr; -+ dst = addr; -+ } -+ edmac_fill_desc(tsf_desc, src, dst, length, num); -+ num++; -+ } -+ -+ last_plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num - 1) * sizeof(edmac_lli)); -+ last_plli->next_lli |= EDMAC_LLI_DISABLE; -+ dump_lli(tsf_desc->llis_vaddr, num); -+ -+ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); -+} -+ -+static struct dma_async_tx_descriptor *edmac_prep_dma_memcpy( -+ struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, -+ size_t len, unsigned long flags) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct transfer_desc *tsf_desc = NULL; -+ u32 config = 0; -+ size_t num = 0; -+ size_t length = 0; -+ edmac_lli *last_plli = NULL; -+ -+ if (!len) { -+ return NULL; -+ } -+ -+ tsf_desc = edmac_get_tsf_desc(edmac); -+ if (!tsf_desc) { -+ edmac_error("get tsf desc fail!\n"); -+ return NULL; -+ } -+ -+ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, &tsf_desc->llis_busaddr); -+ if (!tsf_desc->llis_vaddr) { -+ edmac_free_tsf_desc(edmac, tsf_desc); -+ edmac_error("malloc memory from pool fail !\n"); -+ return 0; -+ } -+ -+ config |= EDMAC_CONFIG_SRC_INC | EDMAC_CONFIG_DST_INC; -+ config |= EDMAC_CXCONFIG_MEM_TYPE << EDMAC_CXCONFIG_TSF_TYPE_SHIFT; -+ -+ /* max burst width is 16 ,but reg value set 0xf */ -+ config |= (EDMAC_MAX_BURST_WIDTH - 1) << EDMAC_CONFIG_SRC_BURST_SHIFT; -+ config |= (EDMAC_MAX_BURST_WIDTH - 1) << EDMAC_CONFIG_DST_BURST_SHIFT; -+ -+ tsf_desc->ccfg = config; -+ -+ do { -+ length = min_t(size_t, len, MAX_TRANSFER_BYTES); -+ edmac_fill_desc(tsf_desc, src, dest, length, num); -+ -+ src += length; -+ dest += length; -+ len -= length; -+ num++; -+ } while(len); -+ -+ last_plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num - 1) * sizeof(edmac_lli)); -+ last_plli->next_lli |= EDMAC_LLI_DISABLE; -+ dump_lli(tsf_desc->llis_vaddr, num); -+ -+ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); -+} -+ -+ -+ -+static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( -+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, -+ size_t period_len, enum dma_transfer_direction direction, -+ unsigned long flags) -+{ -+ struct edmac_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -+ struct edmac_driver_data *edmac = edmac_dma_chan->host; -+ struct transfer_desc *tsf_desc; -+ dma_addr_t src = 0, dst = 0, addr = 0, slave_addr = 0; -+ size_t length = 0, since = 0, total = 0, num = 0, len = 0; -+ edmac_lli *last_plli = NULL; -+ edmac_lli *plli = NULL; -+ -+ tsf_desc = edmac_init_tsf_desc(chan, direction, &slave_addr); -+ if (!tsf_desc) { -+ edmac_error("desc init fail\n"); -+ return NULL; -+ } -+ -+ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, &tsf_desc->llis_busaddr); -+ if (!tsf_desc->llis_vaddr) { -+ edmac_free_tsf_desc(edmac, tsf_desc); -+ edmac_error("malloc memory from pool fail !\n"); -+ return 0; -+ } -+ -+ tsf_desc->cyclic = true; -+ addr = buf_addr; -+ total = buf_len; -+ -+ if (period_len < MAX_TRANSFER_BYTES) { -+ len = period_len; -+ } -+ do { -+ length = min_t(size_t, total, len); -+ -+ if (direction == DMA_MEM_TO_DEV) { -+ src = addr; -+ dst = slave_addr; -+ } else if (direction == DMA_DEV_TO_MEM) { -+ src = slave_addr; -+ dst = addr; -+ } -+ -+ edmac_fill_desc(tsf_desc, src, dst, length, num); -+ -+ since += length; -+ if (since >= period_len) { -+ plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num) * sizeof(edmac_lli)); -+ plli->config |= EDMAC_CXCONFIG_ITC_EN << EDMAC_CXCONFIG_ITC_EN_SHIFT; -+ since -= period_len; -+ } -+ addr += length; -+ total -= length; -+ num++; -+ } while(total); -+ -+ last_plli = (edmac_lli *)((unsigned long)tsf_desc->llis_vaddr + (num - 1) * sizeof(edmac_lli)); -+ -+ last_plli->next_lli = (unsigned long)(tsf_desc->llis_vaddr); -+ -+ dump_lli(tsf_desc->llis_vaddr, num); -+ -+ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); -+} -+ -+ -+static void edmac_phy_reassign(struct edmac_phy_chan *phy_chan, -+ struct edmac_dma_chan *chan) -+{ -+ phy_chan->serving = chan; -+ chan->phychan = phy_chan; -+ chan->state = EDMAC_CHAN_RUNNING; -+ -+ edmac_start_next_txd(chan); -+} -+ -+static void edmac_terminate_phy_chan(struct edmac_driver_data *edmac, -+ struct edmac_dma_chan *edmac_dma_chan) -+{ -+ unsigned int val; -+ struct edmac_phy_chan *phychan = edmac_dma_chan->phychan; -+ -+ edmac_pause_phy_chan(edmac_dma_chan); -+ -+ val = 0x1 << phychan->id; -+ -+ edmac_writel(val, edmac->base + EDMAC_INT_TC1_RAW); -+ edmac_writel(val, edmac->base + EDMAC_INT_ERR1_RAW); -+ edmac_writel(val, edmac->base + EDMAC_INT_ERR2_RAW); -+} -+ -+void edmac_phy_free(struct edmac_dma_chan *chan) -+{ -+ struct edmac_driver_data *edmac = chan->host; -+ struct edmac_dma_chan *p = NULL; -+ struct edmac_dma_chan *next = NULL; -+ -+ list_for_each_entry(p, &edmac->memcpy.channels, virt_chan.chan.device_node) { -+ if (p->state == EDMAC_CHAN_WAITING) { -+ next = p; -+ break; -+ } -+ } -+ -+ if (!next) { -+ list_for_each_entry(p, &edmac->slave.channels, virt_chan.chan.device_node) { -+ if (p->state == EDMAC_CHAN_WAITING) { -+ next = p; -+ break; -+ } -+ } -+ } -+ edmac_terminate_phy_chan(edmac, chan); -+ -+ if (next) { -+ spin_lock(&next->virt_chan.lock); -+ edmac_phy_reassign(chan->phychan, next); -+ spin_unlock(&next->virt_chan.lock); -+ } else { -+ chan->phychan->serving = NULL; -+ } -+ -+ chan->phychan = NULL; -+ chan->state = EDMAC_CHAN_IDLE; -+} -+ -+static irqreturn_t edmac_irq(int irq, void *dev) -+{ -+ struct edmac_driver_data *edmac = (struct edmac_driver_data *)dev; -+ struct edmac_dma_chan *chan = NULL; -+ struct edmac_phy_chan *phy_chan = NULL; -+ struct transfer_desc * tsf_desc = NULL; -+ -+ u32 mask = 0; -+ unsigned int channel_err_status[3]; -+ unsigned int channel_status = 0; -+ unsigned int temp = 0; -+ unsigned int channel_tc_status = -1; -+ unsigned int i = 0; -+ -+ channel_status = edmac_readl(edmac->base + EDMAC_INT_STAT); -+ -+ if (!channel_status) { -+ edmac_error("channel_status = 0x%x\n", channel_status); -+ return IRQ_NONE; -+ } -+ -+ for (i = 0; i < edmac->channels; i++) { -+ temp = (channel_status >> i) & 0x1; -+ if (temp) { -+ phy_chan = &edmac->phy_chans[i]; -+ chan = phy_chan->serving; -+ if (!chan) { -+ edmac_error("error interrupt on chan: %d!\n", i); -+ continue; -+ } -+ tsf_desc = chan->at; -+ -+ channel_tc_status = edmac_readl(edmac->base + EDMAC_INT_TC1_RAW); -+ channel_tc_status = (channel_tc_status >> i) & 0x01; -+ if (channel_tc_status) { -+ edmac_writel(channel_tc_status << i, edmac->base + EDMAC_INT_TC1_RAW); -+ } -+ -+ channel_tc_status = edmac_readl(edmac->base + EDMAC_INT_TC2); -+ channel_tc_status = (channel_tc_status >> i) & 0x01; -+ if (channel_tc_status) { -+ edmac_writel(channel_tc_status << i, edmac->base + EDMAC_INT_TC2_RAW); -+ } -+ -+ channel_err_status[0] = edmac_readl(edmac->base + EDMAC_INT_ERR1); -+ channel_err_status[0] = (channel_err_status[0] >> i) & 0x01; -+ channel_err_status[1] = edmac_readl(edmac->base + EDMAC_INT_ERR2); -+ channel_err_status[1] = (channel_err_status[1] >> i) & 0x01; -+ channel_err_status[2] = edmac_readl(edmac->base + EDMAC_INT_ERR3); -+ channel_err_status[2] = (channel_err_status[2] >> i) & 0x01; -+ if (channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) { -+ edmac_error("Error in edmac %d finish!,ERR1 = 0x%x,ERR2 = 0x%x,ERR3 = 0x%x\n", -+ i, channel_err_status[0], channel_err_status[1], channel_err_status[2]); -+ edmac_writel(1 << i, edmac->base + EDMAC_INT_ERR1_RAW); -+ edmac_writel(1 << i, edmac->base + EDMAC_INT_ERR2_RAW); -+ edmac_writel(1 << i, edmac->base + EDMAC_INT_ERR3_RAW); -+ } -+ -+ spin_lock(&chan->virt_chan.lock); -+ -+ if (tsf_desc->cyclic) { -+ vchan_cyclic_callback(&tsf_desc->virt_desc); -+ spin_unlock(&chan->virt_chan.lock); -+ continue; -+ } -+ chan->at = NULL; -+ tsf_desc->done = true; -+ vchan_cookie_complete(&tsf_desc->virt_desc); -+ -+ if (vchan_next_desc(&chan->virt_chan)) { -+ edmac_start_next_txd(chan); -+ } else { -+ edmac_phy_free(chan); -+ } -+ -+ spin_unlock(&chan->virt_chan.lock); -+ mask |= (1 << i); -+ } -+ } -+ -+ return mask ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+static void edmac_dma_slave_init(struct edmac_dma_chan *chan) -+{ -+ chan->slave = true; -+} -+ -+static void edmac_desc_free(struct virt_dma_desc *vd) -+{ -+ struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx); -+ struct edmac_dma_chan * edmac_dma_chan = to_edamc_chan(vd->tx.chan); -+ -+ dma_descriptor_unmap(&vd->tx); -+ edmac_free_tsf_desc(edmac_dma_chan->host, tsf_desc); -+} -+ -+static int edmac_init_virt_channels(struct edmac_driver_data *edmac, -+ struct dma_device *dmadev, unsigned int channels, bool slave) -+{ -+ struct edmac_dma_chan *chan = NULL; -+ int i; -+ INIT_LIST_HEAD(&dmadev->channels); -+ -+ for (i = 0; i < channels; i++) { -+ chan = kzalloc(sizeof(struct edmac_dma_chan), GFP_KERNEL); -+ if (!chan) { -+ edmac_error("fail to allocate memory for virt channels!"); -+ return -1; -+ } -+ -+ chan->host = edmac; -+ chan->state = EDMAC_CHAN_IDLE; -+ chan->signal = -1; -+ -+ if (slave) { -+ chan->id = i; -+ edmac_dma_slave_init(chan); -+ } -+ chan->virt_chan.desc_free = edmac_desc_free; -+ vchan_init(&chan->virt_chan, dmadev); -+ } -+ return 0; -+} -+ -+void edmac_free_virt_channels(struct dma_device *dmadev) -+{ -+ struct edmac_dma_chan *chan = NULL; -+ struct edmac_dma_chan *next = NULL; -+ -+ list_for_each_entry_safe(chan, -+ next, &dmadev->channels, virt_chan.chan.device_node) { -+ list_del(&chan->virt_chan.chan.device_node); -+ kfree(chan); -+ } -+} -+ -+ -+#define MAX_TSFR_LLIS 32 -+#define EDMACV300_LLI_WORDS 16 -+#define EDMACV300_POOL_ALIGN 16 -+ -+static int __init edmac_probe(struct platform_device *pdev) -+{ -+ -+ int ret = 0, i = 0; -+ struct edmac_driver_data *edmac = NULL; -+ size_t trasfer_size = 0; -+ -+ ret = dma_set_mask_and_coherent(&(pdev->dev), DMA_BIT_MASK(64)); -+ if (ret) { -+ return ret; -+ } -+ -+ edmac = kzalloc(sizeof(*edmac), GFP_KERNEL); -+ if (!edmac) { -+ edmac_error("malloc for edmac fail!"); -+ ret = -ENOMEM; -+ return ret; -+ } -+ edmac->dev = pdev; -+ -+ ret = get_of_probe(edmac); -+ if (ret) { -+ edmac_error("get dts info fail!"); -+ goto free_edmac; -+ } -+ -+ -+ clk_prepare_enable(edmac->clk); -+ clk_prepare_enable(edmac->axi_clk); -+ -+ reset_control_deassert(edmac->rstc); -+ -+ dma_cap_set(DMA_MEMCPY, edmac->memcpy.cap_mask); -+ edmac->memcpy.dev = &pdev->dev; -+ edmac->memcpy.device_free_chan_resources = edmac_free_chan_resources; -+ edmac->memcpy.device_prep_dma_memcpy = edmac_prep_dma_memcpy; -+ edmac->memcpy.device_tx_status = edmac_tx_status; -+ edmac->memcpy.device_issue_pending = edmac_issue_pending; -+ edmac->memcpy.device_config = edmac_config; -+ edmac->memcpy.device_pause = edmac_pause; -+ edmac->memcpy.device_resume = edmac_resume; -+ edmac->memcpy.device_terminate_all = edmac_terminate_all; -+ edmac->memcpy.directions = BIT(DMA_MEM_TO_MEM); -+ edmac->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; -+ -+ dma_cap_set(DMA_SLAVE, edmac->slave.cap_mask); -+ dma_cap_set(DMA_CYCLIC, edmac->slave.cap_mask); -+ edmac->slave.dev = &pdev->dev; -+ edmac->slave.device_free_chan_resources = edmac_free_chan_resources; -+ edmac->slave.device_tx_status = edmac_tx_status; -+ edmac->slave.device_issue_pending = edmac_issue_pending; -+ edmac->slave.device_prep_slave_sg = edmac_perp_slave_sg; -+ edmac->slave.device_prep_dma_cyclic = edma_prep_dma_cyclic; -+ edmac->slave.device_config = edmac_config; -+ edmac->slave.device_resume = edmac_resume; -+ edmac->slave.device_pause = edmac_pause; -+ edmac->slave.device_terminate_all = edmac_terminate_all; -+ edmac->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -+ edmac->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; -+ -+ edmac->max_transfer_size = MAX_TRANSFER_BYTES; -+ trasfer_size = MAX_TSFR_LLIS * EDMACV300_LLI_WORDS * sizeof(u32); -+ -+ edmac->pool = dma_pool_create(DRIVER_NAME, &(pdev->dev), -+ trasfer_size, EDMACV300_POOL_ALIGN, 0); -+ if (!edmac->pool) { -+ edmac_error("create pool fail!"); -+ ret = -ENOMEM; -+ goto free_edmac; -+ } -+ -+ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC1_RAW); -+ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC2_RAW); -+ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR1_RAW); -+ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR2_RAW); -+ edmac_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR3_RAW); -+ -+ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_TC1_MASK); -+ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_TC2_MASK); -+ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_ERR1_MASK); -+ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_ERR2_MASK); -+ edmac_writel(EDMAC_INT_ENABLE_ALL_CHAN, edmac->base + EDMAC_INT_ERR3_MASK); -+ -+ ret = request_irq(edmac->irq, edmac_irq, 0, DRIVER_NAME, edmac); -+ if (ret) { -+ edmac_error("fail to request irq"); -+ goto free_pool; -+ } -+ -+ edmac->phy_chans = kzalloc((edmac->channels * sizeof(struct edmac_phy_chan)), -+ GFP_KERNEL); -+ if (!edmac->phy_chans) { -+ edmac_error("malloc for phy chans fail!"); -+ ret = -ENOMEM; -+ goto free_irq_res; -+ } -+ -+ /* initialize the phy chan */ -+ for (i = 0; i < edmac->channels; i++) { -+ struct edmac_phy_chan* phy_ch = &edmac->phy_chans[i]; -+ phy_ch->id = i; -+ phy_ch->base = edmac->base + EDMAC_Cx_BASE(i); -+ spin_lock_init(&phy_ch->lock); -+ phy_ch->serving = NULL; -+ } -+ -+ /* initialize the memory virt chan */ -+ ret = edmac_init_virt_channels(edmac, &edmac->memcpy, edmac->channels, false); -+ if (ret) { -+ edmac_error("fail to init memory virt channels!"); -+ goto free_phychans; -+ } -+ -+ /* initialize the slave virt chan */ -+ ret = edmac_init_virt_channels(edmac, &edmac->slave, edmac->slave_requests, true); -+ if (ret) { -+ edmac_error("fail to init slave virt channels!"); -+ goto free_memory_virt_channels; -+ -+ } -+ -+ ret = dma_async_device_register(&edmac->memcpy); -+ if (ret) { -+ edmac_error( -+ "%s failed to register memcpy as an async device - %d\n", -+ __func__, ret); -+ goto free_slave_virt_channels; -+ } -+ -+ ret = dma_async_device_register(&edmac->slave); -+ if (ret) { -+ edmac_error( -+ "%s failed to register slave as an async device - %d\n", -+ __func__, ret); -+ goto free_memcpy_device; -+ } -+ -+ return 0; -+ -+free_memcpy_device: -+ dma_async_device_unregister(&edmac->memcpy); -+free_slave_virt_channels: -+ edmac_free_virt_channels(&edmac->slave); -+free_memory_virt_channels: -+ edmac_free_virt_channels(&edmac->memcpy); -+free_phychans: -+ kfree(edmac->phy_chans); -+free_irq_res: -+ free_irq(edmac->irq, edmac); -+free_pool: -+ dma_pool_destroy(edmac->pool); -+free_edmac: -+ kfree(edmac); -+ -+ return ret; -+} -+ -+ -+static int edma_remove(struct platform_device *pdev) -+{ -+ int err = 0; -+ return err; -+} -+ -+ -+static const struct of_device_id edmac_match[] = { -+ { .compatible = "goke,edmac" }, -+ {}, -+}; -+ -+ -+static struct platform_driver edmac_driver = { -+ .remove = edma_remove, -+ .driver = { -+ .name = "edmac", -+ .of_match_table = edmac_match, -+ }, -+}; -+ -+static int __init edmac_init(void) -+{ -+ return platform_driver_probe(&edmac_driver, edmac_probe); -+} -+subsys_initcall(edmac_init); -+ -+static void __exit edmac_exit(void) -+{ -+ platform_driver_unregister(&edmac_driver); -+} -+module_exit(edmac_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Goke"); ---- linux-4.9.37/drivers/dma/edmac_goke.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/dma/edmac_goke.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,132 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __EDMAC_H__ -+#define __EDMAC_H__ -+ -+/* debug control */ -+extern int edmac_trace_level; -+#define EDMAC_TRACE_LEVEL 5 -+ -+#define EDMAC_TRACE_FMT KERN_INFO -+ -+//#define DEBUG_EDMAC -+#ifdef DEBUG_EDMAC -+ -+#define edmac_trace(level, msg...) do { \ -+ if ((level) >= edmac_trace_level) { \ -+ printk(EDMAC_TRACE_FMT"%s:%d: ", __func__, __LINE__); \ -+ printk(msg); \ -+ printk("\n"); \ -+ } \ -+} while (0) -+ -+ -+#define edmac_assert(cond) do { \ -+ if (!(cond)) { \ -+ printk(KERN_ERR "Assert:edmac:%s:%d\n", \ -+ __func__, \ -+ __LINE__); \ -+ BUG(); \ -+ } \ -+} while (0) -+ -+#define edmac_error(s...) do { \ -+ printk(KERN_ERR "edmac:%s:%d: ", __func__, __LINE__); \ -+ printk(s); \ -+ printk("\n"); \ -+} while (0) -+ -+#else -+ -+#define edmac_trace(level, msg...) do { } while (0) -+#define edmac_assert(level, msg...) do { } while (0) -+#define edmac_error(level, msg...) do { } while (0) -+ -+#endif -+ -+#define edmac_readl(addr) ({ unsigned int reg = readl((void *)(addr)); \ -+ reg; }) -+ -+#define edmac_writel(v, addr) do { writel(v, (void *)(addr)); \ -+} while (0) -+ -+ -+#define MAX_TRANSFER_BYTES 0xffff -+ -+/* reg offset */ -+#define EDMAC_INT_STAT (0x0) -+#define EDMAC_INT_TC1 (0x4) -+#define EDMAC_INT_TC2 (0x8) -+#define EDMAC_INT_ERR1 (0xc) -+#define EDMAC_INT_ERR2 (0x10) -+#define EDMAC_INT_ERR3 (0x14) -+ -+#define EDMAC_INT_TC1_MASK (0x18) -+#define EDMAC_INT_TC2_MASK (0x1c) -+#define EDMAC_INT_ERR1_MASK (0x20) -+#define EDMAC_INT_ERR2_MASK (0x24) -+#define EDMAC_INT_ERR3_MASK (0x28) -+ -+#define EDMAC_INT_TC1_RAW (0x600) -+#define EDMAC_INT_TC2_RAW (0x608) -+#define EDMAC_INT_ERR1_RAW (0x610) -+#define EDMAC_INT_ERR2_RAW (0x618) -+#define EDMAC_INT_ERR3_RAW (0x620) -+ -+#define EDMAC_Cx_CURR_CNT0(cn) (0x404+cn*0x20) -+#define EDMAC_Cx_CURR_SRC_ADDR_L(cn) (0x408+cn*0x20) -+#define EDMAC_Cx_CURR_SRC_ADDR_H(cn) (0x40c+cn*0x20) -+#define EDMAC_Cx_CURR_DEST_ADDR_L(cn) (0x410+cn*0x20) -+#define EDMAC_Cx_CURR_DEST_ADDR_H(cn) (0x414+cn*0x20) -+ -+#define EDMAC_CH_PRI (0x688) -+#define EDMAC_CH_STAT (0x690) -+#define EDMAC_DMA_CTRL (0x698) -+ -+#define EDMAC_Cx_BASE(cn) (0x800+cn*0x40) -+#define EDMAC_Cx_LLI_L(cn) (0x800+cn*0x40) -+#define EDMAC_Cx_LLI_H(cn) (0x804+cn*0x40) -+#define EDMAC_Cx_CNT0(cn) (0x81c+cn*0x40) -+#define EDMAC_Cx_SRC_ADDR_L(cn) (0x820+cn*0x40) -+#define EDMAC_Cx_SRC_ADDR_H(cn) (0x824+cn*0x40) -+#define EDMAC_Cx_DEST_ADDR_L(cn) (0x828+cn*0x40) -+#define EDMAC_Cx_DEST_ADDR_H(cn) (0x82c+cn*0x40) -+#define EDMAC_Cx_CONFIG(cn) (0x830+cn*0x40) -+ -+#define EDMAC_ALL_CHAN_CLR (0xff) -+#define EDMAC_INT_ENABLE_ALL_CHAN (0xff) -+ -+ -+#define EDMAC_CONFIG_SRC_INC (1<<31) -+#define EDMAC_CONFIG_DST_INC (1<<30) -+ -+#define EDMAC_CONFIG_SRC_WIDTH_SHIFT (16) -+#define EDMAC_CONFIG_DST_WIDTH_SHIFT (12) -+#define EDMAC_WIDTH_8BIT (0x0) -+#define EDMAC_WIDTH_16BIT (0x1) -+#define EDMAC_WIDTH_32BIT (0x10) -+#define EDMAC_WIDTH_64BIT (0x11) -+ -+#define EDMAC_MAX_BURST_WIDTH (16) -+#define EDMAC_MIN_BURST_WIDTH (1) -+#define EDMAC_CONFIG_SRC_BURST_SHIFT (24) -+#define EDMAC_CONFIG_DST_BURST_SHIFT (20) -+ -+#define EDMAC_LLI_ALIGN 0x40 -+#define EDMAC_LLI_DISABLE 0x0 -+#define EDMAC_LLI_ENABLE 0x2 -+ -+#define EDMAC_CXCONFIG_SIGNAL_SHIFT (0x4) -+#define EDMAC_CXCONFIG_MEM_TYPE (0x0) -+#define EDMAC_CXCONFIG_DEV_MEM_TYPE (0x1) -+#define EDMAC_CXCONFIG_TSF_TYPE_SHIFT (0x2) -+#define EDMAC_CxCONFIG_LLI_START (0x1) -+ -+#define EDMAC_CXCONFIG_ITC_EN (0x1) -+#define EDMAC_CXCONFIG_ITC_EN_SHIFT (0x1) -+ -+#define CCFG_EN 0x1 -+ -+#endif ---- linux-4.9.37/drivers/dma/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/dma/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -564,6 +564,19 @@ - help - Support the DMA engine for ZTE ZX296702 platform devices. - -+config EDMAC -+ tristate "Goke EDMAC Controller support" -+ depends on (ARCH_GK7205V300 || ARCH_GK7205V200 || ARCH_GK7202V300 || ARCH_GK7605V100) -+ select DMA_ENGINE -+ select DMA_VIRTUAL_CHANNELS -+ help -+ The Direction Memory Access(EDMA) is a high-speed data transfer -+ operation. It supports data read/write between peripherals and -+ memories without using the CPU. -+ Goke EDMA Controller(EDMAC) directly transfers data between -+ a memory and a peripheral, between peripherals, or between memories. -+ This avoids the CPU intervention and reduces the interrupt handling -+ overhead of the CPU. - - # driver files - source "drivers/dma/bestcomm/Kconfig" ---- linux-4.9.37/drivers/dma/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/dma/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -67,6 +67,7 @@ - obj-$(CONFIG_TI_EDMA) += edma.o - obj-$(CONFIG_XGENE_DMA) += xgene-dma.o - obj-$(CONFIG_ZX_DMA) += zx296702_dma.o -+obj-$(CONFIG_EDMAC) += edmac_goke.o - - obj-y += qcom/ - obj-y += xilinx/ ---- linux-4.9.37/drivers/dma-buf/fence.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/fence.c 2021-06-07 13:01:33.000000000 +0300 -@@ -68,6 +68,8 @@ - struct fence_cb *cur, *tmp; - int ret = 0; - -+ lockdep_assert_held(fence->lock); -+ - if (WARN_ON(!fence)) - return -EINVAL; - -@@ -159,9 +161,6 @@ - if (WARN_ON(timeout < 0)) - return -EINVAL; - -- if (timeout == 0) -- return fence_is_signaled(fence); -- - trace_fence_wait_start(fence); - ret = fence->ops->wait(fence, intr, timeout); - trace_fence_wait_end(fence); -@@ -304,8 +303,12 @@ - spin_lock_irqsave(fence->lock, flags); - - ret = !list_empty(&cb->node); -- if (ret) -+ if (ret) { - list_del_init(&cb->node); -+ if (list_empty(&fence->cb_list)) -+ if (fence->ops->disable_signaling) -+ fence->ops->disable_signaling(fence); -+ } - - spin_unlock_irqrestore(fence->lock, flags); - ---- linux-4.9.37/drivers/dma-buf/reservation.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/reservation.c 2021-06-07 13:01:33.000000000 +0300 -@@ -280,18 +280,24 @@ - unsigned *pshared_count, - struct fence ***pshared) - { -- unsigned shared_count = 0; -- unsigned retry = 1; -- struct fence **shared = NULL, *fence_excl = NULL; -- int ret = 0; -+ struct fence **shared = NULL; -+ struct fence *fence_excl; -+ unsigned int shared_count; -+ int ret = 1; - -- while (retry) { -+ do { - struct reservation_object_list *fobj; - unsigned seq; -+ unsigned int i; - -- seq = read_seqcount_begin(&obj->seq); -+ shared_count = i = 0; - - rcu_read_lock(); -+ seq = read_seqcount_begin(&obj->seq); -+ -+ fence_excl = rcu_dereference(obj->fence_excl); -+ if (fence_excl && !fence_get_rcu(fence_excl)) -+ goto unlock; - - fobj = rcu_dereference(obj->fence); - if (fobj) { -@@ -309,52 +315,37 @@ - } - - ret = -ENOMEM; -- shared_count = 0; - break; - } - shared = nshared; -- memcpy(shared, fobj->shared, sz); - shared_count = fobj->shared_count; -- } else -- shared_count = 0; -- fence_excl = rcu_dereference(obj->fence_excl); -- -- retry = read_seqcount_retry(&obj->seq, seq); -- if (retry) -- goto unlock; -- -- if (!fence_excl || fence_get_rcu(fence_excl)) { -- unsigned i; - - for (i = 0; i < shared_count; ++i) { -- if (fence_get_rcu(shared[i])) -- continue; -- -- /* uh oh, refcount failed, abort and retry */ -- while (i--) -- fence_put(shared[i]); -- -- if (fence_excl) { -- fence_put(fence_excl); -- fence_excl = NULL; -- } -- -- retry = 1; -- break; -+ shared[i] = rcu_dereference(fobj->shared[i]); -+ if (!fence_get_rcu(shared[i])) -+ break; - } -- } else -- retry = 1; -+ } -+ -+ if ((i > 0) && (i != shared_count || read_seqcount_retry(&obj->seq, seq))) { -+ while (i--) -+ fence_put(shared[i]); -+ fence_put(fence_excl); -+ goto unlock; -+ } - -+ ret = 0; - unlock: - rcu_read_unlock(); -- } -- *pshared_count = shared_count; -- if (shared_count) -- *pshared = shared; -- else { -- *pshared = NULL; -+ } while (ret); -+ -+ if (!shared_count) { - kfree(shared); -+ shared = NULL; - } -+ -+ *pshared_count = shared_count; -+ *pshared = shared; - *pfence_excl = fence_excl; - - return ret; -@@ -379,10 +370,7 @@ - { - struct fence *fence; - unsigned seq, shared_count, i = 0; -- long ret = timeout; -- -- if (!timeout) -- return reservation_object_test_signaled_rcu(obj, wait_all); -+ long ret = timeout ? timeout : 1; - - retry: - fence = NULL; -@@ -397,9 +385,6 @@ - if (fobj) - shared_count = fobj->shared_count; - -- if (read_seqcount_retry(&obj->seq, seq)) -- goto unlock_retry; -- - for (i = 0; i < shared_count; ++i) { - struct fence *lfence = rcu_dereference(fobj->shared[i]); - -@@ -422,9 +407,6 @@ - if (!shared_count) { - struct fence *fence_excl = rcu_dereference(obj->fence_excl); - -- if (read_seqcount_retry(&obj->seq, seq)) -- goto unlock_retry; -- - if (fence_excl && - !test_bit(FENCE_FLAG_SIGNALED_BIT, &fence_excl->flags)) { - if (!fence_get_rcu(fence_excl)) -@@ -439,6 +421,11 @@ - - rcu_read_unlock(); - if (fence) { -+ if (read_seqcount_retry(&obj->seq, seq)) { -+ fence_put(fence); -+ goto retry; -+ } -+ - ret = fence_wait_timeout(fence, intr, ret); - fence_put(fence); - if (ret > 0 && wait_all && (i + 1 < shared_count)) -@@ -484,12 +471,13 @@ - bool test_all) - { - unsigned seq, shared_count; -- int ret = true; -+ int ret; - -+ rcu_read_lock(); - retry: -+ ret = true; - shared_count = 0; - seq = read_seqcount_begin(&obj->seq); -- rcu_read_lock(); - - if (test_all) { - unsigned i; -@@ -500,46 +488,35 @@ - if (fobj) - shared_count = fobj->shared_count; - -- if (read_seqcount_retry(&obj->seq, seq)) -- goto unlock_retry; -- - for (i = 0; i < shared_count; ++i) { - struct fence *fence = rcu_dereference(fobj->shared[i]); - - ret = reservation_object_test_signaled_single(fence); - if (ret < 0) -- goto unlock_retry; -+ goto retry; - else if (!ret) - break; - } - -- /* -- * There could be a read_seqcount_retry here, but nothing cares -- * about whether it's the old or newer fence pointers that are -- * signaled. That race could still have happened after checking -- * read_seqcount_retry. If you care, use ww_mutex_lock. -- */ -+ if (read_seqcount_retry(&obj->seq, seq)) -+ goto retry; - } - - if (!shared_count) { - struct fence *fence_excl = rcu_dereference(obj->fence_excl); - -- if (read_seqcount_retry(&obj->seq, seq)) -- goto unlock_retry; -- - if (fence_excl) { - ret = reservation_object_test_signaled_single( - fence_excl); - if (ret < 0) -- goto unlock_retry; -+ goto retry; -+ -+ if (read_seqcount_retry(&obj->seq, seq)) -+ goto retry; - } - } - - rcu_read_unlock(); - return ret; -- --unlock_retry: -- rcu_read_unlock(); -- goto retry; - } - EXPORT_SYMBOL_GPL(reservation_object_test_signaled_rcu); ---- linux-4.9.37/drivers/dma-buf/sw_sync.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/sw_sync.c 2021-06-07 13:01:33.000000000 +0300 -@@ -234,6 +234,13 @@ - return true; - } - -+static void timeline_fence_disable_signaling(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ -+ list_del_init(&pt->active_list); -+} -+ - static void timeline_fence_value_str(struct fence *fence, - char *str, int size) - { -@@ -252,6 +259,7 @@ - .get_driver_name = timeline_fence_get_driver_name, - .get_timeline_name = timeline_fence_get_timeline_name, - .enable_signaling = timeline_fence_enable_signaling, -+ .disable_signaling = timeline_fence_disable_signaling, - .signaled = timeline_fence_signaled, - .wait = fence_default_wait, - .release = timeline_fence_release, -@@ -316,8 +324,8 @@ - } - - sync_file = sync_file_create(&pt->base); -+ fence_put(&pt->base); - if (!sync_file) { -- fence_put(&pt->base); - err = -ENOMEM; - goto err; - } ---- linux-4.9.37/drivers/dma-buf/_sw_sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/_sw_sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _UAPI_LINUX_SW_SYNC_H -+#define _UAPI_LINUX_SW_SYNC_H -+ -+#include -+ -+struct sw_sync_create_fence_data { -+ __u32 value; -+ char name[32]; -+ __s32 fence; /* fd of new fence */ -+}; -+ -+#define SW_SYNC_IOC_MAGIC 'W' -+ -+#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ -+ struct sw_sync_create_fence_data) -+#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) -+ -+#endif /* _UAPI_LINUX_SW_SYNC_H */ ---- linux-4.9.37/drivers/dma-buf/sw_sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/sw_sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,43 @@ -+/* -+ * include/linux/sw_sync.h -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_SW_SYNC_H -+#define _LINUX_SW_SYNC_H -+ -+#include -+#include -+#include "sync.h" -+#include "_sw_sync.h" -+#include -+ -+struct sw_sync_timeline { -+ struct sync_timeline obj; -+ -+ u32 value; -+}; -+ -+struct sw_sync_pt { -+ struct sync_pt pt; -+ -+ u32 value; -+}; -+ -+struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name); -+void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); -+ -+struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); -+ -+#endif /* _LINUX_SW_SYNC_H */ ---- linux-4.9.37/drivers/dma-buf/sync.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/sync.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,738 @@ -+/* -+ * drivers/base/sync.c -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sync.h" -+ -+#include -+ -+static const struct fence_ops android_fence_ops; -+static const struct file_operations sync_fence_fops; -+ -+struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, -+ int size, const char *name) -+{ -+ struct sync_timeline *obj = NULL; -+ -+ if (size < sizeof(struct sync_timeline)) -+ return NULL; -+ -+ obj = kzalloc(size, GFP_KERNEL); -+ if (obj == NULL) -+ return NULL; -+ -+ kref_init(&obj->kref); -+ obj->ops = ops; -+ obj->context = fence_context_alloc(1); -+ strlcpy(obj->name, name, sizeof(obj->name)); -+ -+ INIT_LIST_HEAD(&obj->child_list_head); -+ INIT_LIST_HEAD(&obj->active_list_head); -+ spin_lock_init(&obj->child_list_lock); -+#if 0 -+ bsp_sync_timeline_debug_add(obj); -+#endif -+ -+ return obj; -+} -+EXPORT_SYMBOL(bsp_sync_timeline_create); -+ -+static void sync_timeline_free(struct kref *kref) -+{ -+ struct sync_timeline *obj = -+ container_of(kref, struct sync_timeline, kref); -+#if 0 -+ bsp_sync_timeline_debug_remove(obj); -+#endif -+ if (obj->ops->release_obj) -+ obj->ops->release_obj(obj); -+ -+ kfree(obj); -+} -+ -+static void sync_timeline_get(struct sync_timeline *obj) -+{ -+ kref_get(&obj->kref); -+} -+ -+static void sync_timeline_put(struct sync_timeline *obj) -+{ -+ kref_put(&obj->kref, sync_timeline_free); -+} -+ -+void bsp_sync_timeline_destroy(struct sync_timeline *obj) -+{ -+ obj->destroyed = true; -+ /* -+ * Ensure timeline is marked as destroyed before -+ * changing timeline's fences status. -+ */ -+ smp_wmb(); -+ -+ /* -+ * signal any children that their parent is going away. -+ */ -+ bsp_sync_timeline_signal(obj); -+ sync_timeline_put(obj); -+} -+EXPORT_SYMBOL(bsp_sync_timeline_destroy); -+ -+void bsp_sync_timeline_signal(struct sync_timeline *obj) -+{ -+ unsigned long flags; -+ LIST_HEAD(signaled_pts); -+ struct sync_pt *pt = NULL; -+ struct sync_pt *next = NULL; -+ -+ spin_lock_irqsave(&obj->child_list_lock, flags); -+ -+ list_for_each_entry_safe(pt, next, &obj->active_list_head, -+ active_list) { -+ if (fence_is_signaled_locked(&pt->base)) { -+ list_del_init(&pt->active_list); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) -+ fence_put(&pt->base); -+#endif -+ } -+ } -+ -+ spin_unlock_irqrestore(&obj->child_list_lock, flags); -+} -+EXPORT_SYMBOL(bsp_sync_timeline_signal); -+ -+struct sync_pt *bsp_sync_pt_create(struct sync_timeline *obj, int size) -+{ -+ unsigned long flags; -+ struct sync_pt *pt = NULL; -+ -+ if (size < sizeof(struct sync_pt)) -+ return NULL; -+ -+ pt = kzalloc(size, GFP_KERNEL); -+ if (pt == NULL) -+ return NULL; -+ -+ spin_lock_irqsave(&obj->child_list_lock, flags); -+ sync_timeline_get(obj); -+ fence_init(&pt->base, &android_fence_ops, &obj->child_list_lock, -+ obj->context, ++obj->value); -+ list_add_tail(&pt->child_list, &obj->child_list_head); -+ INIT_LIST_HEAD(&pt->active_list); -+ spin_unlock_irqrestore(&obj->child_list_lock, flags); -+ return pt; -+} -+EXPORT_SYMBOL(bsp_sync_pt_create); -+ -+void bsp_sync_pt_free(struct sync_pt *pt) -+{ -+ fence_put(&pt->base); -+} -+EXPORT_SYMBOL(bsp_sync_pt_free); -+ -+#if 0 -+static struct sync_fence *sync_fence_alloc(int size, const char *name) -+{ -+ struct sync_fence *fence; -+ -+ fence = kzalloc(size, GFP_KERNEL); -+ if (fence == NULL) -+ return NULL; -+ -+ fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, -+ fence, 0); -+ if (IS_ERR(fence->file)) -+ goto err; -+ -+ kref_init(&fence->kref); -+ strlcpy(fence->name, name, sizeof(fence->name)); -+ -+ init_waitqueue_head(&fence->wq); -+ -+ return fence; -+ -+err: -+ kfree(fence); -+ return NULL; -+} -+ -+static void fence_check_cb_func(struct fence *f, struct fence_cb *cb) -+{ -+ struct sync_fence_cb *check; -+ struct sync_fence *fence; -+ -+ check = container_of(cb, struct sync_fence_cb, cb); -+ fence = check->fence; -+ -+ if (atomic_dec_and_test(&fence->status)) -+ wake_up_all(&fence->wq); -+} -+ -+/* TODO: implement a create which takes more that one sync_pt */ -+struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt) -+{ -+ struct sync_fence *fence; -+ -+ fence = sync_fence_alloc(offsetof(struct sync_fence, cbs[1]), name); -+ if (fence == NULL) -+ return NULL; -+ -+ fence->num_fences = 1; -+ atomic_set(&fence->status, 1); -+ -+ fence->cbs[0].sync_pt = &pt->base; -+ fence->cbs[0].fence = fence; -+ if (fence_add_callback(&pt->base, &fence->cbs[0].cb, -+ fence_check_cb_func)) -+ atomic_dec(&fence->status); -+#if 0 -+ bsp_sync_fence_debug_add(fence); -+#endif -+ -+ return fence; -+} -+EXPORT_SYMBOL(bsp_sync_fence_create); -+ -+struct sync_fence *bsp_sync_fence_fdget(int fd) -+{ -+ struct file *file = fget(fd); -+ -+ if (file == NULL) -+ return NULL; -+ -+ if (file->f_op != &sync_fence_fops) -+ goto err; -+ -+ return file->private_data; -+ -+err: -+ fput(file); -+ return NULL; -+} -+EXPORT_SYMBOL(bsp_sync_fence_fdget); -+ -+void bsp_sync_fence_put(struct sync_fence *fence) -+{ -+ fput(fence->file); -+} -+EXPORT_SYMBOL(bsp_sync_fence_put); -+ -+void bsp_sync_fence_install(struct sync_fence *fence, int fd) -+{ -+ printk("<%s> Line %d: fd =%d, fence=%p, name=%s\n", __func__, __LINE__, fd, fence, fence->name); -+ fd_install(fd, fence->file); -+} -+EXPORT_SYMBOL(bsp_sync_fence_install); -+ -+static void sync_fence_add_pt(struct sync_fence *fence, -+ int *i, struct fence *pt) -+{ -+ fence->cbs[*i].sync_pt = pt; -+ fence->cbs[*i].fence = fence; -+ -+ if (!fence_add_callback(pt, &fence->cbs[*i].cb, fence_check_cb_func)) { -+ fence_get(pt); -+ (*i)++; -+ } -+} -+ -+struct sync_fence *bsp_sync_fence_merge(const char *name, -+ struct sync_fence *a, struct sync_fence *b) -+{ -+ int num_fences = a->num_fences + b->num_fences; -+ struct sync_fence *fence; -+ int i, i_a, i_b; -+ unsigned long size = offsetof(struct sync_fence, cbs[num_fences]); -+ -+ fence = sync_fence_alloc(size, name); -+ if (fence == NULL) -+ return NULL; -+ -+ atomic_set(&fence->status, num_fences); -+ -+ /* -+ * Assume sync_fence a and b are both ordered and have no -+ * duplicates with the same context. -+ * -+ * If a sync_fence can only be created with sync_fence_merge -+ * and sync_fence_create, this is a reasonable assumption. -+ */ -+ for (i = i_a = i_b = 0; i_a < a->num_fences && i_b < b->num_fences; ) { -+ struct fence *pt_a = a->cbs[i_a].sync_pt; -+ struct fence *pt_b = b->cbs[i_b].sync_pt; -+ -+ if (pt_a->context < pt_b->context) { -+ sync_fence_add_pt(fence, &i, pt_a); -+ -+ i_a++; -+ } else if (pt_a->context > pt_b->context) { -+ sync_fence_add_pt(fence, &i, pt_b); -+ -+ i_b++; -+ } else { -+ if (pt_a->seqno - pt_b->seqno <= INT_MAX) -+ sync_fence_add_pt(fence, &i, pt_a); -+ else -+ sync_fence_add_pt(fence, &i, pt_b); -+ -+ i_a++; -+ i_b++; -+ } -+ } -+ -+ for (; i_a < a->num_fences; i_a++) -+ sync_fence_add_pt(fence, &i, a->cbs[i_a].sync_pt); -+ -+ for (; i_b < b->num_fences; i_b++) -+ sync_fence_add_pt(fence, &i, b->cbs[i_b].sync_pt); -+ -+ if (num_fences > i) -+ atomic_sub(num_fences - i, &fence->status); -+ fence->num_fences = i; -+#if 0 -+ bsp_sync_fence_debug_add(fence); -+#endif -+ return fence; -+} -+EXPORT_SYMBOL(bsp_sync_fence_merge); -+ -+int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, -+ int wake_flags, void *key) -+{ -+ struct sync_fence_waiter *wait; -+ -+ wait = container_of(curr, struct sync_fence_waiter, work); -+ list_del_init(&wait->work.task_list); -+ -+ wait->callback(wait->work.private, wait); -+ return 1; -+} -+ -+int bsp_sync_fence_wait_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter) -+{ -+ int err = atomic_read(&fence->status); -+ unsigned long flags; -+ -+ if (err < 0) -+ return err; -+ -+ if (!err) -+ return 1; -+ -+ init_waitqueue_func_entry(&waiter->work, bsp_sync_fence_wake_up_wq); -+ waiter->work.private = fence; -+ -+ spin_lock_irqsave(&fence->wq.lock, flags); -+ err = atomic_read(&fence->status); -+ if (err > 0) -+ __add_wait_queue_tail(&fence->wq, &waiter->work); -+ spin_unlock_irqrestore(&fence->wq.lock, flags); -+ -+ if (err < 0) -+ return err; -+ -+ return !err; -+} -+EXPORT_SYMBOL(bsp_sync_fence_wait_async); -+ -+int bsp_sync_fence_cancel_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter) -+{ -+ unsigned long flags; -+ int ret = 0; -+ -+ spin_lock_irqsave(&fence->wq.lock, flags); -+ if (!list_empty(&waiter->work.task_list)) -+ list_del_init(&waiter->work.task_list); -+ else -+ ret = -ENOENT; -+ spin_unlock_irqrestore(&fence->wq.lock, flags); -+ return ret; -+} -+EXPORT_SYMBOL(bsp_sync_fence_cancel_async); -+ -+int bsp_sync_fence_wait(struct sync_fence *fence, long timeout) -+{ -+ long ret; -+ -+ if (timeout < 0) -+ timeout = MAX_SCHEDULE_TIMEOUT; -+ else -+ timeout = msecs_to_jiffies(timeout); -+ -+ ret = wait_event_interruptible_timeout(fence->wq, -+ atomic_read(&fence->status) <= 0, -+ timeout); -+ -+ if (ret < 0) { -+ return ret; -+ } else if (ret == 0) { -+ if (timeout) { -+ pr_info("fence timeout on [%p] after %dms\n", fence, -+ jiffies_to_msecs(timeout)); -+ bsp_sync_dump(); -+ } -+ return -ETIME; -+ } -+ -+ ret = atomic_read(&fence->status); -+ if (ret) { -+ pr_info("fence error %ld on [%p]\n", ret, fence); -+ bsp_sync_dump(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(bsp_sync_fence_wait); -+ -+#endif -+static const char *android_fence_get_driver_name(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ return parent->ops->driver_name; -+} -+ -+static const char *android_fence_get_timeline_name(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ return parent->name; -+} -+ -+static void android_fence_release(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ unsigned long flags; -+ -+ spin_lock_irqsave(fence->lock, flags); -+ list_del(&pt->child_list); -+ if (WARN_ON_ONCE(!list_empty(&pt->active_list))) -+ list_del(&pt->active_list); -+ spin_unlock_irqrestore(fence->lock, flags); -+ -+ if (parent->ops->free_pt) -+ parent->ops->free_pt(pt); -+ -+ sync_timeline_put(parent); -+ fence_free(&pt->base); -+} -+ -+static bool android_fence_signaled(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ int ret; -+ -+ ret = parent->ops->has_signaled(pt); -+ if (ret < 0) -+ fence->status = ret; -+ return ret; -+} -+ -+static bool android_fence_enable_signaling(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (android_fence_signaled(fence)) -+ return false; -+ -+ list_add_tail(&pt->active_list, &parent->active_list_head); -+ return true; -+} -+ -+static void android_fence_disable_signaling(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ -+ list_del_init(&pt->active_list); -+} -+ -+static int android_fence_fill_driver_data(struct fence *fence, -+ void *data, int size) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (!parent->ops->fill_driver_data) -+ return 0; -+ return parent->ops->fill_driver_data(pt, data, size); -+} -+ -+static void android_fence_value_str(struct fence *fence, -+ char *str, int size) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (!parent->ops->pt_value_str) { -+ if (size) -+ *str = 0; -+ return; -+ } -+ parent->ops->pt_value_str(pt, str, size); -+} -+ -+static void android_fence_timeline_value_str(struct fence *fence, -+ char *str, int size) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (!parent->ops->timeline_value_str) { -+ if (size) -+ *str = 0; -+ return; -+ } -+ parent->ops->timeline_value_str(parent, str, size); -+} -+ -+static const struct fence_ops android_fence_ops = { -+ .get_driver_name = android_fence_get_driver_name, -+ .get_timeline_name = android_fence_get_timeline_name, -+ .enable_signaling = android_fence_enable_signaling, -+ .signaled = android_fence_signaled, -+ .wait = fence_default_wait, -+ .release = android_fence_release, -+ .fill_driver_data = android_fence_fill_driver_data, -+ .fence_value_str = android_fence_value_str, -+ .timeline_value_str = android_fence_timeline_value_str, -+}; -+#if 0 -+static void sync_fence_free(struct kref *kref) -+{ -+ struct sync_fence *fence = container_of(kref, struct sync_fence, kref); -+ int i; -+ -+ for (i = 0; i < fence->num_fences; ++i) { -+ fence_remove_callback(fence->cbs[i].sync_pt, &fence->cbs[i].cb); -+ fence_put(fence->cbs[i].sync_pt); -+ } -+ -+ kfree(fence); -+} -+ -+static int sync_fence_release(struct inode *inode, struct file *file) -+{ -+ struct sync_fence *fence = file->private_data; -+ -+ bsp_sync_fence_debug_remove(fence); -+ -+ kref_put(&fence->kref, sync_fence_free); -+ return 0; -+} -+ -+static unsigned int sync_fence_poll(struct file *file, poll_table *wait) -+{ -+ struct sync_fence *fence = file->private_data; -+ int status; -+ -+ poll_wait(file, &fence->wq, wait); -+ -+ status = atomic_read(&fence->status); -+ -+ if (!status) -+ return POLLIN; -+ else if (status < 0) -+ return POLLERR; -+ return 0; -+} -+ -+static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) -+{ -+ __s32 value; -+ -+ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) -+ return -EFAULT; -+ -+ return bsp_sync_fence_wait(fence, value); -+} -+ -+static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) -+{ -+ int fd = get_unused_fd_flags(O_CLOEXEC); -+ int err; -+ struct sync_fence *fence2, *fence3; -+ struct sync_merge_data data; -+ -+ if (fd < 0) -+ return fd; -+ -+ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { -+ err = -EFAULT; -+ goto err_put_fd; -+ } -+ -+ fence2 = bsp_sync_fence_fdget(data.fd2); -+ if (fence2 == NULL) { -+ err = -ENOENT; -+ goto err_put_fd; -+ } -+ -+ data.name[sizeof(data.name) - 1] = '\0'; -+ fence3 = bsp_sync_fence_merge(data.name, fence, fence2); -+ if (fence3 == NULL) { -+ err = -ENOMEM; -+ goto err_put_fence2; -+ } -+ -+ data.fence = fd; -+ if (copy_to_user((void __user *)arg, &data, sizeof(data))) { -+ err = -EFAULT; -+ goto err_put_fence3; -+ } -+ -+ bsp_sync_fence_install(fence3, fd); -+ bsp_sync_fence_put(fence2); -+ return 0; -+ -+err_put_fence3: -+ bsp_sync_fence_put(fence3); -+ -+err_put_fence2: -+ bsp_sync_fence_put(fence2); -+ -+err_put_fd: -+ put_unused_fd(fd); -+ return err; -+} -+ -+static int sync_fill_pt_info(struct fence *fence, void *data, int size) -+{ -+ struct sync_pt_info *info = data; -+ int ret; -+ -+ if (size < sizeof(struct sync_pt_info)) -+ return -ENOMEM; -+ -+ info->len = sizeof(struct sync_pt_info); -+ -+ if (fence->ops->fill_driver_data) { -+ ret = fence->ops->fill_driver_data(fence, info->driver_data, -+ size - sizeof(*info)); -+ if (ret < 0) -+ return ret; -+ -+ info->len += ret; -+ } -+ -+ strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), -+ sizeof(info->obj_name)); -+ strlcpy(info->driver_name, fence->ops->get_driver_name(fence), -+ sizeof(info->driver_name)); -+ if (fence_is_signaled(fence)) -+ info->status = fence->status >= 0 ? 1 : fence->status; -+ else -+ info->status = 0; -+ info->timestamp_ns = ktime_to_ns(fence->timestamp); -+ -+ return info->len; -+} -+ -+static long sync_fence_ioctl_fence_info(struct sync_fence *fence, -+ unsigned long arg) -+{ -+ struct sync_fence_info_data *data; -+ __u32 size; -+ __u32 len = 0; -+ int ret, i; -+ -+ if (copy_from_user(&size, (void __user *)arg, sizeof(size))) -+ return -EFAULT; -+ -+ if (size < sizeof(struct sync_fence_info_data)) -+ return -EINVAL; -+ -+ if (size > 4096) -+ size = 4096; -+ -+ data = kzalloc(size, GFP_KERNEL); -+ if (data == NULL) -+ return -ENOMEM; -+ -+ strlcpy(data->name, fence->name, sizeof(data->name)); -+ data->status = atomic_read(&fence->status); -+ if (data->status >= 0) -+ data->status = !data->status; -+ -+ len = sizeof(struct sync_fence_info_data); -+ -+ for (i = 0; i < fence->num_fences; ++i) { -+ struct fence *pt = fence->cbs[i].sync_pt; -+ -+ ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len); -+ -+ if (ret < 0) -+ goto out; -+ -+ len += ret; -+ } -+ -+ data->len = len; -+ -+ if (copy_to_user((void __user *)arg, data, len)) -+ ret = -EFAULT; -+ else -+ ret = 0; -+ -+out: -+ kfree(data); -+ -+ return ret; -+} -+ -+static long sync_fence_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct sync_fence *fence = file->private_data; -+ -+ switch (cmd) { -+ case SYNC_IOC_WAIT: -+ return sync_fence_ioctl_wait(fence, arg); -+ -+ case SYNC_IOC_MERGE: -+ return sync_fence_ioctl_merge(fence, arg); -+ -+ case SYNC_IOC_FENCE_INFO: -+ return sync_fence_ioctl_fence_info(fence, arg); -+ -+ default: -+ return -ENOTTY; -+ } -+} -+ -+static const struct file_operations sync_fence_fops = { -+ .release = sync_fence_release, -+ .poll = sync_fence_poll, -+ .unlocked_ioctl = sync_fence_ioctl, -+ .compat_ioctl = sync_fence_ioctl, -+}; -+#endif -+ ---- linux-4.9.37/drivers/dma-buf/sync_file.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/sync_file.c 2021-06-07 13:01:33.000000000 +0300 -@@ -67,9 +67,10 @@ - * sync_file_create() - creates a sync file - * @fence: fence to add to the sync_fence - * -- * Creates a sync_file containg @fence. Once this is called, the sync_file -- * takes ownership of @fence. The sync_file can be released with -- * fput(sync_file->file). Returns the sync_file or NULL in case of error. -+ * Creates a sync_file containg @fence. This function acquires and additional -+ * reference of @fence for the newly-created &sync_file, if it succeeds. The -+ * sync_file can be released with fput(sync_file->file). Returns the -+ * sync_file or NULL in case of error. - */ - struct sync_file *sync_file_create(struct fence *fence) - { -@@ -79,7 +80,7 @@ - if (!sync_file) - return NULL; - -- sync_file->fence = fence; -+ sync_file->fence = fence_get(fence); - - snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d", - fence->ops->get_driver_name(fence), -@@ -90,14 +91,7 @@ - } - EXPORT_SYMBOL(sync_file_create); - --/** -- * sync_file_fdget() - get a sync_file from an fd -- * @fd: fd referencing a fence -- * -- * Ensures @fd references a valid sync_file, increments the refcount of the -- * backing file. Returns the sync_file or NULL in case of error. -- */ --static struct sync_file *sync_file_fdget(int fd) -+struct sync_file *sync_file_fdget(int fd) - { - struct file *file = fget(fd); - -@@ -114,6 +108,8 @@ - return NULL; - } - -+EXPORT_SYMBOL(sync_file_fdget); -+ - /** - * sync_file_get_fence - get the fence related to the sync_file fd - * @fd: sync_file fd to get the fence from -@@ -305,10 +301,9 @@ - - poll_wait(file, &sync_file->wq, wait); - -- if (!poll_does_not_wait(wait) && -- !test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) { -+ if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) { - if (fence_add_callback(sync_file->fence, &sync_file->cb, -- fence_check_cb_func) < 0) -+ fence_check_cb_func) < 0) - wake_up_all(&sync_file->wq); - } - -@@ -370,7 +365,7 @@ - return err; - } - --static void sync_fill_fence_info(struct fence *fence, -+static int sync_fill_fence_info(struct fence *fence, - struct sync_fence_info *info) - { - strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), -@@ -382,6 +377,8 @@ - else - info->status = 0; - info->timestamp_ns = ktime_to_ns(fence->timestamp); -+ -+ return info->status; - } - - static long sync_file_ioctl_fence_info(struct sync_file *sync_file, -@@ -407,8 +404,12 @@ - * sync_fence_info and return the actual number of fences on - * info->num_fences. - */ -- if (!info.num_fences) -+ if (!info.num_fences) { -+ info.status = fence_is_signaled(sync_file->fence); - goto no_fences; -+ } else { -+ info.status = 1; -+ } - - if (info.num_fences < num_fences) - return -EINVAL; -@@ -418,8 +419,10 @@ - if (!fence_info) - return -ENOMEM; - -- for (i = 0; i < num_fences; i++) -- sync_fill_fence_info(fences[i], &fence_info[i]); -+ for (i = 0; i < num_fences; i++) { -+ int status = sync_fill_fence_info(fences[i], &fence_info[i]); -+ info.status = info.status <= 0 ? info.status : status; -+ } - - if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info, - size)) { -@@ -429,7 +432,6 @@ - - no_fences: - strlcpy(info.name, sync_file->name, sizeof(info.name)); -- info.status = fence_is_signaled(sync_file->fence); - info.num_fences = num_fences; - - if (copy_to_user((void __user *)arg, &info, sizeof(info))) -@@ -443,12 +445,26 @@ - return ret; - } - -+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) -+static long sync_fence_ioctl_wait(struct sync_file *sync_file, unsigned long arg) -+{ -+ __s32 value; -+ -+ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) -+ return -EFAULT; -+ if(value <= 0) -+ value = MAX_SCHEDULE_TIMEOUT; -+ return fence_wait_timeout(sync_file->fence, true, value); -+} -+ - static long sync_file_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) - { - struct sync_file *sync_file = file->private_data; - - switch (cmd) { -+ case SYNC_IOC_WAIT: -+ return sync_fence_ioctl_wait(sync_file, arg); - case SYNC_IOC_MERGE: - return sync_file_ioctl_merge(sync_file, arg); - ---- linux-4.9.37/drivers/dma-buf/_sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/_sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,97 @@ -+/* -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _UAPI_LINUX_SYNC_H -+#define _UAPI_LINUX_SYNC_H -+ -+#include -+#include -+ -+/** -+ * struct sync_merge_data - data passed to merge ioctl -+ * @fd2: file descriptor of second fence -+ * @name: name of new fence -+ * @fence: returns the fd of the new fence to userspace -+ */ -+struct sync_merge_data { -+ __s32 fd2; /* fd of second fence */ -+ char name[32]; /* name of new fence */ -+ __s32 fence; /* fd on newly created fence */ -+}; -+ -+/** -+ * struct sync_pt_info - detailed sync_pt information -+ * @len: length of sync_pt_info including any driver_data -+ * @obj_name: name of parent sync_timeline -+ * @driver_name: name of driver implementing the parent -+ * @status: status of the sync_pt 0:active 1:signaled <0:error -+ * @timestamp_ns: timestamp of status change in nanoseconds -+ * @driver_data: any driver dependent data -+ */ -+struct sync_pt_info { -+ __u32 len; -+ char obj_name[32]; -+ char driver_name[32]; -+ __s32 status; -+ __u64 timestamp_ns; -+ -+ __u8 driver_data[0]; -+}; -+ -+/** -+ * struct sync_fence_info_data - data returned from fence info ioctl -+ * @len: ioctl caller writes the size of the buffer its passing in. -+ * ioctl returns length of sync_fence_data returned to userspace -+ * including pt_info. -+ * @name: name of fence -+ * @status: status of fence. 1: signaled 0:active <0:error -+ * @pt_info: a sync_pt_info struct for every sync_pt in the fence -+ */ -+struct sync_fence_info_data { -+ __u32 len; -+ char name[32]; -+ __s32 status; -+ -+ __u8 pt_info[0]; -+}; -+ -+#define SYNC_IOC_MAGIC '>' -+ -+/** -+ * DOC: SYNC_IOC_WAIT - wait for a fence to signal -+ * -+ * pass timeout in milliseconds. Waits indefinitely timeout < 0. -+ */ -+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) -+ -+/** -+ * DOC: SYNC_IOC_MERGE - merge two fences -+ * -+ * Takes a struct sync_merge_data. Creates a new fence containing copies of -+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the -+ * new fence's fd in sync_merge_data.fence -+ */ -+#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) -+ -+/** -+ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence -+ * -+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info. -+ * Caller should write the size of the buffer into len. On return, len is -+ * updated to reflect the total size of the sync_fence_info_data including -+ * pt_info. -+ * -+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. -+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field. -+ */ -+#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ -+ struct sync_fence_info_data) -+ -+#endif /* _UAPI_LINUX_SYNC_H */ ---- linux-4.9.37/drivers/dma-buf/sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/dma-buf/sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,363 @@ -+/* -+ * include/linux/sync.h -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_SYNC_H -+#define _LINUX_SYNC_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "_sync.h" -+ -+struct sync_timeline; -+struct sync_pt; -+#if 0 -+struct sync_fence; -+#endif -+ -+/** -+ * struct sync_timeline_ops - sync object implementation ops -+ * @driver_name: name of the implementation -+ * @dup: duplicate a sync_pt -+ * @has_signaled: returns: -+ * 1 if pt has signaled -+ * 0 if pt has not signaled -+ * <0 on error -+ * @compare: returns: -+ * 1 if b will signal before a -+ * 0 if a and b will signal at the same time -+ * -1 if a will signal before b -+ * @free_pt: called before sync_pt is freed -+ * @release_obj: called before sync_timeline is freed -+ * @fill_driver_data: write implementation specific driver data to data. -+ * should return an error if there is not enough room -+ * as specified by size. This information is returned -+ * to userspace by SYNC_IOC_FENCE_INFO. -+ * @timeline_value_str: fill str with the value of the sync_timeline's counter -+ * @pt_value_str: fill str with the value of the sync_pt -+ */ -+struct sync_timeline_ops { -+ const char *driver_name; -+ -+ /* required */ -+ struct sync_pt * (*dup)(struct sync_pt *pt); -+ -+ /* required */ -+ int (*has_signaled)(struct sync_pt *pt); -+ -+ /* required */ -+ int (*compare)(struct sync_pt *a, struct sync_pt *b); -+ -+ /* optional */ -+ void (*free_pt)(struct sync_pt *sync_pt); -+ -+ /* optional */ -+ void (*release_obj)(struct sync_timeline *sync_timeline); -+ -+ /* optional */ -+ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size); -+ -+ /* optional */ -+ void (*timeline_value_str)(struct sync_timeline *timeline, char *str, -+ int size); -+ -+ /* optional */ -+ void (*pt_value_str)(struct sync_pt *pt, char *str, int size); -+}; -+ -+/** -+ * struct sync_timeline - sync object -+ * @kref: reference count on fence. -+ * @ops: ops that define the implementation of the sync_timeline -+ * @name: name of the sync_timeline. Useful for debugging -+ * @destroyed: set when sync_timeline is destroyed -+ * @child_list_head: list of children sync_pts for this sync_timeline -+ * @child_list_lock: lock protecting @child_list_head, destroyed, and -+ * sync_pt.status -+ * @active_list_head: list of active (unsignaled/errored) sync_pts -+ * @sync_timeline_list: membership in global sync_timeline_list -+ */ -+struct sync_timeline { -+ struct kref kref; -+ const struct sync_timeline_ops *ops; -+ char name[32]; -+ -+ /* protected by child_list_lock */ -+ bool destroyed; -+ int context, value; -+ -+ struct list_head child_list_head; -+ spinlock_t child_list_lock; -+ -+ struct list_head active_list_head; -+ -+#ifdef CONFIG_DEBUG_FS -+ struct list_head sync_timeline_list; -+#endif -+}; -+ -+/** -+ * struct sync_pt - sync point -+ * @fence: base fence class -+ * @child_list: membership in sync_timeline.child_list_head -+ * @active_list: membership in sync_timeline.active_list_head -+ * @signaled_list: membership in temporary signaled_list on stack -+ * @fence: sync_fence to which the sync_pt belongs -+ * @pt_list: membership in sync_fence.pt_list_head -+ * @status: 1: signaled, 0:active, <0: error -+ * @timestamp: time which sync_pt status transitioned from active to -+ * signaled or error. -+ */ -+struct sync_pt { -+ struct fence base; -+ -+ struct list_head child_list; -+ struct list_head active_list; -+}; -+ -+static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt) -+{ -+ return container_of(pt->base.lock, struct sync_timeline, -+ child_list_lock); -+} -+ -+#if 0 -+struct sync_fence_cb { -+ struct fence_cb cb; -+ struct fence *sync_pt; -+ struct sync_fence *fence; -+}; -+ -+/** -+ * struct sync_fence - sync fence -+ * @file: file representing this fence -+ * @kref: reference count on fence. -+ * @name: name of sync_fence. Useful for debugging -+ * @pt_list_head: list of sync_pts in the fence. immutable once fence -+ * is created -+ * @status: 0: signaled, >0:active, <0: error -+ * -+ * @wq: wait queue for fence signaling -+ * @sync_fence_list: membership in global fence list -+ */ -+struct sync_fence { -+ struct file *file; -+ struct kref kref; -+ char name[32]; -+#ifdef CONFIG_DEBUG_FS -+ struct list_head sync_fence_list; -+#endif -+ int num_fences; -+ -+ wait_queue_head_t wq; -+ atomic_t status; -+ -+ struct sync_fence_cb cbs[]; -+}; -+ -+struct sync_fence_waiter; -+typedef void (*sync_callback_t)(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter); -+ -+/** -+ * struct sync_fence_waiter - metadata for asynchronous waiter on a fence -+ * @waiter_list: membership in sync_fence.waiter_list_head -+ * @callback: function pointer to call when fence signals -+ * @callback_data: pointer to pass to @callback -+ */ -+struct sync_fence_waiter { -+ wait_queue_t work; -+ sync_callback_t callback; -+}; -+ -+static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter, -+ sync_callback_t callback) -+{ -+ INIT_LIST_HEAD(&waiter->work.task_list); -+ waiter->callback = callback; -+} -+#endif -+ -+/* -+ * API for sync_timeline implementers -+ */ -+ -+/** -+ * sync_timeline_create() - creates a sync object -+ * @ops: specifies the implementation ops for the object -+ * @size: size to allocate for this obj -+ * @name: sync_timeline name -+ * -+ * Creates a new sync_timeline which will use the implementation specified by -+ * @ops. @size bytes will be allocated allowing for implementation specific -+ * data to be kept after the generic sync_timeline struct. -+ */ -+struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, -+ int size, const char *name); -+ -+/** -+ * sync_timeline_destroy() - destroys a sync object -+ * @obj: sync_timeline to destroy -+ * -+ * A sync implementation should call this when the @obj is going away -+ * (i.e. module unload.) @obj won't actually be freed until all its children -+ * sync_pts are freed. -+ */ -+void bsp_sync_timeline_destroy(struct sync_timeline *obj); -+ -+/** -+ * sync_timeline_signal() - signal a status change on a sync_timeline -+ * @obj: sync_timeline to signal -+ * -+ * A sync implementation should call this any time one of it's sync_pts -+ * has signaled or has an error condition. -+ */ -+void bsp_sync_timeline_signal(struct sync_timeline *obj); -+ -+/** -+ * sync_pt_create() - creates a sync pt -+ * @parent: sync_pt's parent sync_timeline -+ * @size: size to allocate for this pt -+ * -+ * Creates a new sync_pt as a child of @parent. @size bytes will be -+ * allocated allowing for implementation specific data to be kept after -+ * the generic sync_timeline struct. -+ */ -+struct sync_pt *bsp_sync_pt_create(struct sync_timeline *parent, int size); -+ -+/** -+ * sync_pt_free() - frees a sync pt -+ * @pt: sync_pt to free -+ * -+ * This should only be called on sync_pts which have been created but -+ * not added to a fence. -+ */ -+void bsp_sync_pt_free(struct sync_pt *pt); -+ -+#if 0 -+/** -+ * sync_fence_create() - creates a sync fence -+ * @name: name of fence to create -+ * @pt: sync_pt to add to the fence -+ * -+ * Creates a fence containg @pt. Once this is called, the fence takes -+ * ownership of @pt. -+ */ -+struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt); -+ -+/* -+ * API for sync_fence consumers -+ */ -+ -+/** -+ * sync_fence_merge() - merge two fences -+ * @name: name of new fence -+ * @a: fence a -+ * @b: fence b -+ * -+ * Creates a new fence which contains copies of all the sync_pts in both -+ * @a and @b. @a and @b remain valid, independent fences. -+ */ -+struct sync_fence *bsp_sync_fence_merge(const char *name, -+ struct sync_fence *a, struct sync_fence *b); -+ -+/** -+ * sync_fence_fdget() - get a fence from an fd -+ * @fd: fd referencing a fence -+ * -+ * Ensures @fd references a valid fence, increments the refcount of the backing -+ * file, and returns the fence. -+ */ -+struct sync_fence *bsp_sync_fence_fdget(int fd); -+ -+/** -+ * sync_fence_put() - puts a reference of a sync fence -+ * @fence: fence to put -+ * -+ * Puts a reference on @fence. If this is the last reference, the fence and -+ * all it's sync_pts will be freed -+ */ -+void bsp_sync_fence_put(struct sync_fence *fence); -+ -+/** -+ * sync_fence_install() - installs a fence into a file descriptor -+ * @fence: fence to install -+ * @fd: file descriptor in which to install the fence -+ * -+ * Installs @fence into @fd. @fd's should be acquired through -+ * get_unused_fd_flags(O_CLOEXEC). -+ */ -+void bsp_sync_fence_install(struct sync_fence *fence, int fd); -+ -+/** -+ * sync_fence_wait_async() - registers and async wait on the fence -+ * @fence: fence to wait on -+ * @waiter: waiter callback struck -+ * -+ * Returns 1 if @fence has already signaled. -+ * -+ * Registers a callback to be called when @fence signals or has an error. -+ * @waiter should be initialized with sync_fence_waiter_init(). -+ */ -+int bsp_sync_fence_wait_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter); -+ -+/** -+ * sync_fence_cancel_async() - cancels an async wait -+ * @fence: fence to wait on -+ * @waiter: waiter callback struck -+ * -+ * returns 0 if waiter was removed from fence's async waiter list. -+ * returns -ENOENT if waiter was not found on fence's async waiter list. -+ * -+ * Cancels a previously registered async wait. Will fail gracefully if -+ * @waiter was never registered or if @fence has already signaled @waiter. -+ */ -+int bsp_sync_fence_cancel_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter); -+ -+/** -+ * sync_fence_wait() - wait on fence -+ * @fence: fence to wait on -+ * @tiemout: timeout in ms -+ * -+ * Wait for @fence to be signaled or have an error. Waits indefinitely -+ * if @timeout < 0 -+ */ -+int bsp_sync_fence_wait(struct sync_fence *fence, long timeout); -+ -+#ifdef CONFIG_DEBUG_FS -+ -+void bsp_sync_timeline_debug_add(struct sync_timeline *obj); -+void bsp_sync_timeline_debug_remove(struct sync_timeline *obj); -+void bsp_sync_fence_debug_add(struct sync_fence *fence); -+void bsp_sync_fence_debug_remove(struct sync_fence *fence); -+void bsp_sync_dump(void); -+ -+#else -+# define bsp_sync_timeline_debug_add(obj) -+# define bsp_sync_timeline_debug_remove(obj) -+# define bsp_sync_fence_debug_add(fence) -+# define bsp_sync_fence_debug_remove(fence) -+# define bsp_sync_dump() -+#endif -+int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, -+ int wake_flags, void *key); -+ -+#endif -+ -+#endif /* _LINUX_SYNC_H */ ---- linux-4.9.37/drivers/fence/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,8 @@ -+ -+config GOKE_FENCE -+ bool "Goke fence suppport" -+ default y -+ select SW_SYNC -+ select SYNC_FILE -+ help -+ Goke fence suppport ---- linux-4.9.37/drivers/fence/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,2 @@ -+ -+obj-y += sw_sync.o sync.o sync_debug.o ---- linux-4.9.37/drivers/fence/sw_sync.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/sw_sync.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,277 @@ -+/* -+ * drivers/base/sw_sync.c -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sw_sync.h" -+ -+static int sw_sync_cmp(u32 a, u32 b) -+{ -+ if (a == b) -+ return 0; -+ -+ return ((s32)a - (s32)b) < 0 ? -1 : 1; -+} -+ -+struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value) -+{ -+ struct sw_sync_pt *pt; -+ -+ pt = (struct sw_sync_pt *) -+ bsp_sync_pt_create(&obj->obj, sizeof(struct sw_sync_pt)); -+ if (pt != NULL) { -+ pt->value = value; -+ } -+ -+ return (struct sync_pt *)pt; -+} -+EXPORT_SYMBOL(bsp_sw_sync_pt_create); -+ -+static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt) -+{ -+ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; -+ struct sw_sync_timeline *obj = -+ (struct sw_sync_timeline *)sync_pt_parent(sync_pt); -+ -+ return (struct sync_pt *)bsp_sw_sync_pt_create(obj, pt->value); -+} -+ -+static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt) -+{ -+ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; -+ struct sw_sync_timeline *obj = -+ (struct sw_sync_timeline *)sync_pt_parent(sync_pt); -+ -+ return sw_sync_cmp(obj->value, pt->value) >= 0; -+} -+ -+static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b) -+{ -+ struct sw_sync_pt *pt_a = (struct sw_sync_pt *)a; -+ struct sw_sync_pt *pt_b = (struct sw_sync_pt *)b; -+ -+ return sw_sync_cmp(pt_a->value, pt_b->value); -+} -+ -+static int sw_sync_fill_driver_data(struct sync_pt *sync_pt, -+ void *data, int size) -+{ -+ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; -+ -+ if (size < sizeof(pt->value)) -+ return -ENOMEM; -+ -+ memcpy(data, &pt->value, sizeof(pt->value)); -+ -+ return sizeof(pt->value); -+} -+ -+static void sw_sync_timeline_value_str(struct sync_timeline *sync_timeline, -+ char *str, int size) -+{ -+ struct sw_sync_timeline *timeline = -+ (struct sw_sync_timeline *)sync_timeline; -+ snprintf(str, size, "%d", timeline->value); -+} -+ -+static void sw_sync_pt_value_str(struct sync_pt *sync_pt, -+ char *str, int size) -+{ -+ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; -+ -+ snprintf(str, size, "%d", pt->value); -+} -+ -+static struct sync_timeline_ops sw_sync_timeline_ops = { -+ .driver_name = "sw_sync", -+ .dup = sw_sync_pt_dup, -+ .has_signaled = sw_sync_pt_has_signaled, -+ .compare = sw_sync_pt_compare, -+ .fill_driver_data = sw_sync_fill_driver_data, -+ .timeline_value_str = sw_sync_timeline_value_str, -+ .pt_value_str = sw_sync_pt_value_str, -+}; -+ -+struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name) -+{ -+ struct sw_sync_timeline *obj = (struct sw_sync_timeline *) -+ bsp_sync_timeline_create(&sw_sync_timeline_ops, -+ sizeof(struct sw_sync_timeline), -+ name); -+ -+ return obj; -+} -+EXPORT_SYMBOL(bsp_sw_sync_timeline_create); -+ -+void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) -+{ -+ obj->value += inc; -+ -+ bsp_sync_timeline_signal(&obj->obj); -+} -+EXPORT_SYMBOL(bsp_sw_sync_timeline_inc); -+ -+#ifdef CONFIG_SW_SYNC_USER -+/* *WARNING* -+ * -+ * improper use of this can result in deadlocking kernel drivers from userspace. -+ */ -+ -+/* opening sw_sync create a new sync obj */ -+static int sw_sync_open(struct inode *inode, struct file *file) -+{ -+ struct sw_sync_timeline *obj = NULL; -+ char task_comm[TASK_COMM_LEN]; -+ -+ get_task_comm(task_comm, current); -+ -+ obj = bsp_sw_sync_timeline_create(task_comm); -+ if (!obj) -+ return -ENOMEM; -+ -+ file->private_data = obj; -+ -+ return 0; -+} -+ -+static int sw_sync_release(struct inode *inode, struct file *file) -+{ -+ struct sw_sync_timeline *obj = file->private_data; -+ -+ bsp_sync_timeline_destroy(&obj->obj); -+ return 0; -+} -+ -+static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, -+ unsigned long arg) -+{ -+ int fd = get_unused_fd_flags(O_CLOEXEC); -+ int err; -+ struct sync_pt *pt = NULL; -+ #if 0 -+ struct sync_fence *fence; -+ #else -+ struct sync_file *fence = NULL; -+ #endif -+ struct sw_sync_create_fence_data data; -+ -+ if (fd < 0) -+ return fd; -+ -+ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { -+ err = -EFAULT; -+ goto err; -+ } -+ -+ pt = bsp_sw_sync_pt_create(obj, data.value); -+ if (!pt) { -+ err = -ENOMEM; -+ goto err; -+ } -+ -+ data.name[sizeof(data.name) - 1] = '\0'; -+ #if 0 -+ fence = bsp_sync_fence_create(data.name, pt); -+ #else -+ fence = sync_file_create(&pt->base); -+ #endif -+ if (!fence) { -+ bsp_sync_pt_free(pt); -+ err = -ENOMEM; -+ goto err; -+ } -+ -+ data.fence = fd; -+ if (copy_to_user((void __user *)arg, &data, sizeof(data))) { -+ #if 0 -+ bsp_sync_fence_put(fence); -+ #else -+ fput(fence->file); -+ #endif -+ err = -EFAULT; -+ goto err; -+ } -+ -+ #if 0 -+ bsp_sync_fence_install(fence, fd); -+ #else -+ fd_install(fd, fence->file); -+ #endif -+ -+ return 0; -+ -+err: -+ put_unused_fd(fd); -+ return err; -+} -+ -+static long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) -+{ -+ u32 value; -+ -+ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) -+ return -EFAULT; -+ -+ bsp_sw_sync_timeline_inc(obj, value); -+ -+ return 0; -+} -+ -+static long sw_sync_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct sw_sync_timeline *obj = file->private_data; -+ -+ switch (cmd) { -+ case SW_SYNC_IOC_CREATE_FENCE: -+ return sw_sync_ioctl_create_fence(obj, arg); -+ -+ case SW_SYNC_IOC_INC: -+ return sw_sync_ioctl_inc(obj, arg); -+ -+ default: -+ return -ENOTTY; -+ } -+} -+ -+static const struct file_operations sw_sync_fops = { -+ .owner = THIS_MODULE, -+ .open = sw_sync_open, -+ .release = sw_sync_release, -+ .unlocked_ioctl = sw_sync_ioctl, -+ .compat_ioctl = sw_sync_ioctl, -+}; -+ -+static struct miscdevice sw_sync_dev = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = "sw_sync", -+ .fops = &sw_sync_fops, -+}; -+ -+static int __init sw_sync_device_init(void) -+{ -+ return misc_register(&sw_sync_dev); -+} -+device_initcall(sw_sync_device_init); -+ -+#endif /* CONFIG_SW_SYNC_USER */ ---- linux-4.9.37/drivers/fence/_sw_sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/_sw_sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _UAPI_LINUX_SW_SYNC_H -+#define _UAPI_LINUX_SW_SYNC_H -+ -+#include -+ -+struct sw_sync_create_fence_data { -+ __u32 value; -+ char name[32]; -+ __s32 fence; /* fd of new fence */ -+}; -+ -+#define SW_SYNC_IOC_MAGIC 'W' -+ -+#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ -+ struct sw_sync_create_fence_data) -+#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) -+ -+#endif /* _UAPI_LINUX_SW_SYNC_H */ ---- linux-4.9.37/drivers/fence/sw_sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/sw_sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,60 @@ -+/* -+ * include/linux/sw_sync.h -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_SW_SYNC_H -+#define _LINUX_SW_SYNC_H -+ -+#include -+#include -+#include "sync.h" -+#include "_sw_sync.h" -+#include -+ -+struct sw_sync_timeline { -+ struct sync_timeline obj; -+ -+ u32 value; -+}; -+ -+struct sw_sync_pt { -+ struct sync_pt pt; -+ -+ u32 value; -+}; -+ -+#if IS_ENABLED(CONFIG_SW_SYNC) -+struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name); -+void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); -+ -+struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); -+#else -+static inline struct sw_sync_timeline *bsp_sw_sync_timeline_create(const char *name) -+{ -+ return NULL; -+} -+ -+static inline void bsp_sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) -+{ -+} -+ -+static inline struct sync_pt *bsp_sw_sync_pt_create(struct sw_sync_timeline *obj, -+ u32 value) -+{ -+ return NULL; -+} -+#endif /* IS_ENABLED(CONFIG_SW_SYNC) */ -+ -+#endif /* _LINUX_SW_SYNC_H */ ---- linux-4.9.37/drivers/fence/sync.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/sync.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,740 @@ -+/* -+ * drivers/base/sync.c -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sync.h" -+ -+#include -+ -+static const struct fence_ops android_fence_ops; -+static const struct file_operations sync_fence_fops; -+ -+struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, -+ int size, const char *name) -+{ -+ struct sync_timeline *obj = NULL; -+ -+ if (size < sizeof(struct sync_timeline)) -+ return NULL; -+ -+ obj = kzalloc(size, GFP_KERNEL); -+ if (obj == NULL) -+ return NULL; -+ -+ kref_init(&obj->kref); -+ obj->ops = ops; -+ obj->context = fence_context_alloc(1); -+ strlcpy(obj->name, name, sizeof(obj->name)); -+ -+ INIT_LIST_HEAD(&obj->child_list_head); -+ INIT_LIST_HEAD(&obj->active_list_head); -+ spin_lock_init(&obj->child_list_lock); -+#if 0 -+ bsp_sync_timeline_debug_add(obj); -+#endif -+ -+ return obj; -+} -+EXPORT_SYMBOL(bsp_sync_timeline_create); -+ -+static void sync_timeline_free(struct kref *kref) -+{ -+ struct sync_timeline *obj = -+ container_of(kref, struct sync_timeline, kref); -+#if 0 -+ bsp_sync_timeline_debug_remove(obj); -+#endif -+ if (obj->ops->release_obj) -+ obj->ops->release_obj(obj); -+ -+ kfree(obj); -+} -+ -+static void sync_timeline_get(struct sync_timeline *obj) -+{ -+ kref_get(&obj->kref); -+} -+ -+static void sync_timeline_put(struct sync_timeline *obj) -+{ -+ kref_put(&obj->kref, sync_timeline_free); -+} -+ -+void bsp_sync_timeline_destroy(struct sync_timeline *obj) -+{ -+ obj->destroyed = true; -+ /* -+ * Ensure timeline is marked as destroyed before -+ * changing timeline's fences status. -+ */ -+ smp_wmb(); -+ -+ /* -+ * signal any children that their parent is going away. -+ */ -+ bsp_sync_timeline_signal(obj); -+ sync_timeline_put(obj); -+} -+EXPORT_SYMBOL(bsp_sync_timeline_destroy); -+ -+void bsp_sync_timeline_signal(struct sync_timeline *obj) -+{ -+ unsigned long flags; -+ LIST_HEAD(signaled_pts); -+ struct sync_pt *pt = NULL; -+ struct sync_pt *next = NULL; -+ -+ spin_lock_irqsave(&obj->child_list_lock, flags); -+ -+ list_for_each_entry_safe(pt, next, &obj->active_list_head, -+ active_list) { -+ if (fence_is_signaled_locked(&pt->base)) { -+ list_del_init(&pt->active_list); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) -+ fence_put(&pt->base); -+#endif -+ } -+ } -+ -+ spin_unlock_irqrestore(&obj->child_list_lock, flags); -+} -+EXPORT_SYMBOL(bsp_sync_timeline_signal); -+ -+struct sync_pt *bsp_sync_pt_create(struct sync_timeline *obj, int size) -+{ -+ unsigned long flags; -+ struct sync_pt *pt = NULL; -+ -+ if (size < sizeof(struct sync_pt)) -+ return NULL; -+ -+ pt = kzalloc(size, GFP_KERNEL); -+ if (pt == NULL) -+ return NULL; -+ -+ spin_lock_irqsave(&obj->child_list_lock, flags); -+ sync_timeline_get(obj); -+ fence_init(&pt->base, &android_fence_ops, &obj->child_list_lock, -+ obj->context, ++obj->value); -+ list_add_tail(&pt->child_list, &obj->child_list_head); -+ INIT_LIST_HEAD(&pt->active_list); -+ spin_unlock_irqrestore(&obj->child_list_lock, flags); -+ return pt; -+} -+EXPORT_SYMBOL(bsp_sync_pt_create); -+ -+void bsp_sync_pt_free(struct sync_pt *pt) -+{ -+ fence_put(&pt->base); -+} -+EXPORT_SYMBOL(bsp_sync_pt_free); -+ -+#if 0 -+static struct sync_fence *sync_fence_alloc(int size, const char *name) -+{ -+ struct sync_fence *fence; -+ -+ fence = kzalloc(size, GFP_KERNEL); -+ if (fence == NULL) -+ return NULL; -+ -+ fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops, -+ fence, 0); -+ if (IS_ERR(fence->file)) -+ goto err; -+ -+ kref_init(&fence->kref); -+ strlcpy(fence->name, name, sizeof(fence->name)); -+ -+ init_waitqueue_head(&fence->wq); -+ -+ return fence; -+ -+err: -+ kfree(fence); -+ return NULL; -+} -+ -+static void fence_check_cb_func(struct fence *f, struct fence_cb *cb) -+{ -+ struct sync_fence_cb *check; -+ struct sync_fence *fence; -+ -+ check = container_of(cb, struct sync_fence_cb, cb); -+ fence = check->fence; -+ -+ if (atomic_dec_and_test(&fence->status)) -+ wake_up_all(&fence->wq); -+} -+ -+/* TODO: implement a create which takes more that one sync_pt */ -+struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt) -+{ -+ struct sync_fence *fence; -+ -+ fence = sync_fence_alloc(offsetof(struct sync_fence, cbs[1]), name); -+ if (fence == NULL) -+ return NULL; -+ -+ fence->num_fences = 1; -+ atomic_set(&fence->status, 1); -+ -+ fence->cbs[0].sync_pt = &pt->base; -+ fence->cbs[0].fence = fence; -+ if (fence_add_callback(&pt->base, &fence->cbs[0].cb, -+ fence_check_cb_func)) -+ atomic_dec(&fence->status); -+#if 0 -+ bsp_sync_fence_debug_add(fence); -+#endif -+ -+ return fence; -+} -+EXPORT_SYMBOL(bsp_sync_fence_create); -+ -+struct sync_fence *bsp_sync_fence_fdget(int fd) -+{ -+ struct file *file = fget(fd); -+ -+ if (file == NULL) -+ return NULL; -+ -+ if (file->f_op != &sync_fence_fops) -+ goto err; -+ -+ return file->private_data; -+ -+err: -+ fput(file); -+ return NULL; -+} -+EXPORT_SYMBOL(bsp_sync_fence_fdget); -+ -+void bsp_sync_fence_put(struct sync_fence *fence) -+{ -+ fput(fence->file); -+} -+EXPORT_SYMBOL(bsp_sync_fence_put); -+ -+void bsp_sync_fence_install(struct sync_fence *fence, int fd) -+{ -+ printk("<%s> Line %d: fd =%d, fence=%p, name=%s\n", __func__, __LINE__, fd, fence, fence->name); -+ fd_install(fd, fence->file); -+} -+EXPORT_SYMBOL(bsp_sync_fence_install); -+ -+static void sync_fence_add_pt(struct sync_fence *fence, -+ int *i, struct fence *pt) -+{ -+ fence->cbs[*i].sync_pt = pt; -+ fence->cbs[*i].fence = fence; -+ -+ if (!fence_add_callback(pt, &fence->cbs[*i].cb, fence_check_cb_func)) { -+ fence_get(pt); -+ (*i)++; -+ } -+} -+ -+struct sync_fence *bsp_sync_fence_merge(const char *name, -+ struct sync_fence *a, struct sync_fence *b) -+{ -+ int num_fences = a->num_fences + b->num_fences; -+ struct sync_fence *fence; -+ int i, i_a, i_b; -+ unsigned long size = offsetof(struct sync_fence, cbs[num_fences]); -+ -+ fence = sync_fence_alloc(size, name); -+ if (fence == NULL) -+ return NULL; -+ -+ atomic_set(&fence->status, num_fences); -+ -+ /* -+ * Assume sync_fence a and b are both ordered and have no -+ * duplicates with the same context. -+ * -+ * If a sync_fence can only be created with sync_fence_merge -+ * and sync_fence_create, this is a reasonable assumption. -+ */ -+ for (i = i_a = i_b = 0; i_a < a->num_fences && i_b < b->num_fences; ) { -+ struct fence *pt_a = a->cbs[i_a].sync_pt; -+ struct fence *pt_b = b->cbs[i_b].sync_pt; -+ -+ if (pt_a->context < pt_b->context) { -+ sync_fence_add_pt(fence, &i, pt_a); -+ -+ i_a++; -+ } else if (pt_a->context > pt_b->context) { -+ sync_fence_add_pt(fence, &i, pt_b); -+ -+ i_b++; -+ } else { -+ if (pt_a->seqno - pt_b->seqno <= INT_MAX) -+ sync_fence_add_pt(fence, &i, pt_a); -+ else -+ sync_fence_add_pt(fence, &i, pt_b); -+ -+ i_a++; -+ i_b++; -+ } -+ } -+ -+ for (; i_a < a->num_fences; i_a++) -+ sync_fence_add_pt(fence, &i, a->cbs[i_a].sync_pt); -+ -+ for (; i_b < b->num_fences; i_b++) -+ sync_fence_add_pt(fence, &i, b->cbs[i_b].sync_pt); -+ -+ if (num_fences > i) -+ atomic_sub(num_fences - i, &fence->status); -+ fence->num_fences = i; -+#if 0 -+ bsp_sync_fence_debug_add(fence); -+#endif -+ return fence; -+} -+EXPORT_SYMBOL(bsp_sync_fence_merge); -+ -+int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, -+ int wake_flags, void *key) -+{ -+ struct sync_fence_waiter *wait; -+ -+ wait = container_of(curr, struct sync_fence_waiter, work); -+ list_del_init(&wait->work.task_list); -+ -+ wait->callback(wait->work.private, wait); -+ return 1; -+} -+ -+int bsp_sync_fence_wait_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter) -+{ -+ int err = atomic_read(&fence->status); -+ unsigned long flags; -+ -+ if (err < 0) -+ return err; -+ -+ if (!err) -+ return 1; -+ -+ init_waitqueue_func_entry(&waiter->work, bsp_sync_fence_wake_up_wq); -+ waiter->work.private = fence; -+ -+ spin_lock_irqsave(&fence->wq.lock, flags); -+ err = atomic_read(&fence->status); -+ if (err > 0) -+ __add_wait_queue_tail(&fence->wq, &waiter->work); -+ spin_unlock_irqrestore(&fence->wq.lock, flags); -+ -+ if (err < 0) -+ return err; -+ -+ return !err; -+} -+EXPORT_SYMBOL(bsp_sync_fence_wait_async); -+ -+int bsp_sync_fence_cancel_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter) -+{ -+ unsigned long flags; -+ int ret = 0; -+ -+ spin_lock_irqsave(&fence->wq.lock, flags); -+ if (!list_empty(&waiter->work.task_list)) -+ list_del_init(&waiter->work.task_list); -+ else -+ ret = -ENOENT; -+ spin_unlock_irqrestore(&fence->wq.lock, flags); -+ return ret; -+} -+EXPORT_SYMBOL(bsp_sync_fence_cancel_async); -+ -+int bsp_sync_fence_wait(struct sync_fence *fence, long timeout) -+{ -+ long ret; -+ -+ if (timeout < 0) -+ timeout = MAX_SCHEDULE_TIMEOUT; -+ else -+ timeout = msecs_to_jiffies(timeout); -+ -+ ret = wait_event_interruptible_timeout(fence->wq, -+ atomic_read(&fence->status) <= 0, -+ timeout); -+ -+ if (ret < 0) { -+ return ret; -+ } else if (ret == 0) { -+ if (timeout) { -+ pr_info("fence timeout on [%p] after %dms\n", fence, -+ jiffies_to_msecs(timeout)); -+ bsp_sync_dump(); -+ } -+ return -ETIME; -+ } -+ -+ ret = atomic_read(&fence->status); -+ if (ret) { -+ pr_info("fence error %ld on [%p]\n", ret, fence); -+ bsp_sync_dump(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(bsp_sync_fence_wait); -+#endif -+ -+static const char *android_fence_get_driver_name(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ return parent->ops->driver_name; -+} -+ -+static const char *android_fence_get_timeline_name(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ return parent->name; -+} -+ -+static void android_fence_release(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ unsigned long flags; -+ -+ spin_lock_irqsave(fence->lock, flags); -+ list_del(&pt->child_list); -+ if (WARN_ON_ONCE(!list_empty(&pt->active_list))) -+ list_del(&pt->active_list); -+ spin_unlock_irqrestore(fence->lock, flags); -+ -+ if (parent->ops->free_pt) -+ parent->ops->free_pt(pt); -+ -+ sync_timeline_put(parent); -+ fence_free(&pt->base); -+} -+ -+static bool android_fence_signaled(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ int ret; -+ -+ ret = parent->ops->has_signaled(pt); -+ if (ret < 0) -+ fence->status = ret; -+ return ret; -+} -+ -+static bool android_fence_enable_signaling(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (android_fence_signaled(fence)) -+ return false; -+ -+ list_add_tail(&pt->active_list, &parent->active_list_head); -+ return true; -+} -+ -+static void android_fence_disable_signaling(struct fence *fence) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ -+ list_del_init(&pt->active_list); -+} -+ -+static int android_fence_fill_driver_data(struct fence *fence, -+ void *data, int size) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (!parent->ops->fill_driver_data) -+ return 0; -+ return parent->ops->fill_driver_data(pt, data, size); -+} -+ -+static void android_fence_value_str(struct fence *fence, -+ char *str, int size) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (!parent->ops->pt_value_str) { -+ if (size) -+ *str = 0; -+ return; -+ } -+ parent->ops->pt_value_str(pt, str, size); -+} -+ -+static void android_fence_timeline_value_str(struct fence *fence, -+ char *str, int size) -+{ -+ struct sync_pt *pt = container_of(fence, struct sync_pt, base); -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (!parent->ops->timeline_value_str) { -+ if (size) -+ *str = 0; -+ return; -+ } -+ parent->ops->timeline_value_str(parent, str, size); -+} -+ -+static const struct fence_ops android_fence_ops = { -+ .get_driver_name = android_fence_get_driver_name, -+ .get_timeline_name = android_fence_get_timeline_name, -+ .enable_signaling = android_fence_enable_signaling, -+ .disable_signaling = android_fence_disable_signaling, -+ .signaled = android_fence_signaled, -+ .wait = fence_default_wait, -+ .release = android_fence_release, -+ .fill_driver_data = android_fence_fill_driver_data, -+ .fence_value_str = android_fence_value_str, -+ .timeline_value_str = android_fence_timeline_value_str, -+}; -+ -+#if 0 -+static void sync_fence_free(struct kref *kref) -+{ -+ struct sync_fence *fence = container_of(kref, struct sync_fence, kref); -+ int i; -+ -+ for (i = 0; i < fence->num_fences; ++i) { -+ fence_remove_callback(fence->cbs[i].sync_pt, &fence->cbs[i].cb); -+ fence_put(fence->cbs[i].sync_pt); -+ } -+ -+ kfree(fence); -+} -+ -+static int sync_fence_release(struct inode *inode, struct file *file) -+{ -+ struct sync_fence *fence = file->private_data; -+ -+ bsp_sync_fence_debug_remove(fence); -+ -+ kref_put(&fence->kref, sync_fence_free); -+ return 0; -+} -+ -+static unsigned int sync_fence_poll(struct file *file, poll_table *wait) -+{ -+ struct sync_fence *fence = file->private_data; -+ int status; -+ -+ poll_wait(file, &fence->wq, wait); -+ -+ status = atomic_read(&fence->status); -+ -+ if (!status) -+ return POLLIN; -+ else if (status < 0) -+ return POLLERR; -+ return 0; -+} -+ -+static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg) -+{ -+ __s32 value; -+ -+ if (copy_from_user(&value, (void __user *)arg, sizeof(value))) -+ return -EFAULT; -+ -+ return bsp_sync_fence_wait(fence, value); -+} -+ -+static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg) -+{ -+ int fd = get_unused_fd_flags(O_CLOEXEC); -+ int err; -+ struct sync_fence *fence2, *fence3; -+ struct sync_merge_data data; -+ -+ if (fd < 0) -+ return fd; -+ -+ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { -+ err = -EFAULT; -+ goto err_put_fd; -+ } -+ -+ fence2 = bsp_sync_fence_fdget(data.fd2); -+ if (fence2 == NULL) { -+ err = -ENOENT; -+ goto err_put_fd; -+ } -+ -+ data.name[sizeof(data.name) - 1] = '\0'; -+ fence3 = bsp_sync_fence_merge(data.name, fence, fence2); -+ if (fence3 == NULL) { -+ err = -ENOMEM; -+ goto err_put_fence2; -+ } -+ -+ data.fence = fd; -+ if (copy_to_user((void __user *)arg, &data, sizeof(data))) { -+ err = -EFAULT; -+ goto err_put_fence3; -+ } -+ -+ bsp_sync_fence_install(fence3, fd); -+ bsp_sync_fence_put(fence2); -+ return 0; -+ -+err_put_fence3: -+ bsp_sync_fence_put(fence3); -+ -+err_put_fence2: -+ bsp_sync_fence_put(fence2); -+ -+err_put_fd: -+ put_unused_fd(fd); -+ return err; -+} -+ -+static int sync_fill_pt_info(struct fence *fence, void *data, int size) -+{ -+ struct sync_pt_info *info = data; -+ int ret; -+ -+ if (size < sizeof(struct sync_pt_info)) -+ return -ENOMEM; -+ -+ info->len = sizeof(struct sync_pt_info); -+ -+ if (fence->ops->fill_driver_data) { -+ ret = fence->ops->fill_driver_data(fence, info->driver_data, -+ size - sizeof(*info)); -+ if (ret < 0) -+ return ret; -+ -+ info->len += ret; -+ } -+ -+ strlcpy(info->obj_name, fence->ops->get_timeline_name(fence), -+ sizeof(info->obj_name)); -+ strlcpy(info->driver_name, fence->ops->get_driver_name(fence), -+ sizeof(info->driver_name)); -+ if (fence_is_signaled(fence)) -+ info->status = fence->status >= 0 ? 1 : fence->status; -+ else -+ info->status = 0; -+ info->timestamp_ns = ktime_to_ns(fence->timestamp); -+ -+ return info->len; -+} -+ -+static long sync_fence_ioctl_fence_info(struct sync_fence *fence, -+ unsigned long arg) -+{ -+ struct sync_fence_info_data *data; -+ __u32 size; -+ __u32 len = 0; -+ int ret, i; -+ -+ if (copy_from_user(&size, (void __user *)arg, sizeof(size))) -+ return -EFAULT; -+ -+ if (size < sizeof(struct sync_fence_info_data)) -+ return -EINVAL; -+ -+ if (size > 4096) -+ size = 4096; -+ -+ data = kzalloc(size, GFP_KERNEL); -+ if (data == NULL) -+ return -ENOMEM; -+ -+ strlcpy(data->name, fence->name, sizeof(data->name)); -+ data->status = atomic_read(&fence->status); -+ if (data->status >= 0) -+ data->status = !data->status; -+ -+ len = sizeof(struct sync_fence_info_data); -+ -+ for (i = 0; i < fence->num_fences; ++i) { -+ struct fence *pt = fence->cbs[i].sync_pt; -+ -+ ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len); -+ -+ if (ret < 0) -+ goto out; -+ -+ len += ret; -+ } -+ -+ data->len = len; -+ -+ if (copy_to_user((void __user *)arg, data, len)) -+ ret = -EFAULT; -+ else -+ ret = 0; -+ -+out: -+ kfree(data); -+ -+ return ret; -+} -+ -+static long sync_fence_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct sync_fence *fence = file->private_data; -+ -+ switch (cmd) { -+ case SYNC_IOC_WAIT: -+ return sync_fence_ioctl_wait(fence, arg); -+ -+ case SYNC_IOC_MERGE: -+ return sync_fence_ioctl_merge(fence, arg); -+ -+ case SYNC_IOC_FENCE_INFO: -+ return sync_fence_ioctl_fence_info(fence, arg); -+ -+ default: -+ return -ENOTTY; -+ } -+} -+ -+static const struct file_operations sync_fence_fops = { -+ .release = sync_fence_release, -+ .poll = sync_fence_poll, -+ .unlocked_ioctl = sync_fence_ioctl, -+ .compat_ioctl = sync_fence_ioctl, -+}; -+#endif -+ ---- linux-4.9.37/drivers/fence/sync_debug.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/sync_debug.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,259 @@ -+/* -+ * drivers/base/sync.c -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sync.h" -+ -+#ifdef CONFIG_DEBUG_FS -+ -+static LIST_HEAD(sync_timeline_list_head); -+static DEFINE_SPINLOCK(sync_timeline_list_lock); -+#if 0 -+static LIST_HEAD(sync_fence_list_head); -+static DEFINE_SPINLOCK(sync_fence_list_lock); -+#endif -+ -+void bsp_sync_timeline_debug_add(struct sync_timeline *obj) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&sync_timeline_list_lock, flags); -+ list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head); -+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags); -+} -+ -+void bsp_sync_timeline_debug_remove(struct sync_timeline *obj) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&sync_timeline_list_lock, flags); -+ list_del(&obj->sync_timeline_list); -+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags); -+} -+ -+#if 0 -+void bsp_sync_fence_debug_add(struct sync_fence *fence) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&sync_fence_list_lock, flags); -+ list_add_tail(&fence->sync_fence_list, &sync_fence_list_head); -+ spin_unlock_irqrestore(&sync_fence_list_lock, flags); -+} -+ -+void bsp_sync_fence_debug_remove(struct sync_fence *fence) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&sync_fence_list_lock, flags); -+ list_del(&fence->sync_fence_list); -+ spin_unlock_irqrestore(&sync_fence_list_lock, flags); -+} -+#endif -+ -+static const char *sync_status_str(int status) -+{ -+ if (status == 0) -+ return "signaled"; -+ -+ if (status > 0) -+ return "active"; -+ -+ return "error"; -+} -+ -+static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence) -+{ -+ int status = 1; -+ struct sync_timeline *parent = sync_pt_parent(pt); -+ -+ if (fence_is_signaled_locked(&pt->base)) -+ status = pt->base.status; -+ -+ seq_printf(s, " %s%spt %s", -+ fence ? parent->name : "", -+ fence ? "_" : "", -+ sync_status_str(status)); -+ -+ if (status <= 0) { -+ struct timespec64 ts64 = -+ ktime_to_timespec64(pt->base.timestamp); -+ -+ seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec); -+ } -+ -+ if (parent->ops->timeline_value_str && -+ parent->ops->pt_value_str) { -+ char value[64]; -+ -+ parent->ops->pt_value_str(pt, value, sizeof(value)); -+ seq_printf(s, ": %s", value); -+ if (fence) { -+ parent->ops->timeline_value_str(parent, value, -+ sizeof(value)); -+ seq_printf(s, " / %s", value); -+ } -+ } -+ -+ seq_puts(s, "\n"); -+} -+ -+static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) -+{ -+ struct list_head *pos = NULL; -+ unsigned long flags; -+ -+ seq_printf(s, "%s %s", obj->name, obj->ops->driver_name); -+ -+ if (obj->ops->timeline_value_str) { -+ char value[64]; -+ -+ obj->ops->timeline_value_str(obj, value, sizeof(value)); -+ seq_printf(s, ": %s", value); -+ } -+ -+ seq_puts(s, "\n"); -+ -+ spin_lock_irqsave(&obj->child_list_lock, flags); -+ list_for_each(pos, &obj->child_list_head) { -+ struct sync_pt *pt = -+ container_of(pos, struct sync_pt, child_list); -+ sync_print_pt(s, pt, false); -+ } -+ spin_unlock_irqrestore(&obj->child_list_lock, flags); -+} -+#if 0 -+static void sync_print_fence(struct seq_file *s, struct sync_fence *fence) -+{ -+ wait_queue_t *pos; -+ unsigned long flags; -+ int i; -+ -+ seq_printf(s, "[%p] %s: %s\n", fence, fence->name, -+ sync_status_str(atomic_read(&fence->status))); -+ -+ for (i = 0; i < fence->num_fences; ++i) { -+ struct sync_pt *pt = -+ container_of(fence->cbs[i].sync_pt, -+ struct sync_pt, base); -+ -+ sync_print_pt(s, pt, true); -+ } -+ -+ spin_lock_irqsave(&fence->wq.lock, flags); -+ list_for_each_entry(pos, &fence->wq.task_list, task_list) { -+ struct sync_fence_waiter *waiter; -+ -+ if (pos->func != &bsp_sync_fence_wake_up_wq) -+ continue; -+ -+ waiter = container_of(pos, struct sync_fence_waiter, work); -+ -+ seq_printf(s, "waiter %pF\n", waiter->callback); -+ } -+ spin_unlock_irqrestore(&fence->wq.lock, flags); -+} -+#endif -+static int sync_debugfs_show(struct seq_file *s, void *unused) -+{ -+ unsigned long flags; -+ struct list_head *pos = NULL; -+ -+ seq_puts(s, "objs:\n--------------\n"); -+ -+ spin_lock_irqsave(&sync_timeline_list_lock, flags); -+ list_for_each(pos, &sync_timeline_list_head) { -+ struct sync_timeline *obj = -+ container_of(pos, struct sync_timeline, -+ sync_timeline_list); -+ -+ sync_print_obj(s, obj); -+ seq_puts(s, "\n"); -+ } -+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags); -+ -+ seq_puts(s, "fences:\n--------------\n"); -+#if 0 -+ spin_lock_irqsave(&sync_fence_list_lock, flags); -+ list_for_each(pos, &sync_fence_list_head) { -+ struct sync_fence *fence = -+ container_of(pos, struct sync_fence, sync_fence_list); -+ -+ sync_print_fence(s, fence); -+ seq_puts(s, "\n"); -+ } -+ spin_unlock_irqrestore(&sync_fence_list_lock, flags); -+#endif -+ return 0; -+} -+ -+static int sync_debugfs_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, sync_debugfs_show, inode->i_private); -+} -+ -+static const struct file_operations sync_debugfs_fops = { -+ .open = sync_debugfs_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int __init _sync_debugfs_init(void) -+{ -+ debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops); -+ return 0; -+} -+module_init(_sync_debugfs_init); -+ -+#define DUMP_CHUNK 256 -+static char sync_dump_buf[64 * 1024]; -+void bsp_sync_dump(void) -+{ -+ struct seq_file s = { -+ .buf = sync_dump_buf, -+ .size = sizeof(sync_dump_buf) - 1, -+ }; -+ int i; -+ -+ sync_debugfs_show(&s, NULL); -+ -+ for (i = 0; i < s.count; i += DUMP_CHUNK) { -+ if (((s.count - i) > DUMP_CHUNK) && (i + DUMP_CHUNK < sizeof(sync_dump_buf))) { -+ char c = s.buf[i + DUMP_CHUNK]; -+ -+ s.buf[i + DUMP_CHUNK] = 0; -+ pr_cont("%s", s.buf + i); -+ s.buf[i + DUMP_CHUNK] = c; -+ } else { -+ s.buf[s.count] = 0; -+ pr_cont("%s", s.buf + i); -+ } -+ } -+} -+ -+#endif ---- linux-4.9.37/drivers/fence/_sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/_sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,97 @@ -+/* -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _UAPI_LINUX_SYNC_H -+#define _UAPI_LINUX_SYNC_H -+ -+#include -+#include -+ -+/** -+ * struct sync_merge_data - data passed to merge ioctl -+ * @fd2: file descriptor of second fence -+ * @name: name of new fence -+ * @fence: returns the fd of the new fence to userspace -+ */ -+struct sync_merge_data { -+ __s32 fd2; /* fd of second fence */ -+ char name[32]; /* name of new fence */ -+ __s32 fence; /* fd on newly created fence */ -+}; -+ -+/** -+ * struct sync_pt_info - detailed sync_pt information -+ * @len: length of sync_pt_info including any driver_data -+ * @obj_name: name of parent sync_timeline -+ * @driver_name: name of driver implementing the parent -+ * @status: status of the sync_pt 0:active 1:signaled <0:error -+ * @timestamp_ns: timestamp of status change in nanoseconds -+ * @driver_data: any driver dependent data -+ */ -+struct sync_pt_info { -+ __u32 len; -+ char obj_name[32]; -+ char driver_name[32]; -+ __s32 status; -+ __u64 timestamp_ns; -+ -+ __u8 driver_data[0]; -+}; -+ -+/** -+ * struct sync_fence_info_data - data returned from fence info ioctl -+ * @len: ioctl caller writes the size of the buffer its passing in. -+ * ioctl returns length of sync_fence_data returned to userspace -+ * including pt_info. -+ * @name: name of fence -+ * @status: status of fence. 1: signaled 0:active <0:error -+ * @pt_info: a sync_pt_info struct for every sync_pt in the fence -+ */ -+struct sync_fence_info_data { -+ __u32 len; -+ char name[32]; -+ __s32 status; -+ -+ __u8 pt_info[0]; -+}; -+ -+#define SYNC_IOC_MAGIC '>' -+ -+/** -+ * DOC: SYNC_IOC_WAIT - wait for a fence to signal -+ * -+ * pass timeout in milliseconds. Waits indefinitely timeout < 0. -+ */ -+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32) -+ -+/** -+ * DOC: SYNC_IOC_MERGE - merge two fences -+ * -+ * Takes a struct sync_merge_data. Creates a new fence containing copies of -+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the -+ * new fence's fd in sync_merge_data.fence -+ */ -+#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data) -+ -+/** -+ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence -+ * -+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info. -+ * Caller should write the size of the buffer into len. On return, len is -+ * updated to reflect the total size of the sync_fence_info_data including -+ * pt_info. -+ * -+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. -+ * To iterate over the sync_pt_infos, use the sync_pt_info.len field. -+ */ -+#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ -+ struct sync_fence_info_data) -+ -+#endif /* _UAPI_LINUX_SYNC_H */ ---- linux-4.9.37/drivers/fence/sync.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/fence/sync.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,363 @@ -+/* -+ * include/linux/sync.h -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_SYNC_H -+#define _LINUX_SYNC_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "_sync.h" -+ -+struct sync_timeline; -+struct sync_pt; -+#if 0 -+struct sync_fence; -+#endif -+ -+/** -+ * struct sync_timeline_ops - sync object implementation ops -+ * @driver_name: name of the implementation -+ * @dup: duplicate a sync_pt -+ * @has_signaled: returns: -+ * 1 if pt has signaled -+ * 0 if pt has not signaled -+ * <0 on error -+ * @compare: returns: -+ * 1 if b will signal before a -+ * 0 if a and b will signal at the same time -+ * -1 if a will signal before b -+ * @free_pt: called before sync_pt is freed -+ * @release_obj: called before sync_timeline is freed -+ * @fill_driver_data: write implementation specific driver data to data. -+ * should return an error if there is not enough room -+ * as specified by size. This information is returned -+ * to userspace by SYNC_IOC_FENCE_INFO. -+ * @timeline_value_str: fill str with the value of the sync_timeline's counter -+ * @pt_value_str: fill str with the value of the sync_pt -+ */ -+struct sync_timeline_ops { -+ const char *driver_name; -+ -+ /* required */ -+ struct sync_pt * (*dup)(struct sync_pt *pt); -+ -+ /* required */ -+ int (*has_signaled)(struct sync_pt *pt); -+ -+ /* required */ -+ int (*compare)(struct sync_pt *a, struct sync_pt *b); -+ -+ /* optional */ -+ void (*free_pt)(struct sync_pt *sync_pt); -+ -+ /* optional */ -+ void (*release_obj)(struct sync_timeline *sync_timeline); -+ -+ /* optional */ -+ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size); -+ -+ /* optional */ -+ void (*timeline_value_str)(struct sync_timeline *timeline, char *str, -+ int size); -+ -+ /* optional */ -+ void (*pt_value_str)(struct sync_pt *pt, char *str, int size); -+}; -+ -+/** -+ * struct sync_timeline - sync object -+ * @kref: reference count on fence. -+ * @ops: ops that define the implementation of the sync_timeline -+ * @name: name of the sync_timeline. Useful for debugging -+ * @destroyed: set when sync_timeline is destroyed -+ * @child_list_head: list of children sync_pts for this sync_timeline -+ * @child_list_lock: lock protecting @child_list_head, destroyed, and -+ * sync_pt.status -+ * @active_list_head: list of active (unsignaled/errored) sync_pts -+ * @sync_timeline_list: membership in global sync_timeline_list -+ */ -+struct sync_timeline { -+ struct kref kref; -+ const struct sync_timeline_ops *ops; -+ char name[32]; -+ -+ /* protected by child_list_lock */ -+ bool destroyed; -+ int context, value; -+ -+ struct list_head child_list_head; -+ spinlock_t child_list_lock; -+ -+ struct list_head active_list_head; -+ -+#ifdef CONFIG_DEBUG_FS -+ struct list_head sync_timeline_list; -+#endif -+}; -+ -+/** -+ * struct sync_pt - sync point -+ * @fence: base fence class -+ * @child_list: membership in sync_timeline.child_list_head -+ * @active_list: membership in sync_timeline.active_list_head -+ * @signaled_list: membership in temporary signaled_list on stack -+ * @fence: sync_fence to which the sync_pt belongs -+ * @pt_list: membership in sync_fence.pt_list_head -+ * @status: 1: signaled, 0:active, <0: error -+ * @timestamp: time which sync_pt status transitioned from active to -+ * signaled or error. -+ */ -+struct sync_pt { -+ struct fence base; -+ -+ struct list_head child_list; -+ struct list_head active_list; -+}; -+ -+static inline struct sync_timeline *sync_pt_parent(struct sync_pt *pt) -+{ -+ return container_of(pt->base.lock, struct sync_timeline, -+ child_list_lock); -+} -+ -+#if 0 -+struct sync_fence_cb { -+ struct fence_cb cb; -+ struct fence *sync_pt; -+ struct sync_fence *fence; -+}; -+ -+/** -+ * struct sync_fence - sync fence -+ * @file: file representing this fence -+ * @kref: reference count on fence. -+ * @name: name of sync_fence. Useful for debugging -+ * @pt_list_head: list of sync_pts in the fence. immutable once fence -+ * is created -+ * @status: 0: signaled, >0:active, <0: error -+ * -+ * @wq: wait queue for fence signaling -+ * @sync_fence_list: membership in global fence list -+ */ -+struct sync_fence { -+ struct file *file; -+ struct kref kref; -+ char name[32]; -+#ifdef CONFIG_DEBUG_FS -+ struct list_head sync_fence_list; -+#endif -+ int num_fences; -+ -+ wait_queue_head_t wq; -+ atomic_t status; -+ -+ struct sync_fence_cb cbs[]; -+}; -+ -+struct sync_fence_waiter; -+typedef void (*sync_callback_t)(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter); -+ -+/** -+ * struct sync_fence_waiter - metadata for asynchronous waiter on a fence -+ * @waiter_list: membership in sync_fence.waiter_list_head -+ * @callback: function pointer to call when fence signals -+ * @callback_data: pointer to pass to @callback -+ */ -+struct sync_fence_waiter { -+ wait_queue_t work; -+ sync_callback_t callback; -+}; -+ -+static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter, -+ sync_callback_t callback) -+{ -+ INIT_LIST_HEAD(&waiter->work.task_list); -+ waiter->callback = callback; -+} -+#endif -+ -+/* -+ * API for sync_timeline implementers -+ */ -+ -+/** -+ * sync_timeline_create() - creates a sync object -+ * @ops: specifies the implementation ops for the object -+ * @size: size to allocate for this obj -+ * @name: sync_timeline name -+ * -+ * Creates a new sync_timeline which will use the implementation specified by -+ * @ops. @size bytes will be allocated allowing for implementation specific -+ * data to be kept after the generic sync_timeline struct. -+ */ -+struct sync_timeline *bsp_sync_timeline_create(const struct sync_timeline_ops *ops, -+ int size, const char *name); -+ -+/** -+ * sync_timeline_destroy() - destroys a sync object -+ * @obj: sync_timeline to destroy -+ * -+ * A sync implementation should call this when the @obj is going away -+ * (i.e. module unload.) @obj won't actually be freed until all its children -+ * sync_pts are freed. -+ */ -+void bsp_sync_timeline_destroy(struct sync_timeline *obj); -+ -+/** -+ * sync_timeline_signal() - signal a status change on a sync_timeline -+ * @obj: sync_timeline to signal -+ * -+ * A sync implementation should call this any time one of it's sync_pts -+ * has signaled or has an error condition. -+ */ -+void bsp_sync_timeline_signal(struct sync_timeline *obj); -+ -+/** -+ * sync_pt_create() - creates a sync pt -+ * @parent: sync_pt's parent sync_timeline -+ * @size: size to allocate for this pt -+ * -+ * Creates a new sync_pt as a child of @parent. @size bytes will be -+ * allocated allowing for implementation specific data to be kept after -+ * the generic sync_timeline struct. -+ */ -+struct sync_pt *bsp_sync_pt_create(struct sync_timeline *parent, int size); -+ -+/** -+ * sync_pt_free() - frees a sync pt -+ * @pt: sync_pt to free -+ * -+ * This should only be called on sync_pts which have been created but -+ * not added to a fence. -+ */ -+void bsp_sync_pt_free(struct sync_pt *pt); -+ -+#if 0 -+/** -+ * sync_fence_create() - creates a sync fence -+ * @name: name of fence to create -+ * @pt: sync_pt to add to the fence -+ * -+ * Creates a fence containg @pt. Once this is called, the fence takes -+ * ownership of @pt. -+ */ -+struct sync_fence *bsp_sync_fence_create(const char *name, struct sync_pt *pt); -+ -+/* -+ * API for sync_fence consumers -+ */ -+ -+/** -+ * sync_fence_merge() - merge two fences -+ * @name: name of new fence -+ * @a: fence a -+ * @b: fence b -+ * -+ * Creates a new fence which contains copies of all the sync_pts in both -+ * @a and @b. @a and @b remain valid, independent fences. -+ */ -+struct sync_fence *bsp_sync_fence_merge(const char *name, -+ struct sync_fence *a, struct sync_fence *b); -+ -+/** -+ * sync_fence_fdget() - get a fence from an fd -+ * @fd: fd referencing a fence -+ * -+ * Ensures @fd references a valid fence, increments the refcount of the backing -+ * file, and returns the fence. -+ */ -+struct sync_fence *bsp_sync_fence_fdget(int fd); -+ -+/** -+ * sync_fence_put() - puts a reference of a sync fence -+ * @fence: fence to put -+ * -+ * Puts a reference on @fence. If this is the last reference, the fence and -+ * all it's sync_pts will be freed -+ */ -+void bsp_sync_fence_put(struct sync_fence *fence); -+ -+/** -+ * sync_fence_install() - installs a fence into a file descriptor -+ * @fence: fence to install -+ * @fd: file descriptor in which to install the fence -+ * -+ * Installs @fence into @fd. @fd's should be acquired through -+ * get_unused_fd_flags(O_CLOEXEC). -+ */ -+void bsp_sync_fence_install(struct sync_fence *fence, int fd); -+ -+/** -+ * sync_fence_wait_async() - registers and async wait on the fence -+ * @fence: fence to wait on -+ * @waiter: waiter callback struck -+ * -+ * Returns 1 if @fence has already signaled. -+ * -+ * Registers a callback to be called when @fence signals or has an error. -+ * @waiter should be initialized with sync_fence_waiter_init(). -+ */ -+int bsp_sync_fence_wait_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter); -+ -+/** -+ * sync_fence_cancel_async() - cancels an async wait -+ * @fence: fence to wait on -+ * @waiter: waiter callback struck -+ * -+ * returns 0 if waiter was removed from fence's async waiter list. -+ * returns -ENOENT if waiter was not found on fence's async waiter list. -+ * -+ * Cancels a previously registered async wait. Will fail gracefully if -+ * @waiter was never registered or if @fence has already signaled @waiter. -+ */ -+int bsp_sync_fence_cancel_async(struct sync_fence *fence, -+ struct sync_fence_waiter *waiter); -+ -+/** -+ * sync_fence_wait() - wait on fence -+ * @fence: fence to wait on -+ * @tiemout: timeout in ms -+ * -+ * Wait for @fence to be signaled or have an error. Waits indefinitely -+ * if @timeout < 0 -+ */ -+int bsp_sync_fence_wait(struct sync_fence *fence, long timeout); -+ -+#ifdef CONFIG_DEBUG_FS -+ -+void bsp_sync_timeline_debug_add(struct sync_timeline *obj); -+void bsp_sync_timeline_debug_remove(struct sync_timeline *obj); -+void bsp_sync_fence_debug_add(struct sync_fence *fence); -+void bsp_sync_fence_debug_remove(struct sync_fence *fence); -+void bsp_sync_dump(void); -+ -+#else -+# define bsp_sync_timeline_debug_add(obj) -+# define bsp_sync_timeline_debug_remove(obj) -+# define bsp_sync_fence_debug_add(fence) -+# define bsp_sync_fence_debug_remove(fence) -+# define bsp_sync_dump() -+#endif -+int bsp_sync_fence_wake_up_wq(wait_queue_t *curr, unsigned mode, -+ int wake_flags, void *key); -+ -+#endif -+ -+#endif /* _LINUX_SYNC_H */ ---- linux-4.9.37/drivers/firmware/psci.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/firmware/psci.c 2021-06-07 13:01:33.000000000 +0300 -@@ -59,7 +59,9 @@ - return cpu == resident_cpu; - } - --struct psci_operations psci_ops; -+struct psci_operations psci_ops = { -+ .conduit = PSCI_CONDUIT_NONE, -+}; - - typedef unsigned long (psci_fn)(unsigned long, unsigned long, - unsigned long, unsigned long); -@@ -210,6 +212,22 @@ - 0, 0, 0); - } - -+static void set_conduit(enum psci_conduit conduit) -+{ -+ switch (conduit) { -+ case PSCI_CONDUIT_HVC: -+ invoke_psci_fn = __invoke_psci_fn_hvc; -+ break; -+ case PSCI_CONDUIT_SMC: -+ invoke_psci_fn = __invoke_psci_fn_smc; -+ break; -+ default: -+ WARN(1, "Unexpected PSCI conduit %d\n", conduit); -+ } -+ -+ psci_ops.conduit = conduit; -+} -+ - static int get_set_conduit_method(struct device_node *np) - { - const char *method; -@@ -222,9 +240,9 @@ - } - - if (!strcmp("hvc", method)) { -- invoke_psci_fn = __invoke_psci_fn_hvc; -+ set_conduit(PSCI_CONDUIT_HVC); - } else if (!strcmp("smc", method)) { -- invoke_psci_fn = __invoke_psci_fn_smc; -+ set_conduit(PSCI_CONDUIT_SMC); - } else { - pr_warn("invalid \"method\" property: %s\n", method); - return -EINVAL; -@@ -496,6 +514,8 @@ - static void __init psci_0_2_set_functions(void) - { - pr_info("Using standard PSCI v0.2 function IDs\n"); -+ psci_ops.get_version = psci_get_version; -+ - psci_function_id[PSCI_FN_CPU_SUSPEND] = - PSCI_FN_NATIVE(0_2, CPU_SUSPEND); - psci_ops.cpu_suspend = psci_cpu_suspend; -@@ -652,9 +672,9 @@ - pr_info("probing for conduit method from ACPI.\n"); - - if (acpi_psci_use_hvc()) -- invoke_psci_fn = __invoke_psci_fn_hvc; -+ set_conduit(PSCI_CONDUIT_HVC); - else -- invoke_psci_fn = __invoke_psci_fn_smc; -+ set_conduit(PSCI_CONDUIT_SMC); - - return psci_probe(); - } ---- linux-4.9.37/drivers/goke/cma/cma.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/goke/cma/cma.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,178 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include -+ -+static u32 num_zones; -+static struct cma_zone zone[ZONE_MAX]; -+static int use_bootargs; -+ -+unsigned int get_cma_size(void) -+{ -+ int i; -+ u64 total = 0; -+ -+ for (i = 0; i < num_zones; i++) { -+ total += zone[i].nbytes; -+ } -+ -+ /* unit is M */ -+ return (unsigned int)(total >> 20); -+} -+ -+int is_cma_address(phys_addr_t phys, unsigned long size) -+{ -+ phys_addr_t start, end; -+ int i; -+ -+ for (i = 0; i < num_zones; i++) { -+ start = zone[i].phys_start; -+ end = zone[i].phys_start + zone[i].nbytes; -+ -+ if ((phys >= start) && ((phys + size) <= end)) { -+ /* -+ * Yes, found! -+ */ -+ return 1; -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(is_cma_address); -+ -+static int __init mmz_parse_cmdline(char *s) -+{ -+ char *line = NULL; -+ char *tmp = NULL; -+ char tmpline[256]; -+ -+ if (s == NULL) { -+ pr_info("There is no cma zone!\n"); -+ return 0; -+ } -+ strncpy(tmpline, s, sizeof(tmpline)); -+ tmpline[sizeof(tmpline) - 1] = '\0'; -+ tmp = tmpline; -+ -+ while ((line = strsep(&tmp, ":")) != NULL) { -+ int i; -+ char *argv[6]; -+ -+ for (i = 0; (argv[i] = strsep(&line, ",")) != NULL;) -+ if (++i == ARRAY_SIZE(argv)) { -+ break; -+ } -+ -+ zone[num_zones].pdev.coherent_dma_mask = DMA_BIT_MASK(64); -+ if (i == 4) { -+ strlcpy(zone[num_zones].name, argv[0], NAME_LEN_MAX); -+ zone[num_zones].gfp = memparse(argv[1], NULL); -+ zone[num_zones].phys_start = memparse(argv[2], NULL); -+ zone[num_zones].nbytes = memparse(argv[3], NULL); -+ } -+ -+ else if (i == 6) { -+ strlcpy(zone[num_zones].name, argv[0], NAME_LEN_MAX); -+ zone[num_zones].gfp = memparse(argv[1], NULL); -+ zone[num_zones].phys_start = memparse(argv[2], NULL); -+ zone[num_zones].nbytes = memparse(argv[3], NULL); -+ zone[num_zones].alloc_type = memparse(argv[4], NULL); -+ zone[num_zones].block_align = memparse(argv[5], NULL); -+ } else { -+ pr_err("ion parameter is not correct\n"); -+ continue; -+ } -+ -+ num_zones++; -+ } -+ if (num_zones != 0) { -+ use_bootargs = 1; -+ } -+ -+ return 0; -+} -+early_param("mmz", mmz_parse_cmdline); -+ -+phys_addr_t goke_get_zones_start(void) -+{ -+ int i; -+ phys_addr_t lowest_zone_base = memblock_end_of_DRAM(); -+ -+ for (i = 0; i < num_zones; i++) { -+ if (lowest_zone_base > zone[i].phys_start) { -+ lowest_zone_base = zone[i].phys_start; -+ } -+ } -+ -+ return lowest_zone_base; -+} -+EXPORT_SYMBOL(goke_get_zones_start); -+ -+struct cma_zone *goke_get_cma_zone(const char *name) -+{ -+ int i = 0; -+ -+ for (i = 0; i < num_zones; i++) -+ if (strcmp(zone[i].name, name) == 0) { -+ break; -+ } -+ -+ if (i == num_zones) { -+ return NULL; -+ } -+ -+ return &zone[i]; -+} -+EXPORT_SYMBOL(goke_get_cma_zone); -+ -+struct device *goke_get_cma_device(const char *name) -+{ -+ int i = 0; -+ -+ for (i = 0; i < num_zones; i++) -+ if (strcmp(zone[i].name, name) == 0) { -+ break; -+ } -+ -+ if (i == num_zones) { -+ return NULL; -+ } -+ -+ return &zone[i].pdev; -+} -+EXPORT_SYMBOL(goke_get_cma_device); -+ -+int __init goke_declare_heap_memory(void) -+{ -+ int i; -+ int ret = 0; -+ -+ if (use_bootargs == 0) { -+ pr_info("cma zone is not set!\n"); -+ return ret; -+ } -+ -+ for (i = 0; i < num_zones; i++) { -+ ret = dma_declare_contiguous(&zone[i].pdev, -+ zone[i].nbytes, zone[i].phys_start, 0); -+ if (ret) { -+ panic("declare cma zone %s base: %lux size:%lux MB failed. ret:%d", -+ zone[i].name, (unsigned long)zone[i].phys_start, -+ (unsigned long)zone[i].nbytes >> 20, ret); -+ } -+ zone[i].phys_start = cma_get_base(zone[i].pdev.cma_area); -+ zone[i].nbytes = cma_get_size(zone[i].pdev.cma_area); -+ -+ /* FIXME need to fix dma_declare_contiguous return value &&value type */ -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(goke_declare_heap_memory); -+ -+static int mmz_setup(struct reserved_mem *rmem) -+{ -+ return 0; -+} -+RESERVEDMEM_OF_DECLARE(cma, "mmz", mmz_setup); ---- linux-4.9.37/drivers/goke/cma/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/goke/cma/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,16 @@ -+ -+config CMA_MEM_SHARED -+ bool "Support sharing CMA memory with the heap" -+ depends on CMA && DMA_CMA -+ default no -+ help -+ Support sharing CMA memory with the heap. -+ -+config CMA_ADVANCE_SHARE -+ bool "Support cma advance share" -+ depends on CMA && DMA_CMA -+ select CMA_MEM_SHARED -+ default no -+ help -+ Support advance sharing CMA memory with the heap. -+ CMA Multiplex Ratio will be improved when this macro defined. ---- linux-4.9.37/drivers/goke/cma/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/goke/cma/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,2 @@ -+ -+obj-$(CONFIG_CMA) += cma.o ---- linux-4.9.37/drivers/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/goke/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,4 @@ -+menu "goke driver support" -+ -+source "drivers/goke/cma/Kconfig" -+endmenu ---- linux-4.9.37/drivers/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/goke/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1 @@ -+obj-$(CONFIG_CMA) += cma/ ---- linux-4.9.37/drivers/gpio/gpio-pl061.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/gpio/gpio-pl061.c 2021-06-07 13:01:33.000000000 +0300 -@@ -208,6 +208,25 @@ - return 0; - } - -+#ifdef CONFIG_ARCH_GOKE -+static irqreturn_t pl061_irq_handler(int irq, void *data) -+{ -+ unsigned long pending; -+ int offset; -+ struct gpio_chip *gc = data; -+ struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); -+ -+ pending = readb(chip->base + GPIOMIS); -+ writeb(pending, chip->base + GPIOIC); -+ if (pending) { -+ for_each_set_bit(offset, &pending, PL061_GPIO_NR) -+ generic_handle_irq(irq_find_mapping(gc->irqdomain, -+ offset)); -+ } -+ -+ return IRQ_HANDLED; -+} -+#else - static void pl061_irq_handler(struct irq_desc *desc) - { - unsigned long pending; -@@ -227,6 +246,7 @@ - - chained_irq_exit(irqchip, desc); - } -+#endif - - static void pl061_irq_mask(struct irq_data *d) - { -@@ -308,7 +328,17 @@ - return -ENODEV; - } - } else { -+#ifdef CONFIG_ARCH_GOKE -+ if (dev->of_node) { -+ i = of_alias_get_id(dev->of_node, "gpio"); -+ chip->gc.base = i * PL061_GPIO_NR; -+ } -+ -+ if (chip->gc.base < 0) -+ chip->gc.base = -1; -+#else - chip->gc.base = -1; -+#endif - irq_base = 0; - } - -@@ -353,8 +383,21 @@ - dev_info(&adev->dev, "could not add irqchip\n"); - return ret; - } -+#ifdef CONFIG_ARCH_GOKE -+ ret = devm_request_irq(dev, irq, pl061_irq_handler, IRQF_SHARED, -+ dev_name(dev), &chip->gc); -+ if (ret) { -+ dev_info(dev, "request irq failed: %d\n", ret); -+ return ret; -+ } -+ -+ /* Set the parent IRQ for all affected IRQs */ -+ for (i = 0; i < chip->gc.ngpio; i++) -+ irq_set_parent(irq_find_mapping(chip->gc.irqdomain, i), irq); -+#else - gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip, - irq, pl061_irq_handler); -+#endif - - for (i = 0; i < PL061_GPIO_NR; i++) { - if (pdata) { ---- linux-4.9.37/drivers/i2c/busses/i2c-goke.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/i2c/busses/i2c-goke.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,967 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * I2C Registers offsets -+ */ -+#define GOKE_I2C_GLB 0x0 -+#define GOKE_I2C_SCL_H 0x4 -+#define GOKE_I2C_SCL_L 0x8 -+#define GOKE_I2C_DATA1 0x10 -+#define GOKE_I2C_TXF 0x20 -+#define GOKE_I2C_RXF 0x24 -+#define GOKE_I2C_CMD_BASE 0x30 -+#define GOKE_I2C_LOOP1 0xb0 -+#define GOKE_I2C_DST1 0xb4 -+#define GOKE_I2C_TX_WATER 0xc8 -+#define GOKE_I2C_RX_WATER 0xcc -+#define GOKE_I2C_CTRL1 0xd0 -+#define GOKE_I2C_CTRL2 0xd4 -+#define GOKE_I2C_STAT 0xd8 -+#define GOKE_I2C_INTR_RAW 0xe0 -+#define GOKE_I2C_INTR_EN 0xe4 -+#define GOKE_I2C_INTR_STAT 0xe8 -+ -+/* -+ * I2C Global Config Register -- GOKE_I2C_GLB -+ */ -+#define GLB_EN_MASK BIT(0) -+#define GLB_SDA_HOLD_MASK GENMASK(23, 8) -+#define GLB_SDA_HOLD_SHIFT (8) -+ -+/* -+ * I2C Timing CMD Register -- GOKE_I2C_CMD_BASE + n * 4 (n = 0, 1, 2, ... 31) -+ */ -+#define CMD_EXIT 0x0 -+#define CMD_TX_S 0x1 -+#define CMD_TX_D1_2 0x4 -+#define CMD_TX_D1_1 0x5 -+#define CMD_TX_FIFO 0x9 -+#define CMD_RX_FIFO 0x12 -+#define CMD_RX_ACK 0x13 -+#define CMD_IGN_ACK 0x15 -+#define CMD_TX_ACK 0x16 -+#define CMD_TX_NACK 0x17 -+#define CMD_JMP1 0x18 -+#define CMD_UP_TXF 0x1d -+#define CMD_TX_RS 0x1e -+#define CMD_TX_P 0x1f -+ -+/* -+ * I2C Control Register 1 -- GOKE_I2C_CTRL1 -+ */ -+#define CTRL1_CMD_START_MASK BIT(0) -+#define CTRL1_DMA_OP_MASK (0x3 << 8) -+#define CTRL1_DMA_R (0x3 << 8) -+#define CTRL1_DMA_W (0x2 << 8) -+ -+/* -+ * I2C Status Register -- GOKE_I2C_STAT -+ */ -+#define STAT_RXF_NOE_MASK BIT(16) /* RX FIFO not empty flag */ -+#define STAT_TXF_NOF_MASK BIT(19) /* TX FIFO not full flag */ -+ -+ -+/* -+ * I2C Interrupt status and mask Register -- -+ * GOKE_I2C_INTR_RAW, GOKE_I2C_STAT, GOKE_I2C_INTR_STAT -+ */ -+#define INTR_ABORT_MASK (BIT(0) | BIT(11)) -+#define INTR_RX_MASK BIT(2) -+#define INTR_TX_MASK BIT(4) -+#define INTR_CMD_DONE_MASK BIT(12) -+#define INTR_USE_MASK (INTR_ABORT_MASK \ -+ |INTR_RX_MASK \ -+ | INTR_TX_MASK \ -+ | INTR_CMD_DONE_MASK) -+#define INTR_ALL_MASK GENMASK(31, 0) -+ -+#define I2C_DEFAULT_FREQUENCY 100000 -+#define I2C_TXF_DEPTH 64 -+#define I2C_RXF_DEPTH 64 -+#define I2C_TXF_WATER 32 -+#define I2C_RXF_WATER 32 -+#define I2C_WAIT_TIMEOUT 0x400 -+#define I2C_IRQ_TIMEOUT (msecs_to_jiffies(1000)) -+ -+ -+struct goke_i2c_dev { -+ struct device *dev; -+ struct i2c_adapter adap; -+ resource_size_t phybase; -+ void __iomem *base; -+ struct clk *clk; -+ int irq; -+ -+ unsigned int freq; -+ struct i2c_msg *msg; -+ unsigned int msg_num; -+ unsigned int msg_idx; -+ unsigned int msg_buf_ptr; -+ struct completion msg_complete; -+ -+ spinlock_t lock; -+ int status; -+}; -+static inline void goke_i2c_disable(struct goke_i2c_dev *i2c); -+static inline void goke_i2c_cfg_irq(struct goke_i2c_dev *i2c, -+ unsigned int flag); -+static inline unsigned int goke_i2c_clr_irq(struct goke_i2c_dev *i2c); -+static inline void goke_i2c_enable(struct goke_i2c_dev *i2c); -+ -+#define CHECK_SDA_IN_SHIFT (16) -+#define GPIO_MODE_SHIFT (8) -+#define FORCE_SCL_OEN_SHIFT (4) -+#define FORCE_SDA_OEN_SHIFT (0) -+ -+static void goke_i2c_rescue(struct goke_i2c_dev *i2c) -+{ -+ unsigned int val; -+ unsigned int time_cnt; -+ int index; -+ -+ goke_i2c_disable(i2c); -+ goke_i2c_cfg_irq(i2c, 0); -+ goke_i2c_clr_irq(i2c); -+ -+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); -+ writel(val, i2c->base + GOKE_I2C_CTRL2); -+ -+ time_cnt = 0; -+ do { -+ for (index = 0; index < 9; index++) { -+ val = (0x1 << GPIO_MODE_SHIFT) | 0x1; -+ writel(val, i2c->base + GOKE_I2C_CTRL2); -+ -+ udelay(5); -+ -+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); -+ writel(val, i2c->base + GOKE_I2C_CTRL2); -+ -+ udelay(5); -+ } -+ -+ time_cnt++; -+ if (time_cnt > I2C_WAIT_TIMEOUT) { -+ dev_err(i2c->dev, "wait Timeout!\n"); -+ goto disable_rescue; -+ } -+ -+ val = readl(i2c->base + GOKE_I2C_CTRL2); -+ } while(!(val & (0x1 << CHECK_SDA_IN_SHIFT))); -+ -+ -+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); -+ writel(val, i2c->base + GOKE_I2C_CTRL2); -+ -+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT); -+ writel(val, i2c->base + GOKE_I2C_CTRL2); -+ -+ udelay(10); -+ -+ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | (0x1 << FORCE_SDA_OEN_SHIFT); -+ writel(val, i2c->base + GOKE_I2C_CTRL2); -+ -+disable_rescue: -+ val = (0x1 << FORCE_SCL_OEN_SHIFT) | 0x1; -+ writel(val, i2c->base + GOKE_I2C_CTRL2); -+} -+ -+static inline void goke_i2c_disable(struct goke_i2c_dev *i2c) -+{ -+ unsigned int val; -+ -+ val = readl(i2c->base + GOKE_I2C_GLB); -+ val &= ~GLB_EN_MASK; -+ writel(val, i2c->base + GOKE_I2C_GLB); -+} -+ -+static inline void goke_i2c_enable(struct goke_i2c_dev *i2c) -+{ -+ unsigned int val; -+ -+ val = readl(i2c->base + GOKE_I2C_GLB); -+ val |= GLB_EN_MASK; -+ writel(val, i2c->base + GOKE_I2C_GLB); -+} -+ -+static inline void goke_i2c_cfg_irq(struct goke_i2c_dev *i2c, -+ unsigned int flag) -+{ -+ writel(flag, i2c->base + GOKE_I2C_INTR_EN); -+} -+ -+static inline void goke_i2c_disable_irq(struct goke_i2c_dev *i2c, -+ unsigned int flag) -+{ -+ unsigned int val; -+ -+ val = readl(i2c->base + GOKE_I2C_INTR_EN); -+ val &= ~flag; -+ writel(val, i2c->base + GOKE_I2C_INTR_EN); -+} -+ -+static inline unsigned int goke_i2c_clr_irq(struct goke_i2c_dev *i2c) -+{ -+ unsigned int val; -+ -+ val = readl(i2c->base + GOKE_I2C_INTR_STAT); -+ writel(INTR_ALL_MASK, i2c->base + GOKE_I2C_INTR_RAW); -+ -+ return val; -+} -+ -+static inline void goke_i2c_cmdreg_set(struct goke_i2c_dev *i2c, -+ unsigned int cmd, unsigned int *offset) -+{ -+ dev_dbg(i2c->dev, "i2c reg: offset=0x%x, cmd=0x%x...\n", -+ *offset * 4, cmd); -+ writel(cmd, i2c->base + GOKE_I2C_CMD_BASE + *offset * 4); -+ (*offset)++; -+} -+ -+/* -+ * config i2c slave addr -+ */ -+static inline void goke_i2c_set_addr(struct goke_i2c_dev *i2c) -+{ -+ struct i2c_msg *msg = i2c->msg; -+ u16 addr; -+ -+ if (msg->flags & I2C_M_TEN) { -+ /* First byte is 11110XX0 where XX is upper 2 bits */ -+ addr = ((msg->addr & 0x300) << 1) | 0xf000; -+ if (msg->flags & I2C_M_RD) { -+ addr |= 1 << 8; -+ } -+ -+ /* Second byte is the remaining 8 bits */ -+ addr |= msg->addr & 0xff; -+ } else { -+ addr = (msg->addr & 0x7f) << 1; -+ if (msg->flags & I2C_M_RD) { -+ addr |= 1; -+ } -+ } -+ -+ writel(addr, i2c->base + GOKE_I2C_DATA1); -+} -+ -+/* -+ * Start command sequence -+ */ -+static inline void goke_i2c_start_cmd(struct goke_i2c_dev *i2c) -+{ -+ unsigned int val; -+ -+ val = readl(i2c->base + GOKE_I2C_CTRL1); -+ val |= CTRL1_CMD_START_MASK; -+ writel(val, i2c->base + GOKE_I2C_CTRL1); -+} -+ -+static int goke_i2c_wait_rx_noempty(struct goke_i2c_dev *i2c) -+{ -+ unsigned int time_cnt = 0; -+ unsigned int val; -+ -+ do { -+ val = readl(i2c->base + GOKE_I2C_STAT); -+ if (val & STAT_RXF_NOE_MASK) { -+ return 0; -+ } -+ -+ udelay(50); -+ } while (time_cnt++ < I2C_WAIT_TIMEOUT); -+ -+ goke_i2c_rescue(i2c); -+ -+ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", -+ readl(i2c->base + GOKE_I2C_INTR_RAW), val); -+ return -EIO; -+} -+ -+static int goke_i2c_wait_tx_nofull(struct goke_i2c_dev *i2c) -+{ -+ unsigned int time_cnt = 0; -+ unsigned int val; -+ -+ do { -+ val = readl(i2c->base + GOKE_I2C_STAT); -+ if (val & STAT_TXF_NOF_MASK) { -+ return 0; -+ } -+ -+ udelay(50); -+ } while (time_cnt++ < I2C_WAIT_TIMEOUT); -+ -+ goke_i2c_rescue(i2c); -+ -+ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", -+ readl(i2c->base + GOKE_I2C_INTR_RAW), val); -+ return -EIO; -+} -+ -+static int goke_i2c_wait_idle(struct goke_i2c_dev *i2c) -+{ -+ unsigned int time_cnt = 0; -+ unsigned int val; -+ -+ do { -+ val = readl(i2c->base + GOKE_I2C_INTR_RAW); -+ if (val & (INTR_ABORT_MASK)) { -+ dev_err(i2c->dev, "wait idle abort!, RIS: 0x%x\n", -+ val); -+ return -EIO; -+ } -+ -+ if (val & INTR_CMD_DONE_MASK) { -+ return 0; -+ } -+ -+ udelay(50); -+ } while (time_cnt++ < I2C_WAIT_TIMEOUT); -+ -+ goke_i2c_rescue(i2c); -+ -+ dev_err(i2c->dev, "wait idle timeout, RIS: 0x%x, SR: 0x%x\n", -+ val, readl(i2c->base + GOKE_I2C_STAT)); -+ -+ return -EIO; -+} -+ -+static void goke_i2c_set_freq(struct goke_i2c_dev *i2c) -+{ -+ unsigned int max_freq, freq; -+ unsigned int clk_rate; -+ unsigned int val; -+ -+ freq = i2c->freq; -+ clk_rate = clk_get_rate(i2c->clk); -+ max_freq = clk_rate >> 1; -+ -+ if (freq > max_freq) { -+ i2c->freq = max_freq; -+ freq = i2c->freq; -+ } -+ -+ if (!freq) { -+ pr_err("goke_i2c_set_freq:freq can't be zero!"); -+ return; -+ } -+ -+ if (freq <= 100000) { -+ /* in normal mode F_scl: freq -+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.5 -+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.5 -+ */ -+ val = clk_rate / (freq * 2); -+ writel(val, i2c->base + GOKE_I2C_SCL_H); -+ writel(val, i2c->base + GOKE_I2C_SCL_L); -+ } else { -+ /* in fast mode F_scl: freq -+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.36 -+ i2c_scl_hcnt = (F_i2c / F_scl) * 0.64 -+ */ -+ val = ((clk_rate / 100) * 36) / freq; -+ writel(val, i2c->base + GOKE_I2C_SCL_H); -+ val = ((clk_rate / 100) * 64) / freq; -+ writel(val, i2c->base + GOKE_I2C_SCL_L); -+ } -+ -+ val = readl(i2c->base + GOKE_I2C_GLB); -+ val &= ~GLB_SDA_HOLD_MASK; -+ val |= ((0xa << GLB_SDA_HOLD_SHIFT) & GLB_SDA_HOLD_MASK); -+ writel(val, i2c->base + GOKE_I2C_GLB); -+} -+ -+/* -+ * set i2c controller TX and RX FIFO water -+ */ -+static inline void goke_i2c_set_water(struct goke_i2c_dev *i2c) -+{ -+ writel(I2C_TXF_WATER, i2c->base + GOKE_I2C_TX_WATER); -+ writel(I2C_RXF_WATER, i2c->base + GOKE_I2C_RX_WATER); -+} -+ -+/* -+ * initialise the controller, set i2c bus interface freq -+ */ -+static void goke_i2c_hw_init(struct goke_i2c_dev *i2c) -+{ -+ goke_i2c_disable(i2c); -+ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); -+ goke_i2c_set_freq(i2c); -+ goke_i2c_set_water(i2c); -+} -+ -+/* -+ * goke_i2c_cfg_cmd - config i2c controller command sequence -+ * -+ * After all the timing command is configured, -+ * and then start the command, you can i2c communication, -+ * and then only need to read and write i2c fifo. -+ */ -+static void goke_i2c_cfg_cmd(struct goke_i2c_dev *i2c) -+{ -+ struct i2c_msg *msg = i2c->msg; -+ int offset = 0; -+ -+ if (i2c->msg_idx == 0) { -+ goke_i2c_cmdreg_set(i2c, CMD_TX_S, &offset); -+ } else { -+ goke_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset); -+ } -+ -+ if (msg->flags & I2C_M_TEN) { -+ if (i2c->msg_idx == 0) { -+ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); -+ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); -+ } else { -+ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); -+ } -+ } else { -+ goke_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); -+ } -+ -+ if (msg->flags & I2C_M_IGNORE_NAK) { -+ goke_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); -+ } else { -+ goke_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); -+ } -+ -+ if (msg->flags & I2C_M_RD) { -+ if (msg->len >= 2) { -+ writel(offset, i2c->base + GOKE_I2C_DST1); -+ writel(msg->len - 2, i2c->base + GOKE_I2C_LOOP1); -+ goke_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); -+ goke_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset); -+ goke_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); -+ } -+ goke_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); -+ goke_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset); -+ } else { -+ writel(offset, i2c->base + GOKE_I2C_DST1); -+ writel(msg->len - 1, i2c->base + GOKE_I2C_LOOP1); -+ goke_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); -+ goke_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); -+ -+ if (msg->flags & I2C_M_IGNORE_NAK) { -+ goke_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); -+ } else { -+ goke_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); -+ } -+ -+ goke_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); -+ } -+ -+ if ((i2c->msg_idx == (i2c->msg_num - 1)) || (msg->flags & I2C_M_STOP)) { -+ dev_dbg(i2c->dev, "run to %s %d...TX STOP\n", -+ __func__, __LINE__); -+ goke_i2c_cmdreg_set(i2c, CMD_TX_P, &offset); -+ } -+ -+ goke_i2c_cmdreg_set(i2c, CMD_EXIT, &offset); -+} -+ -+static int goke_i2c_polling_xfer_one_msg(struct goke_i2c_dev *i2c) -+{ -+ int status; -+ unsigned int val; -+ struct i2c_msg *msg = i2c->msg; -+ -+ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", -+ __func__, __LINE__, msg->flags, msg->len); -+ -+ goke_i2c_enable(i2c); -+ goke_i2c_clr_irq(i2c); -+ goke_i2c_set_addr(i2c); -+ goke_i2c_cfg_cmd(i2c); -+ goke_i2c_start_cmd(i2c); -+ -+ i2c->msg_buf_ptr = 0; -+ -+ if (msg->flags & I2C_M_RD) { -+ while (i2c->msg_buf_ptr < msg->len) { -+ status = goke_i2c_wait_rx_noempty(i2c); -+ if (status) { -+ goto end; -+ } -+ -+ val = readl(i2c->base + GOKE_I2C_RXF); -+ msg->buf[i2c->msg_buf_ptr] = val; -+ i2c->msg_buf_ptr++; -+ -+ } -+ } else { -+ while (i2c->msg_buf_ptr < msg->len) { -+ status = goke_i2c_wait_tx_nofull(i2c); -+ if (status) { -+ goto end; -+ } -+ -+ val = msg->buf[i2c->msg_buf_ptr]; -+ writel(val, i2c->base + GOKE_I2C_TXF); -+ i2c->msg_buf_ptr++; -+ } -+ } -+ -+ status = goke_i2c_wait_idle(i2c); -+end: -+ goke_i2c_disable(i2c); -+ -+ return status; -+} -+ -+static irqreturn_t goke_i2c_isr(int irq, void *dev_id) -+{ -+ struct goke_i2c_dev *i2c = dev_id; -+ unsigned int irq_status; -+ struct i2c_msg *msg = i2c->msg; -+ -+ spin_lock(&i2c->lock); -+ -+ irq_status = goke_i2c_clr_irq(i2c); -+ dev_dbg(i2c->dev, "%s RIS: 0x%x\n", __func__, irq_status); -+ -+ if (!irq_status) { -+ dev_dbg(i2c->dev, "no irq\n"); -+ goto end; -+ } -+ -+ if (irq_status & INTR_ABORT_MASK) { -+ dev_err(i2c->dev, "irq handle abort, RIS: 0x%x\n", -+ irq_status); -+ i2c->status = -EIO; -+ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); -+ -+ complete(&i2c->msg_complete); -+ goto end; -+ } -+ -+ if (msg->flags & I2C_M_RD) { -+ while ((readl(i2c->base + GOKE_I2C_STAT) & STAT_RXF_NOE_MASK) -+ && (i2c->msg_buf_ptr < msg->len)) { -+ msg->buf[i2c->msg_buf_ptr] = -+ readl(i2c->base + GOKE_I2C_RXF); -+ i2c->msg_buf_ptr++; -+ } -+ } else { -+ while ((readl(i2c->base + GOKE_I2C_STAT) & STAT_TXF_NOF_MASK) -+ && (i2c->msg_buf_ptr < msg->len)) { -+ writel(msg->buf[i2c->msg_buf_ptr], -+ i2c->base + GOKE_I2C_TXF); -+ i2c->msg_buf_ptr++; -+ } -+ } -+ -+ if (i2c->msg_buf_ptr >= msg->len) { -+ goke_i2c_disable_irq(i2c, INTR_TX_MASK | INTR_RX_MASK); -+ } -+ -+ if (irq_status & INTR_CMD_DONE_MASK) { -+ dev_dbg(i2c->dev, "cmd done\n"); -+ i2c->status = 0; -+ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); -+ -+ complete(&i2c->msg_complete); -+ } -+ -+end: -+ spin_unlock(&i2c->lock); -+ -+ return IRQ_HANDLED; -+} -+ -+static int goke_i2c_interrupt_xfer_one_msg(struct goke_i2c_dev *i2c) -+{ -+ int status; -+ struct i2c_msg *msg = i2c->msg; -+ unsigned long timeout; -+ unsigned long flags; -+ -+ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", -+ __func__, __LINE__, msg->flags, msg->len); -+ -+ reinit_completion(&i2c->msg_complete); -+ i2c->msg_buf_ptr = 0; -+ i2c->status = -EIO; -+ -+ spin_lock_irqsave(&i2c->lock, flags); -+ goke_i2c_enable(i2c); -+ goke_i2c_clr_irq(i2c); -+ if (msg->flags & I2C_M_RD) { -+ goke_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_TX_MASK); -+ } else { -+ goke_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_RX_MASK); -+ } -+ -+ goke_i2c_set_addr(i2c); -+ goke_i2c_cfg_cmd(i2c); -+ goke_i2c_start_cmd(i2c); -+ spin_unlock_irqrestore(&i2c->lock, flags); -+ -+ timeout = wait_for_completion_timeout(&i2c->msg_complete, -+ I2C_IRQ_TIMEOUT); -+ -+ spin_lock_irqsave(&i2c->lock, flags); -+ if (timeout == 0) { -+ goke_i2c_disable_irq(i2c, INTR_ALL_MASK); -+ status = -EIO; -+ dev_err(i2c->dev, "%s timeout\n", -+ msg->flags & I2C_M_RD ? "rx" : "tx"); -+ } else { -+ status = i2c->status; -+ } -+ -+ goke_i2c_disable(i2c); -+ -+ spin_unlock_irqrestore(&i2c->lock, flags); -+ return status; -+} -+ -+/* -+ * Master transfer function -+ */ -+static int goke_i2c_xfer(struct i2c_adapter *adap, -+ struct i2c_msg *msgs, int num) -+{ -+ struct goke_i2c_dev *i2c = i2c_get_adapdata(adap); -+ int status = -EINVAL; -+ unsigned long flags; -+ -+ if (!msgs || (num <= 0)) { -+ dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n"); -+ return -EINVAL; -+ } -+ -+ spin_lock_irqsave(&i2c->lock, flags); -+ -+ i2c->msg = msgs; -+ i2c->msg_num = num; -+ i2c->msg_idx = 0; -+ -+ /* FIXME: The wait_for_completion_timeout in goke_i2c_interrupt_xfer_one_msg -+ * function can not be locked by spin_lock_irqsave. And actually I2C interrupt -+ * tranfer is rarely used, so we ignore the irq setting to limit the interrupt -+ * way. But we keep these codes below, reserve for future modifications */ -+ -+ while (i2c->msg_idx < i2c->msg_num) { -+ if (i2c->irq >= 0) { -+ spin_unlock_irqrestore(&i2c->lock, flags); -+ status = goke_i2c_interrupt_xfer_one_msg(i2c); -+ spin_lock_irqsave(&i2c->lock, flags); -+ if (status) { -+ break; -+ } -+ } else { -+ status = goke_i2c_polling_xfer_one_msg(i2c); -+ if (status) { -+ break; -+ } -+ } -+ i2c->msg++; -+ i2c->msg_idx++; -+ } -+ -+ if (!status || i2c->msg_idx > 0) { -+ status = i2c->msg_idx; -+ } -+ -+ spin_unlock_irqrestore(&i2c->lock, flags); -+ return status; -+} -+ -+/* goke_i2c_break_polling_xfer -+ * -+ * I2c polling independent branch, Shielding interrupt interface -+ */ -+static int goke_i2c_break_polling_xfer(struct i2c_adapter *adap, -+ struct i2c_msg *msgs, int num) -+{ -+ struct goke_i2c_dev *i2c = i2c_get_adapdata(adap); -+ int status = -EINVAL; -+ unsigned long flags; -+ if (!msgs || (num <= 0)) { -+ dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n"); -+ return -EINVAL; -+ } -+ spin_lock_irqsave(&i2c->lock, flags); -+ i2c->msg = msgs; -+ i2c->msg_num = num; -+ i2c->msg_idx = 0; -+ while (i2c->msg_idx < i2c->msg_num) { -+ status = goke_i2c_polling_xfer_one_msg(i2c); -+ if (status) { -+ break; -+ } -+ i2c->msg++; -+ i2c->msg_idx++; -+ } -+ if (!status || i2c->msg_idx > 0) { -+ status = i2c->msg_idx; -+ } -+ spin_unlock_irqrestore(&i2c->lock, flags); -+ return status; -+} -+/* -+ * bsp_i2c_master_recv - issue a single I2C message in master receive mode -+ * @client: Handle to slave device -+ * @buf: Where to store data read from slave -+ * @count: How many bytes to read, must be less than 64k since msg.len is u16 -+ * -+ * Returns negative errno, or else the number of bytes read. -+ */ -+int gk_i2c_master_recv(const struct i2c_client *client, char *buf, -+ int count) -+{ -+ printk("Wrong interface call." -+ "bsp_i2c_transfer is the only interface to i2c read!!!\n"); -+ -+ return -EIO; -+} -+EXPORT_SYMBOL(gk_i2c_master_recv); -+ -+/*I2C WRITE* -+ * bsp_i2c_master_send - issue a single I2C message in master transmit mode -+ * @client: Handle to slave device -+ * @buf: Data that will be written to the slave -+ * @count: How many bytes to write, must be less than 64k since msg.len is u16 -+ * -+ * Returns negative errno, or else the number of bytes written. -+ */ -+int gk_i2c_master_send(const struct i2c_client *client, -+ const char *buf, int count) -+{ -+ struct i2c_adapter *adap = client->adapter; -+ struct i2c_msg msg; -+ int msgs_count; -+ -+ if ((client->addr > 0x3ff) -+ || (((client->flags & I2C_M_TEN) == 0) && (client->addr > 0x7f))) { -+ printk(KERN_ERR "dev address out of range\n"); -+ return -EINVAL; -+ } -+ -+ msg.addr = client->addr; -+ msg.flags = client->flags; -+ msg.len = count; -+ -+ if ((!buf)||(count < 0)) { -+ printk(KERN_ERR "buf == NULL || count < 0, Invalid argument!\n"); -+ return -EINVAL; -+ } -+ msg.buf = (__u8 *)buf; -+ -+ msgs_count = goke_i2c_break_polling_xfer(adap, &msg, 1); -+ -+ return (msgs_count == 1) ? count : -EIO; -+} -+EXPORT_SYMBOL(gk_i2c_master_send); -+ -+/** -+ * bsp_i2c_transfer - execute a single or combined I2C message -+ * @adap: Handle to I2C bus -+ * @msgs: One or more messages to execute before STOP is issued to -+ * terminate the operation; each message begins with a START. -+ * @num: Number of messages to be executed. -+ * -+ * Returns negative errno, else the number of messages executed. -+ * -+ * Note that there is no requirement that each message be sent to -+ * the same slave address, although that is the most common model. -+ */ -+int gk_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, -+ int num) -+{ -+ int msgs_count; -+ -+ if((!adap)||(!msgs)) { -+ printk(KERN_ERR "adap == NULL || msgs == NULL, Invalid argument!\n"); -+ return -EINVAL; -+ } -+ -+ if ((msgs[0].addr > 0x3ff) -+ || (((msgs[0].flags & I2C_M_TEN) == 0) && (msgs[0].addr > 0x7f))) { -+ printk(KERN_ERR "msgs[0] dev address out of range\n"); -+ return -EINVAL; -+ } -+ -+ if ((msgs[1].addr > 0x3ff) -+ || (((msgs[1].flags & I2C_M_TEN) == 0) && (msgs[1].addr > 0x7f))) { -+ printk(KERN_ERR "msgs[1] dev address out of range\n"); -+ return -EINVAL; -+ } -+ -+ msgs_count = goke_i2c_xfer(adap, msgs, num); -+ -+ return msgs_count; -+} -+EXPORT_SYMBOL(gk_i2c_transfer); -+ -+static u32 goke_i2c_func(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR -+ | I2C_FUNC_PROTOCOL_MANGLING -+ | I2C_FUNC_SMBUS_WORD_DATA -+ | I2C_FUNC_SMBUS_BYTE_DATA -+ | I2C_FUNC_SMBUS_BYTE -+ | I2C_FUNC_SMBUS_I2C_BLOCK; -+} -+ -+static const struct i2c_algorithm goke_i2c_algo = { -+ .master_xfer = goke_i2c_xfer, -+ .functionality = goke_i2c_func, -+}; -+ -+static int goke_i2c_probe(struct platform_device *pdev) -+{ -+ int status; -+ struct goke_i2c_dev *i2c = NULL; -+ struct i2c_adapter *adap = NULL; -+ struct resource *res = NULL; -+ -+ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); -+ if (!i2c) { -+ return -ENOMEM; -+ } -+ -+ platform_set_drvdata(pdev, i2c); -+ i2c->dev = &pdev->dev; -+ spin_lock_init(&i2c->lock); -+ init_completion(&i2c->msg_complete); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(i2c->dev, "Invalid mem resource./n"); -+ return -ENODEV; -+ } -+ -+ i2c->phybase = res->start; -+ i2c->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(i2c->base)) { -+ dev_err(i2c->dev, "cannot ioremap resource\n"); -+ return -ENOMEM; -+ } -+ -+ i2c->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(i2c->clk)) { -+ dev_err(i2c->dev, "cannot get clock\n"); -+ return -ENOENT; -+ } -+ clk_prepare_enable(i2c->clk); -+ -+ if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", -+ &i2c->freq)) { -+ dev_warn(i2c->dev, "setting default clock-frequency@%dHz\n", -+ I2C_DEFAULT_FREQUENCY); -+ i2c->freq = I2C_DEFAULT_FREQUENCY; -+ } -+ -+ /* i2c controller initialization, disable interrupt */ -+ goke_i2c_hw_init(i2c); -+ -+ i2c->irq = platform_get_irq(pdev, 0); -+ status = devm_request_irq(&pdev->dev, i2c->irq, goke_i2c_isr, -+ IRQF_SHARED, dev_name(&pdev->dev), i2c); -+ if (status) { -+ dev_dbg(i2c->dev, "falling back to polling mode"); -+ i2c->irq = -1; -+ } -+ -+ adap = &i2c->adap; -+ i2c_set_adapdata(adap, i2c); -+ adap->owner = THIS_MODULE; -+ strlcpy(adap->name, "goke-i2c", sizeof(adap->name)); -+ adap->dev.parent = &pdev->dev; -+ adap->dev.of_node = pdev->dev.of_node; -+ adap->algo = &goke_i2c_algo; -+ -+ /* Add the i2c adapter */ -+ status = i2c_add_adapter(adap); -+ if (status) { -+ dev_err(i2c->dev, "failed to add bus to i2c core\n"); -+ goto err_add_adapter; -+ } -+ -+ dev_info(i2c->dev, "%s%d@%dhz registered\n", -+ adap->name, adap->nr, i2c->freq); -+ -+ return 0; -+ -+err_add_adapter: -+ clk_disable_unprepare(i2c->clk); -+ return status; -+} -+ -+static int goke_i2c_remove(struct platform_device *pdev) -+{ -+ struct goke_i2c_dev *i2c = platform_get_drvdata(pdev); -+ if (i2c == NULL){ -+ printk("i2c remove err!!!\n"); -+ return 0; -+ } -+ clk_disable_unprepare(i2c->clk); -+ i2c_del_adapter(&i2c->adap); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_SLEEP -+static int goke_i2c_suspend(struct device *dev) -+{ -+ struct goke_i2c_dev *i2c = dev_get_drvdata(dev); -+ -+ i2c_lock_adapter(&i2c->adap); -+ clk_disable_unprepare(i2c->clk); -+ i2c_unlock_adapter(&i2c->adap); -+ -+ return 0; -+} -+ -+static int goke_i2c_resume(struct device *dev) -+{ -+ struct goke_i2c_dev *i2c = dev_get_drvdata(dev); -+ -+ i2c_lock_adapter(&i2c->adap); -+ clk_prepare_enable(i2c->clk); -+ goke_i2c_hw_init(i2c); -+ i2c_unlock_adapter(&i2c->adap); -+ -+ return 0; -+} -+#endif -+ -+static SIMPLE_DEV_PM_OPS(goke_i2c_dev_pm, goke_i2c_suspend, -+ goke_i2c_resume); -+ -+static const struct of_device_id goke_i2c_match[] = { -+ { .compatible = "goke,goke-i2c"}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, goke_i2c_match); -+ -+static struct platform_driver goke_i2c_driver = { -+ .driver = { -+ .name = "goke-i2c", -+ .of_match_table = goke_i2c_match, -+ .pm = &goke_i2c_dev_pm, -+ }, -+ .probe = goke_i2c_probe, -+ .remove = goke_i2c_remove, -+}; -+ -+module_platform_driver(goke_i2c_driver); -+ -+MODULE_AUTHOR("Goke"); -+MODULE_DESCRIPTION("GOKE I2C Bus driver"); -+MODULE_LICENSE("GPL v2"); ---- linux-4.9.37/drivers/i2c/busses/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/i2c/busses/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -555,6 +555,16 @@ - This is a very simple bitbanging I2C driver utilizing the - arch-neutral GPIO API to control the SCL and SDA lines. - -+config I2C_GOKE -+ tristate "Goke I2C Controller" -+ depends on ARCH_GOKE -+ help -+ Say Y here to include support for Goke I2C controller in the -+ Goke SoCs. -+ -+ This driver can also be built as a module. If so, the module -+ will be called i2c. -+ - config I2C_HIGHLANDER - tristate "Highlander FPGA SMBus interface" - depends on SH_HIGHLANDER -@@ -1214,4 +1224,20 @@ - This driver can also be built as a module. If so, the module will be - called as i2c-opal. - -+config DMA_MSG_MIN_LEN -+ int "Goke I2C support DMA minimum LEN" -+ depends on I2C_GOKE -+ range 1 4090 -+ default 5 -+ help -+ The i2c_msg minimum LEN of i2c support DMA,range from 1 to 4091 -+ -+config DMA_MSG_MAX_LEN -+ int "Goke I2C support DMA maximum LEN" -+ depends on I2C_GOKE -+ range DMA_MSG_MIN_LEN 4090 -+ default 4090 -+ help -+ The i2c_msg maximum LEN of i2c support DMA,range from i2c_msg minimum LEN to 4090, -+ because DMA for 0xFFC one-time largest data transfers; - endmenu ---- linux-4.9.37/drivers/i2c/busses/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/i2c/busses/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -51,6 +51,7 @@ - obj-$(CONFIG_I2C_EMEV2) += i2c-emev2.o - obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o - obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o -+obj-$(CONFIG_I2C_GOKE) += i2c-goke.o - obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o - obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o - obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o ---- linux-4.9.37/drivers/i2c/i2c-dev.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/i2c/i2c-dev.c 2021-06-07 13:01:33.000000000 +0300 -@@ -170,6 +170,9 @@ - if (count > 8192) - count = 8192; - -+ if (count == 0) -+ return -EINVAL; -+ - tmp = memdup_user(buf, count); - if (IS_ERR(tmp)) - return PTR_ERR(tmp); -@@ -273,6 +276,11 @@ - res = -EINVAL; - break; - } -+ -+ if (rdwr_pa[i].len == 0) { -+ res = -EINVAL; -+ break; -+ } - - data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf; - rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len); ---- linux-4.9.37/drivers/irqchip/irq-gic.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/irqchip/irq-gic.c 2021-06-07 13:01:33.000000000 +0300 -@@ -1069,7 +1069,9 @@ - { - irq_hw_number_t hwirq_base; - int gic_irqs, irq_base, ret; -- -+ struct device_node *np; -+ void * sysctrl_reg_base; -+ int gic_dist_init_flag; - if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) { - /* Frankein-GIC without banked registers... */ - unsigned int cpu; -@@ -1149,7 +1151,21 @@ - goto error; - } - -- gic_dist_init(gic); -+#define GIC_DIST_INIT_FLAG 0x47444946 -+#define GIC_DIST_INIT_FLAG_OFFSET 0x0130 -+ /* 0x47444946('G''D''I''F') is abbreviation of GIC_DIST_INIT_FLAG. */ -+ -+ np = of_find_compatible_node(NULL, NULL, "goke,sysctrl"); -+ sysctrl_reg_base = of_iomap(np, 0); -+ gic_dist_init_flag = readl(sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET); -+ -+ if(gic_dist_init_flag != GIC_DIST_INIT_FLAG) { -+ printk("Gic dist init...\n"); -+ gic_dist_init(gic); -+ writel_relaxed(GIC_DIST_INIT_FLAG, sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET); -+ } else -+ printk("Gic dist not init...\n"); -+ - ret = gic_cpu_init(gic); - if (ret) - goto error; ---- linux-4.9.37/drivers/irqchip/irq-gic-v3.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/irqchip/irq-gic-v3.c 2021-06-07 13:01:33.000000000 +0300 -@@ -120,11 +120,10 @@ - } - - #ifdef CONFIG_ARM64 --static DEFINE_STATIC_KEY_FALSE(is_cavium_thunderx); - - static u64 __maybe_unused gic_read_iar(void) - { -- if (static_branch_unlikely(&is_cavium_thunderx)) -+ if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_23154)) - return gic_read_iar_cavium_thunderx(); - else - return gic_read_iar_common(); -@@ -905,14 +904,6 @@ - .select = gic_irq_domain_select, - }; - --static void gicv3_enable_quirks(void) --{ --#ifdef CONFIG_ARM64 -- if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_23154)) -- static_branch_enable(&is_cavium_thunderx); --#endif --} -- - static int __init gic_init_bases(void __iomem *dist_base, - struct redist_region *rdist_regs, - u32 nr_redist_regions, -@@ -935,8 +926,6 @@ - gic_data.nr_redist_regions = nr_redist_regions; - gic_data.redist_stride = redist_stride; - -- gicv3_enable_quirks(); -- - /* - * Find out how many interrupts are supported. - * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) ---- linux-4.9.37/drivers/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -202,4 +202,6 @@ - - source "drivers/fpga/Kconfig" - -+source "drivers/goke/Kconfig" -+ - endmenu ---- linux-4.9.37/drivers/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -70,6 +70,7 @@ - obj-$(CONFIG_LIBNVDIMM) += nvdimm/ - obj-$(CONFIG_DEV_DAX) += dax/ - obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/ -+obj-$(CONFIG_SYNC_FILE) += fence/ - obj-$(CONFIG_NUBUS) += nubus/ - obj-y += macintosh/ - obj-$(CONFIG_IDE) += ide/ -@@ -174,3 +175,4 @@ - obj-$(CONFIG_ANDROID) += android/ - obj-$(CONFIG_NVMEM) += nvmem/ - obj-$(CONFIG_FPGA) += fpga/ -+obj-$(CONFIG_ARCH_GOKE) += goke/ ---- linux-4.9.37/drivers/media/usb/uvc/uvc_video.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/media/usb/uvc/uvc_video.c 2021-06-07 13:01:33.000000000 +0300 -@@ -1467,6 +1467,7 @@ - struct usb_host_endpoint *ep) - { - u16 psize; -+ u16 mult; - - switch (dev->speed) { - case USB_SPEED_SUPER: -@@ -1474,7 +1475,8 @@ - return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); - case USB_SPEED_HIGH: - psize = usb_endpoint_maxp(&ep->desc); -- return (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); -+ mult = usb_endpoint_maxp_mult(&ep->desc); -+ return (psize & 0x07ff) * mult; - case USB_SPEED_WIRELESS: - psize = usb_endpoint_maxp(&ep->desc); - return psize; ---- linux-4.9.37/drivers/media/v4l2-core/videobuf2-v4l2.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/media/v4l2-core/videobuf2-v4l2.c 2021-06-07 13:01:33.000000000 +0300 -@@ -146,7 +146,6 @@ - return; - - check_once = true; -- WARN_ON(1); - - pr_warn("use of bytesused == 0 is deprecated and will be removed in the future,\n"); - if (vb->vb2_queue->allow_zero_bytesused) ---- linux-4.9.37/drivers/mfd/goke_fmc.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mfd/goke_fmc.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,121 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+unsigned char fmc_cs_user[FMC_MAX_CHIP_NUM]; -+ -+DEFINE_MUTEX(fmc_switch_mutex); -+EXPORT_SYMBOL_GPL(fmc_switch_mutex); -+ -+/* ------------------------------------------------------------------------ */ -+static const struct mfd_cell bsp_fmc_devs[] = { -+ { -+ .name = "bsp_spi_nor", -+ .of_compatible = "goke,fmc-spi-nor", -+ }, -+ { -+ .name = "bsp_spi_nand", -+ .of_compatible = "goke,fmc-spi-nand", -+ }, -+}; -+ -+static int bsp_fmc_probe(struct platform_device *pdev) -+{ -+ struct bsp_fmc *fmc; -+ struct resource *res; -+ struct device *dev = &pdev->dev; -+ int ret; -+ -+ fmc = devm_kzalloc(dev, sizeof(*fmc), GFP_KERNEL); -+ if (!fmc) { -+ return -ENOMEM; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control"); -+ fmc->regbase = devm_ioremap_resource(dev, res); -+ if (IS_ERR(fmc->regbase)) { -+ return PTR_ERR(fmc->regbase); -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); -+ fmc->iobase = devm_ioremap_resource(dev, res); -+ if (IS_ERR(fmc->iobase)) { -+ return PTR_ERR(fmc->iobase); -+ } -+ -+ fmc->clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(fmc->clk)) { -+ return PTR_ERR(fmc->clk); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "max-dma-size", &fmc->dma_len)) { -+ dev_err(dev, "Please set the suitable max-dma-size value !!!\n"); -+ return -ENOMEM; -+ } -+ -+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); -+ if (ret) { -+ dev_warn(dev, "Unable to set dma mask\n"); -+ return ret; -+ } -+ -+ fmc->buffer = dmam_alloc_coherent(dev, fmc->dma_len, -+ &fmc->dma_buffer, GFP_KERNEL); -+ if (IS_ERR(fmc->buffer)) { -+ return PTR_ERR(fmc->buffer); -+ } -+ -+ mutex_init(&fmc->lock); -+ -+ platform_set_drvdata(pdev, fmc); -+ -+ ret = mfd_add_devices(dev, 0, bsp_fmc_devs, -+ ARRAY_SIZE(bsp_fmc_devs), NULL, 0, NULL); -+ if (ret) { -+ dev_err(dev, "add mfd devices failed: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int bsp_fmc_remove(struct platform_device *pdev) -+{ -+ struct bsp_fmc *fmc = platform_get_drvdata(pdev); -+ -+ dmam_free_coherent(&pdev->dev, fmc->dma_len, -+ fmc->buffer, fmc->dma_buffer); -+ mfd_remove_devices(&pdev->dev); -+ mutex_destroy(&fmc->lock); -+ -+ return 0; -+} -+ -+static const struct of_device_id bsp_fmc_of_match_tbl[] = { -+ { .compatible = "goke,fmc"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bsp_fmc_of_match_tbl); -+ -+static struct platform_driver bsp_fmc_driver = { -+ .driver = { -+ .name = "fmc", -+ .of_match_table = bsp_fmc_of_match_tbl, -+ }, -+ .probe = bsp_fmc_probe, -+ .remove = bsp_fmc_remove, -+}; -+module_platform_driver(bsp_fmc_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("Goke Flash Memory Controller Driver"); ---- linux-4.9.37/drivers/mfd/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mfd/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -358,6 +358,16 @@ - help - Select this option to enable Hisilicon hi655x series pmic driver. - -+config MFD_GOKE_FMC -+ tristate "Goke Flash Memory Controller" -+ depends on OF -+ depends on ARCH_GOKE -+ select MFD_CORE -+ select REGMAP_MMIO -+ help -+ Select this option to enable the Goke Flash Memory -+ Controller(FMC) driver. -+ - config HTC_PASIC3 - tristate "HTC PASIC3 LED/DS1WM chip support" - select MFD_CORE ---- linux-4.9.37/drivers/mfd/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mfd/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -180,6 +180,7 @@ - obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o - obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o - obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o -+obj-$(CONFIG_MFD_GOKE_FMC) += goke_fmc.o - obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o - obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o - obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o ---- linux-4.9.37/drivers/mmc/card/block.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/card/block.c 2021-06-07 13:01:33.000000000 +0300 -@@ -63,6 +63,8 @@ - #define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ - #define MMC_SANITIZE_REQ_TIMEOUT 240000 - #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) -+#define MMC_CMDQ_STOP_TIMEOUT_MS 100 -+#define MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD 6 /* microseconds */ - - #define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ - (rq_data_dir(req) == WRITE)) -@@ -103,6 +105,7 @@ - #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ - #define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ - #define MMC_BLK_PACKED_CMD (1 << 2) /* MMC packed command support */ -+#define MMC_BLK_CMD_QUEUE (1 << 3) /* MMC command queue support */ - - unsigned int usage; - unsigned int read_only; -@@ -519,21 +522,40 @@ - - mrq.cmd = &cmd; - -+ if (mmc_card_cmdq(card)) { -+ err = mmc_cmdq_halt_on_empty_queue(card->host); -+ if (err) { -+ pr_err("%s: halt failed while doing %s err (%d)\n", -+ mmc_hostname(card->host), -+ __func__, err); -+ return err; -+ } -+ } -+ -+ if (mmc_card_doing_bkops(card)) { -+ err = mmc_stop_bkops(card); -+ if (err) { -+ dev_err(mmc_dev(card->host), -+ "%s: stop_bkops failed %d\n", __func__, err); -+ goto cmd_rel_host; -+ } -+ } -+ - err = mmc_blk_part_switch(card, md); - if (err) -- return err; -+ goto cmd_rel_host; - - if (idata->ic.is_acmd) { - err = mmc_app_cmd(card->host, card); - if (err) -- return err; -+ goto cmd_rel_host; - } - - if (is_rpmb) { - err = mmc_set_blockcount(card, data.blocks, - idata->ic.write_flag & (1 << 31)); - if (err) -- return err; -+ goto cmd_rel_host; - } - - if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) && -@@ -544,7 +566,7 @@ - pr_err("%s: ioctl_do_sanitize() failed. err = %d", - __func__, err); - -- return err; -+ goto cmd_rel_host; - } - - mmc_wait_for_req(card->host, &mrq); -@@ -552,12 +574,14 @@ - if (cmd.error) { - dev_err(mmc_dev(card->host), "%s: cmd error %d\n", - __func__, cmd.error); -- return cmd.error; -+ err = cmd.error; -+ goto cmd_rel_host; - } - if (data.error) { - dev_err(mmc_dev(card->host), "%s: data error %d\n", - __func__, data.error); -- return data.error; -+ err = data.error; -+ goto cmd_rel_host; - } - - /* -@@ -581,6 +605,13 @@ - __func__, status, err); - } - -+cmd_rel_host: -+ if (mmc_card_cmdq(card)) { -+ if (mmc_cmdq_halt(card->host, false)) -+ pr_err("%s: %s: cmdq unhalt failed\n", -+ mmc_hostname(card->host), __func__); -+ } -+ - return err; - } - -@@ -746,13 +777,64 @@ - #endif - }; - -+static int mmc_blk_cmdq_switch(struct mmc_card *card, -+ struct mmc_blk_data *md, bool enable) -+{ -+ int ret = 0; -+ bool cmdq_mode = !!mmc_card_cmdq(card); -+ struct mmc_host *host = card->host; -+ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; -+ -+ if (!(card->host->caps2 & MMC_CAP2_CMD_QUEUE) || -+ !card->ext_csd.cmdq_support || -+ (enable && !(md->flags & MMC_BLK_CMD_QUEUE)) || -+ (cmdq_mode == enable)) -+ return 0; -+ -+ if (enable) { -+ ret = mmc_set_blocklen(card, MMC_CARD_CMDQ_BLK_SIZE); -+ if (ret) { -+ pr_err("%s: failed (%d) to set block-size to %d\n", -+ __func__, ret, MMC_CARD_CMDQ_BLK_SIZE); -+ goto out; -+ } -+ -+ } else { -+ if (!test_bit(CMDQ_STATE_HALT, &ctx->curr_state)) { -+ ret = mmc_cmdq_halt(host, true); -+ if (ret) { -+ pr_err("%s: halt: failed: %d\n", -+ mmc_hostname(host), ret); -+ goto out; -+ } -+ } -+ } -+ -+ ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -+ EXT_CSD_CMDQ, enable, -+ card->ext_csd.generic_cmd6_time); -+ if (ret) { -+ pr_err("%s: cmdq mode %sable failed %d\n", -+ md->disk->disk_name, enable ? "en" : "dis", ret); -+ goto out; -+ } -+ -+ if (enable) -+ mmc_card_set_cmdq(card); -+ else -+ mmc_card_clr_cmdq(card); -+out: -+ return ret; -+} -+ - static inline int mmc_blk_part_switch(struct mmc_card *card, - struct mmc_blk_data *md) - { - int ret; - struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); - -- if (main_md->part_curr == md->part_type) -+ if ((main_md->part_curr == md->part_type) && -+ (card->part_curr == md->part_type)) - return 0; - - if (mmc_card_mmc(card)) { -@@ -761,6 +843,13 @@ - if (md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) - mmc_retune_pause(card->host); - -+ if (md->part_type) { -+ /* disable CQ mode for non-user data partitions */ -+ ret = mmc_blk_cmdq_switch(card, md, false); -+ if (ret) -+ return ret; -+ } -+ - part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; - part_config |= md->part_type; - -@@ -774,6 +863,7 @@ - } - - card->ext_csd.part_config = part_config; -+ card->part_curr = md->part_type; - - if (main_md->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB) - mmc_retune_unpause(card->host); -@@ -2210,6 +2300,813 @@ - !(card->csd.cmdclass & CCC_BLOCK_WRITE); - } - -+/* prepare for non-data commands */ -+static struct mmc_cmdq_req *mmc_cmdq_prep_dcmd( -+ struct mmc_queue_req *mqrq, struct mmc_queue *mq) -+{ -+ struct request *req = mqrq->req; -+ struct mmc_cmdq_req *cmdq_req = &mqrq->cmdq_req; -+ -+ memset(&mqrq->cmdq_req, 0, sizeof(struct mmc_cmdq_req)); -+ -+ cmdq_req->mrq.data = NULL; -+ cmdq_req->cmd_flags = req->cmd_flags; -+ cmdq_req->mrq.req = mqrq->req; -+ req->special = mqrq; -+ cmdq_req->cmdq_req_flags |= DCMD; -+ cmdq_req->mrq.cmdq_req = cmdq_req; -+ -+ return &mqrq->cmdq_req; -+} -+ -+#define IS_RT_CLASS_REQ(x) \ -+ (IOPRIO_PRIO_CLASS(req_get_ioprio(x)) == IOPRIO_CLASS_RT) -+ -+static struct mmc_cmdq_req *mmc_blk_cmdq_rw_prep( -+ struct mmc_queue_req *mqrq, struct mmc_queue *mq) -+{ -+ struct mmc_card *card = mq->card; -+ struct request *req = mqrq->req; -+ struct mmc_blk_data *md = mq->data; -+ bool do_rel_wr = mmc_req_rel_wr(req) && (md->flags & MMC_BLK_REL_WR); -+ bool do_data_tag; -+ bool read_dir = (rq_data_dir(req) == READ); -+ bool prio = IS_RT_CLASS_REQ(req); -+ struct mmc_cmdq_req *cmdq_rq = &mqrq->cmdq_req; -+ -+ memset(&mqrq->cmdq_req, 0, sizeof(struct mmc_cmdq_req)); -+ -+ cmdq_rq->tag = req->tag; -+ if (read_dir) { -+ cmdq_rq->cmdq_req_flags |= DIR; -+ cmdq_rq->data.flags = MMC_DATA_READ; -+ } else { -+ cmdq_rq->data.flags = MMC_DATA_WRITE; -+ } -+ if (prio) -+ cmdq_rq->cmdq_req_flags |= PRIO; -+ -+ if (do_rel_wr) -+ cmdq_rq->cmdq_req_flags |= REL_WR; -+ -+ cmdq_rq->data.blocks = blk_rq_sectors(req); -+ cmdq_rq->blk_addr = blk_rq_pos(req); -+ cmdq_rq->data.blksz = MMC_CARD_CMDQ_BLK_SIZE; -+ -+ mmc_set_data_timeout(&cmdq_rq->data, card); -+ -+ do_data_tag = (card->ext_csd.data_tag_unit_size) && -+ (req->cmd_flags & REQ_META) && -+ (rq_data_dir(req) == WRITE) && -+ ((cmdq_rq->data.blocks * cmdq_rq->data.blksz) >= -+ card->ext_csd.data_tag_unit_size); -+ if (do_data_tag) -+ cmdq_rq->cmdq_req_flags |= DAT_TAG; -+ cmdq_rq->data.sg = mqrq->sg; -+ cmdq_rq->data.sg_len = mmc_queue_map_sg(mq, mqrq); -+ -+ /* -+ * Adjust the sg list so it is the same size as the -+ * request. -+ */ -+ if (cmdq_rq->data.blocks > card->host->max_blk_count) -+ cmdq_rq->data.blocks = card->host->max_blk_count; -+ -+ if (cmdq_rq->data.blocks != blk_rq_sectors(req)) { -+ int i, data_size = cmdq_rq->data.blocks << 9; -+ struct scatterlist *sg; -+ -+ for_each_sg(cmdq_rq->data.sg, sg, cmdq_rq->data.sg_len, i) { -+ data_size -= sg->length; -+ if (data_size <= 0) { -+ sg->length += data_size; -+ i++; -+ break; -+ } -+ } -+ cmdq_rq->data.sg_len = i; -+ } -+ -+ mqrq->cmdq_req.cmd_flags = req->cmd_flags; -+ mqrq->cmdq_req.mrq.req = mqrq->req; -+ mqrq->cmdq_req.mrq.cmdq_req = &mqrq->cmdq_req; -+ mqrq->cmdq_req.mrq.data = &mqrq->cmdq_req.data; -+ mqrq->req->special = mqrq; -+ -+ pr_debug("%s: %s: mrq: 0x%p req: 0x%p mqrq: 0x%p bytes to xf: %d mmc_cmdq_req: 0x%p card-addr: 0x%08x dir(r-1/w-0): %d\n", -+ mmc_hostname(card->host), __func__, &mqrq->cmdq_req.mrq, -+ mqrq->req, mqrq, (cmdq_rq->data.blocks * cmdq_rq->data.blksz), -+ cmdq_rq, cmdq_rq->blk_addr, -+ (cmdq_rq->cmdq_req_flags & DIR) ? 1 : 0); -+ -+ return &mqrq->cmdq_req; -+} -+ -+/* -+ * Complete reqs from block layer softirq context -+ * Invoked in irq context -+ */ -+void mmc_blk_cmdq_req_done(struct mmc_request *mrq) -+{ -+ struct request *req = mrq->req; -+ -+ blk_complete_request(req); -+} -+EXPORT_SYMBOL(mmc_blk_cmdq_req_done); -+ -+static int mmc_blk_cmdq_start_req(struct mmc_host *host, -+ struct mmc_cmdq_req *cmdq_req) -+{ -+ struct mmc_request *mrq = &cmdq_req->mrq; -+ -+ mrq->done = mmc_blk_cmdq_req_done; -+ return mmc_cmdq_start_req(host, cmdq_req); -+} -+ -+static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req) -+{ -+ struct mmc_queue_req *active_mqrq; -+ struct mmc_card *card = mq->card; -+ struct mmc_host *host = card->host; -+ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; -+ struct mmc_cmdq_req *mc_rq; -+ u8 active_small_sector_read = 0; -+ int ret = 0; -+ -+ BUG_ON((req->tag < 0) || (req->tag > card->ext_csd.cmdq_depth)); -+ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.data_active_reqs)); -+ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs)); -+ -+ active_mqrq = &mq->mqrq_cmdq[req->tag]; -+ active_mqrq->req = req; -+ -+ mc_rq = mmc_blk_cmdq_rw_prep(active_mqrq, mq); -+ -+ if (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD) { -+ unsigned int sectors = blk_rq_sectors(req); -+ -+ if (((sectors > 0) && (sectors < 8)) -+ && (rq_data_dir(req) == READ)) -+ active_small_sector_read = 1; -+ } -+ ret = mmc_blk_cmdq_start_req(card->host, mc_rq); -+ if (!ret && active_small_sector_read) -+ host->cmdq_ctx.active_small_sector_read_reqs++; -+ /* -+ * When in SVS2 on low load scenario and there are lots of requests -+ * queued for CMDQ we need to wait till the queue is empty to scale -+ * back up to Nominal even if there is a sudden increase in load. -+ * This impacts performance where lots of IO get executed in SVS2 -+ * frequency since the queue is full. As SVS2 is a low load use case -+ * we can serialize the requests and not queue them in parallel -+ * without impacting other use cases. This makes sure the queue gets -+ * empty faster and we will be able to scale up to Nominal frequency -+ * when needed. -+ */ -+ if (!ret) -+ wait_event_interruptible(ctx->queue_empty_wq, -+ (!ctx->active_reqs)); -+ -+ return ret; -+} -+ -+/* -+ * Issues a flush (dcmd) request -+ */ -+int mmc_blk_cmdq_issue_flush_rq(struct mmc_queue *mq, struct request *req) -+{ -+ int err; -+ struct mmc_queue_req *active_mqrq; -+ struct mmc_card *card = mq->card; -+ struct mmc_host *host; -+ struct mmc_cmdq_req *cmdq_req; -+ struct mmc_cmdq_context_info *ctx_info; -+ -+ BUG_ON(!card); -+ host = card->host; -+ BUG_ON(!host); -+ BUG_ON(req->tag > card->ext_csd.cmdq_depth); -+ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs)); -+ -+ ctx_info = &host->cmdq_ctx; -+ -+ set_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state); -+ -+ active_mqrq = &mq->mqrq_cmdq[req->tag]; -+ active_mqrq->req = req; -+ -+ cmdq_req = mmc_cmdq_prep_dcmd(active_mqrq, mq); -+ cmdq_req->cmdq_req_flags |= QBR; -+ cmdq_req->mrq.cmd = &cmdq_req->cmd; -+ cmdq_req->tag = req->tag; -+ -+ err = mmc_cmdq_prepare_flush(cmdq_req->mrq.cmd); -+ if (err) { -+ pr_err("%s: failed (%d) preparing flush req\n", -+ mmc_hostname(host), err); -+ return err; -+ } -+ err = mmc_blk_cmdq_start_req(card->host, cmdq_req); -+ return err; -+} -+EXPORT_SYMBOL(mmc_blk_cmdq_issue_flush_rq); -+ -+static inline int mmc_blk_cmdq_part_switch(struct mmc_card *card, -+ struct mmc_blk_data *md) -+{ -+ struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); -+ struct mmc_host *host = card->host; -+ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; -+ u8 part_config = card->ext_csd.part_config; -+ -+ if ((main_md->part_curr == md->part_type) && -+ (card->part_curr == md->part_type)) -+ return 0; -+ -+ WARN_ON(!((card->host->caps2 & MMC_CAP2_CMD_QUEUE) && -+ card->ext_csd.cmdq_support && -+ (md->flags & MMC_BLK_CMD_QUEUE))); -+ -+ if (!test_bit(CMDQ_STATE_HALT, &ctx->curr_state)) -+ WARN_ON(mmc_cmdq_halt(host, true)); -+ -+ /* disable CQ mode in card */ -+ if (mmc_card_cmdq(card)) { -+ WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -+ EXT_CSD_CMDQ, 0, -+ card->ext_csd.generic_cmd6_time)); -+ mmc_card_clr_cmdq(card); -+ } -+ -+ part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; -+ part_config |= md->part_type; -+ -+ WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -+ EXT_CSD_PART_CONFIG, part_config, -+ card->ext_csd.part_time)); -+ -+ card->ext_csd.part_config = part_config; -+ card->part_curr = md->part_type; -+ -+ main_md->part_curr = md->part_type; -+ -+ WARN_ON(mmc_blk_cmdq_switch(card, md, true)); -+ WARN_ON(mmc_cmdq_halt(host, false)); -+ -+ return 0; -+} -+ -+static struct mmc_cmdq_req *mmc_blk_cmdq_prep_discard_req(struct mmc_queue *mq, -+ struct request *req) -+{ -+ struct mmc_blk_data *md = mq->data; -+ struct mmc_card *card = md->queue.card; -+ struct mmc_host *host = card->host; -+ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; -+ struct mmc_cmdq_req *cmdq_req; -+ struct mmc_queue_req *active_mqrq; -+ -+ BUG_ON(req->tag > card->ext_csd.cmdq_depth); -+ BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs)); -+ -+ set_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state); -+ -+ active_mqrq = &mq->mqrq_cmdq[req->tag]; -+ active_mqrq->req = req; -+ -+ cmdq_req = mmc_cmdq_prep_dcmd(active_mqrq, mq); -+ cmdq_req->cmdq_req_flags |= QBR; -+ cmdq_req->mrq.cmd = &cmdq_req->cmd; -+ cmdq_req->tag = req->tag; -+ return cmdq_req; -+} -+ -+static int mmc_blk_cmdq_issue_discard_rq(struct mmc_queue *mq, -+ struct request *req) -+{ -+ struct mmc_blk_data *md = mq->data; -+ struct mmc_card *card = md->queue.card; -+ struct mmc_cmdq_req *cmdq_req = NULL; -+ unsigned int from, nr, arg; -+ int err = 0; -+ -+ if (!mmc_can_erase(card)) { -+ err = -EOPNOTSUPP; -+ blk_end_request(req, err, blk_rq_bytes(req)); -+ goto out; -+ } -+ -+ from = blk_rq_pos(req); -+ nr = blk_rq_sectors(req); -+ -+ if (mmc_can_discard(card)) -+ arg = MMC_DISCARD_ARG; -+ else if (mmc_can_trim(card)) -+ arg = MMC_TRIM_ARG; -+ else -+ arg = MMC_ERASE_ARG; -+ -+ cmdq_req = mmc_blk_cmdq_prep_discard_req(mq, req); -+ if (card->quirks & MMC_QUIRK_INAND_CMD38) { -+ __mmc_switch_cmdq_mode(cmdq_req->mrq.cmd, -+ EXT_CSD_CMD_SET_NORMAL, -+ INAND_CMD38_ARG_EXT_CSD, -+ arg == MMC_TRIM_ARG ? -+ INAND_CMD38_ARG_TRIM : -+ INAND_CMD38_ARG_ERASE, -+ 0, true, false); -+ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); -+ if (err) -+ goto clear_dcmd; -+ } -+ err = mmc_cmdq_erase(cmdq_req, card, from, nr, arg); -+clear_dcmd: -+ blk_complete_request(req); -+out: -+ return err ? 1 : 0; -+} -+ -+static int mmc_blk_cmdq_issue_secdiscard_rq(struct mmc_queue *mq, -+ struct request *req) -+{ -+ struct mmc_blk_data *md = mq->data; -+ struct mmc_card *card = md->queue.card; -+ struct mmc_cmdq_req *cmdq_req = NULL; -+ unsigned int from, nr, arg; -+ int err = 0; -+ -+ if (!(mmc_can_secure_erase_trim(card))) { -+ err = -EOPNOTSUPP; -+ blk_end_request(req, err, blk_rq_bytes(req)); -+ goto out; -+ } -+ -+ from = blk_rq_pos(req); -+ nr = blk_rq_sectors(req); -+ -+ if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) -+ arg = MMC_SECURE_TRIM1_ARG; -+ else -+ arg = MMC_SECURE_ERASE_ARG; -+ -+ cmdq_req = mmc_blk_cmdq_prep_discard_req(mq, req); -+ if (card->quirks & MMC_QUIRK_INAND_CMD38) { -+ __mmc_switch_cmdq_mode(cmdq_req->mrq.cmd, -+ EXT_CSD_CMD_SET_NORMAL, -+ INAND_CMD38_ARG_EXT_CSD, -+ arg == MMC_SECURE_TRIM1_ARG ? -+ INAND_CMD38_ARG_SECTRIM1 : -+ INAND_CMD38_ARG_SECERASE, -+ 0, true, false); -+ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); -+ if (err) -+ goto clear_dcmd; -+ } -+ -+ err = mmc_cmdq_erase(cmdq_req, card, from, nr, arg); -+ if (err) -+ goto clear_dcmd; -+ -+ if (arg == MMC_SECURE_TRIM1_ARG) { -+ if (card->quirks & MMC_QUIRK_INAND_CMD38) { -+ __mmc_switch_cmdq_mode(cmdq_req->mrq.cmd, -+ EXT_CSD_CMD_SET_NORMAL, -+ INAND_CMD38_ARG_EXT_CSD, -+ INAND_CMD38_ARG_SECTRIM2, -+ 0, true, false); -+ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); -+ if (err) -+ goto clear_dcmd; -+ } -+ -+ err = mmc_cmdq_erase(cmdq_req, card, from, nr, -+ MMC_SECURE_TRIM2_ARG); -+ } -+clear_dcmd: -+ blk_complete_request(req); -+out: -+ return err ? 1 : 0; -+} -+ -+static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req) -+{ -+ int ret; -+ struct mmc_blk_data *md = mq->data; -+ struct mmc_card *card = md->queue.card; -+ -+ mmc_get_card(card); -+ -+#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME -+ if (mmc_bus_needs_resume(card->host)) -+ mmc_resume_bus(card->host); -+#endif -+ if (!card->host->cmdq_ctx.active_reqs && mmc_card_doing_bkops(card)) { -+ ret = mmc_cmdq_halt(card->host, true); -+ if (ret) -+ goto out; -+ ret = mmc_stop_bkops(card); -+ if (ret) { -+ pr_err("%s: %s: mmc_stop_bkops failed %d\n", -+ md->disk->disk_name, __func__, ret); -+ goto out; -+ } -+ ret = mmc_cmdq_halt(card->host, false); -+ if (ret) -+ goto out; -+ } -+ -+ ret = mmc_blk_cmdq_part_switch(card, md); -+ if (ret) { -+ pr_err("%s: %s: partition switch failed %d\n", -+ md->disk->disk_name, __func__, ret); -+ goto out; -+ } -+ -+ if (req) { -+ struct mmc_host *host = card->host; -+ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; -+ -+ if ((req_op(req) == REQ_OP_FLUSH || req_op(req) == REQ_OP_DISCARD) && -+ (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD) && -+ ctx->active_small_sector_read_reqs) { -+ ret = wait_event_interruptible(ctx->queue_empty_wq, -+ !ctx->active_reqs); -+ if (ret) { -+ pr_err("%s: failed while waiting for the CMDQ to be empty %s err (%d)\n", -+ mmc_hostname(host), -+ __func__, ret); -+ BUG_ON(1); -+ } -+ /* clear the counter now */ -+ ctx->active_small_sector_read_reqs = 0; -+ /* -+ * If there were small sector (less than 8 sectors) read -+ * operations in progress then we have to wait for the -+ * outstanding requests to finish and should also have -+ * atleast 6 microseconds delay before queuing the DCMD -+ * request. -+ */ -+ udelay(MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD); -+ } -+ -+ if (req_op(req) == REQ_OP_DISCARD) { -+ if (req_op(req) == REQ_OP_SECURE_ERASE && -+ !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN)) -+ ret = mmc_blk_cmdq_issue_secdiscard_rq(mq, req); -+ else -+ ret = mmc_blk_cmdq_issue_discard_rq(mq, req); -+ } else if (req_op(req) == REQ_OP_FLUSH) { -+ ret = mmc_blk_cmdq_issue_flush_rq(mq, req); -+ } else { -+ ret = mmc_blk_cmdq_issue_rw_rq(mq, req); -+ } -+ } -+ -+ return ret; -+ -+out: -+ if (req) -+ blk_end_request_all(req, ret); -+ mmc_put_card(card); -+ -+ return ret; -+} -+ -+static void mmc_blk_cmdq_reset(struct mmc_host *host, bool clear_all) -+{ -+ int err = 0; -+ -+ if (mmc_cmdq_halt(host, true)) { -+ pr_err("%s: halt failed\n", mmc_hostname(host)); -+ goto reset; -+ } -+ -+ if (clear_all) -+ mmc_cmdq_discard_queue(host, 0); -+reset: -+ host->cmdq_ops->disable(host, true); -+ err = mmc_cmdq_hw_reset(host); -+ if (err && err != -EOPNOTSUPP) { -+ pr_err("%s: failed to cmdq_hw_reset err = %d\n", -+ mmc_hostname(host), err); -+ host->cmdq_ops->enable(host); -+ mmc_cmdq_halt(host, false); -+ goto out; -+ } -+ /* -+ * CMDQ HW reset would have already made CQE -+ * in unhalted state, but reflect the same -+ * in software state of cmdq_ctx. -+ */ -+ mmc_host_clr_halt(host); -+out: -+ return; -+} -+ -+/** -+ * is_cmdq_dcmd_req - Checks if tag belongs to DCMD request. -+ * @q: request_queue pointer. -+ * @tag: tag number of request to check. -+ * -+ * This function checks if the request with tag number "tag" -+ * is a DCMD request or not based on cmdq_req_flags set. -+ * -+ * returns true if DCMD req, otherwise false. -+ */ -+static bool is_cmdq_dcmd_req(struct request_queue *q, int tag) -+{ -+ struct request *req; -+ struct mmc_queue_req *mq_rq; -+ struct mmc_cmdq_req *cmdq_req; -+ -+ req = blk_queue_find_tag(q, tag); -+ if (WARN_ON(!req)) -+ goto out; -+ mq_rq = req->special; -+ if (WARN_ON(!mq_rq)) -+ goto out; -+ cmdq_req = &(mq_rq->cmdq_req); -+ return (cmdq_req->cmdq_req_flags & DCMD); -+out: -+ return -ENOENT; -+} -+ -+/** -+ * mmc_blk_cmdq_reset_all - Reset everything for CMDQ block request. -+ * @host: mmc_host pointer. -+ * @err: error for which reset is performed. -+ * -+ * This function implements reset_all functionality for -+ * cmdq. It resets the controller, power cycle the card, -+ * and invalidate all busy tags(requeue all request back to -+ * elevator). -+ */ -+static void mmc_blk_cmdq_reset_all(struct mmc_host *host, int err) -+{ -+ struct mmc_request *mrq = host->err_mrq; -+ struct mmc_card *card = host->card; -+ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; -+ struct request_queue *q; -+ int itag = 0; -+ int ret = 0; -+ -+ if (WARN_ON(!mrq)) -+ return; -+ -+ q = mrq->req->q; -+ WARN_ON(!test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)); -+ -+ pr_debug("%s: %s: active_reqs = %lu\n", -+ mmc_hostname(host), __func__, -+ ctx_info->active_reqs); -+ -+ mmc_blk_cmdq_reset(host, false); -+ -+ for_each_set_bit(itag, &ctx_info->active_reqs, -+ host->num_cq_slots) { -+ ret = is_cmdq_dcmd_req(q, itag); -+ if (WARN_ON(ret == -ENOENT)) -+ continue; -+ if (!ret) { -+ WARN_ON(!test_and_clear_bit(itag, -+ &ctx_info->data_active_reqs)); -+ mmc_cmdq_post_req(host, itag, err); -+ } else { -+ clear_bit(CMDQ_STATE_DCMD_ACTIVE, -+ &ctx_info->curr_state); -+ } -+ WARN_ON(!test_and_clear_bit(itag, -+ &ctx_info->active_reqs)); -+ mmc_put_card(card); -+ } -+ -+ spin_lock_irq(q->queue_lock); -+ blk_queue_invalidate_tags(q); -+ spin_unlock_irq(q->queue_lock); -+} -+ -+static void mmc_blk_cmdq_shutdown(struct mmc_queue *mq) -+{ -+ int err; -+ struct mmc_card *card = mq->card; -+ struct mmc_host *host = card->host; -+ -+ mmc_get_card(card); -+ err = mmc_cmdq_halt(host, true); -+ if (err) { -+ pr_err("%s: halt: failed: %d\n", __func__, err); -+ goto out; -+ } -+ -+ /* disable CQ mode in card */ -+ if (mmc_card_cmdq(card)) { -+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -+ EXT_CSD_CMDQ, 0, -+ card->ext_csd.generic_cmd6_time); -+ if (err) { -+ pr_err("%s: failed to switch card to legacy mode: %d\n", -+ __func__, err); -+ goto out; -+ } -+ mmc_card_clr_cmdq(card); -+ } -+ host->cmdq_ops->disable(host, false); -+ host->card->cmdq_init = false; -+out: -+ mmc_put_card(card); -+} -+ -+static enum blk_eh_timer_return mmc_blk_cmdq_req_timed_out(struct request *req) -+{ -+ struct mmc_queue *mq = req->q->queuedata; -+ struct mmc_host *host = mq->card->host; -+ struct mmc_queue_req *mq_rq = req->special; -+ struct mmc_request *mrq; -+ struct mmc_cmdq_req *cmdq_req; -+ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; -+ -+ BUG_ON(!host); -+ -+ /* -+ * The mmc_queue_req will be present only if the request -+ * is issued to the LLD. The request could be fetched from -+ * block layer queue but could be waiting to be issued -+ * (for e.g. clock scaling is waiting for an empty cmdq queue) -+ * Reset the timer in such cases to give LLD more time -+ */ -+ if (!mq_rq) { -+ pr_warn("%s: restart timer for tag: %d\n", __func__, req->tag); -+ return BLK_EH_RESET_TIMER; -+ } -+ -+ mrq = &mq_rq->cmdq_req.mrq; -+ cmdq_req = &mq_rq->cmdq_req; -+ -+ BUG_ON(!mrq || !cmdq_req); -+ -+ if (cmdq_req->cmdq_req_flags & DCMD) -+ mrq->cmd->error = -ETIMEDOUT; -+ else -+ mrq->data->error = -ETIMEDOUT; -+ -+ if (mrq->cmd && mrq->cmd->error) { -+ if (!(req_op(req) == REQ_OP_FLUSH)) { -+ /* -+ * Notify completion for non flush commands like -+ * discard that wait for DCMD finish. -+ */ -+ set_bit(CMDQ_STATE_REQ_TIMED_OUT, -+ &ctx_info->curr_state); -+ complete(&mrq->completion); -+ return BLK_EH_NOT_HANDLED; -+ } -+ } -+ -+ if (test_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state) || -+ test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)) -+ return BLK_EH_NOT_HANDLED; -+ -+ set_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state); -+ return BLK_EH_HANDLED; -+} -+ -+/* -+ * mmc_blk_cmdq_err: error handling of cmdq error requests. -+ * Function should be called in context of error out request -+ * which has claim_host and rpm acquired. -+ * This may be called with CQ engine halted. Make sure to -+ * unhalt it after error recovery. -+ * -+ * TODO: Currently cmdq error handler does reset_all in case -+ * of any erorr. Need to optimize error handling. -+ */ -+static void mmc_blk_cmdq_err(struct mmc_queue *mq) -+{ -+ struct mmc_host *host = mq->card->host; -+ struct mmc_request *mrq = host->err_mrq; -+ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; -+ struct request_queue *q; -+ int err; -+ -+ host->cmdq_ops->dumpstate(host); -+ -+ if (WARN_ON(!mrq)) -+ return; -+ -+ q = mrq->req->q; -+ err = mmc_cmdq_halt(host, true); -+ if (err) { -+ pr_err("halt: failed: %d\n", err); -+ goto reset; -+ } -+ -+ /* RED error - Fatal: requires reset */ -+ if (mrq->cmdq_req->resp_err) { -+ err = mrq->cmdq_req->resp_err; -+ pr_crit("%s: Response error detected: Device in bad state\n", -+ mmc_hostname(host)); -+ goto reset; -+ } -+ -+ /* -+ * In case of software request time-out, we schedule err work only for -+ * the first error out request and handles all other request in flight -+ * here. -+ */ -+ if (test_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state)) { -+ err = -ETIMEDOUT; -+ } else if (mrq->data && mrq->data->error) { -+ err = mrq->data->error; -+ } else if (mrq->cmd && mrq->cmd->error) { -+ /* DCMD commands */ -+ err = mrq->cmd->error; -+ } -+ -+reset: -+ mmc_blk_cmdq_reset_all(host, err); -+ if (mrq->cmdq_req->resp_err) -+ mrq->cmdq_req->resp_err = false; -+ mmc_cmdq_halt(host, false); -+ -+ host->err_mrq = NULL; -+ clear_bit(CMDQ_STATE_REQ_TIMED_OUT, &ctx_info->curr_state); -+ WARN_ON(!test_and_clear_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)); -+ wake_up(&ctx_info->wait); -+} -+ -+/* invoked by block layer in softirq context */ -+void mmc_blk_cmdq_complete_rq(struct request *rq) -+{ -+ struct mmc_queue_req *mq_rq = rq->special; -+ struct mmc_request *mrq = &mq_rq->cmdq_req.mrq; -+ struct mmc_host *host = mrq->host; -+ struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx; -+ struct mmc_cmdq_req *cmdq_req = &mq_rq->cmdq_req; -+ struct mmc_queue *mq = (struct mmc_queue *)rq->q->queuedata; -+ int err = 0; -+ bool is_dcmd = false; -+ -+ if (mrq->cmd && mrq->cmd->error) -+ err = mrq->cmd->error; -+ else if (mrq->data && mrq->data->error) -+ err = mrq->data->error; -+ -+ if (err || cmdq_req->resp_err) { -+ pr_err("%s: %s: txfr error(%d)/resp_err(%d)\n", -+ mmc_hostname(mrq->host), __func__, err, -+ cmdq_req->resp_err); -+ if (test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)) { -+ pr_err("%s: CQ in error state, ending current req: %d\n", -+ __func__, err); -+ } else { -+ set_bit(CMDQ_STATE_ERR, &ctx_info->curr_state); -+ BUG_ON(host->err_mrq != NULL); -+ host->err_mrq = mrq; -+ schedule_work(&mq->cmdq_err_work); -+ } -+ goto out; -+ } -+ /* -+ * In case of error CMDQ is expected to be either in halted -+ * or disable state so cannot receive any completion of -+ * other requests. -+ */ -+ BUG_ON(test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)); -+ -+ /* clear pending request */ -+ BUG_ON(!test_and_clear_bit(cmdq_req->tag, -+ &ctx_info->active_reqs)); -+ if (cmdq_req->cmdq_req_flags & DCMD) -+ is_dcmd = true; -+ else -+ BUG_ON(!test_and_clear_bit(cmdq_req->tag, -+ &ctx_info->data_active_reqs)); -+ if (!is_dcmd) -+ mmc_cmdq_post_req(host, cmdq_req->tag, err); -+ if (cmdq_req->cmdq_req_flags & DCMD) { -+ clear_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state); -+ blk_end_request_all(rq, err); -+ goto out; -+ } -+ -+ blk_end_request(rq, err, cmdq_req->data.bytes_xfered); -+ -+out: -+ -+ if (!test_bit(CMDQ_STATE_ERR, &ctx_info->curr_state)) { -+ wake_up(&ctx_info->wait); -+ mmc_put_card(host->card); -+ } -+ -+ if (!ctx_info->active_reqs) -+ wake_up_interruptible(&host->cmdq_ctx.queue_empty_wq); -+ -+ if (blk_queue_stopped(mq->queue) && !ctx_info->active_reqs) -+ complete(&mq->cmdq_shutdown_complete); -+ -+ return; -+} -+ - static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - struct device *parent, - sector_t size, -@@ -2262,7 +3159,7 @@ - INIT_LIST_HEAD(&md->part); - md->usage = 1; - -- ret = mmc_init_queue(&md->queue, card, &md->lock, subname); -+ ret = mmc_init_queue(&md->queue, card, &md->lock, subname, area_type); - if (ret) - goto err_putdisk; - -@@ -2318,7 +3215,16 @@ - blk_queue_write_cache(md->queue.queue, true, true); - } - -- if (mmc_card_mmc(card) && -+ if (card->cmdq_init) { -+ md->flags |= MMC_BLK_CMD_QUEUE; -+ md->queue.cmdq_complete_fn = mmc_blk_cmdq_complete_rq; -+ md->queue.cmdq_issue_fn = mmc_blk_cmdq_issue_rq; -+ md->queue.cmdq_error_fn = mmc_blk_cmdq_err; -+ md->queue.cmdq_req_timed_out = mmc_blk_cmdq_req_timed_out; -+ md->queue.cmdq_shutdown = mmc_blk_cmdq_shutdown; -+ } -+ -+ if (mmc_card_mmc(card) && !card->cmdq_init && - (area_type == MMC_BLK_DATA_AREA_MAIN) && - (md->flags & MMC_BLK_CMD23) && - card->ext_csd.packed_event_en) { -@@ -2431,6 +3337,8 @@ - mmc_cleanup_queue(&md->queue); - if (md->flags & MMC_BLK_PACKED_CMD) - mmc_packed_clean(&md->queue); -+ if (md->flags & MMC_BLK_CMD_QUEUE) -+ mmc_cmdq_clean(&md->queue, card); - if (md->disk->flags & GENHD_FL_UP) { - device_remove_file(disk_to_dev(md->disk), &md->force_ro); - if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && -@@ -2648,23 +3556,36 @@ - dev_set_drvdata(&card->dev, NULL); - } - --static int _mmc_blk_suspend(struct mmc_card *card) -+static int _mmc_blk_suspend(struct mmc_card *card, bool wait) - { - struct mmc_blk_data *part_md; - struct mmc_blk_data *md = dev_get_drvdata(&card->dev); -+ int rc = 0; - - if (md) { -- mmc_queue_suspend(&md->queue); -+ rc = mmc_queue_suspend(&md->queue, wait); -+ if (rc) -+ goto out; - list_for_each_entry(part_md, &md->part, part) { -- mmc_queue_suspend(&part_md->queue); -+ rc = mmc_queue_suspend(&part_md->queue, wait); -+ if (rc) -+ goto out_resume; - } - } -- return 0; -+ goto out; -+ -+ out_resume: -+ mmc_queue_resume(&md->queue); -+ list_for_each_entry(part_md, &md->part, part) { -+ mmc_queue_resume(&part_md->queue); -+ } -+ out: -+ return rc; - } - - static void mmc_blk_shutdown(struct mmc_card *card) - { -- _mmc_blk_suspend(card); -+ _mmc_blk_suspend(card, 1); - } - - #ifdef CONFIG_PM_SLEEP -@@ -2672,7 +3593,7 @@ - { - struct mmc_card *card = mmc_dev_to_card(dev); - -- return _mmc_blk_suspend(card); -+ return _mmc_blk_suspend(card, 0); - } - - static int mmc_blk_resume(struct device *dev) ---- linux-4.9.37/drivers/mmc/card/queue.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/card/queue.c 2021-06-07 13:01:33.000000000 +0300 -@@ -179,6 +179,122 @@ - queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); - } - -+static struct request *mmc_peek_request(struct mmc_queue *mq) -+{ -+ struct request_queue *q = mq->queue; -+ mq->cmdq_req_peeked = NULL; -+ -+ spin_lock_irq(q->queue_lock); -+ if (!blk_queue_stopped(q)) -+ mq->cmdq_req_peeked = blk_peek_request(q); -+ spin_unlock_irq(q->queue_lock); -+ -+ return mq->cmdq_req_peeked; -+} -+ -+static bool mmc_check_blk_queue_start_tag(struct request_queue *q, -+ struct request *req) -+{ -+ int ret; -+ -+ spin_lock_irq(q->queue_lock); -+ ret = blk_queue_start_tag(q, req); -+ spin_unlock_irq(q->queue_lock); -+ -+ return !!ret; -+} -+ -+static inline void mmc_cmdq_ready_wait(struct mmc_host *host, -+ struct mmc_queue *mq) -+{ -+ struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx; -+ struct request_queue *q = mq->queue; -+ -+ /* -+ * Wait until all of the following conditions are true: -+ * 1. There is a request pending in the block layer queue -+ * to be processed. -+ * 2. If the peeked request is flush/discard then there shouldn't -+ * be any other direct command active. -+ * 3. cmdq state should be unhalted. -+ * 4. cmdq state shouldn't be in error state. -+ * 5. free tag available to process the new request. -+ */ -+ wait_event(ctx->wait, kthread_should_stop() -+ || (mmc_peek_request(mq) && -+ !((mq->cmdq_req_peeked->cmd_flags & (REQ_OP_FLUSH | REQ_OP_DISCARD)) -+ && test_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx->curr_state)) -+ && !(!host->card->part_curr && !mmc_card_suspended(host->card) -+ && mmc_host_halt(host)) -+ && !(!host->card->part_curr && mmc_host_cq_disable(host) && -+ !mmc_card_suspended(host->card)) -+ && !test_bit(CMDQ_STATE_ERR, &ctx->curr_state) -+ && !mmc_check_blk_queue_start_tag(q, mq->cmdq_req_peeked))); -+} -+ -+static int mmc_cmdq_thread(void *d) -+{ -+ struct mmc_queue *mq = d; -+ struct mmc_card *card = mq->card; -+ struct mmc_host *host = card->host; -+ -+ current->flags |= PF_MEMALLOC; -+ -+ while (1) { -+ int ret = 0; -+ -+ mmc_cmdq_ready_wait(host, mq); -+ if (kthread_should_stop()) -+ break; -+ -+ ret = mq->cmdq_issue_fn(mq, mq->cmdq_req_peeked); -+ /* -+ * Don't requeue if issue_fn fails, just bug on. -+ * We don't expect failure here and there is no recovery other -+ * than fixing the actual issue if there is any. -+ * Also we end the request if there is a partition switch error, -+ * so we should not requeue the request here. -+ */ -+ if (ret) -+ BUG_ON(1); -+ } /* loop */ -+ -+ return 0; -+} -+ -+static void mmc_cmdq_dispatch_req(struct request_queue *q) -+{ -+ struct mmc_queue *mq = q->queuedata; -+ -+ wake_up(&mq->card->host->cmdq_ctx.wait); -+} -+ -+/** -+ * mmc_blk_cmdq_setup_queue -+ * @mq: mmc queue -+ * @card: card to attach to this queue -+ * -+ * Setup queue for CMDQ supporting MMC card -+ */ -+void mmc_cmdq_setup_queue(struct mmc_queue *mq, struct mmc_card *card) -+{ -+ u64 limit = BLK_BOUNCE_HIGH; -+ struct mmc_host *host = card->host; -+ -+ if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) -+ limit = *mmc_dev(host)->dma_mask; -+ -+ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); -+ if (mmc_can_erase(card)) -+ mmc_queue_setup_discard(mq->queue, card); -+ -+ blk_queue_bounce_limit(mq->queue, limit); -+ blk_queue_max_hw_sectors(mq->queue, min(host->max_blk_count, -+ host->max_req_size / 512)); -+ blk_queue_max_segment_size(mq->queue, host->max_seg_size); -+ blk_queue_max_segments(mq->queue, host->max_segs); -+} -+ - /** - * mmc_init_queue - initialise a queue structure. - * @mq: mmc queue -@@ -189,7 +305,7 @@ - * Initialise a MMC card request queue. - */ - int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, -- spinlock_t *lock, const char *subname) -+ spinlock_t *lock, const char *subname, int area_type) - { - struct mmc_host *host = card->host; - u64 limit = BLK_BOUNCE_HIGH; -@@ -201,6 +317,37 @@ - limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; - - mq->card = card; -+ if (card->ext_csd.cmdq_support && -+ (area_type == MMC_BLK_DATA_AREA_MAIN)) { -+ mq->queue = blk_init_queue(mmc_cmdq_dispatch_req, lock); -+ if (!mq->queue) -+ return -ENOMEM; -+ mmc_cmdq_setup_queue(mq, card); -+ ret = mmc_cmdq_init(mq, card); -+ if (ret) { -+ pr_err("%s: %d: cmdq: unable to set-up\n", -+ mmc_hostname(card->host), ret); -+ blk_cleanup_queue(mq->queue); -+ } else { -+ sema_init(&mq->thread_sem, 1); -+ /* hook for pm qos cmdq init */ -+ if (card->host->cmdq_ops->init) -+ card->host->cmdq_ops->init(card->host); -+ mq->queue->queuedata = mq; -+ mq->thread = kthread_run(mmc_cmdq_thread, mq, -+ "mmc-cmdqd/%d%s", -+ host->index, -+ subname ? subname : ""); -+ if (IS_ERR(mq->thread)) { -+ pr_err("%s: %d: cmdq: failed to start mmc-cmdqd thread\n", -+ mmc_hostname(card->host), ret); -+ ret = PTR_ERR(mq->thread); -+ } -+ -+ return ret; -+ } -+ } -+ - mq->queue = blk_init_queue(mmc_request_fn, lock); - if (!mq->queue) - return -ENOMEM; -@@ -413,20 +560,76 @@ - * complete any outstanding requests. This ensures that we - * won't suspend while a request is being processed. - */ --void mmc_queue_suspend(struct mmc_queue *mq) -+int mmc_queue_suspend(struct mmc_queue *mq, int wait) - { - struct request_queue *q = mq->queue; - unsigned long flags; -+ int rc = 0; -+ struct mmc_card *card = mq->card; -+ struct request *req; - - if (!(mq->flags & MMC_QUEUE_SUSPENDED)) { - mq->flags |= MMC_QUEUE_SUSPENDED; - -- spin_lock_irqsave(q->queue_lock, flags); -- blk_stop_queue(q); -- spin_unlock_irqrestore(q->queue_lock, flags); -+ if (card->cmdq_init && blk_queue_tagged(q)) { -+ struct mmc_host *host = card->host; - -- down(&mq->thread_sem); -+ if (wait) { -+ /* -+ * After blk_stop_queue is called, wait for all -+ * active_reqs to complete. -+ * Then wait for cmdq thread to exit before calling -+ * cmdq shutdown to avoid race between issuing -+ * requests and shutdown of cmdq. -+ */ -+ spin_lock_irqsave(q->queue_lock, flags); -+ blk_stop_queue(q); -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ -+ if (host->cmdq_ctx.active_reqs) -+ wait_for_completion( -+ &mq->cmdq_shutdown_complete); -+ kthread_stop(mq->thread); -+ mq->cmdq_shutdown(mq); -+ } else { -+ spin_lock_irqsave(q->queue_lock, flags); -+ blk_stop_queue(q); -+ wake_up(&host->cmdq_ctx.wait); -+ req = blk_peek_request(q); -+ if (req || mq->cmdq_req_peeked || -+ host->cmdq_ctx.active_reqs) { -+ mq->flags &= ~MMC_QUEUE_SUSPENDED; -+ blk_start_queue(q); -+ rc = -EBUSY; -+ } -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ } -+ -+ goto out; -+ } else { -+ spin_lock_irqsave(q->queue_lock, flags); -+ blk_stop_queue(q); -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ -+ rc = down_trylock(&mq->thread_sem); -+ if (rc && !wait) { -+ /* -+ * Failed to take the lock so better to abort the -+ * suspend because mmcqd thread is processing requests. -+ */ -+ mq->flags &= ~MMC_QUEUE_SUSPENDED; -+ spin_lock_irqsave(q->queue_lock, flags); -+ blk_start_queue(q); -+ spin_unlock_irqrestore(q->queue_lock, flags); -+ rc = -EBUSY; -+ } else if (rc && wait) { -+ down(&mq->thread_sem); -+ rc = 0; -+ } -+ } - } -+out: -+ return rc; - } - - /** -@@ -555,3 +758,105 @@ - sg_copy_from_buffer(mqrq->bounce_sg, mqrq->bounce_sg_len, - mqrq->bounce_buf, mqrq->sg[0].length); - } -+ -+static void mmc_cmdq_softirq_done(struct request *rq) -+{ -+ struct mmc_queue *mq = rq->q->queuedata; -+ mq->cmdq_complete_fn(rq); -+} -+ -+static void mmc_cmdq_error_work(struct work_struct *work) -+{ -+ struct mmc_queue *mq = container_of(work, struct mmc_queue, -+ cmdq_err_work); -+ -+ mq->cmdq_error_fn(mq); -+} -+ -+enum blk_eh_timer_return mmc_cmdq_rq_timed_out(struct request *req) -+{ -+ struct mmc_queue *mq = req->q->queuedata; -+ -+ pr_err("%s: request with tag: %d flags: 0x%llx timed out\n", -+ mmc_hostname(mq->card->host), req->tag, req->cmd_flags); -+ -+ return mq->cmdq_req_timed_out(req); -+} -+ -+int mmc_cmdq_init(struct mmc_queue *mq, struct mmc_card *card) -+{ -+ int i, ret = 0; -+ /* one slot is reserved for dcmd requests */ -+ int q_depth = card->ext_csd.cmdq_depth - 1; -+ -+ card->cmdq_init = false; -+ if (!(card->host->caps2 & MMC_CAP2_CMD_QUEUE)) { -+ ret = -ENOTSUPP; -+ goto out; -+ } -+ -+ init_waitqueue_head(&card->host->cmdq_ctx.queue_empty_wq); -+ init_waitqueue_head(&card->host->cmdq_ctx.wait); -+ -+ mq->mqrq_cmdq = kzalloc( -+ sizeof(struct mmc_queue_req) * q_depth, GFP_KERNEL); -+ if (!mq->mqrq_cmdq) { -+ pr_warn("%s: unable to allocate mqrq's for q_depth %d\n", -+ mmc_card_name(card), q_depth); -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ /* sg is allocated for data request slots only */ -+ for (i = 0; i < q_depth; i++) { -+ mq->mqrq_cmdq[i].sg = mmc_alloc_sg(card->host->max_segs, &ret); -+ if (ret) { -+ pr_warn("%s: unable to allocate cmdq sg of size %d\n", -+ mmc_card_name(card), -+ card->host->max_segs); -+ goto free_mqrq_sg; -+ } -+ } -+ -+ ret = blk_queue_init_tags(mq->queue, q_depth, NULL, BLK_TAG_ALLOC_FIFO); -+ if (ret) { -+ pr_warn("%s: unable to allocate cmdq tags %d\n", -+ mmc_card_name(card), q_depth); -+ goto free_mqrq_sg; -+ } -+ -+ blk_queue_softirq_done(mq->queue, mmc_cmdq_softirq_done); -+ INIT_WORK(&mq->cmdq_err_work, mmc_cmdq_error_work); -+ init_completion(&mq->cmdq_shutdown_complete); -+ init_completion(&mq->cmdq_pending_req_done); -+ -+ blk_queue_rq_timed_out(mq->queue, mmc_cmdq_rq_timed_out); -+ blk_queue_rq_timeout(mq->queue, 120 * HZ); -+ card->cmdq_init = true; -+ -+ goto out; -+ -+free_mqrq_sg: -+ for (i = 0; i < q_depth; i++) -+ kfree(mq->mqrq_cmdq[i].sg); -+ kfree(mq->mqrq_cmdq); -+ mq->mqrq_cmdq = NULL; -+out: -+ return ret; -+} -+ -+void mmc_cmdq_clean(struct mmc_queue *mq, struct mmc_card *card) -+{ -+ int i; -+ int q_depth = card->ext_csd.cmdq_depth - 1; -+ -+ blk_free_tags(mq->queue->queue_tags); -+ mq->queue->queue_tags = NULL; -+ blk_queue_free_tags(mq->queue); -+ -+ for (i = 0; i < q_depth; i++) -+ kfree(mq->mqrq_cmdq[i].sg); -+ kfree(mq->mqrq_cmdq); -+ mq->mqrq_cmdq = NULL; -+} -+ ---- linux-4.9.37/drivers/mmc/card/queue.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/card/queue.h 2021-06-07 13:01:33.000000000 +0300 -@@ -48,6 +48,7 @@ - struct mmc_async_req mmc_active; - enum mmc_packed_type cmd_type; - struct mmc_packed *packed; -+ struct mmc_cmdq_req cmdq_req; - }; - - struct mmc_queue { -@@ -62,12 +63,25 @@ - struct mmc_queue_req mqrq[2]; - struct mmc_queue_req *mqrq_cur; - struct mmc_queue_req *mqrq_prev; -+ struct mmc_queue_req *mqrq_cmdq; -+ struct work_struct cmdq_err_work; -+ -+ struct completion cmdq_pending_req_done; -+ struct completion cmdq_shutdown_complete; -+ struct request *cmdq_req_peeked; -+ -+ int (*cmdq_issue_fn)(struct mmc_queue *, -+ struct request *); -+ void (*cmdq_complete_fn)(struct request *); -+ void (*cmdq_error_fn)(struct mmc_queue *); -+ enum blk_eh_timer_return (*cmdq_req_timed_out)(struct request *); -+ void (*cmdq_shutdown)(struct mmc_queue *); - }; - - extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, -- const char *); -+ const char *, int); - extern void mmc_cleanup_queue(struct mmc_queue *); --extern void mmc_queue_suspend(struct mmc_queue *); -+extern int mmc_queue_suspend(struct mmc_queue *, int); - extern void mmc_queue_resume(struct mmc_queue *); - - extern unsigned int mmc_queue_map_sg(struct mmc_queue *, -@@ -79,5 +93,6 @@ - extern void mmc_packed_clean(struct mmc_queue *); - - extern int mmc_access_rpmb(struct mmc_queue *); -- -+extern int mmc_cmdq_init(struct mmc_queue *mq, struct mmc_card *card); -+extern void mmc_cmdq_clean(struct mmc_queue *mq, struct mmc_card *card); - #endif ---- linux-4.9.37/drivers/mmc/core/core.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/core/core.c 2021-06-07 13:01:33.000000000 +0300 -@@ -569,7 +569,12 @@ - mmc_hostname(host), __func__); - } - } -- if (!cmd->error || !cmd->retries || -+ -+ /* -+ * If the return code is EACCES, exit the loop. This solves the problem -+ * that the system suspends for a long time when the protected card is accessed. -+ */ -+ if ((cmd->error == -EACCES) || !cmd->error || !cmd->retries || - mmc_card_removed(host->card)) - break; - -@@ -641,6 +646,179 @@ - host->ops->post_req(host, mrq, err); - } - -+int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host) -+{ -+ int err = 0; -+ -+ err = wait_event_interruptible(host->cmdq_ctx.queue_empty_wq, -+ (!host->cmdq_ctx.active_reqs)); -+ if (host->cmdq_ctx.active_reqs) { -+ pr_err("%s: %s: unexpected active requests (%lu)\n", -+ mmc_hostname(host), __func__, -+ host->cmdq_ctx.active_reqs); -+ return -EPERM; -+ } -+ -+ err = mmc_cmdq_halt(host, true); -+ if (err) { -+ pr_err("%s: %s: mmc_cmdq_halt failed (%d)\n", -+ mmc_hostname(host), __func__, err); -+ goto out; -+ } -+ -+out: -+ return err; -+} -+EXPORT_SYMBOL(mmc_cmdq_halt_on_empty_queue); -+ -+/** -+ * mmc_cmdq_discard_card_queue - discard the task[s] in the device -+ * @host: host instance -+ * @tasks: mask of tasks to be knocked off -+ * 0: remove all queued tasks -+ */ -+int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks) -+{ -+ return mmc_discard_queue(host, tasks); -+} -+EXPORT_SYMBOL(mmc_cmdq_discard_queue); -+ -+ -+/** -+ * mmc_cmdq_post_req - post process of a completed request -+ * @host: host instance -+ * @tag: the request tag. -+ * @err: non-zero is error, success otherwise -+ */ -+void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err) -+{ -+ if (likely(host->cmdq_ops->post_req)) -+ host->cmdq_ops->post_req(host, tag, err); -+} -+EXPORT_SYMBOL(mmc_cmdq_post_req); -+ -+/** -+ * mmc_cmdq_halt - halt/un-halt the command queue engine -+ * @host: host instance -+ * @halt: true - halt, un-halt otherwise -+ * -+ * Host halts the command queue engine. It should complete -+ * the ongoing transfer and release the bus. -+ * All legacy commands can be sent upon successful -+ * completion of this function. -+ * Returns 0 on success, negative otherwise -+ */ -+int mmc_cmdq_halt(struct mmc_host *host, bool halt) -+{ -+ int err = 0; -+ -+ if ((halt && mmc_host_halt(host)) || -+ (!halt && !mmc_host_halt(host))) { -+ pr_debug("%s: %s: CQE is already %s\n", mmc_hostname(host), -+ __func__, halt ? "halted" : "un-halted"); -+ return 0; -+ } -+ -+ if (host->cmdq_ops->halt) { -+ err = host->cmdq_ops->halt(host, halt); -+ if (!err && host->ops->notify_halt) -+ host->ops->notify_halt(host, halt); -+ if (!err && halt) -+ mmc_host_set_halt(host); -+ else if (!err && !halt) { -+ mmc_host_clr_halt(host); -+ wake_up(&host->cmdq_ctx.wait); -+ } -+ } else { -+ err = -ENOSYS; -+ } -+ return err; -+} -+EXPORT_SYMBOL(mmc_cmdq_halt); -+ -+static void mmc_start_cmdq_request(struct mmc_host *host, -+ struct mmc_request *mrq) -+{ -+ if (mrq->data) { -+ pr_debug("%s: blksz %d blocks %d flags %08x tsac %lu ms nsac %d\n", -+ mmc_hostname(host), mrq->data->blksz, -+ mrq->data->blocks, mrq->data->flags, -+ mrq->data->timeout_ns / NSEC_PER_MSEC, -+ mrq->data->timeout_clks); -+ -+ BUG_ON(mrq->data->blksz > host->max_blk_size); -+ BUG_ON(mrq->data->blocks > host->max_blk_count); -+ BUG_ON(mrq->data->blocks * mrq->data->blksz > -+ host->max_req_size); -+ mrq->data->error = 0; -+ mrq->data->mrq = mrq; -+ } -+ -+ if (mrq->cmd) { -+ mrq->cmd->error = 0; -+ mrq->cmd->mrq = mrq; -+ } -+ -+ if (likely(host->cmdq_ops->request)) -+ host->cmdq_ops->request(host, mrq); -+ else -+ pr_err("%s: %s: issue request failed\n", mmc_hostname(host), -+ __func__); -+} -+ -+int mmc_cmdq_start_req(struct mmc_host *host, struct mmc_cmdq_req *cmdq_req) -+{ -+ struct mmc_request *mrq = &cmdq_req->mrq; -+ -+ mrq->host = host; -+ if (mmc_card_removed(host->card)) { -+ mrq->cmd->error = -ENOMEDIUM; -+ return -ENOMEDIUM; -+ } -+ mmc_start_cmdq_request(host, mrq); -+ return 0; -+} -+EXPORT_SYMBOL(mmc_cmdq_start_req); -+ -+static void mmc_cmdq_dcmd_req_done(struct mmc_request *mrq) -+{ -+ complete(&mrq->completion); -+} -+ -+int mmc_cmdq_wait_for_dcmd(struct mmc_host *host, -+ struct mmc_cmdq_req *cmdq_req) -+{ -+ struct mmc_request *mrq = &cmdq_req->mrq; -+ struct mmc_command *cmd = mrq->cmd; -+ int err = 0; -+ -+ init_completion(&mrq->completion); -+ mrq->done = mmc_cmdq_dcmd_req_done; -+ err = mmc_cmdq_start_req(host, cmdq_req); -+ if (err) -+ return err; -+ -+ wait_for_completion_io(&mrq->completion); -+ if (cmd->error) { -+ pr_err("%s: DCMD %d failed with err %d\n", -+ mmc_hostname(host), cmd->opcode, -+ cmd->error); -+ err = cmd->error; -+ if (host->cmdq_ops->dumpstate) -+ host->cmdq_ops->dumpstate(host); -+ } -+ return err; -+} -+EXPORT_SYMBOL(mmc_cmdq_wait_for_dcmd); -+ -+int mmc_cmdq_prepare_flush(struct mmc_command *cmd) -+{ -+ return __mmc_switch_cmdq_mode(cmd, EXT_CSD_CMD_SET_NORMAL, -+ EXT_CSD_FLUSH_CACHE, 1, -+ 0, true, true); -+} -+EXPORT_SYMBOL(mmc_cmdq_prepare_flush); -+ - /** - * mmc_start_req - start a non-blocking request - * @host: MMC host to start command -@@ -1873,6 +2051,9 @@ - - void mmc_power_cycle(struct mmc_host *host, u32 ocr) - { -+ if(host->type == MMC_HOST_TYPE_MMC) -+ return; -+ - mmc_power_off(host); - /* Wait at least 1 ms according to SD spec */ - mmc_delay(1); -@@ -2149,6 +2330,125 @@ - return mmc_mmc_erase_timeout(card, arg, qty); - } - -+static u32 mmc_get_erase_qty(struct mmc_card *card, u32 from, u32 to) -+{ -+ u32 qty = 0; -+ /* -+ * qty is used to calculate the erase timeout which depends on how many -+ * erase groups (or allocation units in SD terminology) are affected. -+ * We count erasing part of an erase group as one erase group. -+ * For SD, the allocation units are always a power of 2. For MMC, the -+ * erase group size is almost certainly also power of 2, but it does not -+ * seem to insist on that in the JEDEC standard, so we fall back to -+ * division in that case. SD may not specify an allocation unit size, -+ * in which case the timeout is based on the number of write blocks. -+ * -+ * Note that the timeout for secure trim 2 will only be correct if the -+ * number of erase groups specified is the same as the total of all -+ * preceding secure trim 1 commands. Since the power may have been -+ * lost since the secure trim 1 commands occurred, it is generally -+ * impossible to calculate the secure trim 2 timeout correctly. -+ */ -+ if (card->erase_shift) -+ qty += ((to >> card->erase_shift) - -+ (from >> card->erase_shift)) + 1; -+ else if (mmc_card_sd(card)) -+ qty += to - from + 1; -+ else -+ qty += ((to / card->erase_size) - -+ (from / card->erase_size)) + 1; -+ return qty; -+} -+ -+static int mmc_cmdq_send_erase_cmd(struct mmc_cmdq_req *cmdq_req, -+ struct mmc_card *card, u32 opcode, u32 arg, u32 qty) -+{ -+ struct mmc_command *cmd = cmdq_req->mrq.cmd; -+ int err; -+ -+ memset(cmd, 0, sizeof(struct mmc_command)); -+ -+ cmd->opcode = opcode; -+ cmd->arg = arg; -+ if (cmd->opcode == MMC_ERASE) { -+ cmd->flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; -+ cmd->busy_timeout = mmc_erase_timeout(card, arg, qty); -+ } else { -+ cmd->flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; -+ } -+ -+ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); -+ if (err) { -+ pr_err("mmc_erase: group start error %d, status %#x\n", -+ err, cmd->resp[0]); -+ return -EIO; -+ } -+ return 0; -+} -+ -+static int mmc_cmdq_do_erase(struct mmc_cmdq_req *cmdq_req, -+ struct mmc_card *card, unsigned int from, -+ unsigned int to, unsigned int arg) -+{ -+ struct mmc_command *cmd = cmdq_req->mrq.cmd; -+ unsigned int qty = 0; -+ unsigned long timeout; -+ int err; -+ -+ mmc_retune_hold(card->host); -+ -+ qty = mmc_get_erase_qty(card, from, to); -+ -+ if (!mmc_card_blockaddr(card)) { -+ from <<= 9; -+ to <<= 9; -+ } -+ -+ err = mmc_cmdq_send_erase_cmd(cmdq_req, card, MMC_ERASE_GROUP_START, -+ from, qty); -+ if (err) -+ goto out; -+ -+ err = mmc_cmdq_send_erase_cmd(cmdq_req, card, MMC_ERASE_GROUP_END, -+ to, qty); -+ if (err) -+ goto out; -+ -+ err = mmc_cmdq_send_erase_cmd(cmdq_req, card, MMC_ERASE, -+ arg, qty); -+ if (err) -+ goto out; -+ -+ timeout = jiffies + msecs_to_jiffies(MMC_CORE_TIMEOUT_MS); -+ do { -+ memset(cmd, 0, sizeof(struct mmc_command)); -+ cmd->opcode = MMC_SEND_STATUS; -+ cmd->arg = card->rca << 16; -+ cmd->flags = MMC_RSP_R1 | MMC_CMD_AC; -+ /* Do not retry else we can't see errors */ -+ err = mmc_cmdq_wait_for_dcmd(card->host, cmdq_req); -+ if (err || (cmd->resp[0] & 0xFDF92000)) { -+ pr_err("error %d requesting status %#x\n", -+ err, cmd->resp[0]); -+ err = -EIO; -+ goto out; -+ } -+ /* Timeout if the device never becomes ready for data and -+ * never leaves the program state. -+ */ -+ if (time_after(jiffies, timeout)) { -+ pr_err("%s: Card stuck in programming state! %s\n", -+ mmc_hostname(card->host), __func__); -+ err = -EIO; -+ goto out; -+ } -+ } while (!(cmd->resp[0] & R1_READY_FOR_DATA) || -+ (R1_CURRENT_STATE(cmd->resp[0]) == R1_STATE_PRG)); -+out: -+ mmc_retune_release(card->host); -+ return err; -+} -+ - static int mmc_do_erase(struct mmc_card *card, unsigned int from, - unsigned int to, unsigned int arg) - { -@@ -2336,21 +2636,9 @@ - return nr_new; - } - --/** -- * mmc_erase - erase sectors. -- * @card: card to erase -- * @from: first sector to erase -- * @nr: number of sectors to erase -- * @arg: erase command argument (SD supports only %MMC_ERASE_ARG) -- * -- * Caller must claim host before calling this function. -- */ --int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, -- unsigned int arg) -+static int mmc_erase_sanity_check(struct mmc_card *card, unsigned int from, -+ unsigned int nr, unsigned int arg) - { -- unsigned int rem, to = from + nr; -- int err; -- - if (!(card->host->caps & MMC_CAP_ERASE) || - !(card->csd.cmdclass & CCC_ERASE)) - return -EOPNOTSUPP; -@@ -2373,6 +2661,70 @@ - if (from % card->erase_size || nr % card->erase_size) - return -EINVAL; - } -+ return 0; -+} -+ -+int mmc_cmdq_erase(struct mmc_cmdq_req *cmdq_req, -+ struct mmc_card *card, unsigned int from, unsigned int nr, -+ unsigned int arg) -+{ -+ unsigned int rem, to = from + nr; -+ int err; -+ -+ err = mmc_erase_sanity_check(card, from, nr, arg); -+ if (err) -+ return err; -+ -+ if (arg == MMC_ERASE_ARG) -+ nr = mmc_align_erase_size(card, &from, &to, nr); -+ -+ if (nr == 0) -+ return 0; -+ -+ if (to <= from) -+ return -EINVAL; -+ -+ /* 'from' and 'to' are inclusive */ -+ to -= 1; -+ -+ /* -+ * Special case where only one erase-group fits in the timeout budget: -+ * If the region crosses an erase-group boundary on this particular -+ * case, we will be trimming more than one erase-group which, does not -+ * fit in the timeout budget of the controller, so we need to split it -+ * and call mmc_do_erase() twice if necessary. This special case is -+ * identified by the card->eg_boundary flag. -+ */ -+ rem = card->erase_size - (from % card->erase_size); -+ if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) { -+ err = mmc_cmdq_do_erase(cmdq_req, card, from, from + rem - 1, arg); -+ from += rem; -+ if ((err) || (to <= from)) -+ return err; -+ } -+ -+ return mmc_cmdq_do_erase(cmdq_req, card, from, to, arg); -+} -+EXPORT_SYMBOL(mmc_cmdq_erase); -+ -+/** -+ * mmc_erase - erase sectors. -+ * @card: card to erase -+ * @from: first sector to erase -+ * @nr: number of sectors to erase -+ * @arg: erase command argument (SD supports only %MMC_ERASE_ARG) -+ * -+ * Caller must claim host before calling this function. -+ */ -+int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, -+ unsigned int arg) -+{ -+ unsigned int rem, to = from + nr; -+ int err; -+ -+ err = mmc_erase_sanity_check(card, from, nr, arg); -+ if (err) -+ return err; - - if (arg == MMC_ERASE_ARG) - nr = mmc_align_erase_size(card, &from, &to, nr); -@@ -2631,6 +2983,22 @@ - return ret; - } - EXPORT_SYMBOL(mmc_hw_reset); -+/* -+ * mmc_cmdq_hw_reset: Helper API for doing -+ * reset_all of host and reinitializing card. -+ * This must be called with mmc_claim_host -+ * acquired by the caller. -+ */ -+int mmc_cmdq_hw_reset(struct mmc_host *host) -+{ -+ if (!host->bus_ops->power_restore) -+ return -EOPNOTSUPP; -+ -+ mmc_power_cycle(host, host->ocr_avail); -+ mmc_select_voltage(host, host->card->ocr); -+ return host->bus_ops->power_restore(host); -+} -+EXPORT_SYMBOL(mmc_cmdq_hw_reset); - - static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) - { -@@ -2798,16 +3166,27 @@ - mmc_bus_put(host); - - mmc_claim_host(host); -+ host->card_status = MMC_CARD_UNINIT; - if (mmc_card_is_removable(host) && host->ops->get_cd && - host->ops->get_cd(host) == 0) { - mmc_power_off(host); -+ if (host->ops->card_info_save) -+ host->ops->card_info_save(host); - mmc_release_host(host); - goto out; - } - - for (i = 0; i < ARRAY_SIZE(freqs); i++) { -- if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) -+ if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) { -+ host->card_status = MMC_CARD_INIT; -+ if (host->ops->card_info_save) -+ host->ops->card_info_save(host); - break; -+ } else if ((i == (ARRAY_SIZE(freqs) - 1)) || -+ (freqs[i] <= host->f_min)) { -+ host->card_status = MMC_CARD_INIT_FAIL; -+ } -+ - if (freqs[i] <= host->f_min) - break; - } ---- linux-4.9.37/drivers/mmc/core/mmc.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/core/mmc.c 2021-06-07 13:01:33.000000000 +0300 -@@ -528,6 +528,9 @@ - card->ext_csd.man_bkops_en = - (ext_csd[EXT_CSD_BKOPS_EN] & - EXT_CSD_MANUAL_BKOPS_MASK); -+ card->ext_csd.auto_bkops_en = -+ (ext_csd[EXT_CSD_BKOPS_EN] & -+ EXT_CSD_AUTO_BKOPS_MASK) ? 1 : 0; - card->ext_csd.raw_bkops_status = - ext_csd[EXT_CSD_BKOPS_STATUS]; - if (!card->ext_csd.man_bkops_en) -@@ -617,6 +620,21 @@ - card->ext_csd.ffu_capable = - (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) && - !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1); -+ card->ext_csd.cmdq_support = ext_csd[EXT_CSD_CMDQ_SUPPORT]; -+ if (card->ext_csd.cmdq_support) { -+ /* -+ * Queue Depth = N + 1, -+ * see JEDEC JESD84-B51 section 7.4.19 -+ */ -+ card->ext_csd.cmdq_depth = -+ ext_csd[EXT_CSD_CMDQ_DEPTH] + 1; -+ pr_info("%s: CMDQ supported: depth: %d\n", -+ mmc_hostname(card->host), -+ card->ext_csd.cmdq_depth); -+ } -+ } else { -+ card->ext_csd.cmdq_support = 0; -+ card->ext_csd.cmdq_depth = 0; - } - out: - return err; -@@ -1318,6 +1336,9 @@ - - /* Set host controller to HS400 timing and frequency */ - mmc_set_timing(host, MMC_TIMING_MMC_HS400); -+#if defined(CONFIG_MMC_SDHCI_GOKE) || (defined(MODULE) && defined(CONFIG_MMC_SDHCI_GOKE_MODULE)) -+ mmc_set_bus_speed(card); -+#endif - - /* Controller enable enhanced strobe function */ - host->ios.enhanced_strobe = true; -@@ -1466,6 +1487,41 @@ - return mmc_execute_tuning(card); - } - -+static int mmc_select_cmdq(struct mmc_card *card) -+{ -+ struct mmc_host *host = card->host; -+ int ret = 0; -+ -+ if (!host->cmdq_ops) { -+ pr_err("%s: host controller doesn't support CMDQ\n", -+ mmc_hostname(host)); -+ return 0; -+ } -+ -+ ret = mmc_set_blocklen(card, MMC_CARD_CMDQ_BLK_SIZE); -+ if (ret) -+ goto out; -+ -+ ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CMDQ, 1, -+ card->ext_csd.generic_cmd6_time); -+ if (ret) -+ goto out; -+ -+ mmc_card_set_cmdq(card); -+ ret = host->cmdq_ops->enable(card->host); -+ if (ret) { -+ pr_err("%s: failed (%d) enabling CMDQ on host\n", -+ mmc_hostname(host), ret); -+ mmc_card_clr_cmdq(card); -+ ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_CMDQ, 0, -+ card->ext_csd.generic_cmd6_time); -+ goto out; -+ } -+ -+ pr_info_once("%s: CMDQ enabled on card\n", mmc_hostname(host)); -+out: -+ return ret; -+} - /* - * Handle the detection and initialisation of a card. - * -@@ -1690,7 +1746,7 @@ - err = mmc_select_hs400(card); - if (err) - goto free_card; -- } else { -+ } else if (!mmc_card_hs400es(card)) { - /* Select the desired bus width optionally */ - err = mmc_select_bus_width(card); - if (err > 0 && mmc_card_hs(card)) { -@@ -1773,6 +1829,18 @@ - if (!oldcard) - host->card = card; - -+ if (card->ext_csd.cmdq_support && (card->host->caps2 & -+ MMC_CAP2_CMD_QUEUE)) { -+ err = mmc_select_cmdq(card); -+ if (err) { -+ pr_err("%s: selecting CMDQ mode: failed: %d\n", -+ mmc_hostname(card->host), err); -+ card->ext_csd.cmdq_support = 0; -+ oldcard = card; -+ goto err; -+ } -+ } -+ - return 0; - - free_card: -@@ -1928,6 +1996,17 @@ - if (mmc_card_suspended(host->card)) - goto out; - -+ if (host->card->cmdq_init) { -+ BUG_ON(host->cmdq_ctx.active_reqs); -+ -+ err = mmc_cmdq_halt(host, true); -+ if (err) { -+ pr_err("%s: halt: failed: %d\n", __func__, err); -+ goto out; -+ } -+ host->cmdq_ops->disable(host, true); -+ } -+ - if (mmc_card_doing_bkops(host->card)) { - err = mmc_stop_bkops(host->card); - if (err) -@@ -1951,6 +2030,10 @@ - mmc_card_set_suspended(host->card); - } - out: -+ /* Kick CMDQ thread to process any requests came in while suspending */ -+ if (host->card->cmdq_init) -+ wake_up(&host->cmdq_ctx.wait); -+ - mmc_release_host(host); - return err; - } -@@ -2125,6 +2208,7 @@ - if (err) - return err; - -+ host->type = MMC_HOST_TYPE_MMC; - mmc_attach_bus(host, &mmc_ops); - if (host->ocr_avail_mmc) - host->ocr_avail = host->ocr_avail_mmc; ---- linux-4.9.37/drivers/mmc/core/mmc_ops.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/core/mmc_ops.c 2021-06-07 13:01:33.000000000 +0300 -@@ -456,6 +456,45 @@ - } - - /** -+ * mmc_prepare_switch - helper; prepare to modify EXT_CSD register -+ * @card: the MMC card associated with the data transfer -+ * @set: cmd set values -+ * @index: EXT_CSD register index -+ * @value: value to program into EXT_CSD register -+ * @tout_ms: timeout (ms) for operation performed by register write, -+ * timeout of zero implies maximum possible timeout -+ * @use_busy_signal: use the busy signal as response type -+ * -+ * Helper to prepare to modify EXT_CSD register for selected card. -+ */ -+ -+static inline void mmc_prepare_switch(struct mmc_command *cmd, u8 index, -+ u8 value, u8 set, unsigned int tout_ms, -+ bool use_busy_signal) -+{ -+ cmd->opcode = MMC_SWITCH; -+ cmd->arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | -+ (index << 16) | -+ (value << 8) | -+ set; -+ cmd->flags = MMC_CMD_AC; -+ cmd->busy_timeout = tout_ms; -+ if (use_busy_signal) -+ cmd->flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; -+ else -+ cmd->flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; -+} -+ -+int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, u8 value, -+ unsigned int timeout_ms, bool use_busy_signal, -+ bool ignore_timeout) -+{ -+ mmc_prepare_switch(cmd, index, value, set, timeout_ms, use_busy_signal); -+ return 0; -+} -+EXPORT_SYMBOL(__mmc_switch_cmdq_mode); -+ -+/** - * __mmc_switch - modify EXT_CSD register - * @card: the MMC card associated with the data transfer - * @set: cmd set values -@@ -797,3 +836,21 @@ - { - return (card && card->csd.mmca_vsn > CSD_SPEC_VER_3); - } -+ -+int mmc_discard_queue(struct mmc_host *host, u32 tasks) -+{ -+ struct mmc_command cmd = {0}; -+ -+ cmd.opcode = MMC_CMDQ_TASK_MGMT; -+ if (tasks) { -+ cmd.arg = DISCARD_TASK; -+ cmd.arg |= (tasks << 16); -+ } else { -+ cmd.arg = DISCARD_QUEUE; -+ } -+ -+ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; -+ -+ return mmc_wait_for_cmd(host, &cmd, 0); -+} -+EXPORT_SYMBOL(mmc_discard_queue); ---- linux-4.9.37/drivers/mmc/core/mmc_ops.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/core/mmc_ops.h 2021-06-07 13:01:33.000000000 +0300 -@@ -27,6 +27,7 @@ - int mmc_bus_test(struct mmc_card *card, u8 bus_width); - int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); - int mmc_can_ext_csd(struct mmc_card *card); -+int mmc_discard_queue(struct mmc_host *host, u32 tasks); - int mmc_switch_status_error(struct mmc_host *host, u32 status); - int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, - unsigned int timeout_ms, bool use_busy_signal, bool send_status, ---- linux-4.9.37/drivers/mmc/core/sd.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/core/sd.c 2021-06-07 13:01:33.000000000 +0300 -@@ -1236,6 +1236,7 @@ - if (err) - return err; - -+ host->type = MMC_HOST_TYPE_SD; - mmc_attach_bus(host, &mmc_sd_ops); - if (host->ocr_avail_sd) - host->ocr_avail = host->ocr_avail_sd; ---- linux-4.9.37/drivers/mmc/core/sdio.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/core/sdio.c 2021-06-07 13:01:33.000000000 +0300 -@@ -28,6 +28,10 @@ - #include "sdio_ops.h" - #include "sdio_cis.h" - -+#ifdef CONFIG_ARCH_GOKE -+#include "host.h" -+#endif -+ - static int sdio_read_fbr(struct sdio_func *func) - { - int ret; -@@ -158,15 +162,19 @@ - if (mmc_host_uhs(card->host)) { - if (data & SDIO_UHS_DDR50) - card->sw_caps.sd3_bus_mode -- |= SD_MODE_UHS_DDR50; -+ |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50 | -+ SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12; - - if (data & SDIO_UHS_SDR50) - card->sw_caps.sd3_bus_mode -- |= SD_MODE_UHS_SDR50; -+ |= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25 | -+ SD_MODE_UHS_SDR12; - - if (data & SDIO_UHS_SDR104) - card->sw_caps.sd3_bus_mode -- |= SD_MODE_UHS_SDR104; -+ |= SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50 | -+ SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25 | -+ SD_MODE_UHS_SDR12; - } - - ret = mmc_io_rw_direct(card, 0, 0, -@@ -1070,6 +1078,7 @@ - if (err) - return err; - -+ host->type = MMC_HOST_TYPE_SDIO; - mmc_attach_bus(host, &mmc_sdio_ops); - if (host->ocr_avail_sdio) - host->ocr_avail = host->ocr_avail_sdio; -@@ -1173,3 +1182,40 @@ - return err; - } - -+#ifdef CONFIG_ARCH_GOKE -+/* sdio_reset_comm has been fixed in latest kernel/msm.git for Linux -+ * 2.6.27. The implementation prior to that buggy, and needs broadcom's -+ * patch for it*/ -+int sdio_reset_comm(struct mmc_card *card) -+{ -+ struct mmc_host *host = card->host; -+ u32 ocr; -+ u32 rocr; -+ int err; -+ -+ mmc_claim_host(host); -+ mmc_retune_disable(host); -+ mmc_go_idle(host); -+ mmc_set_clock(host, host->f_min); -+ err = mmc_send_io_op_cond(host, 0, &ocr); -+ if (err) -+ goto err; -+ rocr = mmc_select_voltage(host, ocr); -+ if (!rocr) { -+ err = -EINVAL; -+ goto err; -+ } -+ err = mmc_sdio_init_card(host, rocr, card, 0); -+ if (err) -+ goto err; -+ mmc_release_host(host); -+ return 0; -+err: -+ printk("%s: Error resetting SDIO communications (%d)\n", -+ mmc_hostname(host), err); -+ mmc_release_host(host); -+ return err; -+} -+EXPORT_SYMBOL(sdio_reset_comm); -+#endif -+ ---- linux-4.9.37/drivers/mmc/host/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -176,6 +176,15 @@ - - If unsure, say N. - -+config MMC_SDHCI_GOKE -+ tristate "SDHCI support on the Goke SoC" -+ depends on ARCH_GK7205V200 || ARCH_GK7205V300 || ARCH_GK7202V300 || ARCH_GK7605V100 -+ depends on MMC_SDHCI_PLTFM -+ help -+ This selects the SDHCI support for Goke System-on-Chip devices. -+ If you have a controller with this interface, say Y or M here. -+ If unsure, say N. -+ - config MMC_SDHCI_ESDHC_IMX - tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller" - depends on ARCH_MXC -@@ -798,3 +807,17 @@ - Broadcom STB SoCs. - - If unsure, say Y. -+ -+config MMC_CQ_HCI -+ tristate "Command Queue Support" -+ depends on HAS_DMA -+ help -+ This selects the Command Queue Host Controller Interface (CQHCI) -+ support present in host controllers of Qualcomm Technologies, Inc -+ amongst others. -+ This controller supports eMMC devices with command queue support. -+ -+ If you have a controller with this interface, say Y or M here. -+ -+ If unsure, say N. -+ ---- linux-4.9.37/drivers/mmc/host/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -70,6 +70,12 @@ - obj-$(CONFIG_MMC_SDHCI_OF_AT91) += sdhci-of-at91.o - obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o - obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o -+obj-$(CONFIG_MMC_SDHCI_GOKE) += sdhci-proc.o -+obj-$(CONFIG_MMC_CQ_HCI) += sdhci-cmdq.o -+obj-$(CONFIG_ARCH_GK7205V200) += sdhci-gk7205v200.o -+obj-$(CONFIG_ARCH_GK7205V300) += sdhci-gk7205v300.o -+obj-$(CONFIG_ARCH_GK7202V300) += sdhci-gk7202v300.o -+obj-$(CONFIG_ARCH_GK7605V100) += sdhci-gk7605v100.o - obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o - obj-$(CONFIG_MMC_SDHCI_IPROC) += sdhci-iproc.o - obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o ---- linux-4.9.37/drivers/mmc/host/sdhci.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci.c 2021-06-07 13:01:33.000000000 +0300 -@@ -32,6 +32,7 @@ - #include - - #include "sdhci.h" -+#include "sdhci-cmdq.h" - - #define DRIVER_NAME "sdhci" - -@@ -76,8 +77,8 @@ - pr_err(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", - sdhci_readl(host, SDHCI_INT_ENABLE), - sdhci_readl(host, SDHCI_SIGNAL_ENABLE)); -- pr_err(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", -- sdhci_readw(host, SDHCI_ACMD12_ERR), -+ pr_err(DRIVER_NAME ": ACMD err: 0x%08x | Slot int: 0x%08x\n", -+ sdhci_readw(host, SDHCI_AUTO_CMD_ERR), - sdhci_readw(host, SDHCI_SLOT_INT_STATUS)); - pr_err(DRIVER_NAME ": Caps: 0x%08x | Caps_1: 0x%08x\n", - sdhci_readl(host, SDHCI_CAPABILITIES), -@@ -227,7 +228,7 @@ - SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | - SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC | - SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | -- SDHCI_INT_RESPONSE; -+ SDHCI_INT_RESPONSE | SDHCI_INT_ACMD_ERR; - - if (host->tuning_mode == SDHCI_TUNING_MODE_2 || - host->tuning_mode == SDHCI_TUNING_MODE_3) -@@ -240,11 +241,17 @@ - /* force clock reconfiguration */ - host->clock = 0; - mmc->ops->set_ios(mmc, &mmc->ios); -+ } else { -+ if (host->ops->extra_init) -+ host->ops->extra_init(host); - } - } - - static void sdhci_reinit(struct sdhci_host *host) - { -+ if (host->ops->pre_init) -+ host->ops->pre_init(host); -+ - sdhci_init(host, 0); - sdhci_enable_card_detection(host); - } -@@ -522,6 +529,60 @@ - dma_desc->addr_hi = cpu_to_le32((u64)addr >> 32); - } - -+static void sdhci_write_cmd_table(u8 *desc, u32 reg, u32 attr) -+{ -+ __le32 *reg_addr = (__le32 __force *)(desc + 4); -+ __le32 *attr_addr = (__le32 __force *)desc; -+ -+ attr_addr[0] = cpu_to_le32(attr); -+ reg_addr[0] = cpu_to_le32(reg); -+} -+ -+static void sdhci_write_adma3_desc(struct sdhci_host *host, u8 *desc, -+ dma_addr_t addr, unsigned int attr) -+{ -+ __le32 *attr_addr = (__le32 __force *)desc; -+ -+ attr_addr[0] = cpu_to_le32(attr); -+ -+ if (host->flags & SDHCI_USE_64_BIT_DMA) { -+ __le64 *cmd_ddr = (__le64 __force *)(desc + 4); -+ cmd_ddr[0] = cpu_to_le64(addr); -+ } else { -+ __le32 *cmd_ddr = (__le32 __force *)(desc + 4); -+ cmd_ddr[0] = cpu_to_le32(addr); -+ } -+} -+ -+static void sdhci_prep_adma3_desc(struct sdhci_host *host, -+ struct mmc_command *cmd, int flags) -+{ -+ struct mmc_data *data = cmd->data; -+ unsigned int ctrl_2, cmd_xfer, blksz; -+ u16 mode; -+ -+ blksz = SDHCI_MAKE_BLKSZ(0, data->blksz); -+ mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); -+ cmd_xfer = (SDHCI_MAKE_CMD(cmd->opcode, flags) << 16) | mode; -+ -+ sdhci_write_cmd_table(host->cmd_table, data->blocks, ADMA3_CMD_VALID); -+ sdhci_write_cmd_table(host->cmd_table + 0x8, blksz, ADMA3_CMD_VALID); -+ sdhci_write_cmd_table(host->cmd_table + 0x10, -+ cmd->arg, ADMA3_CMD_VALID); -+ sdhci_write_cmd_table(host->cmd_table + 0x18, -+ cmd_xfer, ADMA3_CMD_VALID); -+ sdhci_adma_write_desc(host, host->cmd_table + 0x20, -+ host->adma_addr, 0x0, ADMA2_LINK_VALID); -+ sdhci_write_adma3_desc(host, host->adma3_table, -+ host->cmd_addr, ADMA3_END); -+ -+ ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); -+ ctrl_2 |= SDHCI_CTRL_HOST_VER4_ENABLE; -+ if (host->flags & SDHCI_USE_64_BIT_DMA) -+ ctrl_2 |= SDHCI_CTRL_ADDRESSING_64BIT; -+ sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); -+} -+ - static void sdhci_adma_mark_end(void *desc) - { - struct sdhci_adma2_64_desc *dma_desc = desc; -@@ -589,6 +650,17 @@ - BUG_ON(len > 65536); - - if (len) { -+ /* work around for buffer across 128M boundary, split the buffer */ -+ if (((addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)) + len) > -+ SDHCI_DMA_BOUNDARY_SIZE) { -+ offset = SDHCI_DMA_BOUNDARY_SIZE - -+ (addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)); -+ sdhci_adma_write_desc(host, desc, addr, offset, -+ ADMA2_TRAN_VALID); -+ desc += host->desc_sz; -+ addr += offset; -+ len -= offset; -+ } - /* tran, valid */ - sdhci_adma_write_desc(host, desc, addr, len, - ADMA2_TRAN_VALID); -@@ -855,10 +927,14 @@ - ctrl &= ~SDHCI_CTRL_DMA_MASK; - if ((host->flags & SDHCI_REQ_USE_DMA) && - (host->flags & SDHCI_USE_ADMA)) { -- if (host->flags & SDHCI_USE_64_BIT_DMA) -- ctrl |= SDHCI_CTRL_ADMA64; -- else -- ctrl |= SDHCI_CTRL_ADMA32; -+ if (host->flags & SDHCI_USE_ADMA3) { -+ ctrl |= SDHCI_CTRL_ADMA3; -+ } else { -+ if (host->flags & SDHCI_USE_64_BIT_DMA) -+ ctrl |= SDHCI_CTRL_ADMA64; -+ else -+ ctrl |= SDHCI_CTRL_ADMA32; -+ } - } else { - ctrl |= SDHCI_CTRL_SDMA; - } -@@ -1121,7 +1197,8 @@ - - sdhci_prepare_data(host, cmd); - -- sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); -+ if (!(host->flags & SDHCI_USE_ADMA3) || !cmd->data) -+ sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); - - sdhci_set_transfer_mode(host, cmd); - -@@ -1152,10 +1229,29 @@ - cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) - flags |= SDHCI_CMD_DATA; - -- sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); -+ if (host->flags & SDHCI_USE_ADMA3 && cmd->data) { -+ sdhci_prep_adma3_desc(host, cmd, flags); -+ -+ sdhci_writel(host, (u32)host->adma3_addr, -+ SDHCI_ADMA3_ID_ADDR_LOW); -+ if (host->flags & SDHCI_USE_64_BIT_DMA) -+ sdhci_writel(host, (u32)((u64)host->adma3_addr >> 32), -+ SDHCI_ADMA3_ID_ADDR_HI); -+ } else { -+ sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), -+ SDHCI_COMMAND); -+ } - } - EXPORT_SYMBOL_GPL(sdhci_send_command); - -+#define CMD_ERRORS \ -+ (R1_OUT_OF_RANGE | /* Command argument out of range */ \ -+ R1_ADDRESS_ERROR | /* Misaligned address */ \ -+ R1_BLOCK_LEN_ERROR | /* Transferred block length incorrect */\ -+ R1_WP_VIOLATION | /* Tried to write to protected block */ \ -+ R1_CC_ERROR | /* Card controller error */ \ -+ R1_ERROR) /* General/unknown error */ -+ - static void sdhci_finish_command(struct sdhci_host *host) - { - struct mmc_command *cmd = host->cmd; -@@ -1177,6 +1273,15 @@ - } else { - cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE); - } -+ -+ if (((cmd->flags & MMC_RSP_R1) == MMC_RSP_R1) && -+ ((cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)) { -+ if ((cmd->resp[0] & CMD_ERRORS) && !host->is_tuning) { -+ host->error_count++; -+ cmd->mrq->cmd->error = -EACCES; -+ pr_err("The status of the card is abnormal, cmd->resp[0]: %x", cmd->resp[0]); -+ } -+ } - } - - if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd) -@@ -1430,6 +1535,12 @@ - sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); - if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) - sdhci_runtime_pm_bus_off(host); -+ /* -+ * Controllers need an extra 100ms delay to ensure power off -+ * completely -+ */ -+ msleep(100); -+ - } else { - /* - * Spec says that we should clear the power reg before setting -@@ -1568,13 +1679,9 @@ - static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - { - struct sdhci_host *host = mmc_priv(mmc); -- unsigned long flags; - u8 ctrl; - -- spin_lock_irqsave(&host->lock, flags); -- - if (host->flags & SDHCI_DEVICE_DEAD) { -- spin_unlock_irqrestore(&host->lock, flags); - if (!IS_ERR(mmc->supply.vmmc) && - ios->power_mode == MMC_POWER_OFF) - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); -@@ -1710,7 +1817,9 @@ - } - - /* Re-enable SD Clock */ -- host->ops->set_clock(host, host->clock); -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ clk |= SDHCI_CLOCK_CARD_EN; -+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - } else - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); - -@@ -1723,7 +1832,6 @@ - sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); - - mmiowb(); -- spin_unlock_irqrestore(&host->lock, flags); - } - - static int sdhci_get_cd(struct mmc_host *mmc) -@@ -1846,6 +1954,9 @@ - u16 ctrl; - int ret; - -+ if (host->ops->start_signal_voltage_switch) -+ return host->ops->start_signal_voltage_switch(host, ios); -+ - /* - * Signal Voltage Switching is only applicable for Host Controllers - * v3.00 and above. -@@ -2281,6 +2392,33 @@ - spin_unlock_irqrestore(&host->lock, flags); - } - -+static int sdhci_card_info_save(struct mmc_host *mmc) -+{ -+ struct mmc_card *card = mmc->card; -+ struct sdhci_host *host= mmc_priv(mmc); -+ struct card_info *c_info = &host->c_info; -+ -+ if (!card) { -+ memset(c_info,0,sizeof(struct card_info)); -+ c_info->card_connect = CARD_DISCONNECT; -+ goto out; -+ } -+ -+ c_info->card_type = card->type; -+ c_info->card_state = card->state; -+ -+ c_info->timing = mmc->ios.timing; -+ c_info->card_support_clock = mmc->ios.clock; -+ -+ c_info->sd_bus_speed = card->sd_bus_speed; -+ -+ memcpy(c_info->ssr, card->raw_ssr, ARRAY_SIZE(c_info->ssr)); -+ -+ c_info->card_connect = CARD_CONNECT; -+out: -+ return 0; -+} -+ - static const struct mmc_host_ops sdhci_ops = { - .request = sdhci_request, - .post_req = sdhci_post_req, -@@ -2296,6 +2434,7 @@ - .select_drive_strength = sdhci_select_drive_strength, - .card_event = sdhci_card_event, - .card_busy = sdhci_card_busy, -+ .card_info_save = sdhci_card_info_save, - }; - - /*****************************************************************************\ -@@ -2370,6 +2509,9 @@ - host->pending_reset = false; - } - -+ if (mrq->data && mrq->data->error && !host->is_tuning) -+ host->error_count++; -+ - if (!sdhci_has_requests(host)) - sdhci_led_deactivate(host); - -@@ -2460,17 +2602,32 @@ - */ - if (host->pending_reset) - return; -- pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", -+ -+ /*pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); -- sdhci_dumpregs(host); -+ sdhci_dumpregs(host);*/ -+ - return; - } - - if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | -- SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) { -+ SDHCI_INT_END_BIT | SDHCI_INT_INDEX | -+ SDHCI_INT_ACMD_ERR)) { - if (intmask & SDHCI_INT_TIMEOUT) - host->cmd->error = -ETIMEDOUT; -- else -+ else if (intmask & SDHCI_INT_ACMD_ERR) { -+ u16 acmd_stat = sdhci_readw(host, SDHCI_AUTO_CMD_ERR); -+ -+ if (acmd_stat & (SDHCI_AUTO_CMD12_NOT_EXEC | -+ SDHCI_AUTO_CMD_INDEX_ERR | -+ SDHCI_AUTO_CMD12_NOT_ISSUED)) -+ host->cmd->error = -EIO; -+ else if (acmd_stat & SDHCI_AUTO_CMD_TIMEOUT_ERR) -+ host->cmd->error = -ETIMEDOUT; -+ else -+ host->cmd->error = -EILSEQ; -+ -+ } else - host->cmd->error = -EILSEQ; - - /* -@@ -2533,6 +2690,8 @@ - - static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) - { -+ -+#ifndef SDHCI_GOKE_EDGE_TUNING - u32 command; - - /* CMD19 generates _only_ Buffer Read Ready interrupt */ -@@ -2545,6 +2704,7 @@ - return; - } - } -+#endif - - if (!host->data) { - struct mmc_command *data_cmd = host->data_cmd; -@@ -2584,6 +2744,9 @@ - if (host->pending_reset) - return; - -+ if (host->is_tuning) -+ return; -+ - pr_err("%s: Got data interrupt 0x%08x even though no data operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - sdhci_dumpregs(host); -@@ -2655,6 +2818,58 @@ - } - } - -+#ifdef CONFIG_MMC_CQ_HCI -+static int sdhci_get_cmd_err(u32 intmask) -+{ -+ if (intmask & SDHCI_INT_TIMEOUT) -+ return -ETIMEDOUT; -+ else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT | -+ SDHCI_INT_INDEX)) -+ return -EILSEQ; -+ return 0; -+} -+ -+static int sdhci_get_data_err(u32 intmask) -+{ -+ if (intmask & SDHCI_INT_DATA_TIMEOUT) -+ return -ETIMEDOUT; -+ else if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) -+ return -EILSEQ; -+ else if (intmask & SDHCI_INT_ADMA_ERROR) -+ return -EIO; -+ return 0; -+} -+ -+static irqreturn_t sdhci_cmdq_irq(struct sdhci_host *host, u32 intmask) -+{ -+ int err = 0; -+ u32 mask = 0; -+ irqreturn_t ret; -+ -+ if (intmask & SDHCI_INT_CMD_MASK) -+ err = sdhci_get_cmd_err(intmask); -+ else if (intmask & SDHCI_INT_DATA_MASK) -+ err = sdhci_get_data_err(intmask); -+ -+ ret = cmdq_irq(host->mmc, err); -+ if (err) { -+ /* Clear the error interrupts */ -+ mask = intmask & SDHCI_INT_ERROR_MASK; -+ sdhci_writel(host, mask, SDHCI_INT_STATUS); -+ } -+ return ret; -+ -+} -+ -+#else -+static irqreturn_t sdhci_cmdq_irq(struct sdhci_host *host, u32 intmask) -+{ -+ pr_err("%s: Received cmdq-irq when disabled !!!!\n", -+ mmc_hostname(host->mmc)); -+ return IRQ_NONE; -+} -+#endif -+ - static irqreturn_t sdhci_irq(int irq, void *dev_id) - { - irqreturn_t result = IRQ_NONE; -@@ -2676,6 +2891,19 @@ - } - - do { -+ if (host->mmc->card && mmc_card_cmdq(host->mmc->card) && -+ !mmc_host_halt(host->mmc) && !mmc_host_cq_disable(host->mmc)) { -+ DBG("*** %s: cmdq intr: 0x%08x\n", -+ mmc_hostname(host->mmc), -+ intmask); -+ result = sdhci_cmdq_irq(host, intmask); -+ if (result == IRQ_HANDLED) { -+ mask = intmask & SDHCI_INT_CQE; -+ sdhci_writel(host, mask, SDHCI_INT_STATUS); -+ goto out; -+ } -+ } -+ - /* Clear selected interrupts. */ - mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | - SDHCI_INT_BUS_POWER); -@@ -3093,7 +3321,7 @@ - - override_timeout_clk = host->timeout_clk; - -- if (host->version > SDHCI_SPEC_300) { -+ if (host->version > SDHCI_SPEC_420) { - pr_err("%s: Unknown controller version (%d). You may experience problems.\n", - mmc_hostname(mmc), host->version); - } -@@ -3121,6 +3349,15 @@ - host->flags &= ~SDHCI_USE_ADMA; - } - -+ if ((host->version >= SDHCI_SPEC_400) && -+ (host->caps1 & SDHCI_CAN_DO_ADMA3)) -+ host->flags |= SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE; -+ -+ if ((host->quirks2 & SDHCI_QUIRK2_BROKEN_ADMA3) && -+ (host->flags & SDHCI_USE_ADMA3)) { -+ DBG("Disabling ADMA3 as it is marked broken\n"); -+ host->flags &= ~(SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE); -+ } - /* - * It is assumed that a 64-bit capable device has set a 64-bit DMA mask - * and *must* do 64-bit DMA. A driver has the opportunity to change -@@ -3161,14 +3398,14 @@ - * all multipled by the descriptor size. - */ - if (host->flags & SDHCI_USE_64_BIT_DMA) { -- host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * -- SDHCI_ADMA2_64_DESC_SZ; -- host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; -- } else { -- host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * -- SDHCI_ADMA2_32_DESC_SZ; -+ if (host->flags & SDHCI_HOST_VER4_ENABLE) -+ host->desc_sz = 16; -+ else -+ host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; -+ } else - host->desc_sz = SDHCI_ADMA2_32_DESC_SZ; -- } -+ -+ host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * host->desc_sz; - - host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN; - buf = dma_alloc_coherent(mmc_dev(mmc), host->align_buffer_sz + -@@ -3191,6 +3428,36 @@ - host->adma_table = buf + host->align_buffer_sz; - host->adma_addr = dma + host->align_buffer_sz; - } -+ -+ if (!(host->flags & SDHCI_USE_ADMA)) -+ host->flags &= ~SDHCI_USE_ADMA3; -+ -+ if (host->flags & SDHCI_USE_ADMA3) { -+#define MAX_CMD_NUM 32 -+#define SDHCI_CMD_DESC_SZ 16 -+ if (host->flags & SDHCI_USE_64_BIT_DMA) -+ host->adma3_desc_sz = SDHCI_ADMA3_64_DESC_SZ; -+ else -+ host->adma3_desc_sz = SDHCI_ADMA3_32_DESC_SZ; -+ -+ host->adma3_table_sz = MAX_CMD_NUM * host->adma3_desc_sz; -+ host->cmd_table_sz = MAX_CMD_NUM * -+ (SDHCI_CMD_DESC_SZ + 16); -+ buf = dma_alloc_coherent(mmc_dev(mmc), host->adma3_table_sz + -+ host->cmd_table_sz, &dma, GFP_KERNEL); -+ if (!buf) { -+ pr_warn("%s: Unable to allocate ADMA3 buffers - falling back to standard DMA\n", -+ mmc_hostname(mmc)); -+ host->flags &= ~SDHCI_USE_ADMA3; -+ } else { -+ host->adma3_table = buf; -+ host->adma3_addr = dma; -+ -+ host->cmd_table = buf + host->adma3_desc_sz; -+ host->cmd_addr = dma + host->adma3_desc_sz; -+ } -+ } -+ - } - - /* -@@ -3557,10 +3824,165 @@ - host->adma_table = NULL; - host->align_buffer = NULL; - -+ if (host->adma3_table) -+ dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz + -+ host->cmd_table_sz, host->adma3_table, -+ host->adma3_addr); -+ -+ host->adma3_table = NULL; -+ host->cmd_table = NULL; -+ - return ret; - } - EXPORT_SYMBOL_GPL(sdhci_setup_host); - -+#ifdef CONFIG_MMC_CQ_HCI -+static void sdhci_cmdq_set_transfer_params(struct mmc_host *mmc) -+{ -+ struct sdhci_host *host = mmc_priv(mmc); -+ u8 ctrl; -+ u16 mode, ctrl2; -+ -+ if (host->version >= SDHCI_SPEC_200) { -+ -+ ctrl2 = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ ctrl2 |= SDHCI_CLOCK_PLL_EN; -+ sdhci_writew(host, ctrl2, SDHCI_CLOCK_CONTROL); -+ -+ ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); -+ ctrl2 |= SDHCI_CTRL_ADDRESSING_64BIT; -+ ctrl2 |= SDHCI_CTRL_HOST_VER4_ENABLE; -+ sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2); -+ -+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); -+ ctrl &= ~SDHCI_CTRL_DMA_MASK; -+ if (host->flags & SDHCI_USE_64_BIT_DMA) -+ ctrl |= SDHCI_CTRL_ADMA64; -+ else -+ ctrl |= SDHCI_CTRL_ADMA32; -+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -+ -+ mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); -+ sdhci_writew(host, mode | SDHCI_TRNS_MULTI, SDHCI_TRANSFER_MODE); -+ } -+} -+ -+static void sdhci_cmdq_clear_set_irqs(struct mmc_host *mmc, bool clear) -+{ -+ struct sdhci_host *host = mmc_priv(mmc); -+ u32 ier = 0; -+ -+ ier &= ~SDHCI_INT_ALL_MASK; -+ -+ if (clear) { -+ ier = SDHCI_INT_CQE | SDHCI_INT_ERROR_MASK; -+ sdhci_writel(host, ier, SDHCI_INT_ENABLE); -+ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); -+ } else { -+ ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | -+ SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | -+ SDHCI_INT_INDEX | SDHCI_INT_END_BIT | -+ SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | -+ SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE | -+ SDHCI_INT_ACMD_ERR; -+ sdhci_writel(host, ier, SDHCI_INT_ENABLE); -+ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); -+ } -+} -+ -+static void sdhci_cmdq_set_data_timeout(struct mmc_host *mmc, u32 val) -+{ -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ val = 0xe; -+ sdhci_writeb(host, val, SDHCI_TIMEOUT_CONTROL); -+} -+ -+static void sdhci_cmdq_dump_goke_regs(struct mmc_host *mmc) -+{ -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ sdhci_dumpregs(host); -+} -+ -+static int sdhci_cmdq_init(struct sdhci_host *host, struct mmc_host *mmc, -+ bool dma64) -+{ -+ struct cmdq_host *cq_host; -+ -+ cq_host = kzalloc(sizeof(*cq_host), GFP_KERNEL); -+ if (!cq_host) { -+ pr_err("failed to allocate memory for CMDQ\n"); -+ host->cq_host = NULL; -+ return -ENOMEM; -+ } else { -+ cq_host->mmio = host->ioaddr + 0x180; -+ host->cq_host = cq_host; -+ } -+ -+ return cmdq_init(host->cq_host, mmc, dma64); -+} -+ -+static void sdhci_cmdq_set_block_size(struct mmc_host *mmc) -+{ -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(0, 512), SDHCI_BLOCK_SIZE); -+} -+ -+static void sdhci_cmdq_post_cqe_halt(struct mmc_host *mmc) -+{ -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ sdhci_writel(host, sdhci_readl(host, SDHCI_INT_ENABLE) | -+ SDHCI_INT_RESPONSE, SDHCI_INT_ENABLE); -+ sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS); -+} -+#else -+static void sdhci_cmdq_set_transfer_params(struct mmc_host *mmc) -+{ -+ -+} -+static void sdhci_cmdq_clear_set_irqs(struct mmc_host *mmc, bool clear) -+{ -+ -+} -+ -+static void sdhci_cmdq_set_data_timeout(struct mmc_host *mmc, u32 val) -+{ -+ -+} -+ -+static void sdhci_cmdq_dump_goke_regs(struct mmc_host *mmc) -+{ -+ -+} -+ -+static int sdhci_cmdq_init(struct sdhci_host *host, struct mmc_host *mmc, -+ bool dma64) -+{ -+ return -ENOSYS; -+} -+ -+static void sdhci_cmdq_set_block_size(struct mmc_host *mmc) -+{ -+ -+} -+ -+static void sdhci_cmdq_post_cqe_halt(struct mmc_host *mmc) -+{ -+} -+#endif -+ -+static const struct cmdq_host_ops sdhci_cmdq_ops = { -+ .clear_set_irqs = sdhci_cmdq_clear_set_irqs, -+ .set_data_timeout = sdhci_cmdq_set_data_timeout, -+ .dump_goke_regs = sdhci_cmdq_dump_goke_regs, -+ .set_block_size = sdhci_cmdq_set_block_size, -+ .post_cqe_halt = sdhci_cmdq_post_cqe_halt, -+ .set_transfer_params = sdhci_cmdq_set_transfer_params, -+}; -+ - int __sdhci_add_host(struct sdhci_host *host) - { - struct mmc_host *mmc = host->mmc; -@@ -3605,11 +4027,25 @@ - if (ret) - goto unled; - -- pr_info("%s: SDHCI controller on %s [%s] using %s\n", -+ if (mmc->caps2 & MMC_CAP2_CMD_QUEUE) { -+ bool dma64 = (host->flags & SDHCI_USE_64_BIT_DMA) ? -+ true : false; -+ ret = sdhci_cmdq_init(host, mmc, dma64); -+ if (ret) -+ pr_err("%s: CMDQ init: failed (%d)\n", -+ mmc_hostname(host->mmc), ret); -+ else -+ host->cq_host->ops = &sdhci_cmdq_ops; -+ } -+ -+ pr_info("%s: SDHCI controller on %s [%s] using %s in %s mode\n", - mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), -+ (host->flags & SDHCI_USE_ADMA3) ? "ADMA3" : - (host->flags & SDHCI_USE_ADMA) ? - (host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" : -- (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); -+ ((host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"), -+ ((mmc->caps2 & MMC_CAP2_CMD_QUEUE) && !ret) ? -+ "CMDQ" : "legacy"); - - sdhci_enable_card_detection(host); - -@@ -3635,6 +4071,14 @@ - host->adma_table = NULL; - host->align_buffer = NULL; - -+ if (host->adma3_table) -+ dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz + -+ host->cmd_table_sz, host->adma3_table, -+ host->adma3_addr); -+ -+ host->adma3_table = NULL; -+ host->cmd_table = NULL; -+ - return ret; - } - EXPORT_SYMBOL_GPL(__sdhci_add_host); -@@ -3672,6 +4116,8 @@ - - sdhci_disable_card_detection(host); - -+ free_irq(host->irq, host); -+ - mmc_remove_host(mmc); - - sdhci_led_unregister(host); -@@ -3681,7 +4127,6 @@ - - sdhci_writel(host, 0, SDHCI_INT_ENABLE); - sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); -- free_irq(host->irq, host); - - del_timer_sync(&host->timer); - del_timer_sync(&host->data_timer); -@@ -3698,6 +4143,14 @@ - - host->adma_table = NULL; - host->align_buffer = NULL; -+ -+ if (host->adma3_table) -+ dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz + -+ host->cmd_table_sz, host->adma3_table, -+ host->adma3_addr); -+ -+ host->adma3_table = NULL; -+ host->cmd_table = NULL; - } - - EXPORT_SYMBOL_GPL(sdhci_remove_host); ---- linux-4.9.37/drivers/mmc/host/sdhci-cmdq.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-cmdq.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,1108 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+//#include -+#include -+ -+#include "sdhci-cmdq.h" -+#include "sdhci.h" -+ -+#define DCMD_SLOT 31 -+#define NUM_SLOTS 32 -+ -+/* 1 sec */ -+#define HALT_TIMEOUT_MS 1000 -+ -+static int cmdq_halt_poll(struct mmc_host *mmc, bool halt); -+static int cmdq_halt(struct mmc_host *mmc, bool halt); -+ -+#ifdef CONFIG_PM_RUNTIME -+static int cmdq_runtime_pm_get(struct cmdq_host *host) -+{ -+ return pm_runtime_get_sync(host->mmc->parent); -+} -+static int cmdq_runtime_pm_put(struct cmdq_host *host) -+{ -+ pm_runtime_mark_last_busy(host->mmc->parent); -+ return pm_runtime_put_autosuspend(host->mmc->parent); -+} -+#else -+static inline int cmdq_runtime_pm_get(struct cmdq_host *host) -+{ -+ return 0; -+} -+static inline int cmdq_runtime_pm_put(struct cmdq_host *host) -+{ -+ return 0; -+} -+#endif -+static inline struct mmc_request *get_req_by_tag(struct cmdq_host *cq_host, -+ unsigned int tag) -+{ -+ return cq_host->mrq_slot[tag]; -+} -+ -+static inline u8 *get_desc(struct cmdq_host *cq_host, u8 tag) -+{ -+ return cq_host->desc_base + (tag * cq_host->slot_sz); -+} -+ -+static inline u8 *get_link_desc(struct cmdq_host *cq_host, u8 tag) -+{ -+ u8 *desc = get_desc(cq_host, tag); -+ -+ return desc + cq_host->task_desc_len; -+} -+ -+static inline dma_addr_t get_trans_desc_dma(struct cmdq_host *cq_host, u8 tag) -+{ -+ return cq_host->trans_desc_dma_base + -+ (cq_host->slot_desc_sz * tag); -+} -+ -+static inline u8 *get_trans_desc(struct cmdq_host *cq_host, u8 tag) -+{ -+ return cq_host->trans_desc_base + -+ (cq_host->slot_desc_sz * tag); -+} -+ -+static void setup_trans_desc(struct cmdq_host *cq_host, u8 tag) -+{ -+ u8 *link_temp; -+ dma_addr_t trans_temp; -+ -+ link_temp = get_link_desc(cq_host, tag); -+ trans_temp = get_trans_desc_dma(cq_host, tag); -+ -+ memset(link_temp, 0, cq_host->link_desc_len); -+ if (cq_host->link_desc_len > 8) -+ *(link_temp + 8) = 0; -+ -+ if (tag == DCMD_SLOT) { -+ *link_temp = VALID(0) | ACT(0) | END(1); -+ return; -+ } -+ -+ *link_temp = VALID(1) | ACT(0x6) | END(0); -+ -+ if (cq_host->dma64) { -+ __le64 *data_addr = (__le64 __force *)(link_temp + 4); -+ data_addr[0] = cpu_to_le64(trans_temp); -+ } else { -+ __le32 *data_addr = (__le32 __force *)(link_temp + 4); -+ data_addr[0] = cpu_to_le32(trans_temp); -+ } -+} -+ -+static void cmdq_set_halt_irq(struct cmdq_host *cq_host, bool enable) -+{ -+ u32 ier; -+ -+ ier = cmdq_readl(cq_host, CQISTE); -+ if (enable) { -+ cmdq_writel(cq_host, ier | HALT, CQISTE); -+ cmdq_writel(cq_host, ier | HALT, CQISGE); -+ } else { -+ cmdq_writel(cq_host, ier & ~HALT, CQISTE); -+ cmdq_writel(cq_host, ier & ~HALT, CQISGE); -+ } -+} -+ -+static void cmdq_clear_set_irqs(struct cmdq_host *cq_host, u32 clear, u32 set) -+{ -+ u32 ier; -+ -+ ier = cmdq_readl(cq_host, CQISTE); -+ ier &= ~clear; -+ ier |= set; -+ cmdq_writel(cq_host, ier, CQISTE); -+ cmdq_writel(cq_host, ier, CQISGE); -+ /* ensure the writes are done */ -+ mb(); -+} -+ -+ -+#define DRV_NAME "cmdq-host" -+ -+static void cmdq_dump_task_history(struct cmdq_host *cq_host) -+{ -+ int i; -+ -+ if (likely(!cq_host->mmc->cmdq_thist_enabled)) -+ return; -+ -+ if (!cq_host->thist) { -+ pr_err("%s: %s: CMDQ task history buffer not allocated\n", -+ mmc_hostname(cq_host->mmc), __func__); -+ return; -+ } -+ -+ pr_err("---- Circular Task History ----\n"); -+ pr_err(DRV_NAME ": Last entry index: %d", cq_host->thist_idx - 1); -+ -+ for (i = 0; i < cq_host->num_slots; i++) { -+ pr_err(DRV_NAME ": [%02d]%s Task: 0x%08x | Args: 0x%08x\n", i, -+ (cq_host->thist[i].is_dcmd) ? "DCMD" : "DATA", -+ lower_32_bits(cq_host->thist[i].task), -+ upper_32_bits(cq_host->thist[i].task)); -+ } -+ pr_err("-------------------------\n"); -+} -+ -+static void cmdq_dump_adma_mem(struct cmdq_host *cq_host) -+{ -+ struct mmc_host *mmc = cq_host->mmc; -+ dma_addr_t desc_dma; -+ int tag = 0; -+ unsigned long data_active_reqs = -+ mmc->cmdq_ctx.data_active_reqs; -+ unsigned long desc_size = cq_host->slot_desc_sz; -+ -+ for_each_set_bit(tag, &data_active_reqs, cq_host->num_slots) { -+ desc_dma = get_trans_desc_dma(cq_host, tag); -+ pr_err("%s: %s: tag = %d, trans_dma(phys) = %pad, trans_desc(virt) = 0x%p\n", -+ mmc_hostname(mmc), __func__, tag, -+ &desc_dma, get_trans_desc(cq_host, tag)); -+ print_hex_dump(KERN_ERR, "cmdq-adma:", DUMP_PREFIX_ADDRESS, -+ 32, 8, get_trans_desc(cq_host, tag), -+ (desc_size), false); -+ } -+} -+ -+static void cmdq_dumpregs(struct cmdq_host *cq_host) -+{ -+ struct mmc_host *mmc = cq_host->mmc; -+ -+ pr_err(DRV_NAME ": ========== REGISTER DUMP (%s)==========\n", -+ mmc_hostname(mmc)); -+ -+ pr_err(DRV_NAME ": Caps: 0x%08x | Version: 0x%08x\n", -+ cmdq_readl(cq_host, CQCAP), -+ cmdq_readl(cq_host, CQVER)); -+ pr_err(DRV_NAME ": Queing config: 0x%08x | Queue Ctrl: 0x%08x\n", -+ cmdq_readl(cq_host, CQCFG), -+ cmdq_readl(cq_host, CQCTL)); -+ pr_err(DRV_NAME ": Int stat: 0x%08x | Int enab: 0x%08x\n", -+ cmdq_readl(cq_host, CQIS), -+ cmdq_readl(cq_host, CQISTE)); -+ pr_err(DRV_NAME ": Int sig: 0x%08x | Int Coal: 0x%08x\n", -+ cmdq_readl(cq_host, CQISGE), -+ cmdq_readl(cq_host, CQIC)); -+ pr_err(DRV_NAME ": TDL base: 0x%08x | TDL up32: 0x%08x\n", -+ cmdq_readl(cq_host, CQTDLBA), -+ cmdq_readl(cq_host, CQTDLBAU)); -+ pr_err(DRV_NAME ": Doorbell: 0x%08x | Comp Notif: 0x%08x\n", -+ cmdq_readl(cq_host, CQTDBR), -+ cmdq_readl(cq_host, CQTCN)); -+ pr_err(DRV_NAME ": Dev queue: 0x%08x | Dev Pend: 0x%08x\n", -+ cmdq_readl(cq_host, CQDQS), -+ cmdq_readl(cq_host, CQDPT)); -+ pr_err(DRV_NAME ": Task clr: 0x%08x | Send stat 1: 0x%08x\n", -+ cmdq_readl(cq_host, CQTCLR), -+ cmdq_readl(cq_host, CQSSC1)); -+ pr_err(DRV_NAME ": Send stat 2: 0x%08x | DCMD resp: 0x%08x\n", -+ cmdq_readl(cq_host, CQSSC2), -+ cmdq_readl(cq_host, CQCRDCT)); -+ pr_err(DRV_NAME ": Resp err mask: 0x%08x | Task err: 0x%08x\n", -+ cmdq_readl(cq_host, CQRMEM), -+ cmdq_readl(cq_host, CQTERRI)); -+ pr_err(DRV_NAME ": Resp idx 0x%08x | Resp arg: 0x%08x\n", -+ cmdq_readl(cq_host, CQCRI), -+ cmdq_readl(cq_host, CQCRA)); -+ pr_err(DRV_NAME": Goke cfg 0x%08x\n", -+ cmdq_readl(cq_host, CQ_GOKE_CFG)); -+ pr_err(DRV_NAME ": ===========================================\n"); -+ -+ cmdq_dump_task_history(cq_host); -+ if (cq_host->ops->dump_goke_regs) -+ cq_host->ops->dump_goke_regs(mmc); -+} -+ -+/** -+ * The allocated descriptor table for task, link & transfer descritors -+ * looks like: -+ * |----------| -+ * |task desc | |->|----------| -+ * |----------| | |trans desc| -+ * |link desc-|->| |----------| -+ * |----------| . -+ * . . -+ * no. of slots max-segs -+ * . |----------| -+ * |----------| -+ * The idea here is to create the [task+trans] table and mark & point the -+ * link desc to the transfer desc table on a per slot basis. -+ */ -+static int cmdq_host_alloc_tdl(struct cmdq_host *cq_host) -+{ -+ -+ size_t desc_size; -+ size_t data_size; -+ int i = 0; -+ -+ /* task descriptor can be 64/128 bit irrespective of arch */ -+ if (cq_host->caps & CMDQ_TASK_DESC_SZ_128) { -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCFG) | -+ CQ_TASK_DESC_SZ, CQCFG); -+ cq_host->task_desc_len = 16; -+ } else { -+ cq_host->task_desc_len = 8; -+ } -+ -+ /* -+ * 96 bits length of transfer desc instead of 128 bits which means -+ * ADMA would expect next valid descriptor at the 96th bit -+ * or 128th bit -+ */ -+ if (cq_host->dma64) { -+ if (cq_host->quirks & CMDQ_QUIRK_SHORT_TXFR_DESC_SZ) -+ cq_host->trans_desc_len = 12; -+ else -+ cq_host->trans_desc_len = 16; -+ cq_host->link_desc_len = 16; -+ } else { -+ cq_host->trans_desc_len = 8; -+ cq_host->link_desc_len = 8; -+ } -+ -+ /* total size of a slot: 1 task & 1 transfer (link) */ -+ cq_host->slot_sz = cq_host->task_desc_len + cq_host->link_desc_len; -+ -+ desc_size = cq_host->slot_sz * cq_host->num_slots; -+ -+ cq_host->slot_desc_sz = cq_host->trans_desc_len * -+ cq_host->mmc->max_segs * 2; -+ data_size = cq_host->slot_desc_sz * (cq_host->num_slots - 1); -+ -+ pr_debug("%s: desc_size: %d data_sz: %d slot-sz: %d\n", __func__, -+ (int)desc_size, (int)data_size, cq_host->slot_sz); -+ -+ /* -+ * allocate a dma-mapped chunk of memory for the descriptors -+ * allocate a dma-mapped chunk of memory for link descriptors -+ * setup each link-desc memory offset per slot-number to -+ * the descriptor table. -+ */ -+ cq_host->desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc), -+ desc_size, -+ &cq_host->desc_dma_base, -+ GFP_KERNEL); -+ cq_host->trans_desc_base = dmam_alloc_coherent(mmc_dev(cq_host->mmc), -+ data_size, -+ &cq_host->trans_desc_dma_base, -+ GFP_KERNEL); -+ cq_host->thist = devm_kzalloc(mmc_dev(cq_host->mmc), -+ (sizeof(*cq_host->thist) * -+ cq_host->num_slots), -+ GFP_KERNEL); -+ if (!cq_host->desc_base || !cq_host->trans_desc_base) -+ return -ENOMEM; -+ -+ pr_debug("desc-base: 0x%p trans-base: 0x%p\ndesc_dma 0x%llx trans_dma: 0x%llx\n", -+ cq_host->desc_base, cq_host->trans_desc_base, -+ (unsigned long long)cq_host->desc_dma_base, -+ (unsigned long long) cq_host->trans_desc_dma_base); -+ -+ for (; i < (cq_host->num_slots); i++) -+ setup_trans_desc(cq_host, i); -+ -+ return 0; -+} -+ -+static int cmdq_enable(struct mmc_host *mmc) -+{ -+ int err = 0; -+ u32 cqcfg; -+ bool dcmd_enable = false; -+ struct cmdq_host *cq_host = mmc_cmdq_private(mmc); -+ -+ if (!cq_host || !mmc->card || !mmc_card_cmdq(mmc->card)) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ if (cq_host->enabled) -+ goto out; -+ -+ cmdq_runtime_pm_get(cq_host); -+ cqcfg = cmdq_readl(cq_host, CQCFG); -+ if (cqcfg & 0x1) { -+ pr_info("%s: %s: cq_host is already enabled\n", -+ mmc_hostname(mmc), __func__); -+ WARN_ON(1); -+ goto pm_ref_count; -+ } -+ -+ if (cq_host->quirks & CMDQ_QUIRK_NO_DCMD) -+ dcmd_enable = false; -+ else -+ dcmd_enable = true; -+ -+ cqcfg = ((cq_host->caps & CMDQ_TASK_DESC_SZ_128 ? CQ_TASK_DESC_SZ : 0) | -+ (dcmd_enable ? CQ_DCMD : 0)); -+ -+ cmdq_writel(cq_host, cqcfg, CQCFG); -+ /* enable CQ_HOST */ -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCFG) | CQ_ENABLE, -+ CQCFG); -+ -+ if (!cq_host->desc_base || -+ !cq_host->trans_desc_base) { -+ err = cmdq_host_alloc_tdl(cq_host); -+ if (err) -+ goto pm_ref_count; -+ } -+ -+ cmdq_writel(cq_host, lower_32_bits(cq_host->desc_dma_base), CQTDLBA); -+ cmdq_writel(cq_host, upper_32_bits(cq_host->desc_dma_base), CQTDLBAU); -+ -+ /* -+ * disable all goke interrupts -+ * enable CMDQ interrupts -+ * enable the goke error interrupts -+ */ -+ if (cq_host->ops->clear_set_irqs) -+ cq_host->ops->clear_set_irqs(mmc, true); -+ -+ cmdq_clear_set_irqs(cq_host, 0x0, CQ_INT_ALL); -+ -+ /* cq_host would use this rca to address the card */ -+ cmdq_writel(cq_host, mmc->card->rca, CQSSC2); -+ -+ /* send QSR at lesser intervals than the default */ -+ cmdq_writel(cq_host, SEND_QSR_INTERVAL, CQSSC1); -+ -+ /* enable bkops exception indication */ -+ if (mmc_card_configured_manual_bkops(mmc->card) && -+ !mmc_card_configured_auto_bkops(mmc->card)) -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQRMEM) | CQ_EXCEPTION, -+ CQRMEM); -+ -+ /* ensure the writes are done before enabling CQE */ -+ mb(); -+ -+ cq_host->enabled = true; -+ mmc_host_clr_cq_disable(mmc); -+ -+ if (cq_host->ops->set_transfer_params) -+ cq_host->ops->set_transfer_params(mmc); -+ -+ if (cq_host->ops->set_block_size) -+ cq_host->ops->set_block_size(cq_host->mmc); -+ -+ if (cq_host->ops->set_data_timeout) -+ cq_host->ops->set_data_timeout(mmc, 0xf); -+ -+ if (cq_host->ops->clear_set_dumpregs) -+ cq_host->ops->clear_set_dumpregs(mmc, 1); -+ -+ if (cq_host->ops->enhanced_strobe_mask) -+ cq_host->ops->enhanced_strobe_mask(mmc, true); -+ -+pm_ref_count: -+ cmdq_runtime_pm_put(cq_host); -+out: -+ return err; -+} -+ -+static void cmdq_disable_nosync(struct mmc_host *mmc, bool soft) -+{ -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ -+ if (soft) { -+ cmdq_writel(cq_host, cmdq_readl( -+ cq_host, CQCFG) & ~(CQ_ENABLE), -+ CQCFG); -+ } -+ if (cq_host->ops->enhanced_strobe_mask) -+ cq_host->ops->enhanced_strobe_mask(mmc, false); -+ -+ cq_host->enabled = false; -+ mmc_host_set_cq_disable(mmc); -+} -+ -+static void cmdq_disable(struct mmc_host *mmc, bool soft) -+{ -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ -+ cmdq_runtime_pm_get(cq_host); -+ cmdq_disable_nosync(mmc, soft); -+ cmdq_runtime_pm_put(cq_host); -+} -+ -+static void cmdq_reset(struct mmc_host *mmc, bool soft) -+{ -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ unsigned int cqcfg; -+ unsigned int tdlba; -+ unsigned int tdlbau; -+ unsigned int rca; -+ int ret; -+ -+ cmdq_runtime_pm_get(cq_host); -+ cqcfg = cmdq_readl(cq_host, CQCFG); -+ tdlba = cmdq_readl(cq_host, CQTDLBA); -+ tdlbau = cmdq_readl(cq_host, CQTDLBAU); -+ rca = cmdq_readl(cq_host, CQSSC2); -+ -+ cmdq_disable(mmc, true); -+ -+ if (cq_host->ops->reset) { -+ ret = cq_host->ops->reset(mmc); -+ if (ret) { -+ pr_crit("%s: reset CMDQ controller: failed\n", -+ mmc_hostname(mmc)); -+ BUG(); -+ } -+ } -+ -+ cmdq_writel(cq_host, tdlba, CQTDLBA); -+ cmdq_writel(cq_host, tdlbau, CQTDLBAU); -+ -+ if (cq_host->ops->clear_set_irqs) -+ cq_host->ops->clear_set_irqs(mmc, true); -+ -+ cmdq_clear_set_irqs(cq_host, 0x0, CQ_INT_ALL); -+ -+ /* cq_host would use this rca to address the card */ -+ cmdq_writel(cq_host, rca, CQSSC2); -+ -+ /* ensure the writes are done before enabling CQE */ -+ mb(); -+ -+ cmdq_writel(cq_host, cqcfg, CQCFG); -+ cmdq_runtime_pm_put(cq_host); -+ cq_host->enabled = true; -+ mmc_host_clr_cq_disable(mmc); -+} -+ -+static void cmdq_prep_task_desc(struct mmc_request *mrq, -+ u64 *data, bool intr, bool qbr) -+{ -+ struct mmc_cmdq_req *cmdq_req = mrq->cmdq_req; -+ u32 req_flags = cmdq_req->cmdq_req_flags; -+ -+ pr_debug("%s: %s: data-tag: 0x%08x - dir: %d - prio: %d - cnt: 0x%08x - addr: 0x%llx\n", -+ mmc_hostname(mrq->host), __func__, -+ !!(req_flags & DAT_TAG), !!(req_flags & DIR), -+ !!(req_flags & PRIO), cmdq_req->data.blocks, -+ (u64)mrq->cmdq_req->blk_addr); -+ -+ *data = VALID(1) | -+ END(1) | -+ INT(intr) | -+ ACT(0x5) | -+ FORCED_PROG(!!(req_flags & FORCED_PRG)) | -+ CONTEXT(mrq->cmdq_req->ctx_id) | -+ DATA_TAG(!!(req_flags & DAT_TAG)) | -+ DATA_DIR(!!(req_flags & DIR)) | -+ PRIORITY(!!(req_flags & PRIO)) | -+ QBAR(qbr) | -+ REL_WRITE(!!(req_flags & REL_WR)) | -+ BLK_COUNT(mrq->cmdq_req->data.blocks) | -+ BLK_ADDR((u64)mrq->cmdq_req->blk_addr); -+} -+ -+static int cmdq_dma_map(struct mmc_host *host, struct mmc_request *mrq) -+{ -+ int sg_count; -+ struct mmc_data *data = mrq->data; -+ -+ if (!data) -+ return -EINVAL; -+ -+ sg_count = dma_map_sg(mmc_dev(host), data->sg, -+ data->sg_len, -+ (data->flags & MMC_DATA_WRITE) ? -+ DMA_TO_DEVICE : DMA_FROM_DEVICE); -+ if (!sg_count) { -+ pr_err("%s: sg-len: %d\n", __func__, data->sg_len); -+ return -ENOMEM; -+ } -+ -+ return sg_count; -+} -+ -+static void cmdq_set_tran_desc(u8 *desc, dma_addr_t addr, int len, -+ bool end, bool is_dma64) -+{ -+ __le32 *attr = (__le32 __force *)desc; -+ -+ *attr = (VALID(1) | -+ END(end ? 1 : 0) | -+ INT(0) | -+ ACT(0x4) | -+ DAT_LENGTH(len)); -+ -+ if (is_dma64) { -+ __le64 *dataddr = (__le64 __force *)(desc + 4); -+ -+ dataddr[0] = cpu_to_le64(addr); -+ } else { -+ __le32 *dataddr = (__le32 __force *)(desc + 4); -+ -+ dataddr[0] = cpu_to_le32(addr); -+ } -+} -+ -+static int cmdq_prep_tran_desc(struct mmc_request *mrq, -+ struct cmdq_host *cq_host, int tag) -+{ -+ struct mmc_data *data = mrq->data; -+ int i, sg_count, len; -+ bool end = false; -+ dma_addr_t addr; -+ u8 *desc = NULL; -+ struct scatterlist *sg = NULL; -+ -+ sg_count = cmdq_dma_map(mrq->host, mrq); -+ if (sg_count < 0) { -+ pr_err("%s: %s: unable to map sg lists, %d\n", -+ mmc_hostname(mrq->host), __func__, sg_count); -+ return sg_count; -+ } -+ -+ desc = get_trans_desc(cq_host, tag); -+ memset(desc, 0, cq_host->slot_desc_sz); -+ -+ for_each_sg(data->sg, sg, sg_count, i) { -+ addr = sg_dma_address(sg); -+ len = sg_dma_len(sg); -+ -+ if ((i+1) == sg_count) -+ end = true; -+ /* work around for buffer across 128M boundary, split the buffer */ -+ if (((addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)) + len) > -+ SDHCI_DMA_BOUNDARY_SIZE) { -+ int offset; -+ -+ offset = SDHCI_DMA_BOUNDARY_SIZE - -+ (addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)); -+ cmdq_set_tran_desc(desc, addr, offset, false, cq_host->dma64); -+ desc += cq_host->trans_desc_len; -+ addr += offset; -+ len -= offset; -+ } -+ cmdq_set_tran_desc(desc, addr, len, end, cq_host->dma64); -+ desc += cq_host->trans_desc_len; -+ } -+ -+ pr_debug("%s: req: 0x%p tag: %d calc_trans_des: 0x%p sg-cnt: %d\n", -+ __func__, mrq->req, tag, desc, sg_count); -+ -+ return 0; -+} -+ -+static void cmdq_log_task_desc_history(struct cmdq_host *cq_host, u64 task, -+ bool is_dcmd) -+{ -+ if (likely(!cq_host->mmc->cmdq_thist_enabled)) -+ return; -+ -+ if (!cq_host->thist) { -+ pr_err("%s: %s: CMDQ task history buffer not allocated\n", -+ mmc_hostname(cq_host->mmc), __func__); -+ return; -+ } -+ -+ if (cq_host->thist_idx >= cq_host->num_slots) -+ cq_host->thist_idx = 0; -+ -+ cq_host->thist[cq_host->thist_idx].is_dcmd = is_dcmd; -+ memcpy(&cq_host->thist[cq_host->thist_idx++].task, -+ &task, cq_host->task_desc_len); -+} -+ -+static void cmdq_prep_dcmd_desc(struct mmc_host *mmc, -+ struct mmc_request *mrq) -+{ -+ u64 *task_desc = NULL; -+ u64 data = 0; -+ u8 resp_type; -+ u8 *desc; -+ __le64 *dataddr == NULL; -+ struct cmdq_host *cq_host = mmc_cmdq_private(mmc); -+ u8 timing; -+ -+ if (!(mrq->cmd->flags & MMC_RSP_PRESENT)) { -+ resp_type = 0x0; -+ timing = 0x1; -+ } else { -+ if (mrq->cmd->flags & MMC_RSP_BUSY) { -+ resp_type = 0x3; -+ timing = 0x0; -+ } else { -+ resp_type = 0x2; -+ timing = 0x1; -+ } -+ } -+ -+ task_desc = (__le64 __force *)get_desc(cq_host, cq_host->dcmd_slot); -+ memset(task_desc, 0, cq_host->task_desc_len); -+ data |= (VALID(1) | -+ END(1) | -+ INT(1) | -+ QBAR(1) | -+ ACT(0x5) | -+ CMD_INDEX(mrq->cmd->opcode) | -+ CMD_TIMING(timing) | RESP_TYPE(resp_type)); -+ *task_desc |= data; -+ desc = (u8 *)task_desc; -+ pr_debug("cmdq: dcmd: cmd: %d timing: %d resp: %d\n", -+ mrq->cmd->opcode, timing, resp_type); -+ dataddr = (__le64 __force *)(desc + 4); -+ dataddr[0] = cpu_to_le64((u64)mrq->cmd->arg); -+ cmdq_log_task_desc_history(cq_host, *task_desc, true); -+} -+ -+static int cmdq_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ int err = 0; -+ u64 data = 0; -+ u64 *task_desc = NULL; -+ u32 tag = mrq->cmdq_req->tag; -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ -+ if (!cq_host->enabled) { -+ pr_err("%s: CMDQ host not enabled yet !!!\n", -+ mmc_hostname(mmc)); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ cmdq_runtime_pm_get(cq_host); -+ -+ if (mrq->cmdq_req->cmdq_req_flags & DCMD) { -+ cmdq_prep_dcmd_desc(mmc, mrq); -+ cq_host->mrq_slot[DCMD_SLOT] = mrq; -+ /* DCMD's are always issued on a fixed slot */ -+ tag = DCMD_SLOT; -+ goto ring_doorbell; -+ } -+ -+ if (cq_host->ops->crypto_cfg) { -+ err = cq_host->ops->crypto_cfg(mmc, mrq, tag); -+ if (err) { -+ pr_err("%s: failed to configure crypto: err %d tag %d\n", -+ mmc_hostname(mmc), err, tag); -+ goto out; -+ } -+ } -+ -+ task_desc = (__le64 __force *)get_desc(cq_host, tag); -+ -+ cmdq_prep_task_desc(mrq, &data, 1, -+ (mrq->cmdq_req->cmdq_req_flags & QBR)); -+ *task_desc = cpu_to_le64(data); -+ cmdq_log_task_desc_history(cq_host, *task_desc, false); -+ -+ err = cmdq_prep_tran_desc(mrq, cq_host, tag); -+ if (err) { -+ pr_err("%s: %s: failed to setup tx desc: %d\n", -+ mmc_hostname(mmc), __func__, err); -+ goto out; -+ } -+ -+ cq_host->mrq_slot[tag] = mrq; -+ -+ring_doorbell: -+ /* Ensure the task descriptor list is flushed before ringing doorbell */ -+ wmb(); -+ if (cmdq_readl(cq_host, CQTDBR) & (1 << tag)) { -+ cmdq_dumpregs(cq_host); -+ BUG_ON(1); -+ } -+ cmdq_writel(cq_host, 1 << tag, CQTDBR); -+ /* Commit the doorbell write immediately */ -+ wmb(); -+ -+out: -+ return err; -+} -+ -+static void cmdq_finish_data(struct mmc_host *mmc, unsigned int tag) -+{ -+ struct mmc_request *mrq; -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ -+ mrq = get_req_by_tag(cq_host, tag); -+ if (tag == cq_host->dcmd_slot) -+ mrq->cmd->resp[0] = cmdq_readl(cq_host, CQCRDCT); -+ -+ if (mrq->cmdq_req->cmdq_req_flags & DCMD) -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQ_GOKE_CFG) | -+ CMDQ_SEND_STATUS_TRIGGER, CQ_GOKE_CFG); -+ -+ cmdq_runtime_pm_put(cq_host); -+ if (cq_host->ops->crypto_cfg_reset) -+ cq_host->ops->crypto_cfg_reset(mmc, tag); -+ mrq->done(mrq); -+} -+ -+irqreturn_t cmdq_irq(struct mmc_host *mmc, int err) -+{ -+ u32 status; -+ unsigned long tag = 0, comp_status; -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ unsigned long err_info = 0; -+ struct mmc_request *mrq = NULL; -+ int ret; -+ u32 dbr_set = 0; -+ -+ status = cmdq_readl(cq_host, CQIS); -+ cmdq_writel(cq_host, status, CQIS); -+ -+ if (!status && !err) -+ return IRQ_NONE; -+ -+ if (err || (status & CQIS_RED)) { -+ err_info = cmdq_readl(cq_host, CQTERRI); -+ pr_err("%s: err: %d status: 0x%08x task-err-info (0x%08lx)\n", -+ mmc_hostname(mmc), err, status, err_info); -+ -+ /* -+ * Need to halt CQE in case of error in interrupt context itself -+ * otherwise CQE may proceed with sending CMD to device even if -+ * CQE/card is in error state. -+ * CMDQ error handling will make sure that it is unhalted after -+ * handling all the errors. -+ */ -+ ret = cmdq_halt_poll(mmc, true); -+ if (ret) -+ pr_err("%s: %s: halt failed ret=%d\n", -+ mmc_hostname(mmc), __func__, ret); -+ cmdq_dumpregs(cq_host); -+ -+ if (!err_info) { -+ /* -+ * It may so happen sometimes for few errors(like ADMA) -+ * that HW cannot give CQTERRI info. -+ * Thus below is a HW WA for recovering from such -+ * scenario. -+ * - To halt/disable CQE and do reset_all. -+ * Since there is no way to know which tag would -+ * have caused such error, so check for any first -+ * bit set in doorbell and proceed with an error. -+ */ -+ dbr_set = cmdq_readl(cq_host, CQTDBR); -+ if (!dbr_set) { -+ pr_err("%s: spurious/force error interrupt\n", -+ mmc_hostname(mmc)); -+ cmdq_halt_poll(mmc, false); -+ mmc_host_clr_halt(mmc); -+ return IRQ_HANDLED; -+ } -+ -+ tag = ffs(dbr_set) - 1; -+ pr_err("%s: error tag selected: tag = %lu\n", -+ mmc_hostname(mmc), tag); -+ mrq = get_req_by_tag(cq_host, tag); -+ if (mrq->data) -+ mrq->data->error = err; -+ else -+ mrq->cmd->error = err; -+ /* -+ * Get ADMA descriptor memory in case of ADMA -+ * error for debug. -+ */ -+ if (err == -EIO) -+ cmdq_dump_adma_mem(cq_host); -+ goto skip_cqterri; -+ } -+ -+ if (err_info & CQ_RMEFV) { -+ tag = GET_CMD_ERR_TAG(err_info); -+ pr_err("%s: CMD err tag: %lu\n", __func__, tag); -+ -+ mrq = get_req_by_tag(cq_host, tag); -+ /* CMD44/45/46/47 will not have a valid cmd */ -+ if (mrq->cmd) -+ mrq->cmd->error = err; -+ else -+ mrq->data->error = err; -+ } else if (err_info & CQ_DTEFV) { -+ tag = GET_DAT_ERR_TAG(err_info); -+ pr_err("%s: Dat err tag: %lu\n", __func__, tag); -+ mrq = get_req_by_tag(cq_host, tag); -+ mrq->data->error = err; -+ } -+ -+skip_cqterri: -+ /* -+ * If CQE halt fails then, disable CQE -+ * from processing any further requests -+ */ -+ if (ret) { -+ cmdq_disable_nosync(mmc, true); -+ /* -+ * Enable legacy interrupts as CQE halt has failed. -+ * This is needed to send legacy commands like status -+ * cmd as part of error handling work. -+ */ -+ if (cq_host->ops->clear_set_irqs) -+ cq_host->ops->clear_set_irqs(mmc, false); -+ } -+ -+ /* -+ * CQE detected a reponse error from device -+ * In most cases, this would require a reset. -+ */ -+ if (status & CQIS_RED) { -+ /* -+ * will check if the RED error is due to a bkops -+ * exception once the queue is empty -+ */ -+ BUG_ON(!mmc->card); -+ /*if (mmc_card_configured_manual_bkops(mmc->card) || -+ mmc_card_configured_auto_bkops(mmc->card)) -+ mmc->card->bkops.needs_check = true;*/ -+ -+ mrq->cmdq_req->resp_err = true; -+ pr_err("%s: Response error (0x%08x) from card !!!", -+ mmc_hostname(mmc), status); -+ } else { -+ mrq->cmdq_req->resp_idx = cmdq_readl(cq_host, CQCRI); -+ mrq->cmdq_req->resp_arg = cmdq_readl(cq_host, CQCRA); -+ } -+ -+ cmdq_finish_data(mmc, tag); -+ } -+ -+ if (status & CQIS_TCC) { -+ /* read CQTCN and complete the request */ -+ comp_status = cmdq_readl(cq_host, CQTCN); -+ if (!comp_status) -+ goto out; -+ /* -+ * The CQTCN must be cleared before notifying req completion -+ * to upper layers to avoid missing completion notification -+ * of new requests with the same tag. -+ */ -+ cmdq_writel(cq_host, comp_status, CQTCN); -+ /* -+ * A write memory barrier is necessary to guarantee that CQTCN -+ * gets cleared first before next doorbell for the same tag is -+ * set but that is already achieved by the barrier present -+ * before setting doorbell, hence one is not needed here. -+ */ -+ for_each_set_bit(tag, &comp_status, cq_host->num_slots) { -+ /* complete the corresponding mrq */ -+ pr_debug("%s: completing tag -> %lu\n", -+ mmc_hostname(mmc), tag); -+ cmdq_finish_data(mmc, tag); -+ } -+ } -+ -+ if (status & CQIS_HAC) { -+ if (cq_host->ops->post_cqe_halt) -+ cq_host->ops->post_cqe_halt(mmc); -+ /* halt is completed, wakeup waiting thread */ -+ complete(&cq_host->halt_comp); -+ } -+ -+out: -+ return IRQ_HANDLED; -+} -+EXPORT_SYMBOL(cmdq_irq); -+ -+/* cmdq_halt_poll - Halting CQE using polling method. -+ * @mmc: struct mmc_host -+ * @halt: bool halt -+ * This is used mainly from interrupt context to halt/unhalt -+ * CQE engine. -+ */ -+static int cmdq_halt_poll(struct mmc_host *mmc, bool halt) -+{ -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ int retries = 100; -+ -+ if (!halt) { -+ if (cq_host->ops->set_data_timeout) -+ cq_host->ops->set_data_timeout(mmc, 0xf); -+ if (cq_host->ops->clear_set_irqs) -+ cq_host->ops->clear_set_irqs(mmc, true); -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) & ~HALT, -+ CQCTL); -+ return 0; -+ } -+ -+ cmdq_set_halt_irq(cq_host, false); -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) | HALT, CQCTL); -+ while (retries) { -+ if (!(cmdq_readl(cq_host, CQCTL) & HALT)) { -+ udelay(5); -+ retries--; -+ continue; -+ } else { -+ if (cq_host->ops->post_cqe_halt) -+ cq_host->ops->post_cqe_halt(mmc); -+ /* halt done: re-enable legacy interrupts */ -+ if (cq_host->ops->clear_set_irqs) -+ cq_host->ops->clear_set_irqs(mmc, -+ false); -+ mmc_host_set_halt(mmc); -+ break; -+ } -+ } -+ cmdq_set_halt_irq(cq_host, true); -+ return retries ? 0 : -ETIMEDOUT; -+} -+ -+/* May sleep */ -+static int cmdq_halt(struct mmc_host *mmc, bool halt) -+{ -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ u32 ret = 0; -+ int retries = 3; -+ -+ cmdq_runtime_pm_get(cq_host); -+ if (halt) { -+ while (retries) { -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) | HALT, -+ CQCTL); -+ ret = wait_for_completion_timeout(&cq_host->halt_comp, -+ msecs_to_jiffies(HALT_TIMEOUT_MS)); -+ if (!ret && !(cmdq_readl(cq_host, CQCTL) & HALT)) { -+ retries--; -+ continue; -+ } else { -+ /* halt done: re-enable legacy interrupts */ -+ if (cq_host->ops->clear_set_irqs) -+ cq_host->ops->clear_set_irqs(mmc, -+ false); -+ break; -+ } -+ } -+ ret = retries ? 0 : -ETIMEDOUT; -+ } else { -+ if (cq_host->ops->set_transfer_params) -+ cq_host->ops->set_transfer_params(mmc); -+ if (cq_host->ops->set_block_size) -+ cq_host->ops->set_block_size(mmc); -+ if (cq_host->ops->set_data_timeout) -+ cq_host->ops->set_data_timeout(mmc, 0xf); -+ if (cq_host->ops->clear_set_irqs) -+ cq_host->ops->clear_set_irqs(mmc, true); -+ cmdq_writel(cq_host, cmdq_readl(cq_host, CQCTL) & ~HALT, -+ CQCTL); -+ } -+ cmdq_runtime_pm_put(cq_host); -+ return ret; -+} -+ -+static void cmdq_post_req(struct mmc_host *mmc, int tag, int err) -+{ -+ struct cmdq_host *cq_host = NULL; -+ struct mmc_request *mrq = NULL; -+ struct mmc_data *data = NULL; -+ -+ if (WARN_ON(!mmc)) -+ return; -+ -+ cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ mrq = get_req_by_tag(cq_host, tag); -+ data = mrq->data; -+ -+ if (data) { -+ data->error = err; -+ dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, -+ (data->flags & MMC_DATA_READ) ? -+ DMA_FROM_DEVICE : DMA_TO_DEVICE); -+ if (err) -+ data->bytes_xfered = 0; -+ else -+ data->bytes_xfered = blk_rq_bytes(mrq->req); -+ -+ } -+} -+ -+static void cmdq_dumpstate(struct mmc_host *mmc) -+{ -+ struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc); -+ cmdq_runtime_pm_get(cq_host); -+ cmdq_dumpregs(cq_host); -+ cmdq_runtime_pm_put(cq_host); -+} -+ -+static const struct mmc_cmdq_host_ops cmdq_host_ops = { -+ .enable = cmdq_enable, -+ .disable = cmdq_disable, -+ .request = cmdq_request, -+ .post_req = cmdq_post_req, -+ .halt = cmdq_halt, -+ .reset = cmdq_reset, -+ .dumpstate = cmdq_dumpstate, -+}; -+ -+struct cmdq_host *cmdq_pltfm_init(struct platform_device *pdev) -+{ -+ struct cmdq_host *cq_host = NULL; -+ struct resource *cmdq_memres = NULL; -+ -+ /* check and setup CMDQ interface */ -+ cmdq_memres = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ "cmdq_mem"); -+ if (!cmdq_memres) { -+ dev_dbg(&pdev->dev, "CMDQ not supported\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ cq_host = kzalloc(sizeof(*cq_host), GFP_KERNEL); -+ if (!cq_host) { -+ dev_err(&pdev->dev, "failed to allocate memory for CMDQ\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ cq_host->mmio = devm_ioremap(&pdev->dev, -+ cmdq_memres->start, -+ resource_size(cmdq_memres)); -+ if (!cq_host->mmio) { -+ dev_err(&pdev->dev, "failed to remap cmdq regs\n"); -+ kfree(cq_host); -+ return ERR_PTR(-EBUSY); -+ } -+ dev_dbg(&pdev->dev, "CMDQ ioremap: done\n"); -+ -+ return cq_host; -+} -+EXPORT_SYMBOL(cmdq_pltfm_init); -+ -+int cmdq_init(struct cmdq_host *cq_host, struct mmc_host *mmc, -+ bool dma64) -+{ -+ int err = 0; -+ -+ cq_host->dma64 = dma64; -+ cq_host->mmc = mmc; -+ cq_host->mmc->cmdq_private = cq_host; -+ -+ cq_host->num_slots = NUM_SLOTS; -+ cq_host->dcmd_slot = DCMD_SLOT; -+ -+ mmc->cmdq_ops = &cmdq_host_ops; -+ mmc->num_cq_slots = NUM_SLOTS; -+ mmc->dcmd_cq_slot = DCMD_SLOT; -+ -+ cq_host->mrq_slot = kzalloc(sizeof(cq_host->mrq_slot) * -+ cq_host->num_slots, GFP_KERNEL); -+ if (!cq_host->mrq_slot) -+ return -ENOMEM; -+ -+ init_completion(&cq_host->halt_comp); -+ return err; -+} -+EXPORT_SYMBOL(cmdq_init); ---- linux-4.9.37/drivers/mmc/host/sdhci-cmdq.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-cmdq.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,230 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#ifndef LINUX_MMC_CQ_HCI_H -+#define LINUX_MMC_CQ_HCI_H -+#include -+ -+/* registers */ -+/* version */ -+#define CQVER 0x00 -+/* capabilities */ -+#define CQCAP 0x04 -+/* configuration */ -+#define CQCFG 0x08 -+#define CQ_DCMD 0x00001000 -+#define CQ_TASK_DESC_SZ 0x00000100 -+#define CQ_ENABLE 0x00000001 -+ -+/* control */ -+#define CQCTL 0x0C -+#define CLEAR_ALL_TASKS 0x00000100 -+#define HALT 0x00000001 -+ -+/* interrupt status */ -+#define CQIS 0x10 -+#define CQIS_HAC (1 << 0) -+#define CQIS_TCC (1 << 1) -+#define CQIS_RED (1 << 2) -+#define CQIS_TCL (1 << 3) -+ -+/* interrupt status enable */ -+#define CQISTE 0x14 -+ -+/* interrupt signal enable */ -+#define CQISGE 0x18 -+ -+/* interrupt coalescing */ -+#define CQIC 0x1C -+#define CQIC_ENABLE (1 << 31) -+#define CQIC_RESET (1 << 16) -+#define CQIC_ICCTHWEN (1 << 15) -+#define CQIC_ICCTH(x) ((x & 0x1F) << 8) -+#define CQIC_ICTOVALWEN (1 << 7) -+#define CQIC_ICTOVAL(x) (x & 0x7F) -+ -+/* task list base address */ -+#define CQTDLBA 0x20 -+ -+/* task list base address upper */ -+#define CQTDLBAU 0x24 -+ -+/* door-bell */ -+#define CQTDBR 0x28 -+ -+/* task completion notification */ -+#define CQTCN 0x2C -+ -+/* device queue status */ -+#define CQDQS 0x30 -+ -+/* device pending tasks */ -+#define CQDPT 0x34 -+ -+/* task clear */ -+#define CQTCLR 0x38 -+ -+/* send status config 1 */ -+#define CQSSC1 0x40 -+/* -+ * Value n means CQE would send CMD13 during the transfer of data block -+ * BLOCK_CNT-n -+ */ -+#define SEND_QSR_INTERVAL 0x70001 -+ -+/* send status config 2 */ -+#define CQSSC2 0x44 -+ -+/* response for dcmd */ -+#define CQCRDCT 0x48 -+ -+/* response mode error mask */ -+#define CQRMEM 0x50 -+#define CQ_EXCEPTION (1 << 6) -+ -+/* task error info */ -+#define CQTERRI 0x54 -+ -+/* CQTERRI bit fields */ -+#define CQ_RMECI 0x1F -+#define CQ_RMETI (0x1F << 8) -+#define CQ_RMEFV (1 << 15) -+#define CQ_DTECI (0x3F << 16) -+#define CQ_DTETI (0x1F << 24) -+#define CQ_DTEFV (1 << 31) -+ -+#define GET_CMD_ERR_TAG(__r__) ((__r__ & CQ_RMETI) >> 8) -+#define GET_DAT_ERR_TAG(__r__) ((__r__ & CQ_DTETI) >> 24) -+ -+/* command response index */ -+#define CQCRI 0x58 -+ -+/* command response argument */ -+#define CQCRA 0x5C -+ -+#define CQ_INT_ALL 0xF -+#define CQIC_DEFAULT_ICCTH 31 -+#define CQIC_DEFAULT_ICTOVAL 1 -+ -+/* attribute fields */ -+#define VALID(x) ((x & 1) << 0) -+#define END(x) ((x & 1) << 1) -+#define INT(x) ((x & 1) << 2) -+#define ACT(x) ((x & 0x7) << 3) -+ -+/* data command task descriptor fields */ -+#define FORCED_PROG(x) ((x & 1) << 6) -+#define CONTEXT(x) ((x & 0xF) << 7) -+#define DATA_TAG(x) ((x & 1) << 11) -+#define DATA_DIR(x) ((x & 1) << 12) -+#define PRIORITY(x) ((x & 1) << 13) -+#define QBAR(x) ((x & 1) << 14) -+#define REL_WRITE(x) ((x & 1) << 15) -+#define BLK_COUNT(x) ((x & 0xFFFF) << 16) -+#define BLK_ADDR(x) ((x & 0xFFFFFFFF) << 32) -+ -+/* direct command task descriptor fields */ -+#define CMD_INDEX(x) ((x & 0x3F) << 16) -+#define CMD_TIMING(x) ((x & 1) << 22) -+#define RESP_TYPE(x) ((x & 0x3) << 23) -+ -+/* transfer descriptor fields */ -+#define DAT_LENGTH(x) ((x & 0xFFFF) << 16) -+#define DAT_ADDR_LO(x) ((x & 0xFFFFFFFF) << 32) -+#define DAT_ADDR_HI(x) ((x & 0xFFFFFFFF) << 0) -+ -+#define CQ_GOKE_CFG 0x100 -+#define CMDQ_SEND_STATUS_TRIGGER (1 << 31) -+ -+struct task_history { -+ u64 task; -+ bool is_dcmd; -+}; -+ -+struct cmdq_host { -+ const struct cmdq_host_ops *ops; -+ void __iomem *mmio; -+ struct mmc_host *mmc; -+ -+ /* 64 bit DMA */ -+ bool dma64; -+ int num_slots; -+ -+ u32 dcmd_slot; -+ u32 caps; -+#define CMDQ_TASK_DESC_SZ_128 0x1 -+ -+ u32 quirks; -+#define CMDQ_QUIRK_SHORT_TXFR_DESC_SZ 0x1 -+#define CMDQ_QUIRK_NO_DCMD 0x2 -+ -+ bool enabled; -+ bool halted; -+ bool init_done; -+ -+ u8 *desc_base; -+ -+ /* total descriptor size */ -+ u8 slot_sz; -+ -+ /* 64/128 bit depends on CQCFG */ -+ u8 task_desc_len; -+ -+ /* 64 bit on 32-bit arch, 128 bit on 64-bit */ -+ u8 link_desc_len; -+ -+ u8 *trans_desc_base; -+ /* same length as transfer descriptor */ -+ u8 trans_desc_len; -+ /* descriptor size per slot */ -+ u32 slot_desc_sz; -+ -+ dma_addr_t desc_dma_base; -+ dma_addr_t trans_desc_dma_base; -+ -+ struct task_history *thist; -+ u8 thist_idx; -+ -+ struct completion halt_comp; -+ struct mmc_request **mrq_slot; -+ void *private; -+}; -+ -+struct cmdq_host_ops { -+ void (*set_transfer_params)(struct mmc_host *mmc); -+ void (*set_data_timeout)(struct mmc_host *mmc, u32 val); -+ void (*clear_set_irqs)(struct mmc_host *mmc, bool clear); -+ void (*set_block_size)(struct mmc_host *mmc); -+ void (*dump_goke_regs)(struct mmc_host *mmc); -+ void (*write_l)(struct cmdq_host *host, u32 val, int reg); -+ u32 (*read_l)(struct cmdq_host *host, int reg); -+ void (*clear_set_dumpregs)(struct mmc_host *mmc, bool set); -+ void (*enhanced_strobe_mask)(struct mmc_host *mmc, bool set); -+ int (*reset)(struct mmc_host *mmc); -+ int (*crypto_cfg)(struct mmc_host *mmc, struct mmc_request *mrq, -+ u32 slot); -+ void (*crypto_cfg_reset)(struct mmc_host *mmc, unsigned int slot); -+ void (*post_cqe_halt)(struct mmc_host *mmc); -+}; -+ -+static inline void cmdq_writel(struct cmdq_host *host, u32 val, int reg) -+{ -+ if (unlikely(host->ops && host->ops->write_l)) -+ host->ops->write_l(host, val, reg); -+ else -+ writel_relaxed(val, host->mmio + reg); -+} -+ -+static inline u32 cmdq_readl(struct cmdq_host *host, int reg) -+{ -+ if (unlikely(host->ops && host->ops->read_l)) -+ return host->ops->read_l(host, reg); -+ else -+ return readl_relaxed(host->mmio + reg); -+} -+ -+extern irqreturn_t cmdq_irq(struct mmc_host *mmc, int err); -+extern int cmdq_init(struct cmdq_host *cq_host, struct mmc_host *mmc, -+ bool dma64); -+extern struct cmdq_host *cmdq_pltfm_init(struct platform_device *pdev); -+#endif ---- linux-4.9.37/drivers/mmc/host/sdhci-gk7202v300.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-gk7202v300.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,495 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sdhci-pltfm.h" -+#include "sdhci-proc.h" -+ -+#ifdef CONFIG_MMC_SDHCI_GOKE -+#define PHASE_SCALE 32 -+#define EDGE_TUNING_PHASE_STEP 4 -+#define NOT_FOUND (-1) -+#define MAX_TUNING_NUM 1 -+#define MAX_FREQ 200000000 -+ -+#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 -+ -+#define REG_EMMC_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO0_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO1_DRV_DLL_CTRL 0x220 -+#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ -+#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) -+#define sdio_drv_sel(phase) ((phase) << 24) -+ -+#define REG_EMMC_DRV_DLL_STATUS 0x210 -+#define REG_SDIO0_DRV_DLL_STATUS 0x210 -+#define REG_SDIO1_DRV_DLL_STATUS 0x228 -+#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ -+#define SDIO_DRV_DLL_LOCK BIT(15) -+#define SDIO_DRV_DLL_READY BIT(14) -+ -+#define REG_EMMC_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 -+#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) -+ -+#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c -+#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) -+ -+#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c -+#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) -+#define sdio_samplb_sel(phase) ((phase) << 0) -+ -+#define REG_EMMC_DS_DLL_CTRL 0x200 -+#define EMMC_DS_DLL_MODE_SSEL BIT(13) -+#define EMMC_DS_DLL_SSEL_MASK 0x7f -+ -+#define REG_EMMC_DS180_DLL_CTRL 0x204 -+#define EMMC_DS180_DLL_BYPASS BIT(15) -+#define REG_EMMC_DS180_DLL_STATUS 0x218 -+#define EMMC_DS180_DLL_READY BIT(0) -+ -+#define REG_EMMC_DS_DLL_STATUS 0x214 -+#define EMMC_DS_DLL_READY BIT(0) -+ -+#define REG_EMMC_CLK_CTRL 0x1f4 -+#define REG_SDIO0_CLK_CTRL 0x1f4 -+#define REG_SDIO1_CLK_CTRL 0x22c -+#define REG_SDIO2_CLK_CTRL /* no sdio2 */ -+#define SDIO_CLK_DRV_DLL_RST BIT(29) -+#define SDIO_CLK_CRG_RST BIT(27) -+ -+#define IO_CFG_SR BIT(10) -+#define IO_CFG_PULL_DOWN BIT(9) -+#define IO_CFG_PULL_UP BIT(8) -+#define IO_CFG_DRV_STR_MASK (0xf << 4) -+#define io_cfg_drv_str_sel(str) ((str) << 4) -+#define IO_CFG_PIN_MUX_MASK (0xf << 0) -+#define io_cfg_pin_mux_sel(type) ((type) << 0) -+#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 -+#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 -+ -+#define IO_CFG_EMMC_DATA_LINE_COUNT 4 -+#define REG_CTRL_EMMC_CLK 0x0014 -+#define REG_CTRL_EMMC_CMD 0x0018 -+#define REG_CTRL_EMMC_DATA0 0x001c -+#define REG_CTRL_EMMC_DATA1 0x0028 -+#define REG_CTRL_EMMC_DATA2 0x0024 -+#define REG_CTRL_EMMC_DATA3 0x0020 -+ -+#define REG_CTRL_EMMC_DS 0x0058 -+#define REG_CTRL_EMMC_RST 0x005c -+static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { -+ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, -+ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3 -+}; -+ -+#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO0_CLK 0x0040 -+#define REG_CTRL_SDIO0_CMD 0x0044 -+#define REG_CTRL_SDIO0_DATA0 0x0048 -+#define REG_CTRL_SDIO0_DATA1 0x004C -+#define REG_CTRL_SDIO0_DATA2 0x0050 -+#define REG_CTRL_SDIO0_DATA3 0x0054 -+static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, -+ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 -+}; -+ -+#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO1_CLK 0x0048 -+#define REG_CTRL_SDIO1_CMD 0x004C -+#define REG_CTRL_SDIO1_DATA0 0x0064 -+#define REG_CTRL_SDIO1_DATA1 0x0060 -+#define REG_CTRL_SDIO1_DATA2 0x005C -+#define REG_CTRL_SDIO1_DATA3 0x0058 -+static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, -+ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 -+}; -+ -+struct sdhci_bsp_priv { -+ struct reset_control *crg_rst; -+ struct reset_control *dll_rst; -+ struct reset_control *sampl_rst; /* Not used */ -+ struct regmap *crg_regmap; -+ struct regmap *iocfg_regmap; -+ unsigned int f_max; -+ unsigned int devid; -+ unsigned int drv_phase; -+ unsigned int sampl_phase; -+ unsigned int tuning_phase; -+}; -+ -+static void bsp_mmc_crg_init(struct sdhci_host *host); -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); -+static int sdhci_bsp_parse_dt(struct sdhci_host *host); -+ -+static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) -+{ -+ return sdhci_pltfm_priv(sdhci_priv(host)); -+} -+ -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ u32 ctrl; -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ if (ios->enhanced_strobe) -+ ctrl |= SDHCI_ENH_STROBE_EN; -+ else -+ ctrl &= ~SDHCI_ENH_STROBE_EN; -+ -+ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); -+} -+ -+static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) -+{ -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); -+ struct device_node *np = pdev->dev.of_node; -+ struct clk *clk = NULL; -+ int ret; -+ -+ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { -+ dev_err(&pdev->dev, "get crg_rst failed.\n"); -+ return PTR_ERR(bsp_priv->crg_rst); -+ } -+ -+ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { -+ dev_err(&pdev->dev, "get dll_rst failed.\n"); -+ return PTR_ERR(bsp_priv->dll_rst); -+ } -+ -+ bsp_priv->sampl_rst = NULL; -+ -+ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); -+ if (IS_ERR(bsp_priv->crg_regmap)) { -+ dev_err(&pdev->dev, "get crg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->crg_regmap); -+ } -+ -+ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); -+ if (IS_ERR(bsp_priv->iocfg_regmap)) { -+ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->iocfg_regmap); -+ } -+ -+ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) -+ return -EINVAL; -+ -+ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); -+ if (IS_ERR_OR_NULL(clk)) { -+ dev_err(mmc_dev(host->mmc), "get clk err\n"); -+ return -EINVAL; -+ } -+ -+ pltfm_host->clk = clk; -+ -+ bsp_mmc_crg_init(host); -+ ret = sdhci_bsp_parse_dt(host); -+ if (ret) -+ return ret; -+ -+ /* -+ * Only eMMC has a hw reset, and now eMMC signaling -+ * is fixed to 180 -+ */ -+ if (host->mmc->caps & MMC_CAP_HW_RESET) { -+ host->flags &= ~SDHCI_SIGNALING_330; -+ host->flags |= SDHCI_SIGNALING_180; -+ } -+ -+ /* -+ * We parse the support timings from dts, so we read the -+ * host capabilities early and clear the timing capabilities, -+ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would -+ * not read it again -+ */ -+ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); -+ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); -+ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); -+ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | -+ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); -+ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | -+ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | -+ SDHCI_QUIRK_SINGLE_POWER_WRITE; -+ -+ host->mmc_host_ops.hs400_enhanced_strobe = -+ sdhci_bsp_hs400_enhanced_strobe; -+ -+ mci_host[slot_index++] = host->mmc; -+ -+ return 0; -+} -+ -+static void bsp_wait_ds_dll_lock(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int reg; -+ unsigned int timeout = 20; -+ -+ do { -+ reg = 0; -+ regmap_read(bsp_priv->crg_regmap, -+ REG_EMMC_DS180_DLL_STATUS, ®); -+ if (reg & EMMC_DS180_DLL_READY) -+ return; -+ -+ mdelay(1); -+ timeout--; -+ } while (timeout > 0); -+ -+ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); -+} -+ -+static void bsp_set_ds_dll_delay(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_host_extra_init(struct sdhci_host *host) -+{ -+ unsigned short ctrl; -+ unsigned int mbiiu_ctrl, val; -+ -+ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); -+ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; -+ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); -+ -+ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); -+ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | -+ SDHCI_UNDEFL_INCR_EN); -+ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ -+ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ -+ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); -+ -+ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ val &= ~SDHCI_CMD_DLY_EN; -+ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; -+ val &= ~SDHCI_DOUT_EN_F_EDGE; -+ -+ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); -+ host->error_count = 0; -+} -+ -+static void bsp_set_drv_str(struct regmap *iocfg_regmap, -+ unsigned int offset, unsigned int pull_up, -+ unsigned int pull_down, unsigned int sr, -+ unsigned int drv_str) -+{ -+ unsigned int reg = 0; -+ -+ regmap_read(iocfg_regmap, offset, ®); -+ -+ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | -+ IO_CFG_DRV_STR_MASK | IO_CFG_SR); -+ reg |= (pull_up ? IO_CFG_PULL_UP : 0); -+ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); -+ reg |= (sr ? IO_CFG_SR : 0); -+ reg |= io_cfg_drv_str_sel(drv_str); -+ -+ regmap_write(iocfg_regmap, offset, reg); -+} -+ -+static void bsp_set_emmc_ctrl(struct sdhci_host *host) -+{ -+ unsigned int reg; -+ -+ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ reg |= SDHCI_CARD_IS_EMMC; -+ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); -+} -+ -+ -+static void bsp_set_mmc_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_MMC_HS400: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS200: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ case MMC_TIMING_MMC_DDR52: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ } -+} -+ -+static void bsp_set_sd_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_SD_HS: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ } -+} -+ -+static void bsp_set_sdio_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio1_data_reg[i], 1, 0, 0, 0x6); /* set drv level 6 */ -+} -+ -+static void bsp_set_io_config(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ unsigned int reg = 0; -+ -+ if (devid == 0) { -+ /* For mmc0: eMMC and SD card */ -+ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) -+ bsp_set_mmc_drv(host); -+ -+ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) -+ bsp_set_sd_drv(host); -+ } else { -+ /* For mmc1: sdio wifi */ -+ bsp_set_sdio_drv(host); -+ } -+} -+ -+static void bsp_get_phase(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ if (devid == 0) { -+ /* For eMMC and SD card */ -+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { -+ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { -+ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { -+ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { -+ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } else { -+ /* For SDIO device */ -+ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || -+ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else { -+ /* UHS_SDR12 */ -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } -+} -+ -+static int bsp_support_runtime_pm(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ /* Only enable for mmc0 eMMC and SD card */ -+ if (devid == 0) -+ return 1; -+ else -+ return 0; -+} -+ -+#include "sdhci-goke.c" -+#endif -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/mmc/host/sdhci-gk7205v200.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-gk7205v200.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,495 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sdhci-pltfm.h" -+#include "sdhci-proc.h" -+ -+#ifdef CONFIG_MMC_SDHCI_GOKE -+#define PHASE_SCALE 32 -+#define EDGE_TUNING_PHASE_STEP 4 -+#define NOT_FOUND (-1) -+#define MAX_TUNING_NUM 1 -+#define MAX_FREQ 200000000 -+ -+#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 -+ -+#define REG_EMMC_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO0_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO1_DRV_DLL_CTRL 0x220 -+#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ -+#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) -+#define sdio_drv_sel(phase) ((phase) << 24) -+ -+#define REG_EMMC_DRV_DLL_STATUS 0x210 -+#define REG_SDIO0_DRV_DLL_STATUS 0x210 -+#define REG_SDIO1_DRV_DLL_STATUS 0x228 -+#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ -+#define SDIO_DRV_DLL_LOCK BIT(15) -+#define SDIO_DRV_DLL_READY BIT(14) -+ -+#define REG_EMMC_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 -+#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) -+ -+#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c -+#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) -+ -+#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c -+#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) -+#define sdio_samplb_sel(phase) ((phase) << 0) -+ -+#define REG_EMMC_DS_DLL_CTRL 0x200 -+#define EMMC_DS_DLL_MODE_SSEL BIT(13) -+#define EMMC_DS_DLL_SSEL_MASK 0x7f -+ -+#define REG_EMMC_DS180_DLL_CTRL 0x204 -+#define EMMC_DS180_DLL_BYPASS BIT(15) -+#define REG_EMMC_DS180_DLL_STATUS 0x218 -+#define EMMC_DS180_DLL_READY BIT(0) -+ -+#define REG_EMMC_DS_DLL_STATUS 0x214 -+#define EMMC_DS_DLL_READY BIT(0) -+ -+#define REG_EMMC_CLK_CTRL 0x1f4 -+#define REG_SDIO0_CLK_CTRL 0x1f4 -+#define REG_SDIO1_CLK_CTRL 0x22c -+#define REG_SDIO2_CLK_CTRL /* no sdio2 */ -+#define SDIO_CLK_DRV_DLL_RST BIT(29) -+#define SDIO_CLK_CRG_RST BIT(27) -+ -+#define IO_CFG_SR BIT(10) -+#define IO_CFG_PULL_DOWN BIT(9) -+#define IO_CFG_PULL_UP BIT(8) -+#define IO_CFG_DRV_STR_MASK (0xf << 4) -+#define io_cfg_drv_str_sel(str) ((str) << 4) -+#define IO_CFG_PIN_MUX_MASK (0xf << 0) -+#define io_cfg_pin_mux_sel(type) ((type) << 0) -+#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 -+#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 -+ -+#define IO_CFG_EMMC_DATA_LINE_COUNT 4 -+#define REG_CTRL_EMMC_CLK 0x0014 -+#define REG_CTRL_EMMC_CMD 0x0018 -+#define REG_CTRL_EMMC_DATA0 0x001c -+#define REG_CTRL_EMMC_DATA1 0x0028 -+#define REG_CTRL_EMMC_DATA2 0x0024 -+#define REG_CTRL_EMMC_DATA3 0x0020 -+ -+#define REG_CTRL_EMMC_DS 0x0058 -+#define REG_CTRL_EMMC_RST 0x005c -+static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { -+ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, -+ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3 -+}; -+ -+#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO0_CLK 0x0040 -+#define REG_CTRL_SDIO0_CMD 0x0044 -+#define REG_CTRL_SDIO0_DATA0 0x0048 -+#define REG_CTRL_SDIO0_DATA1 0x004C -+#define REG_CTRL_SDIO0_DATA2 0x0050 -+#define REG_CTRL_SDIO0_DATA3 0x0054 -+static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, -+ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 -+}; -+ -+#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO1_CLK 0x0048 -+#define REG_CTRL_SDIO1_CMD 0x004C -+#define REG_CTRL_SDIO1_DATA0 0x0064 -+#define REG_CTRL_SDIO1_DATA1 0x0060 -+#define REG_CTRL_SDIO1_DATA2 0x005C -+#define REG_CTRL_SDIO1_DATA3 0x0058 -+static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, -+ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 -+}; -+ -+struct sdhci_bsp_priv { -+ struct reset_control *crg_rst; -+ struct reset_control *dll_rst; -+ struct reset_control *sampl_rst; /* Not used */ -+ struct regmap *crg_regmap; -+ struct regmap *iocfg_regmap; -+ unsigned int f_max; -+ unsigned int devid; -+ unsigned int drv_phase; -+ unsigned int sampl_phase; -+ unsigned int tuning_phase; -+}; -+ -+static void bsp_mmc_crg_init(struct sdhci_host *host); -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); -+static int sdhci_bsp_parse_dt(struct sdhci_host *host); -+ -+static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) -+{ -+ return sdhci_pltfm_priv(sdhci_priv(host)); -+} -+ -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ u32 ctrl; -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ if (ios->enhanced_strobe) -+ ctrl |= SDHCI_ENH_STROBE_EN; -+ else -+ ctrl &= ~SDHCI_ENH_STROBE_EN; -+ -+ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); -+} -+ -+static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) -+{ -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); -+ struct device_node *np = pdev->dev.of_node; -+ struct clk *clk = NULL; -+ int ret; -+ -+ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { -+ dev_err(&pdev->dev, "get crg_rst failed.\n"); -+ return PTR_ERR(bsp_priv->crg_rst); -+ } -+ -+ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { -+ dev_err(&pdev->dev, "get dll_rst failed.\n"); -+ return PTR_ERR(bsp_priv->dll_rst); -+ } -+ -+ bsp_priv->sampl_rst = NULL; -+ -+ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); -+ if (IS_ERR(bsp_priv->crg_regmap)) { -+ dev_err(&pdev->dev, "get crg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->crg_regmap); -+ } -+ -+ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); -+ if (IS_ERR(bsp_priv->iocfg_regmap)) { -+ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->iocfg_regmap); -+ } -+ -+ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) -+ return -EINVAL; -+ -+ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); -+ if (IS_ERR_OR_NULL(clk)) { -+ dev_err(mmc_dev(host->mmc), "get clk err\n"); -+ return -EINVAL; -+ } -+ -+ pltfm_host->clk = clk; -+ -+ bsp_mmc_crg_init(host); -+ ret = sdhci_bsp_parse_dt(host); -+ if (ret) -+ return ret; -+ -+ /* -+ * Only eMMC has a hw reset, and now eMMC signaling -+ * is fixed to 180 -+ */ -+ if (host->mmc->caps & MMC_CAP_HW_RESET) { -+ host->flags &= ~SDHCI_SIGNALING_330; -+ host->flags |= SDHCI_SIGNALING_180; -+ } -+ -+ /* -+ * We parse the support timings from dts, so we read the -+ * host capabilities early and clear the timing capabilities, -+ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would -+ * not read it again -+ */ -+ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); -+ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); -+ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); -+ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | -+ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); -+ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | -+ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | -+ SDHCI_QUIRK_SINGLE_POWER_WRITE; -+ -+ host->mmc_host_ops.hs400_enhanced_strobe = -+ sdhci_bsp_hs400_enhanced_strobe; -+ -+ mci_host[slot_index++] = host->mmc; -+ -+ return 0; -+} -+ -+static void bsp_wait_ds_dll_lock(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int reg; -+ unsigned int timeout = 20; -+ -+ do { -+ reg = 0; -+ regmap_read(bsp_priv->crg_regmap, -+ REG_EMMC_DS180_DLL_STATUS, ®); -+ if (reg & EMMC_DS180_DLL_READY) -+ return; -+ -+ mdelay(1); -+ timeout--; -+ } while (timeout > 0); -+ -+ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); -+} -+ -+static void bsp_set_ds_dll_delay(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_host_extra_init(struct sdhci_host *host) -+{ -+ unsigned short ctrl; -+ unsigned int mbiiu_ctrl, val; -+ -+ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); -+ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; -+ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); -+ -+ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); -+ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | -+ SDHCI_UNDEFL_INCR_EN); -+ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ -+ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ -+ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); -+ -+ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ val &= ~SDHCI_CMD_DLY_EN; -+ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; -+ val &= ~SDHCI_DOUT_EN_F_EDGE; -+ -+ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); -+ host->error_count = 0; -+} -+ -+static void bsp_set_drv_str(struct regmap *iocfg_regmap, -+ unsigned int offset, unsigned int pull_up, -+ unsigned int pull_down, unsigned int sr, -+ unsigned int drv_str) -+{ -+ unsigned int reg = 0; -+ -+ regmap_read(iocfg_regmap, offset, ®); -+ -+ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | -+ IO_CFG_DRV_STR_MASK | IO_CFG_SR); -+ reg |= (pull_up ? IO_CFG_PULL_UP : 0); -+ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); -+ reg |= (sr ? IO_CFG_SR : 0); -+ reg |= io_cfg_drv_str_sel(drv_str); -+ -+ regmap_write(iocfg_regmap, offset, reg); -+} -+ -+static void bsp_set_emmc_ctrl(struct sdhci_host *host) -+{ -+ unsigned int reg; -+ -+ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ reg |= SDHCI_CARD_IS_EMMC; -+ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); -+} -+ -+ -+static void bsp_set_mmc_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_MMC_HS400: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS200: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ case MMC_TIMING_MMC_DDR52: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ } -+} -+ -+static void bsp_set_sd_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_SD_HS: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ } -+} -+ -+static void bsp_set_sdio_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio1_data_reg[i], 1, 0, 0, 0x7); /* set drv level 7 */ -+} -+ -+static void bsp_set_io_config(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ unsigned int reg = 0; -+ -+ if (devid == 0) { -+ /* For mmc0: eMMC and SD card */ -+ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) -+ bsp_set_mmc_drv(host); -+ -+ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) -+ bsp_set_sd_drv(host); -+ } else { -+ /* For mmc1: sdio wifi */ -+ bsp_set_sdio_drv(host); -+ } -+} -+ -+static void bsp_get_phase(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ if (devid == 0) { -+ /* For eMMC and SD card */ -+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { -+ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { -+ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { -+ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { -+ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } else { -+ /* For SDIO device */ -+ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || -+ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else { -+ /* UHS_SDR12 */ -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } -+} -+ -+static int bsp_support_runtime_pm(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ /* Only enable for mmc0 eMMC and SD card */ -+ if (devid == 0) -+ return 1; -+ else -+ return 0; -+} -+ -+#include "sdhci-goke.c" -+#endif -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/mmc/host/sdhci-gk7205v300.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-gk7205v300.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,508 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sdhci-pltfm.h" -+#include "sdhci-proc.h" -+ -+#ifdef CONFIG_MMC_SDHCI_GOKE -+#define PHASE_SCALE 32 -+#define EDGE_TUNING_PHASE_STEP 4 -+#define NOT_FOUND (-1) -+#define MAX_TUNING_NUM 1 -+#define MAX_FREQ 200000000 -+ -+#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 -+ -+#define REG_EMMC_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO0_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO1_DRV_DLL_CTRL 0x220 -+#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ -+#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) -+#define sdio_drv_sel(phase) ((phase) << 24) -+ -+#define REG_EMMC_DRV_DLL_STATUS 0x210 -+#define REG_SDIO0_DRV_DLL_STATUS 0x210 -+#define REG_SDIO1_DRV_DLL_STATUS 0x228 -+#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ -+#define SDIO_DRV_DLL_LOCK BIT(15) -+#define SDIO_DRV_DLL_READY BIT(14) -+ -+#define REG_EMMC_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 -+#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) -+ -+#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c -+#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) -+ -+#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c -+#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) -+#define sdio_samplb_sel(phase) ((phase) << 0) -+ -+#define REG_EMMC_DS_DLL_CTRL 0x200 -+#define EMMC_DS_DLL_MODE_SSEL BIT(13) -+#define EMMC_DS_DLL_SSEL_MASK 0x7f -+ -+#define REG_EMMC_DS180_DLL_CTRL 0x204 -+#define EMMC_DS180_DLL_BYPASS BIT(15) -+#define REG_EMMC_DS180_DLL_STATUS 0x218 -+#define EMMC_DS180_DLL_READY BIT(0) -+ -+#define REG_EMMC_DS_DLL_STATUS 0x214 -+#define EMMC_DS_DLL_READY BIT(0) -+ -+#define REG_EMMC_CLK_CTRL 0x1f4 -+#define REG_SDIO0_CLK_CTRL 0x1f4 -+#define REG_SDIO1_CLK_CTRL 0x22c -+#define REG_SDIO2_CLK_CTRL /* no sdio2 */ -+#define SDIO_CLK_DRV_DLL_RST BIT(29) -+#define SDIO_CLK_CRG_RST BIT(27) -+ -+#define IO_CFG_SR BIT(10) -+#define IO_CFG_PULL_DOWN BIT(9) -+#define IO_CFG_PULL_UP BIT(8) -+#define IO_CFG_DRV_STR_MASK (0xf << 4) -+#define io_cfg_drv_str_sel(str) ((str) << 4) -+#define IO_CFG_PIN_MUX_MASK (0xf << 0) -+#define io_cfg_pin_mux_sel(type) ((type) << 0) -+#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 -+#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 -+ -+#define IO_CFG_EMMC_DATA_LINE_COUNT 8 -+#define REG_CTRL_EMMC_CLK 0x0014 -+#define REG_CTRL_EMMC_CMD 0x0018 -+#define REG_CTRL_EMMC_DATA0 0x001c -+#define REG_CTRL_EMMC_DATA1 0x0028 -+#define REG_CTRL_EMMC_DATA2 0x0024 -+#define REG_CTRL_EMMC_DATA3 0x0020 -+#define REG_CTRL_EMMC_DATA4 0x0030 -+#define REG_CTRL_EMMC_DATA5 0x0034 -+#define REG_CTRL_EMMC_DATA6 0x0038 -+#define REG_CTRL_EMMC_DATA7 0x003c -+#define REG_CTRL_EMMC_DS 0x0058 -+#define REG_CTRL_EMMC_RST 0x005c -+static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { -+ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, -+ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3, -+ REG_CTRL_EMMC_DATA4, REG_CTRL_EMMC_DATA5, -+ REG_CTRL_EMMC_DATA6, REG_CTRL_EMMC_DATA7 -+}; -+ -+#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO0_CLK 0x0040 -+#define REG_CTRL_SDIO0_CMD 0x0044 -+#define REG_CTRL_SDIO0_DATA0 0x0048 -+#define REG_CTRL_SDIO0_DATA1 0x004C -+#define REG_CTRL_SDIO0_DATA2 0x0050 -+#define REG_CTRL_SDIO0_DATA3 0x0054 -+static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, -+ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 -+}; -+ -+#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO1_CLK 0x0060 -+#define REG_CTRL_SDIO1_CMD 0x0064 -+#define REG_CTRL_SDIO1_DATA0 0x0068 -+#define REG_CTRL_SDIO1_DATA1 0x006C -+#define REG_CTRL_SDIO1_DATA2 0x0070 -+#define REG_CTRL_SDIO1_DATA3 0x0074 -+static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, -+ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 -+}; -+ -+struct sdhci_bsp_priv { -+ struct reset_control *crg_rst; -+ struct reset_control *dll_rst; -+ struct reset_control *sampl_rst; /* Not used */ -+ struct regmap *crg_regmap; -+ struct regmap *iocfg_regmap; -+ unsigned int f_max; -+ unsigned int devid; -+ unsigned int drv_phase; -+ unsigned int sampl_phase; -+ unsigned int tuning_phase; -+}; -+ -+static void bsp_mmc_crg_init(struct sdhci_host *host); -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); -+static int sdhci_bsp_parse_dt(struct sdhci_host *host); -+ -+static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) -+{ -+ return sdhci_pltfm_priv(sdhci_priv(host)); -+} -+ -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ u32 ctrl; -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ if (ios->enhanced_strobe) -+ ctrl |= SDHCI_ENH_STROBE_EN; -+ else -+ ctrl &= ~SDHCI_ENH_STROBE_EN; -+ -+ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); -+ -+ ctrl = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ if (ios->enhanced_strobe) -+ ctrl |= SDHCI_CMD_DLY_EN; -+ else -+ ctrl &= ~SDHCI_CMD_DLY_EN; -+ -+ sdhci_writel(host, ctrl, SDHCI_MULTI_CYCLE); -+} -+ -+static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) -+{ -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); -+ struct device_node *np = pdev->dev.of_node; -+ struct clk *clk = NULL; -+ int ret; -+ -+ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { -+ dev_err(&pdev->dev, "get crg_rst failed.\n"); -+ return PTR_ERR(bsp_priv->crg_rst); -+ } -+ -+ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { -+ dev_err(&pdev->dev, "get dll_rst failed.\n"); -+ return PTR_ERR(bsp_priv->dll_rst); -+ } -+ -+ bsp_priv->sampl_rst = NULL; -+ -+ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); -+ if (IS_ERR(bsp_priv->crg_regmap)) { -+ dev_err(&pdev->dev, "get crg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->crg_regmap); -+ } -+ -+ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); -+ if (IS_ERR(bsp_priv->iocfg_regmap)) { -+ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->iocfg_regmap); -+ } -+ -+ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) -+ return -EINVAL; -+ -+ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); -+ if (IS_ERR_OR_NULL(clk)) { -+ dev_err(mmc_dev(host->mmc), "get clk err\n"); -+ return -EINVAL; -+ } -+ -+ pltfm_host->clk = clk; -+ -+ bsp_mmc_crg_init(host); -+ ret = sdhci_bsp_parse_dt(host); -+ if (ret) -+ return ret; -+ -+ /* -+ * Only eMMC has a hw reset, and now eMMC signaling -+ * is fixed to 180 -+ */ -+ if (host->mmc->caps & MMC_CAP_HW_RESET) { -+ host->flags &= ~SDHCI_SIGNALING_330; -+ host->flags |= SDHCI_SIGNALING_180; -+ } -+ -+ /* -+ * We parse the support timings from dts, so we read the -+ * host capabilities early and clear the timing capabilities, -+ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would -+ * not read it again -+ */ -+ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); -+ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); -+ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); -+ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | -+ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); -+ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | -+ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | -+ SDHCI_QUIRK_SINGLE_POWER_WRITE; -+ -+ host->mmc_host_ops.hs400_enhanced_strobe = -+ sdhci_bsp_hs400_enhanced_strobe; -+ -+ mci_host[slot_index++] = host->mmc; -+ -+ return 0; -+} -+ -+static void bsp_wait_ds_dll_lock(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int reg; -+ unsigned int timeout = 20; -+ -+ do { -+ reg = 0; -+ regmap_read(bsp_priv->crg_regmap, -+ REG_EMMC_DS180_DLL_STATUS, ®); -+ if (reg & EMMC_DS180_DLL_READY) -+ return; -+ -+ mdelay(1); -+ timeout--; -+ } while (timeout > 0); -+ -+ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); -+} -+ -+static void bsp_set_ds_dll_delay(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_host_extra_init(struct sdhci_host *host) -+{ -+ unsigned short ctrl; -+ unsigned int mbiiu_ctrl, val; -+ -+ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); -+ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; -+ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); -+ -+ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); -+ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | -+ SDHCI_UNDEFL_INCR_EN); -+ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ -+ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ -+ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); -+ -+ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ val &= ~SDHCI_CMD_DLY_EN; -+ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; -+ val &= ~SDHCI_DOUT_EN_F_EDGE; -+ -+ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); -+ host->error_count = 0; -+} -+ -+static void bsp_set_drv_str(struct regmap *iocfg_regmap, -+ unsigned int offset, unsigned int pull_up, -+ unsigned int pull_down, unsigned int sr, -+ unsigned int drv_str) -+{ -+ unsigned int reg = 0; -+ -+ regmap_read(iocfg_regmap, offset, ®); -+ -+ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | -+ IO_CFG_DRV_STR_MASK | IO_CFG_SR); -+ reg |= (pull_up ? IO_CFG_PULL_UP : 0); -+ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); -+ reg |= (sr ? IO_CFG_SR : 0); -+ reg |= io_cfg_drv_str_sel(drv_str); -+ -+ regmap_write(iocfg_regmap, offset, reg); -+} -+ -+static void bsp_set_emmc_ctrl(struct sdhci_host *host) -+{ -+ unsigned int reg; -+ -+ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ reg |= SDHCI_CARD_IS_EMMC; -+ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); -+} -+ -+ -+static void bsp_set_mmc_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_MMC_HS400: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS200: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ case MMC_TIMING_MMC_DDR52: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ } -+} -+ -+static void bsp_set_sd_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_SD_HS: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ } -+} -+ -+static void bsp_set_sdio_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio1_data_reg[i], 1, 0, 0, 0x7); /* set drv level 7 */ -+} -+ -+static void bsp_set_io_config(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ unsigned int reg = 0; -+ -+ if (devid == 0) { -+ /* For mmc0: eMMC and SD card */ -+ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) -+ bsp_set_mmc_drv(host); -+ -+ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) -+ bsp_set_sd_drv(host); -+ } else { -+ /* For mmc1: sdio wifi */ -+ bsp_set_sdio_drv(host); -+ } -+} -+ -+static void bsp_get_phase(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ if (devid == 0) { -+ /* For eMMC and SD card */ -+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { -+ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { -+ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { -+ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { -+ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } else { -+ /* For SDIO device */ -+ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || -+ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else { -+ /* UHS_SDR12 */ -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } -+} -+ -+static int bsp_support_runtime_pm(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ /* Only enable for mmc0 eMMC and SD card */ -+ if (devid == 0) -+ return 1; -+ else -+ return 0; -+} -+ -+#include "sdhci-goke.c" -+#endif -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/mmc/host/sdhci-gk7605v100.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-gk7605v100.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,508 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sdhci-pltfm.h" -+#include "sdhci-proc.h" -+ -+#ifdef CONFIG_MMC_SDHCI_GOKE -+#define PHASE_SCALE 32 -+#define EDGE_TUNING_PHASE_STEP 4 -+#define NOT_FOUND (-1) -+#define MAX_TUNING_NUM 1 -+#define MAX_FREQ 200000000 -+ -+#define GOKE_MMC_AUTOSUSPEND_DELAY_MS 50 -+ -+#define REG_EMMC_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO0_DRV_DLL_CTRL 0x1fc -+#define REG_SDIO1_DRV_DLL_CTRL 0x220 -+#define REG_SDIO2_DRV_DLL_CTRL /* no sdio2 */ -+#define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24) -+#define sdio_drv_sel(phase) ((phase) << 24) -+ -+#define REG_EMMC_DRV_DLL_STATUS 0x210 -+#define REG_SDIO0_DRV_DLL_STATUS 0x210 -+#define REG_SDIO1_DRV_DLL_STATUS 0x228 -+#define REG_SDIO2_DRV_DLL_STATUS /* no sdio2 */ -+#define SDIO_DRV_DLL_LOCK BIT(15) -+#define SDIO_DRV_DLL_READY BIT(14) -+ -+#define REG_EMMC_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO0_SAMPL_DLL_STATUS 0x208 -+#define REG_SDIO1_SAMPL_DLL_STATUS 0x224 -+#define REG_SDIO2_SAMPL_DLL_STATUS /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_READY BIT(0) -+ -+#define REG_EMMC_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO0_SAMPL_DLL_CTRL 0x1f4 -+#define REG_SDIO1_SAMPL_DLL_CTRL 0x22c -+#define REG_SDIO2_SAMPL_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPL_DLL_SLAVE_EN BIT(16) -+ -+#define REG_EMMC_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO0_SAMPLB_DLL_CTRL 0x1f8 -+#define REG_SDIO1_SAMPLB_DLL_CTRL 0x21c -+#define REG_SDIO2_SAMPLB_DLL_CTRL /* no sdio2 */ -+#define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0) -+#define sdio_samplb_sel(phase) ((phase) << 0) -+ -+#define REG_EMMC_DS_DLL_CTRL 0x200 -+#define EMMC_DS_DLL_MODE_SSEL BIT(13) -+#define EMMC_DS_DLL_SSEL_MASK 0x7f -+ -+#define REG_EMMC_DS180_DLL_CTRL 0x204 -+#define EMMC_DS180_DLL_BYPASS BIT(15) -+#define REG_EMMC_DS180_DLL_STATUS 0x218 -+#define EMMC_DS180_DLL_READY BIT(0) -+ -+#define REG_EMMC_DS_DLL_STATUS 0x214 -+#define EMMC_DS_DLL_READY BIT(0) -+ -+#define REG_EMMC_CLK_CTRL 0x1f4 -+#define REG_SDIO0_CLK_CTRL 0x1f4 -+#define REG_SDIO1_CLK_CTRL 0x22c -+#define REG_SDIO2_CLK_CTRL /* no sdio2 */ -+#define SDIO_CLK_DRV_DLL_RST BIT(29) -+#define SDIO_CLK_CRG_RST BIT(27) -+ -+#define IO_CFG_SR BIT(10) -+#define IO_CFG_PULL_DOWN BIT(9) -+#define IO_CFG_PULL_UP BIT(8) -+#define IO_CFG_DRV_STR_MASK (0xf << 4) -+#define io_cfg_drv_str_sel(str) ((str) << 4) -+#define IO_CFG_PIN_MUX_MASK (0xf << 0) -+#define io_cfg_pin_mux_sel(type) ((type) << 0) -+#define IO_CFG_PIN_MUX_TYPE_CLK_EMMC 0x0 -+#define IO_CFG_PIN_MUX_TYPE_CLK_SD 0x1 -+ -+#define IO_CFG_EMMC_DATA_LINE_COUNT 8 -+#define REG_CTRL_EMMC_CLK 0x0014 -+#define REG_CTRL_EMMC_CMD 0x0018 -+#define REG_CTRL_EMMC_DATA0 0x001c -+#define REG_CTRL_EMMC_DATA1 0x0028 -+#define REG_CTRL_EMMC_DATA2 0x0024 -+#define REG_CTRL_EMMC_DATA3 0x0020 -+#define REG_CTRL_EMMC_DATA4 0x0030 -+#define REG_CTRL_EMMC_DATA5 0x0034 -+#define REG_CTRL_EMMC_DATA6 0x0038 -+#define REG_CTRL_EMMC_DATA7 0x003c -+#define REG_CTRL_EMMC_DS 0x0058 -+#define REG_CTRL_EMMC_RST 0x005c -+static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = { -+ REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1, -+ REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3, -+ REG_CTRL_EMMC_DATA4, REG_CTRL_EMMC_DATA5, -+ REG_CTRL_EMMC_DATA6, REG_CTRL_EMMC_DATA7 -+}; -+ -+#define IO_CFG_SDIO0_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO0_CLK 0x0040 -+#define REG_CTRL_SDIO0_CMD 0x0044 -+#define REG_CTRL_SDIO0_DATA0 0x0048 -+#define REG_CTRL_SDIO0_DATA1 0x004C -+#define REG_CTRL_SDIO0_DATA2 0x0050 -+#define REG_CTRL_SDIO0_DATA3 0x0054 -+static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1, -+ REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3 -+}; -+ -+#define IO_CFG_SDIO1_DATA_LINE_COUNT 4 -+#define REG_CTRL_SDIO1_CLK 0x0060 -+#define REG_CTRL_SDIO1_CMD 0x0064 -+#define REG_CTRL_SDIO1_DATA0 0x0068 -+#define REG_CTRL_SDIO1_DATA1 0x006C -+#define REG_CTRL_SDIO1_DATA2 0x0070 -+#define REG_CTRL_SDIO1_DATA3 0x0074 -+static unsigned int io_sdio1_data_reg[IO_CFG_SDIO1_DATA_LINE_COUNT] = { -+ REG_CTRL_SDIO1_DATA0, REG_CTRL_SDIO1_DATA1, -+ REG_CTRL_SDIO1_DATA2, REG_CTRL_SDIO1_DATA3 -+}; -+ -+struct sdhci_bsp_priv { -+ struct reset_control *crg_rst; -+ struct reset_control *dll_rst; -+ struct reset_control *sampl_rst; /* Not used */ -+ struct regmap *crg_regmap; -+ struct regmap *iocfg_regmap; -+ unsigned int f_max; -+ unsigned int devid; -+ unsigned int drv_phase; -+ unsigned int sampl_phase; -+ unsigned int tuning_phase; -+}; -+ -+static void bsp_mmc_crg_init(struct sdhci_host *host); -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); -+static int sdhci_bsp_parse_dt(struct sdhci_host *host); -+ -+static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host) -+{ -+ return sdhci_pltfm_priv(sdhci_priv(host)); -+} -+ -+static void sdhci_bsp_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ u32 ctrl; -+ struct sdhci_host *host = mmc_priv(mmc); -+ -+ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ if (ios->enhanced_strobe) -+ ctrl |= SDHCI_ENH_STROBE_EN; -+ else -+ ctrl &= ~SDHCI_ENH_STROBE_EN; -+ -+ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); -+ -+ ctrl = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ if (ios->enhanced_strobe) -+ ctrl |= SDHCI_CMD_DLY_EN; -+ else -+ ctrl &= ~SDHCI_CMD_DLY_EN; -+ -+ sdhci_writel(host, ctrl, SDHCI_MULTI_CYCLE); -+} -+ -+static int sdhci_bsp_pltfm_init(struct platform_device *pdev, struct sdhci_host *host) -+{ -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); -+ struct device_node *np = pdev->dev.of_node; -+ struct clk *clk = NULL; -+ int ret; -+ -+ bsp_priv->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->crg_rst)) { -+ dev_err(&pdev->dev, "get crg_rst failed.\n"); -+ return PTR_ERR(bsp_priv->crg_rst); -+ } -+ -+ bsp_priv->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); -+ if (IS_ERR_OR_NULL(bsp_priv->dll_rst)) { -+ dev_err(&pdev->dev, "get dll_rst failed.\n"); -+ return PTR_ERR(bsp_priv->dll_rst); -+ } -+ -+ bsp_priv->sampl_rst = NULL; -+ -+ bsp_priv->crg_regmap = syscon_regmap_lookup_by_phandle(np, "crg_regmap"); -+ if (IS_ERR(bsp_priv->crg_regmap)) { -+ dev_err(&pdev->dev, "get crg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->crg_regmap); -+ } -+ -+ bsp_priv->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, "iocfg_regmap"); -+ if (IS_ERR(bsp_priv->iocfg_regmap)) { -+ dev_err(&pdev->dev, "get iocfg regmap failed.\n"); -+ return PTR_ERR(bsp_priv->iocfg_regmap); -+ } -+ -+ if (of_property_read_u32(np, "devid", &bsp_priv->devid)) -+ return -EINVAL; -+ -+ clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); -+ if (IS_ERR_OR_NULL(clk)) { -+ dev_err(mmc_dev(host->mmc), "get clk err\n"); -+ return -EINVAL; -+ } -+ -+ pltfm_host->clk = clk; -+ -+ bsp_mmc_crg_init(host); -+ ret = sdhci_bsp_parse_dt(host); -+ if (ret) -+ return ret; -+ -+ /* -+ * Only eMMC has a hw reset, and now eMMC signaling -+ * is fixed to 180 -+ */ -+ if (host->mmc->caps & MMC_CAP_HW_RESET) { -+ host->flags &= ~SDHCI_SIGNALING_330; -+ host->flags |= SDHCI_SIGNALING_180; -+ } -+ -+ /* -+ * We parse the support timings from dts, so we read the -+ * host capabilities early and clear the timing capabilities, -+ * SDHCI_QUIRK_MISSING_CAPS is set so that sdhci driver would -+ * not read it again -+ */ -+ host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); -+ host->caps &= ~(SDHCI_CAN_DO_HISPD | SDHCI_CAN_VDD_300); -+ host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); -+ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | -+ SDHCI_SUPPORT_DDR50 | SDHCI_CAN_DO_ADMA3); -+ host->quirks |= SDHCI_QUIRK_MISSING_CAPS | -+ SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | -+ SDHCI_QUIRK_SINGLE_POWER_WRITE; -+ -+ host->mmc_host_ops.hs400_enhanced_strobe = -+ sdhci_bsp_hs400_enhanced_strobe; -+ -+ mci_host[slot_index++] = host->mmc; -+ -+ return 0; -+} -+ -+static void bsp_wait_ds_dll_lock(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_wait_ds_180_dll_ready(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int reg; -+ unsigned int timeout = 20; -+ -+ do { -+ reg = 0; -+ regmap_read(bsp_priv->crg_regmap, -+ REG_EMMC_DS180_DLL_STATUS, ®); -+ if (reg & EMMC_DS180_DLL_READY) -+ return; -+ -+ mdelay(1); -+ timeout--; -+ } while (timeout > 0); -+ -+ pr_err("%s: DS 180 DLL master not ready.\n", mmc_hostname(host->mmc)); -+} -+ -+static void bsp_set_ds_dll_delay(struct sdhci_host *host) -+{ -+ /* Do nothing */ -+} -+ -+static void bsp_host_extra_init(struct sdhci_host *host) -+{ -+ unsigned short ctrl; -+ unsigned int mbiiu_ctrl, val; -+ -+ ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL); -+ ctrl &= ~SDHCI_CMD_CONFLIT_CHECK; -+ sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL); -+ -+ mbiiu_ctrl = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL); -+ mbiiu_ctrl &= ~(SDHCI_GM_WR_OSRC_LMT_MASK | SDHCI_GM_RD_OSRC_LMT_MASK | -+ SDHCI_UNDEFL_INCR_EN); -+ mbiiu_ctrl |= (SDHCI_GM_WR_OSRC_LMT_SEL(0x7) | /* set write outstanding 8 (lmt + 1) */ -+ SDHCI_GM_RD_OSRC_LMT_SEL(0x7)); /* set read outstanding 8 (lmt + 1) */ -+ sdhci_writel(host, mbiiu_ctrl, SDHCI_AXI_MBIIU_CTRL); -+ -+ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ val &= ~SDHCI_CMD_DLY_EN; -+ val |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN; -+ val &= ~SDHCI_DOUT_EN_F_EDGE; -+ -+ sdhci_writel(host, val, SDHCI_MULTI_CYCLE); -+ host->error_count = 0; -+} -+ -+static void bsp_set_drv_str(struct regmap *iocfg_regmap, -+ unsigned int offset, unsigned int pull_up, -+ unsigned int pull_down, unsigned int sr, -+ unsigned int drv_str) -+{ -+ unsigned int reg = 0; -+ -+ regmap_read(iocfg_regmap, offset, ®); -+ -+ reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN | -+ IO_CFG_DRV_STR_MASK | IO_CFG_SR); -+ reg |= (pull_up ? IO_CFG_PULL_UP : 0); -+ reg |= (pull_down ? IO_CFG_PULL_DOWN : 0); -+ reg |= (sr ? IO_CFG_SR : 0); -+ reg |= io_cfg_drv_str_sel(drv_str); -+ -+ regmap_write(iocfg_regmap, offset, reg); -+} -+ -+static void bsp_set_emmc_ctrl(struct sdhci_host *host) -+{ -+ unsigned int reg; -+ -+ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); -+ reg |= SDHCI_CARD_IS_EMMC; -+ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); -+} -+ -+ -+static void bsp_set_mmc_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_MMC_HS400: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 0, 0x5); /* set drv level 5 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 0, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS200: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_MMC_HS: -+ bsp_set_emmc_ctrl(host); -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ case MMC_TIMING_MMC_DDR52: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */ -+ for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */ -+ break; -+ } -+} -+ -+static void bsp_set_sd_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ switch (host->timing) { -+ case MMC_TIMING_SD_HS: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ case MMC_TIMING_LEGACY: -+ default: -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */ -+ break; -+ } -+} -+ -+static void bsp_set_sdio_drv(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ int i; -+ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CLK, 0, 1, 1, 0x5); /* set drv level 5 */ -+ bsp_set_drv_str(iocfg_regmap, REG_CTRL_SDIO1_CMD, 1, 0, 0, 0x7); /* set drv level 7 */ -+ for (i = 0; i < IO_CFG_SDIO1_DATA_LINE_COUNT; i++) -+ bsp_set_drv_str(iocfg_regmap, -+ io_sdio1_data_reg[i], 1, 0, 0, 0x7); /* set drv level 7 */ -+} -+ -+static void bsp_set_io_config(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ void *iocfg_regmap = bsp_priv->iocfg_regmap; -+ unsigned int reg = 0; -+ -+ if (devid == 0) { -+ /* For mmc0: eMMC and SD card */ -+ regmap_read(iocfg_regmap, REG_CTRL_EMMC_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_EMMC)) -+ bsp_set_mmc_drv(host); -+ -+ regmap_read(iocfg_regmap, REG_CTRL_SDIO0_CLK, ®); -+ if ((reg & IO_CFG_PIN_MUX_MASK) == -+ io_cfg_pin_mux_sel(IO_CFG_PIN_MUX_TYPE_CLK_SD)) -+ bsp_set_sd_drv(host); -+ } else { -+ /* For mmc1: sdio wifi */ -+ bsp_set_sdio_drv(host); -+ } -+} -+ -+static void bsp_get_phase(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ if (devid == 0) { -+ /* For eMMC and SD card */ -+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { -+ bsp_priv->drv_phase = 9; /* 9 for 101.25 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) { -+ bsp_priv->drv_phase = 23; /* 23 for 258.75 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_SD_HS) { -+ bsp_priv->drv_phase = 20; /* 20 for 225 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_LEGACY) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } else if (host->mmc->ios.timing == MMC_TIMING_MMC_DDR52) { -+ bsp_priv->drv_phase = 8; /* 8 for 90 degree */ -+ bsp_priv->sampl_phase = bsp_priv->tuning_phase; -+ } else { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } else { -+ /* For SDIO device */ -+ if ((host->mmc->ios.timing == MMC_TIMING_SD_HS) || -+ (host->mmc->ios.timing == MMC_TIMING_UHS_SDR25)) { -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 4; /* 4 for 45 degree */ -+ } else { -+ /* UHS_SDR12 */ -+ bsp_priv->drv_phase = 16; /* 16 for 180 degree */ -+ bsp_priv->sampl_phase = 0; /* 0 for 0 degree */ -+ } -+ } -+} -+ -+static int bsp_support_runtime_pm(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ -+ /* Only enable for mmc0 eMMC and SD card */ -+ if (devid == 0) -+ return 1; -+ else -+ return 0; -+} -+ -+#include "sdhci-goke.c" -+#endif -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/mmc/host/sdhci-goke.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-goke.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,714 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+static unsigned int sdhci_bsp_get_max_clk(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ -+ return bsp_priv->f_max; -+} -+ -+static int sdhci_bsp_parse_dt(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ struct device_node *np = host->mmc->parent->of_node; -+ int ret, len; -+ -+ ret = mmc_of_parse(host->mmc); -+ if (ret) -+ return ret; -+ -+ if (of_property_read_u32(np, "max-frequency", &bsp_priv->f_max)) -+ bsp_priv->f_max = MAX_FREQ; -+ -+ if (of_find_property(np, "mmc-cmd-queue", &len)) -+ host->mmc->caps2 |= MMC_CAP2_CMD_QUEUE; -+ -+ if (of_find_property(np, "mmc-broken-cmd23", &len) || -+ (host->mmc->caps2 & MMC_CAP2_CMD_QUEUE)) -+ host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; -+ -+ return 0; -+} -+ -+static void bsp_mmc_crg_init(struct sdhci_host *host) -+{ -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); -+ -+ clk_prepare_enable(pltfm_host->clk); -+ reset_control_assert(bsp_priv->crg_rst); -+ reset_control_assert(bsp_priv->dll_rst); -+ if (bsp_priv->sampl_rst) -+ reset_control_assert(bsp_priv->sampl_rst); -+ -+ udelay(25); /* delay 25us */ -+ reset_control_deassert(bsp_priv->crg_rst); -+ udelay(10); /* delay 10us */ -+} -+ -+static void bsp_set_drv_phase(struct sdhci_host *host, unsigned int phase) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ unsigned int offset[] = { -+ REG_EMMC_DRV_DLL_CTRL, -+ REG_SDIO0_DRV_DLL_CTRL, -+ REG_SDIO1_DRV_DLL_CTRL, -+ REG_SDIO2_DRV_DLL_CTRL -+ }; -+ -+ regmap_write_bits(bsp_priv->crg_regmap, offset[devid], -+ SDIO_DRV_PHASE_SEL_MASK, sdio_drv_sel(phase)); -+} -+ -+static void bsp_set_sampl_phase(struct sdhci_host *host, unsigned int phase) -+{ -+ unsigned int reg; -+ -+ reg = sdhci_readl(host, SDHCI_AT_STAT); -+ reg &= ~SDHCI_PHASE_SEL_MASK; -+ reg |= phase; -+ sdhci_writel(host, reg, SDHCI_AT_STAT); -+} -+ -+static void bsp_disable_card_clk(struct sdhci_host *host) -+{ -+ u16 clk; -+ -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ clk &= ~SDHCI_CLOCK_CARD_EN; -+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -+} -+ -+static void bsp_enable_card_clk(struct sdhci_host *host) -+{ -+ u16 clk; -+ -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ clk |= SDHCI_CLOCK_CARD_EN; -+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -+} -+ -+static void bsp_disable_inter_clk(struct sdhci_host *host) -+{ -+ u16 clk; -+ -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ clk &= ~SDHCI_CLOCK_INT_EN; -+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -+} -+ -+static void bsp_enable_sampl_dll_slave(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ unsigned int offset[] = { -+ REG_EMMC_SAMPL_DLL_CTRL, -+ REG_SDIO0_SAMPL_DLL_CTRL, -+ REG_SDIO1_SAMPL_DLL_CTRL, -+ REG_SDIO2_SAMPL_DLL_CTRL -+ }; -+ -+ regmap_write_bits(bsp_priv->crg_regmap, offset[devid], -+ SDIO_SAMPL_DLL_SLAVE_EN, SDIO_SAMPL_DLL_SLAVE_EN); -+} -+ -+static void bsp_wait_drv_dll_lock(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ unsigned int reg; -+ unsigned int timeout = 20; -+ unsigned int offset[] = { -+ REG_EMMC_DRV_DLL_STATUS, -+ REG_SDIO0_DRV_DLL_STATUS, -+ REG_SDIO1_DRV_DLL_STATUS, -+ REG_SDIO2_DRV_DLL_STATUS -+ }; -+ -+ do { -+ reg = 0; -+ regmap_read(bsp_priv->crg_regmap, offset[devid], ®); -+ if (reg & SDIO_DRV_DLL_LOCK) -+ return; -+ -+ mdelay(1); -+ timeout--; -+ } while (timeout > 0); -+ -+ pr_err("%s: DRV DLL master not locked.\n", mmc_hostname(host->mmc)); -+} -+ -+static void bsp_wait_sampl_dll_slave_ready(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ unsigned int reg; -+ unsigned int timeout = 20; -+ unsigned int offset[] = { -+ REG_EMMC_SAMPL_DLL_STATUS, -+ REG_SDIO0_SAMPL_DLL_STATUS, -+ REG_SDIO1_SAMPL_DLL_STATUS, -+ REG_SDIO2_SAMPL_DLL_STATUS -+ }; -+ -+ do { -+ reg = 0; -+ regmap_read(bsp_priv->crg_regmap, offset[devid], ®); -+ if (reg & SDIO_SAMPL_DLL_SLAVE_READY) -+ return; -+ -+ mdelay(1); -+ timeout--; -+ } while (timeout > 0); -+ -+ pr_err("%s: SAMPL DLL slave not ready.\n", mmc_hostname(host->mmc)); -+} -+ -+static void bsp_enable_sample(struct sdhci_host *host) -+{ -+ unsigned int reg; -+ -+ reg = sdhci_readl(host, SDHCI_AT_CTRL); -+ reg |= SDHCI_SAMPLE_EN; -+ sdhci_writel(host, reg, SDHCI_AT_CTRL); -+} -+ -+static void sdhci_bsp_set_clock(struct sdhci_host *host, unsigned int clock) -+{ -+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -+ struct sdhci_bsp_priv *bsp_priv = sdhci_pltfm_priv(pltfm_host); -+ unsigned long timeout; -+ u16 clk; -+ -+ host->mmc->actual_clock = 0; -+ bsp_disable_card_clk(host); -+ udelay(25); /* delay 25us */ -+ bsp_disable_inter_clk(host); -+ if (clock == 0) -+ return; -+ -+ reset_control_assert(bsp_priv->dll_rst); -+ if (bsp_priv->sampl_rst) -+ reset_control_assert(bsp_priv->sampl_rst); -+ udelay(25); /* delay 25us */ -+ -+ clk_set_rate(pltfm_host->clk, clock); -+ host->mmc->actual_clock = clk_get_rate(pltfm_host->clk); -+ -+ bsp_get_phase(host); -+ bsp_set_drv_phase(host, bsp_priv->drv_phase); -+ bsp_enable_sample(host); -+ bsp_set_sampl_phase(host, bsp_priv->sampl_phase); -+ udelay(25); /* delay 25us */ -+ -+ if (host->mmc->actual_clock > MMC_HIGH_52_MAX_DTR) { -+ bsp_enable_sampl_dll_slave(host); -+ reset_control_deassert(bsp_priv->dll_rst); -+ if (bsp_priv->sampl_rst) -+ reset_control_deassert(bsp_priv->sampl_rst); -+ } -+ -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_PLL_EN; -+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -+ timeout = 20; /* default timeout 20ms */ -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ while (!(clk & SDHCI_CLOCK_INT_STABLE)) { -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ if (timeout == 0) { -+ pr_err("%s: Internal clock never stabilised.\n", -+ mmc_hostname(host->mmc)); -+ return; -+ } -+ timeout--; -+ mdelay(1); -+ } -+ -+ if (host->mmc->actual_clock > MMC_HIGH_52_MAX_DTR) { -+ bsp_wait_drv_dll_lock(host); -+ bsp_wait_sampl_dll_slave_ready(host); -+ } -+ -+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) -+ bsp_wait_ds_180_dll_ready(host); -+ -+ clk |= SDHCI_CLOCK_CARD_EN; -+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -+ udelay(100); /* delay 100us */ -+ -+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { -+ bsp_wait_ds_dll_lock(host); -+ bsp_set_ds_dll_delay(host); -+ } -+} -+ -+static void bsp_select_sampl_phase(struct sdhci_host *host, unsigned int phase) -+{ -+ bsp_disable_card_clk(host); -+ bsp_set_sampl_phase(host, phase); -+ bsp_wait_sampl_dll_slave_ready(host); -+ bsp_enable_card_clk(host); -+ udelay(1); -+} -+ -+static int bsp_send_tuning(struct sdhci_host *host, u32 opcode) -+{ -+ int count, err; -+ -+ count = 0; -+ do { -+ err = mmc_send_tuning(host->mmc, opcode, NULL); -+ if (err) -+ break; -+ -+ count++; -+ } while (count < MAX_TUNING_NUM); -+ -+ return err; -+} -+ -+static void bsp_pre_tuning(struct sdhci_host *host) -+{ -+ sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE); -+ sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, -+ SDHCI_SIGNAL_ENABLE); -+ -+ bsp_wait_drv_dll_lock(host); -+ bsp_enable_sampl_dll_slave(host); -+ bsp_enable_sample(host); -+ host->is_tuning = 1; -+} -+ -+static void bsp_post_tuning(struct sdhci_host *host) -+{ -+ unsigned short ctrl; -+ -+ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); -+ ctrl |= SDHCI_CTRL_TUNED_CLK; -+ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); -+ -+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); -+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ host->is_tuning = 0; -+} -+ -+#ifndef SDHCI_GOKE_EDGE_TUNING -+static int bsp_get_best_sampl(u32 candidates) -+{ -+ int rise = NOT_FOUND; -+ int fall = NOT_FOUND; -+ int win_max_r = NOT_FOUND; -+ int win_max_f = NOT_FOUND; -+ int end_fall = NOT_FOUND; -+ int found = NOT_FOUND; -+ int win_max = 0; -+ int i, win; -+ -+ for (i = 0; i < PHASE_SCALE; i++) { -+ if ((candidates & 0x3) == 0x2) -+ rise = (i + 1) % PHASE_SCALE; -+ -+ if ((candidates & 0x3) == 0x1) { -+ fall = i; -+ if (rise != NOT_FOUND) { -+ win = fall - rise + 1; -+ if (win > win_max) { -+ win_max = win; -+ found = (fall + rise) / 2; /* Get window center by devide 2 */ -+ win_max_r = rise; -+ win_max_f = fall; -+ rise = NOT_FOUND; -+ fall = NOT_FOUND; -+ } -+ } else { -+ end_fall = fall; -+ } -+ } -+ candidates = ror32(candidates, 1); -+ } -+ -+ if (end_fall != NOT_FOUND && rise != NOT_FOUND) { -+ fall = end_fall; -+ if (end_fall < rise) -+ end_fall += PHASE_SCALE; -+ -+ win = end_fall - rise + 1; -+ if (win > win_max) { -+ found = (rise + (win / 2)) % PHASE_SCALE; /* Get window center by devide 2 */ -+ win_max_r = rise; -+ win_max_f = fall; -+ } -+ } -+ -+ if (found != NOT_FOUND) -+ pr_info("valid phase shift [%d, %d] Final Phase:%d\n", -+ win_max_r, win_max_f, found); -+ -+ return found; -+} -+ -+static int sdhci_bsp_exec_tuning(struct sdhci_host *host, u32 opcode) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int sampl; -+ unsigned int candidates = 0; -+ int phase, err; -+ -+ bsp_pre_tuning(host); -+ -+ for (sampl = 0; sampl < PHASE_SCALE; sampl++) { -+ bsp_select_sampl_phase(host, sampl); -+ -+ err = bsp_send_tuning(host, opcode); -+ if (err) -+ pr_debug("send tuning CMD%u fail! phase:%d err:%d\n", -+ opcode, sampl, err); -+ else -+ candidates |= (0x1 << sampl); -+ } -+ -+ pr_info("%s: tuning done! candidates 0x%X: ", -+ mmc_hostname(host->mmc), candidates); -+ -+ phase = bsp_get_best_sampl(candidates); -+ if (phase == NOT_FOUND) { -+ phase = bsp_priv->sampl_phase; -+ pr_err("no valid phase shift! use default %d\n", phase); -+ } -+ -+ bsp_priv->tuning_phase = phase; -+ bsp_select_sampl_phase(host, phase); -+ bsp_post_tuning(host); -+ -+ return 0; -+} -+ -+#else -+static void bsp_enable_edge_tuning(struct sdhci_host *host) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int devid = bsp_priv->devid; -+ unsigned int samplb_offset[] = { -+ REG_EMMC_SAMPLB_DLL_CTRL, -+ REG_SDIO0_SAMPLB_DLL_CTRL, -+ REG_SDIO1_SAMPLB_DLL_CTRL, -+ REG_SDIO2_SAMPLB_DLL_CTRL -+ }; -+ unsigned int reg; -+ -+ regmap_write_bits(bsp_priv->crg_regmap, samplb_offset[devid], -+ SDIO_SAMPLB_DLL_CLK_MASK, sdio_samplb_sel(8)); /* 8 for 180 degree */ -+ -+ reg = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ reg |= SDHCI_EDGE_DETECT_EN; -+ sdhci_writel(host, reg, SDHCI_MULTI_CYCLE); -+} -+ -+static void bsp_disable_edge_tuning(struct sdhci_host *host) -+{ -+ unsigned int reg; -+ -+ reg = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ reg &= ~SDHCI_EDGE_DETECT_EN; -+ sdhci_writel(host, reg, SDHCI_MULTI_CYCLE); -+} -+ -+static int sdhci_bsp_exec_edge_tuning(struct sdhci_host *host, u32 opcode) -+{ -+ struct sdhci_bsp_priv *bsp_priv = sdhci_get_pltfm_priv(host); -+ unsigned int index, val; -+ unsigned int edge_p2f, edge_f2p, start, end, phase; -+ unsigned int fall, rise, fall_updat_flag; -+ unsigned int found = 0; -+ unsigned int prev_found = 0; -+ int prev_err = 0; -+ int err; -+ -+ bsp_pre_tuning(host); -+ bsp_enable_edge_tuning(host); -+ -+ start = 0; -+ end = PHASE_SCALE / EDGE_TUNING_PHASE_STEP; -+ -+ edge_p2f = start; -+ edge_f2p = end; -+ for (index = 0; index <= end; index++) { -+ bsp_select_sampl_phase(host, index * EDGE_TUNING_PHASE_STEP); -+ -+ err = mmc_send_tuning(host->mmc, opcode, NULL); -+ if (!err) { -+ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); -+ found = val & SDHCI_FOUND_EDGE; -+ } else { -+ found = 1; -+ } -+ -+ if (prev_found && !found) -+ edge_f2p = index; -+ else if (!prev_found && found) -+ edge_p2f = index; -+ -+ if ((edge_p2f != start) && (edge_f2p != end)) -+ break; -+ -+ prev_found = found; -+ found = 0; -+ } -+ -+ if ((edge_p2f == start) && (edge_f2p == end)) { -+ pr_err("%s: tuning failed! can not found edge!\n", -+ mmc_hostname(host->mmc)); -+ return -1; -+ } -+ -+ bsp_disable_edge_tuning(host); -+ -+ start = edge_p2f * EDGE_TUNING_PHASE_STEP; -+ end = edge_f2p * EDGE_TUNING_PHASE_STEP; -+ if (end <= start) -+ end += PHASE_SCALE; -+ -+ fall = start; -+ rise = end; -+ fall_updat_flag = 0; -+ for (index = start; index <= end; index++) { -+ bsp_select_sampl_phase(host, index % PHASE_SCALE); -+ -+ err = bsp_send_tuning(host, opcode); -+ if (err) -+ pr_debug("send tuning CMD%u fail! phase:%d err:%d\n", -+ opcode, index, err); -+ -+ if (err && index == start) { -+ if (!fall_updat_flag) { -+ fall_updat_flag = 1; -+ fall = start; -+ } -+ } else { -+ if (!prev_err && err) { -+ if (!fall_updat_flag) { -+ fall_updat_flag = 1; -+ fall = index; -+ } -+ } -+ } -+ -+ -+ if (prev_err && !err) -+ rise = index; -+ -+ if (err && index == end) -+ rise = end; -+ -+ -+ prev_err = err; -+ } -+ -+ phase = ((fall + rise) / 2 + PHASE_SCALE / 2) % PHASE_SCALE; /* Get window center by divide 2 */ -+ -+ pr_info("%s: tuning done! valid phase shift [%d, %d] Final Phase:%d\n", -+ mmc_hostname(host->mmc), rise % PHASE_SCALE, -+ fall % PHASE_SCALE, phase); -+ -+ bsp_priv->tuning_phase = phase; -+ bsp_select_sampl_phase(host, phase); -+ bsp_post_tuning(host); -+ -+ return 0; -+} -+#endif -+ -+static void sdhci_bsp_set_uhs_signaling(struct sdhci_host *host, unsigned timing) -+{ -+ sdhci_set_uhs_signaling(host, timing); -+ host->timing = timing; -+ -+ /* Goke add set io config here to set pin drv strength */ -+ bsp_set_io_config(host); -+} -+ -+static void sdhci_bsp_hw_reset(struct sdhci_host *host) -+{ -+ sdhci_writel(host, 0x0, SDHCI_EMMC_HW_RESET); -+ udelay(10); /* delay 10us */ -+ sdhci_writel(host, 0x1, SDHCI_EMMC_HW_RESET); -+ udelay(200); /* delay 200us */ -+} -+ -+/* -+ * This api is for wifi driver rescan the sdio device, -+ * ugly but it is needed -+ */ -+int bsp_sdio_rescan(int slot) -+{ -+ struct mmc_host *mmc = mci_host[slot]; -+ -+ if (mmc == NULL) { -+ pr_err("invalid mmc, please check the argument\n"); -+ return -EINVAL; -+ } -+ -+ mmc_detect_change(mmc, 0); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(bsp_sdio_rescan); -+ -+static const struct sdhci_ops sdhci_bsp_ops = { -+ .get_max_clock = sdhci_bsp_get_max_clk, -+ .set_clock = sdhci_bsp_set_clock, -+ .set_bus_width = sdhci_set_bus_width, -+ .reset = sdhci_reset, -+ .set_uhs_signaling = sdhci_bsp_set_uhs_signaling, -+ .hw_reset = sdhci_bsp_hw_reset, -+ -+#ifdef SDHCI_GOKE_EDGE_TUNING -+ .platform_execute_tuning = sdhci_bsp_exec_edge_tuning, -+#else -+ .platform_execute_tuning = sdhci_bsp_exec_tuning, -+#endif -+ .pre_init = bsp_mmc_crg_init, -+ .extra_init = bsp_host_extra_init, -+}; -+ -+static const struct sdhci_pltfm_data sdhci_bsp_pdata = { -+ .ops = &sdhci_bsp_ops, -+ .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | -+ SDHCI_QUIRK_INVERTED_WRITE_PROTECT | -+ SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | -+ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, -+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, -+}; -+static int sdhci_bsp_probe(struct platform_device *pdev) -+{ -+ struct sdhci_host *host; -+ struct sdhci_pltfm_host *pltfm_host = NULL; -+ int ret; -+ -+ host = sdhci_pltfm_init(pdev, &sdhci_bsp_pdata, -+ sizeof(struct sdhci_bsp_priv)); -+ if (IS_ERR(host)) -+ return PTR_ERR(host); -+ -+ ret = sdhci_bsp_pltfm_init(pdev, host); -+ if (ret) -+ goto err_sdhci_add; -+ -+ if (bsp_support_runtime_pm(host)) { -+ pm_runtime_get_noresume(&pdev->dev); -+ pm_runtime_set_autosuspend_delay(&pdev->dev, -+ GOKE_MMC_AUTOSUSPEND_DELAY_MS); -+ pm_runtime_use_autosuspend(&pdev->dev); -+ pm_runtime_set_active(&pdev->dev); -+ pm_runtime_enable(&pdev->dev); -+ } -+ -+ ret = sdhci_add_host(host); -+ if (ret) -+ goto pm_runtime_disable; -+ -+ if (bsp_support_runtime_pm(host)) { -+ pm_runtime_mark_last_busy(&pdev->dev); -+ pm_runtime_put_autosuspend(&pdev->dev); -+ } -+ -+ return 0; -+ -+pm_runtime_disable: -+ if (bsp_support_runtime_pm(host)) { -+ pm_runtime_disable(&pdev->dev); -+ pm_runtime_set_suspended(&pdev->dev); -+ pm_runtime_put_noidle(&pdev->dev); -+ } -+ -+err_sdhci_add: -+ pltfm_host = sdhci_priv(host); -+ clk_disable_unprepare(pltfm_host->clk); -+ sdhci_pltfm_free(pdev); -+ return ret; -+} -+ -+static int sdhci_bsp_remove(struct platform_device *pdev) -+{ -+ struct sdhci_host *host = platform_get_drvdata(pdev); -+ -+ if (bsp_support_runtime_pm(host)) { -+ pm_runtime_get_sync(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ pm_runtime_put_noidle(&pdev->dev); -+ } -+ return sdhci_pltfm_unregister(pdev); -+} -+ -+#ifdef CONFIG_PM -+static int sdhci_bsp_runtime_suspend(struct device *dev) -+{ -+ struct sdhci_host *host = dev_get_drvdata(dev); -+ -+ bsp_disable_card_clk(host); -+ return 0; -+} -+ -+static int sdhci_bsp_runtime_resume(struct device *dev) -+{ -+ struct sdhci_host *host = dev_get_drvdata(dev); -+ -+ bsp_enable_card_clk(host); -+ return 0; -+} -+#endif -+ -+static const struct of_device_id sdhci_bsp_match[] = { -+ { .compatible = "goke,sdhci" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, sdhci_bsp_match); -+ -+static const struct dev_pm_ops sdhci_bsp_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, -+ sdhci_pltfm_resume) -+ -+ SET_RUNTIME_PM_OPS(sdhci_bsp_runtime_suspend, -+ sdhci_bsp_runtime_resume, -+ NULL) -+}; -+ -+static struct platform_driver sdhci_bsp_driver = { -+ .driver = { -+ .name = "sdhci-goke", -+ .of_match_table = sdhci_bsp_match, -+ .pm = &sdhci_bsp_pm_ops, -+ }, -+ .probe = sdhci_bsp_probe, -+ .remove = sdhci_bsp_remove, -+}; -+ -+static int __init sdhci_bsp_init(void) -+{ -+ int ret; -+ -+ ret = platform_driver_register(&sdhci_bsp_driver); -+ if (ret) -+ return ret; -+ -+ ret = mci_proc_init(); -+ if (ret) -+ platform_driver_unregister(&sdhci_bsp_driver); -+ -+ return ret; -+} -+ -+static void __exit sdhci_bsp_exit(void) -+{ -+ mci_proc_shutdown(); -+ -+ platform_driver_unregister(&sdhci_bsp_driver); -+} -+ -+module_init(sdhci_bsp_init); -+module_exit(sdhci_bsp_exit); -+ -+MODULE_DESCRIPTION("SDHCI driver for goke"); -+MODULE_LICENSE("GPL v2"); ---- linux-4.9.37/drivers/mmc/host/sdhci.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci.h 2021-06-07 13:01:33.000000000 +0300 -@@ -20,6 +20,8 @@ - - #include - -+#define SDHCI_GOKE_EDGE_TUNING /* enable edge tuning */ -+ - /* - * Controller registers - */ -@@ -84,6 +86,7 @@ - #define SDHCI_CTRL_ADMA1 0x08 - #define SDHCI_CTRL_ADMA32 0x10 - #define SDHCI_CTRL_ADMA64 0x18 -+#define SDHCI_CTRL_ADMA3 0x18 - #define SDHCI_CTRL_8BITBUS 0x20 - #define SDHCI_CTRL_CDTEST_INS 0x40 - #define SDHCI_CTRL_CDTEST_EN 0x80 -@@ -108,6 +111,7 @@ - #define SDHCI_DIV_MASK_LEN 8 - #define SDHCI_DIV_HI_MASK 0x300 - #define SDHCI_PROG_CLOCK_MODE 0x0020 -+#define SDHCI_CLOCK_PLL_EN 0x0008 - #define SDHCI_CLOCK_CARD_EN 0x0004 - #define SDHCI_CLOCK_INT_STABLE 0x0002 - #define SDHCI_CLOCK_INT_EN 0x0001 -@@ -132,6 +136,7 @@ - #define SDHCI_INT_CARD_REMOVE 0x00000080 - #define SDHCI_INT_CARD_INT 0x00000100 - #define SDHCI_INT_RETUNE 0x00001000 -+#define SDHCI_INT_CQE 0x00004000 - #define SDHCI_INT_ERROR 0x00008000 - #define SDHCI_INT_TIMEOUT 0x00010000 - #define SDHCI_INT_CRC 0x00020000 -@@ -141,14 +146,16 @@ - #define SDHCI_INT_DATA_CRC 0x00200000 - #define SDHCI_INT_DATA_END_BIT 0x00400000 - #define SDHCI_INT_BUS_POWER 0x00800000 --#define SDHCI_INT_ACMD12ERR 0x01000000 -+#define SDHCI_INT_ACMD_ERR 0x01000000 - #define SDHCI_INT_ADMA_ERROR 0x02000000 - - #define SDHCI_INT_NORMAL_MASK 0x00007FFF - #define SDHCI_INT_ERROR_MASK 0xFFFF8000 - - #define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ -- SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) -+ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX | \ -+ SDHCI_INT_ACMD_ERR) -+ - #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ - SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ - SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ -@@ -156,7 +163,13 @@ - SDHCI_INT_BLK_GAP) - #define SDHCI_INT_ALL_MASK ((unsigned int)-1) - --#define SDHCI_ACMD12_ERR 0x3C -+#define SDHCI_AUTO_CMD_ERR 0x3C -+#define SDHCI_AUTO_CMD12_NOT_EXEC 0x0001 -+#define SDHCI_AUTO_CMD_TIMEOUT_ERR 0x0002 -+#define SDHCI_AUTO_CMD_CRC_ERR 0x0004 -+#define SDHCI_AUTO_CMD_ENDBIT_ERR 0x0008 -+#define SDHCI_AUTO_CMD_INDEX_ERR 0x0010 -+#define SDHCI_AUTO_CMD12_NOT_ISSUED 0x0080 - - #define SDHCI_HOST_CONTROL2 0x3E - #define SDHCI_CTRL_UHS_MASK 0x0007 -@@ -165,7 +178,7 @@ - #define SDHCI_CTRL_UHS_SDR50 0x0002 - #define SDHCI_CTRL_UHS_SDR104 0x0003 - #define SDHCI_CTRL_UHS_DDR50 0x0004 --#define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ -+#define SDHCI_CTRL_HS400 0x0007 /* Non-standard */ - #define SDHCI_CTRL_VDD_180 0x0008 - #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 - #define SDHCI_CTRL_DRV_TYPE_B 0x0000 -@@ -174,6 +187,9 @@ - #define SDHCI_CTRL_DRV_TYPE_D 0x0030 - #define SDHCI_CTRL_EXEC_TUNING 0x0040 - #define SDHCI_CTRL_TUNED_CLK 0x0080 -+#define SDHCI_CTRL_HOST_VER4_ENABLE 0x1000 -+#define SDHCI_CTRL_ADDRESSING_64BIT 0x2000 -+#define SDHCI_CTRL_ASYNC_INT_ENABLE 0x4000 - #define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 - - #define SDHCI_CAPABILITIES 0x40 -@@ -195,6 +211,7 @@ - #define SDHCI_CAN_VDD_300 0x02000000 - #define SDHCI_CAN_VDD_180 0x04000000 - #define SDHCI_CAN_64BIT 0x10000000 -+#define SDHCI_CAN_ASYNC_INT 0x20000000 - - #define SDHCI_SUPPORT_SDR50 0x00000001 - #define SDHCI_SUPPORT_SDR104 0x00000002 -@@ -209,6 +226,7 @@ - #define SDHCI_RETUNING_MODE_SHIFT 14 - #define SDHCI_CLOCK_MUL_MASK 0x00FF0000 - #define SDHCI_CLOCK_MUL_SHIFT 16 -+#define SDHCI_CAN_DO_ADMA3 0x08000000 - #define SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ - - #define SDHCI_CAPABILITIES_1 0x44 -@@ -250,6 +268,9 @@ - #define SDHCI_PRESET_SDCLK_FREQ_MASK 0x3FF - #define SDHCI_PRESET_SDCLK_FREQ_SHIFT 0 - -+#define SDHCI_ADMA3_ID_ADDR_LOW 0x78 -+#define SDHCI_ADMA3_ID_ADDR_HI 0x7C -+ - #define SDHCI_SLOT_INT_STATUS 0xFC - - #define SDHCI_HOST_VERSION 0xFE -@@ -260,7 +281,38 @@ - #define SDHCI_SPEC_100 0 - #define SDHCI_SPEC_200 1 - #define SDHCI_SPEC_300 2 -- -+#define SDHCI_SPEC_400 3 -+#define SDHCI_SPEC_410 4 -+#define SDHCI_SPEC_420 5 -+ -+#define SDHCI_MSHC_CTRL 0x508 -+#define SDHCI_CMD_CONFLIT_CHECK 0x01 -+ -+#define SDHCI_AXI_MBIIU_CTRL 0x510 -+#define SDHCI_GM_WR_OSRC_LMT_MASK (0x7 << 24) -+#define SDHCI_GM_WR_OSRC_LMT_SEL(x) ((x) << 24) -+#define SDHCI_GM_RD_OSRC_LMT_MASK (0x7 << 16) -+#define SDHCI_GM_RD_OSRC_LMT_SEL(x) ((x) << 16) -+#define SDHCI_UNDEFL_INCR_EN 0x1 -+ -+#define SDHCI_EMMC_CTRL 0x52c -+#define SDHCI_CARD_IS_EMMC 0x00000001 -+#define SDHCI_ENH_STROBE_EN 0x00000100 -+ -+#define SDHCI_EMMC_HW_RESET 0x534 -+ -+#define SDHCI_AT_CTRL 0x540 -+#define SDHCI_SAMPLE_EN 0x00000010 -+ -+#define SDHCI_AT_STAT 0x544 -+#define SDHCI_PHASE_SEL_MASK 0x000000ff -+ -+#define SDHCI_MULTI_CYCLE 0x54c -+#define SDHCI_FOUND_EDGE (0x1 << 11) -+#define SDHCI_EDGE_DETECT_EN (0x1 << 8) -+#define SDHCI_DOUT_EN_F_EDGE (0x1 << 6) -+#define SDHCI_DATA_DLY_EN (0x1 << 3) -+#define SDHCI_CMD_DLY_EN (0x1 << 2) - /* - * End of controller registers. - */ -@@ -273,6 +325,7 @@ - */ - #define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024) - #define SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12) -+#define SDHCI_DMA_BOUNDARY_SIZE (0x1 << 27) - - /* ADMA2 32-bit DMA descriptor size */ - #define SDHCI_ADMA2_32_DESC_SZ 8 -@@ -298,6 +351,12 @@ - /* ADMA2 64-bit DMA descriptor size */ - #define SDHCI_ADMA2_64_DESC_SZ 12 - -+/* ADMA3 32-bit DMA descriptor size */ -+#define SDHCI_ADMA3_32_DESC_SZ 8 -+ -+/* ADMA3 64-bit DMA descriptor size */ -+#define SDHCI_ADMA3_64_DESC_SZ 16 -+ - /* - * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte - * aligned. -@@ -312,6 +371,9 @@ - #define ADMA2_TRAN_VALID 0x21 - #define ADMA2_NOP_END_VALID 0x3 - #define ADMA2_END 0x2 -+#define ADMA2_LINK_VALID 0x31 -+#define ADMA3_CMD_VALID 0x9 -+#define ADMA3_END 0x3b - - /* - * Maximum segments assuming a 512KiB maximum requisition size and a minimum -@@ -328,6 +390,18 @@ - COOKIE_MAPPED, /* mapped by sdhci_prepare_data() */ - }; - -+struct card_info { -+ unsigned int card_type; -+ unsigned char timing; -+ unsigned char card_connect; -+#define CARD_CONNECT 1 -+#define CARD_DISCONNECT 0 -+ unsigned int card_support_clock; /* clock rate */ -+ unsigned int card_state; /* (our) card state */ -+ unsigned int sd_bus_speed; -+ unsigned int ssr[16]; -+}; -+ - struct sdhci_host { - /* Data set by hardware interface driver */ - const char *hw_name; /* Hardware bus name */ -@@ -425,6 +499,7 @@ - #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14) - /* Broken Clock divider zero in controller */ - #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) -+#define SDHCI_QUIRK2_BROKEN_ADMA3 (1<<16) - - int irq; /* Device IRQ */ - void __iomem *ioaddr; /* Mapped address */ -@@ -458,6 +533,8 @@ - #define SDHCI_SIGNALING_330 (1<<14) /* Host is capable of 3.3V signaling */ - #define SDHCI_SIGNALING_180 (1<<15) /* Host is capable of 1.8V signaling */ - #define SDHCI_SIGNALING_120 (1<<16) /* Host is capable of 1.2V signaling */ -+#define SDHCI_USE_ADMA3 (1<<17) /* Host is ADMA3 capable */ -+#define SDHCI_HOST_VER4_ENABLE (1<<18) /* Host version 4 enable */ - - unsigned int version; /* SDHCI spec. version */ - -@@ -486,14 +563,21 @@ - - void *adma_table; /* ADMA descriptor table */ - void *align_buffer; /* Bounce buffer */ -+ void *adma3_table; /* ADMA3 integrated descriptor table */ -+ void *cmd_table; /* ADMA3 command descriptor table */ - - size_t adma_table_sz; /* ADMA descriptor table size */ - size_t align_buffer_sz; /* Bounce buffer size */ -+ size_t adma3_table_sz; /* ADMA3 integrated descriptor table size */ -+ size_t cmd_table_sz; /* ADMA3 command descriptor table size */ - - dma_addr_t adma_addr; /* Mapped ADMA descr. table */ - dma_addr_t align_addr; /* Mapped bounce buffer */ -+ dma_addr_t adma3_addr; /* Mapped ADMA3 integrated descr. table */ -+ dma_addr_t cmd_addr; /* Mapped ADMA3 command descr. table */ - - unsigned int desc_sz; /* ADMA descriptor size */ -+ unsigned int adma3_desc_sz; /* ADMA3 integrated descriptor size */ - - struct tasklet_struct finish_tasklet; /* Tasklet structures */ - -@@ -525,6 +609,10 @@ - #define SDHCI_TUNING_MODE_2 1 - #define SDHCI_TUNING_MODE_3 2 - -+ struct cmdq_host *cq_host; -+ unsigned int is_tuning; -+ unsigned int error_count; -+ struct card_info c_info; - unsigned long private[0] ____cacheline_aligned; - }; - -@@ -564,6 +652,10 @@ - struct mmc_card *card, - unsigned int max_dtr, int host_drv, - int card_drv, int *drv_type); -+ int (*start_signal_voltage_switch)(struct sdhci_host *host, -+ struct mmc_ios *ios); -+ void (*pre_init)(struct sdhci_host *host); -+ void (*extra_init)(struct sdhci_host *host); - }; - - #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS -@@ -698,4 +790,18 @@ - extern int sdhci_runtime_resume_host(struct sdhci_host *host); - #endif - -+#define UNSTUFF_BITS(resp,start,size) \ -+ ({ \ -+ const int __size = size; \ -+ const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ -+ const int __off = 3 - ((start) / 32); \ -+ const int __shft = (start) & 31; \ -+ u32 __res; \ -+ \ -+ __res = resp[__off] >> __shft; \ -+ if (__size + __shft > 32) \ -+ __res |= resp[__off-1] << ((32 - __shft) % 32); \ -+ __res & __mask; \ -+ }) -+ - #endif /* __SDHCI_HW_H */ ---- linux-4.9.37/drivers/mmc/host/sdhci-pltfm.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-pltfm.c 2021-06-07 13:01:33.000000000 +0300 -@@ -209,19 +209,21 @@ - EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); - - #ifdef CONFIG_PM_SLEEP --static int sdhci_pltfm_suspend(struct device *dev) -+int sdhci_pltfm_suspend(struct device *dev) - { - struct sdhci_host *host = dev_get_drvdata(dev); - - return sdhci_suspend_host(host); - } -+EXPORT_SYMBOL_GPL(sdhci_pltfm_suspend); - --static int sdhci_pltfm_resume(struct device *dev) -+int sdhci_pltfm_resume(struct device *dev) - { - struct sdhci_host *host = dev_get_drvdata(dev); - - return sdhci_resume_host(host); - } -+EXPORT_SYMBOL_GPL(sdhci_pltfm_resume); - #endif - - const struct dev_pm_ops sdhci_pltfm_pmops = { ---- linux-4.9.37/drivers/mmc/host/sdhci-pltfm.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-pltfm.h 2021-06-07 13:01:33.000000000 +0300 -@@ -109,6 +109,8 @@ - return (void *)host->private; - } - -+int sdhci_pltfm_suspend(struct device *dev); -+int sdhci_pltfm_resume(struct device *dev); - extern const struct dev_pm_ops sdhci_pltfm_pmops; - - #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ ---- linux-4.9.37/drivers/mmc/host/sdhci-proc.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-proc.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,272 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "sdhci.h" -+#include "sdhci-proc.h" -+ -+#define MCI_PARENT "mci" -+#define MCI_STATS_PROC "mci_info" -+#define MAX_CLOCK_SCALE 4 -+ -+unsigned int slot_index; -+struct mmc_host *mci_host[MCI_SLOT_NUM] = {NULL}; -+static struct proc_dir_entry *proc_mci_dir; -+ -+static char *card_type[MAX_CARD_TYPE + 1] = { -+ "MMC card", -+ "SD card", -+ "SDIO card", -+ "SD combo (IO+mem) card", -+ "unknown" -+}; -+static char *clock_unit[MAX_CLOCK_SCALE] = { -+ "Hz", -+ "KHz", -+ "MHz", -+ "GHz" -+}; -+ -+static char *mci_get_card_type(unsigned int sd_type) -+{ -+ if (sd_type >= MAX_CARD_TYPE) -+ return card_type[MAX_CARD_TYPE]; -+ else -+ return card_type[sd_type]; -+} -+ -+static unsigned int analyze_clock_scale(unsigned int clock, unsigned int *clock_val) -+{ -+ unsigned int scale = 0; -+ unsigned int tmp = clock; -+ -+ while (1) { -+ tmp = tmp / 1000; /* 1000 for clk calculate */ -+ if (tmp > 0) { -+ *clock_val = tmp; -+ scale++; -+ } else { -+ break; -+ } -+ } -+ return scale; -+} -+ -+static inline int is_card_uhs(unsigned char timing) -+{ -+ return timing >= MMC_TIMING_UHS_SDR12 && -+ timing <= MMC_TIMING_UHS_DDR50; -+}; -+ -+static inline int is_card_hs(unsigned char timing) -+{ -+ return timing == MMC_TIMING_SD_HS || timing == MMC_TIMING_MMC_HS; -+}; -+ -+static void mci_stats_seq_printout(struct seq_file *s) -+{ -+ unsigned int index_mci; -+ unsigned int clock; -+ unsigned int clock_scale; -+ unsigned int clock_value = 0; -+ const char *type = NULL; -+ static struct mmc_host *mmc = NULL; -+ const char *uhs_bus_speed_mode = ""; -+ static const char *uhs_speeds[] = { -+ [UHS_SDR12_BUS_SPEED] = "SDR12 ", -+ [UHS_SDR25_BUS_SPEED] = "SDR25 ", -+ [UHS_SDR50_BUS_SPEED] = "SDR50 ", -+ [UHS_SDR104_BUS_SPEED] = "SDR104 ", -+ [UHS_DDR50_BUS_SPEED] = "DDR50 ", -+ }; -+ unsigned int speed_class, grade_speed_uhs; -+ struct card_info *info = NULL; -+ unsigned int present; -+ struct sdhci_host *host = NULL; -+ -+ for (index_mci = 0; index_mci < MCI_SLOT_NUM; index_mci++) { -+ mmc = mci_host[index_mci]; -+ if (mmc == NULL) { -+ seq_printf(s, "MCI%d: invalid\n", index_mci); -+ continue; -+ } else { -+ seq_printf(s, "MCI%d", index_mci); -+ } -+ host = mmc_priv(mmc); -+ info = &host->c_info; -+ -+ present = host->mmc->ops->get_cd(host->mmc); -+ if (present) -+ seq_puts(s, ": pluged"); -+ else -+ seq_puts(s, ": unplugged"); -+ -+ if (info->card_connect != CARD_CONNECT) { -+ if (mmc->card_status == MMC_CARD_INIT_FAIL) -+ seq_puts(s, "_init_failed\n"); -+ else -+ seq_puts(s, "_disconnected\n"); -+ } else { -+ seq_puts(s, "_connected\n"); -+ -+ seq_printf(s, "\tType: %s", -+ mci_get_card_type(info->card_type)); -+ -+ if (info->card_state & MMC_STATE_BLOCKADDR) { -+ if (info->card_state & MMC_CARD_SDXC) -+ type = "SDXC"; -+ else -+ type = "SDHC"; -+ seq_printf(s, "(%s)\n", type); -+ } -+ -+ if (is_card_uhs(info->timing) && -+ info->sd_bus_speed < ARRAY_SIZE(uhs_speeds)) -+ uhs_bus_speed_mode = -+ uhs_speeds[info->sd_bus_speed]; -+ -+ seq_printf(s, "\tMode: %s%s%s%s\n", -+ is_card_uhs(info->timing) ? "UHS " : -+ (is_card_hs(info->timing) ? "HS " : ""), -+ info->timing == MMC_TIMING_MMC_HS400 ? "HS400 " : -+ (info->timing == MMC_TIMING_MMC_HS200 ? "HS200 " : ""), -+ info->timing == MMC_TIMING_MMC_DDR52 ? "DDR " : "", -+ uhs_bus_speed_mode); -+ -+ speed_class = UNSTUFF_BITS(info->ssr, 56, 8); /* 56 equal 440 -384 */ -+ grade_speed_uhs = UNSTUFF_BITS(info->ssr, 12, 4); /* 12 equal 396 - 384 */ -+ seq_printf(s, "\tSpeed Class: Class %s\n", -+ (speed_class == 0x00) ? "0" : -+ (speed_class == 0x01) ? "2" : -+ (speed_class == 0x02) ? "4" : -+ (speed_class == 0x03) ? "6" : -+ (speed_class == 0x04) ? "10" : -+ "Reserved"); -+ seq_printf(s, "\tUhs Speed Grade: %s\n", -+ (grade_speed_uhs == 0x00) ? -+ "Less than 10MB/sec(0h)" : -+ (grade_speed_uhs == 0x01) ? -+ "10MB/sec and above(1h)" : -+ "Reserved"); -+ -+ clock = info->card_support_clock; -+ clock_scale = analyze_clock_scale(clock, &clock_value); -+ seq_printf(s, "\tHost work clock: %d%s\n", -+ clock_value, clock_unit[clock_scale]); -+ -+ clock = info->card_support_clock; -+ clock_scale = analyze_clock_scale(clock, &clock_value); -+ seq_printf(s, "\tCard support clock: %d%s\n", -+ clock_value, clock_unit[clock_scale]); -+ -+ clock = mmc->actual_clock; -+ clock_scale = analyze_clock_scale(clock, &clock_value); -+ seq_printf(s, "\tCard work clock: %d%s\n", -+ clock_value, clock_unit[clock_scale]); -+ -+ /* add card read/write error count */ -+ seq_printf(s, "\tCard error count: %d\n", -+ host->error_count); -+ } -+ } -+} -+ -+/* proc interface setup */ -+static void *mci_seq_start(struct seq_file *s, loff_t *pos) -+{ -+ /* counter is used to tracking multi proc interfaces -+ * We have only one interface so return zero -+ * pointer to start the sequence. -+ */ -+ static unsigned long counter; -+ -+ if (*pos == 0) -+ return &counter; -+ -+ *pos = 0; -+ return NULL; -+} -+ -+/* proc interface next */ -+static void *mci_seq_next(struct seq_file *s, void *v, loff_t *pos) -+{ -+ (*pos)++; -+ if (*pos >= MCI_SLOT_NUM) -+ return NULL; -+ -+ return NULL; -+} -+ -+/* define parameters where showed in proc file */ -+static int mci_stats_seq_show(struct seq_file *s, void *v) -+{ -+ mci_stats_seq_printout(s); -+ return 0; -+} -+ -+/* proc interface stop */ -+static void mci_seq_stop(struct seq_file *s, void *v) -+{ -+} -+ -+/* proc interface operation */ -+static const struct seq_operations mci_stats_seq_ops = { -+ .start = mci_seq_start, -+ .next = mci_seq_next, -+ .stop = mci_seq_stop, -+ .show = mci_stats_seq_show -+}; -+ -+/* proc file open */ -+static int mci_stats_proc_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &mci_stats_seq_ops); -+}; -+ -+/* proc file operation */ -+static const struct file_operations mci_stats_proc_ops = { -+ .owner = THIS_MODULE, -+ .open = mci_stats_proc_open, -+ .read = seq_read, -+ .release = seq_release -+}; -+ -+int mci_proc_init(void) -+{ -+ struct proc_dir_entry *proc_stats_entry = NULL; -+ -+ proc_mci_dir = proc_mkdir(MCI_PARENT, NULL); -+ if (!proc_mci_dir) { -+ pr_err("%s: failed to create proc file %s\n", -+ __func__, MCI_PARENT); -+ return 1; -+ } -+ -+ proc_stats_entry = proc_create(MCI_STATS_PROC, -+ 0, proc_mci_dir, &mci_stats_proc_ops); -+ if (!proc_stats_entry) { -+ pr_err("%s: failed to create proc file %s\n", -+ __func__, MCI_STATS_PROC); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+int mci_proc_shutdown(void) -+{ -+ if (proc_mci_dir) { -+ remove_proc_entry(MCI_STATS_PROC, proc_mci_dir); -+ remove_proc_entry(MCI_PARENT, NULL); -+ proc_mci_dir = NULL; -+ } -+ -+ return 0; -+} ---- linux-4.9.37/drivers/mmc/host/sdhci-proc.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mmc/host/sdhci-proc.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+/* -+ * MCI connection table manager -+ */ -+#ifndef __MCI_PROC_H__ -+#define __MCI_PROC_H__ -+ -+#include -+ -+#define MAX_CARD_TYPE 4 -+#define MAX_SPEED_MODE 5 -+ -+ -+ -+#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) ||\ -+ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) -+ #define MCI_SLOT_NUM 3 -+#endif -+ -+extern unsigned int slot_index; -+extern struct mmc_host *mci_host[MCI_SLOT_NUM]; -+ -+int mci_proc_init(void); -+int mci_proc_shutdown(void); -+ -+#endif /* __MCI_PROC_H__ */ ---- linux-4.9.37/drivers/mtd/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -30,7 +30,7 @@ - nftl-objs := nftlcore.o nftlmount.o - inftl-objs := inftlcore.o inftlmount.o - -+obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ - obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/ - --obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ - obj-$(CONFIG_MTD_UBI) += ubi/ ---- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,1199 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../nfc_gen.h" -+#include "fmc100.h" -+ -+/*****************************************************************************/ -+static void fmc100_switch_to_spi_nand(struct fmc_host *host) -+{ -+ u32 reg; -+ -+ reg = fmc_readl(host, FMC_CFG); -+ reg &= ~FLASH_TYPE_SEL_MASK; -+ reg |= FMC_CFG_FLASH_SEL(FLASH_TYPE_SPI_NAND); -+ fmc_writel(host, FMC_CFG, reg); -+} -+ -+/*****************************************************************************/ -+static void fmc100_set_str_mode(struct fmc_host *host) -+{ -+ u32 reg; -+ -+ reg = fmc_readl(host, FMC_GLOBAL_CFG); -+ reg &= (~FMC_GLOBAL_CFG_DTR_MODE); -+ fmc_writel(host, FMC_GLOBAL_CFG, reg); -+} -+ -+/*****************************************************************************/ -+static void fmc100_operation_config(struct fmc_host *host, int op) -+{ -+ int ret, clkrate = 0; -+ struct fmc_spi *spi = host->spi; -+ -+ fmc100_switch_to_spi_nand(host); -+ clk_prepare_enable(host->clk); -+ switch (op) { -+ case OP_STYPE_WRITE: -+ clkrate = min((u_long)host->clkrate, -+ (u_long)CLK_FMC_TO_CRG_MHZ(spi->write->clock)); -+ break; -+ case OP_STYPE_READ: -+ clkrate = min((u_long)host->clkrate, -+ (u_long)CLK_FMC_TO_CRG_MHZ(spi->read->clock)); -+ break; -+ case OP_STYPE_ERASE: -+ clkrate = min((u_long)host->clkrate, -+ (u_long)CLK_FMC_TO_CRG_MHZ(spi->erase->clock)); -+ break; -+ default: -+ break; -+ } -+ -+ ret = clk_set_rate(host->clk, clkrate); -+ if (WARN_ON(ret)) { -+ pr_err("clk_set_rate failed: %d\n", ret); -+ } -+} -+ -+/*****************************************************************************/ -+static void fmc100_send_cmd_write(struct fmc_host *host) -+{ -+ unsigned char pages_per_block_shift; -+ unsigned int reg, block_num, block_num_h, page_num; -+ struct fmc_spi *spi = host->spi; -+ struct nand_chip *chip = host->chip; -+#ifdef FMC100_SPI_NAND_SUPPORT_REG_WRITE -+ const char *op = "Reg"; -+#else -+ const char *op = "Dma"; -+#endif -+ -+ if (WR_DBG) { -+ pr_info("\n"); -+ } -+ FMC_PR(WR_DBG, "*-Start send %s page write command\n", op); -+ -+ mutex_lock(host->lock); -+ fmc100_operation_config(host, OP_STYPE_WRITE); -+ -+ reg = spi->driver->wait_ready(spi); -+ if (reg) { -+ DB_MSG("Error: %s program wait ready failed! status: %#x\n", -+ op, reg); -+ goto end; -+ } -+ -+ reg = spi->driver->write_enable(spi); -+ if (reg) { -+ DB_MSG("Error: %s program write enable failed! reg: %#x\n", -+ op, reg); -+ goto end; -+ } -+ -+ reg = FMC_INT_CLR_ALL; -+ fmc_writel(host, FMC_INT_CLR, reg); -+ FMC_PR(WR_DBG, "|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) -+ | OP_CFG_MEM_IF_TYPE(spi->write->iftype) -+ | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(WR_DBG, "|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ pages_per_block_shift = chip->phys_erase_shift - chip->page_shift; -+ block_num = host->addr_value[1] >> pages_per_block_shift; -+ block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT; -+ reg = FMC_ADDRH_SET(block_num_h); -+ fmc_writel(host, FMC_ADDRH, reg); -+ FMC_PR(WR_DBG, "|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); -+ -+ page_num = host->addr_value[1] - (block_num << pages_per_block_shift); -+ reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT) -+ | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT); -+ fmc_writel(host, FMC_ADDRL, reg); -+ FMC_PR(WR_DBG, "|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); -+ -+ *host->epm = 0x0000; -+ -+#ifndef FMC100_SPI_NAND_SUPPORT_REG_WRITE -+ reg = host->dma_buffer; -+ fmc_writel(host, FMC_DMA_SADDR_D0, reg); -+ FMC_PR(WR_DBG, "|-Set DMA_SADDR_D[0x40]%#x\n", reg); -+ -+#ifdef CONFIG_64BIT -+ reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32; -+ fmc_writel(host, FMC_DMA_SADDRH_D0, reg); -+ FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg); -+#endif -+ -+ reg = host->dma_oob; -+ fmc_writel(host, FMC_DMA_SADDR_OOB, reg); -+ FMC_PR(WR_DBG, "|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, reg); -+#ifdef CONFIG_64BIT -+ reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32; -+ fmc_writel(host, FMC_DMA_SADDRH_OOB, reg); -+ FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB, -+ reg); -+#endif -+#endif -+ -+ reg = OP_CTRL_WR_OPCODE(spi->write->cmd) -+#ifdef FMC100_SPI_NAND_SUPPORT_REG_WRITE -+ | OP_CTRL_DMA_OP(OP_TYPE_REG) -+#else -+ | OP_CTRL_DMA_OP(OP_TYPE_DMA) -+#endif -+ | OP_CTRL_RW_OP(RW_OP_WRITE) -+ | OP_CTRL_DMA_OP_READY; -+ fmc_writel(host, FMC_OP_CTRL, reg); -+ FMC_PR(WR_DBG, "|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg); -+ -+ FMC_DMA_WAIT_INT_FINISH(host); -+ -+end: -+ mutex_unlock(host->lock); -+ FMC_PR(WR_DBG, "*-End %s page program!\n", op); -+} -+ -+/*****************************************************************************/ -+static void fmc100_send_cmd_status(struct fmc_host *host) -+{ -+ unsigned char status, addr = STATUS_ADDR; -+ struct fmc_spi *spi = host->spi; -+ -+ if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) { -+ addr = PROTECT_ADDR; -+ } -+ -+ status = spi_nand_feature_op(spi, GET_OP, addr, 0); -+ FMC_PR((ER_DBG || WR_DBG), "\t*-Get status[%#x]: %#x\n", addr, status); -+} -+ -+/*****************************************************************************/ -+static void fmc100_send_cmd_read(struct fmc_host *host) -+{ -+ unsigned char pages_per_block_shift, only_oob = 0; -+ unsigned short wrap = 0; -+ unsigned int reg, block_num, block_num_h, page_num, addr_of = 0; -+ struct fmc_spi *spi = host->spi; -+ struct nand_chip *chip = host->chip; -+#ifdef FMC100_SPI_NAND_SUPPORT_REG_READ -+ char *op = "Reg"; -+#else -+ char *op = "Dma"; -+#endif -+ -+ if (RD_DBG) { -+ pr_info("\n"); -+ } -+ FMC_PR(RD_DBG, "\t*-Start %s page read\n", op); -+ -+ if ((host->addr_value[0] == host->cache_addr_value[0]) -+ && (host->addr_value[1] == host->cache_addr_value[1])) { -+ FMC_PR(RD_DBG, "\t*-%s read cache hit, addr[%#x %#x]\n", -+ op, host->addr_value[1], host->addr_value[0]); -+ return; -+ } -+ -+ mutex_lock(host->lock); -+ fmc100_operation_config(host, OP_STYPE_READ); -+ -+ FMC_PR(RD_DBG, "\t|-Wait ready before %s page read\n", op); -+ reg = spi->driver->wait_ready(spi); -+ if (reg) { -+ DB_MSG("Error: %s read wait ready fail! reg: %#x\n", op, reg); -+ goto end; -+ } -+ -+ reg = FMC_INT_CLR_ALL; -+ fmc_writel(host, FMC_INT_CLR, reg); -+ FMC_PR(RD_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); -+ -+ if (host->cmd_op.l_cmd == NAND_CMD_READOOB) { -+ only_oob = 1; -+ host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_OOB); -+ } else { -+ host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_ALL_PAGE); -+ } -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) -+ | OP_CFG_MEM_IF_TYPE(spi->read->iftype) -+ | OP_CFG_DUMMY_NUM(spi->read->dummy) -+ | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(RD_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ pages_per_block_shift = chip->phys_erase_shift - chip->page_shift; -+ block_num = host->addr_value[1] >> pages_per_block_shift; -+ block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT; -+ -+ reg = FMC_ADDRH_SET(block_num_h); -+ fmc_writel(host, FMC_ADDRH, reg); -+ FMC_PR(RD_DBG, "\t|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg); -+ -+ page_num = host->addr_value[1] - (block_num << pages_per_block_shift); -+ if (only_oob) -+ switch (host->ecctype) { -+ case NAND_ECC_8BIT: -+ addr_of = REG_CNT_ECC_8BIT_OFFSET; -+ break; -+ case NAND_ECC_16BIT: -+ addr_of = REG_CNT_ECC_16BIT_OFFSET; -+ break; -+ case NAND_ECC_24BIT: -+ addr_of = REG_CNT_ECC_24BIT_OFFSET; -+ break; -+ case NAND_ECC_0BIT: -+ default: -+ break; -+ } -+ -+ reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT) -+ | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT) -+ | ((wrap & REG_CNT_WRAP_MASK) << REG_CNT_WRAP_SHIFT) -+ | (addr_of & REG_CNT_ECC_OFFSET_MASK); -+ fmc_writel(host, FMC_ADDRL, reg); -+ FMC_PR(RD_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); -+ -+#ifndef FMC100_SPI_NAND_SUPPORT_REG_READ -+ reg = host->dma_buffer; -+ fmc_writel(host, FMC_DMA_SADDR_D0, reg); -+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_D0[%#x]%#x\n", FMC_DMA_SADDR_D0, reg); -+ -+#ifdef CONFIG_64BIT -+ reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32; -+ fmc_writel(host, FMC_DMA_SADDRH_D0, reg); -+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg); -+#endif -+ -+ reg = host->dma_oob; -+ fmc_writel(host, FMC_DMA_SADDR_OOB, reg); -+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, -+ reg); -+ -+#ifdef CONFIG_64BIT -+ reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32; -+ fmc_writel(host, FMC_DMA_SADDRH_OOB, reg); -+ FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB, -+ reg); -+#endif -+#endif -+ -+ reg = OP_CTRL_RD_OPCODE(spi->read->cmd) | host->cmd_op.op_cfg -+#ifdef FMC100_SPI_NAND_SUPPORT_REG_READ -+ | OP_CTRL_DMA_OP(OP_TYPE_REG) -+#else -+ | OP_CTRL_DMA_OP(OP_TYPE_DMA) -+#endif -+ | OP_CTRL_RW_OP(RW_OP_READ) | OP_CTRL_DMA_OP_READY; -+ fmc_writel(host, FMC_OP_CTRL, reg); -+ FMC_PR(RD_DBG, "\t|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg); -+ -+ FMC_DMA_WAIT_INT_FINISH(host); -+ -+ host->cache_addr_value[0] = host->addr_value[0]; -+ host->cache_addr_value[1] = host->addr_value[1]; -+ -+end: -+ mutex_unlock(host->lock); -+ FMC_PR(RD_DBG, "\t*-End %s page read\n", op); -+} -+ -+/*****************************************************************************/ -+static void fmc100_send_cmd_erase(struct fmc_host *host) -+{ -+ unsigned int reg; -+ struct fmc_spi *spi = host->spi; -+ -+ if (ER_DBG) { -+ pr_info("\n"); -+ } -+ FMC_PR(ER_DBG, "\t*-Start send cmd erase!\n"); -+ -+ mutex_lock(host->lock); -+ fmc100_operation_config(host, OP_STYPE_ERASE); -+ -+ reg = spi->driver->wait_ready(spi); -+ FMC_PR(ER_DBG, "\t|-Erase wait ready, reg: %#x\n", reg); -+ if (reg) { -+ DB_MSG("Error: Erase wait ready fail! status: %#x\n", reg); -+ goto end; -+ } -+ -+ reg = spi->driver->write_enable(spi); -+ if (reg) { -+ DB_MSG("Error: Erase write enable failed! reg: %#x\n", reg); -+ goto end; -+ } -+ -+ reg = FMC_INT_CLR_ALL; -+ fmc_writel(host, FMC_INT_CLR, reg); -+ FMC_PR(ER_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg); -+ -+ reg = spi->erase->cmd; -+ fmc_writel(host, FMC_CMD, FMC_CMD_CMD1(reg)); -+ FMC_PR(ER_DBG, "\t|-Set CMD[%#x]%#x\n", FMC_CMD, reg); -+ -+ reg = FMC_ADDRL_BLOCK_H_MASK(host->addr_value[1]) -+ | FMC_ADDRL_BLOCK_L_MASK(host->addr_value[0]); -+ fmc_writel(host, FMC_ADDRL, reg); -+ FMC_PR(ER_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) -+ | OP_CFG_MEM_IF_TYPE(spi->erase->iftype) -+ | OP_CFG_ADDR_NUM(STD_OP_ADDR_NUM) -+ | OP_CFG_DUMMY_NUM(spi->erase->dummy) -+ | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(ER_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ reg = FMC_OP_CMD1_EN -+ | FMC_OP_ADDR_EN -+ | FMC_OP_REG_OP_START; -+ fmc_writel(host, FMC_OP, reg); -+ FMC_PR(ER_DBG, "\t|-Set OP[%#x]%#x\n", FMC_OP, reg); -+ -+ FMC_CMD_WAIT_CPU_FINISH(host); -+ -+end: -+ mutex_unlock(host->lock); -+ FMC_PR(ER_DBG, "\t*-End send cmd erase!\n"); -+} -+ -+/*****************************************************************************/ -+void fmc100_ecc0_switch(struct fmc_host *host, unsigned char op) -+{ -+ unsigned int config; -+#if EC_DBG -+ unsigned int cmp_cfg; -+ -+ config = fmc_readl(host, FMC_CFG); -+ FMC_PR(EC_DBG, "\t *-Get CFG[%#x]%#x\n", FMC_CFG, config); -+ -+ if (op) { -+ cmp_cfg = host->fmc_cfg; -+ } else { -+ cmp_cfg = host->fmc_cfg_ecc0; -+ } -+ -+ if (cmp_cfg != config) -+ DB_MSG("Warning: FMC config[%#x] is different.\n", -+ cmp_cfg); -+#endif -+ -+ if (op == ENABLE) { -+ config = host->fmc_cfg_ecc0; -+ } else if (op == DISABLE) { -+ config = host->fmc_cfg; -+ } else { -+ DB_MSG("Error: Invalid opcode: %d\n", op); -+ return; -+ } -+ -+ fmc_writel(host, FMC_CFG, config); -+ FMC_PR(EC_DBG, "\t *-Set CFG[%#x]%#x\n", FMC_CFG, config); -+} -+ -+/*****************************************************************************/ -+static void fmc100_send_cmd_readid(struct fmc_host *host) -+{ -+ unsigned int reg; -+ -+ FMC_PR(BT_DBG, "\t|*-Start send cmd read ID\n"); -+ -+ fmc100_ecc0_switch(host, ENABLE); -+ -+ reg = FMC_CMD_CMD1(SPI_CMD_RDID); -+ fmc_writel(host, FMC_CMD, reg); -+ FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); -+ -+ reg = READ_ID_ADDR; -+ fmc_writel(host, FMC_ADDRL, reg); -+ FMC_PR(BT_DBG, "\t||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) -+ | OP_CFG_ADDR_NUM(READ_ID_ADDR_NUM) -+ | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ reg = FMC_DATA_NUM_CNT(MAX_SPI_NAND_ID_LEN); -+ fmc_writel(host, FMC_DATA_NUM, reg); -+ FMC_PR(BT_DBG, "\t||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg); -+ -+ reg = FMC_OP_CMD1_EN -+ | FMC_OP_ADDR_EN -+ | FMC_OP_READ_DATA_EN -+ | FMC_OP_REG_OP_START; -+ fmc_writel(host, FMC_OP, reg); -+ FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); -+ -+ host->addr_cycle = 0x0; -+ -+ FMC_CMD_WAIT_CPU_FINISH(host); -+ -+ fmc100_ecc0_switch(host, DISABLE); -+ -+ FMC_PR(BT_DBG, "\t|*-End read flash ID\n"); -+} -+ -+/*****************************************************************************/ -+static void fmc100_send_cmd_reset(struct fmc_host *host) -+{ -+ unsigned int reg; -+ -+ FMC_PR(BT_DBG, "\t|*-Start send cmd reset\n"); -+ -+ reg = FMC_CMD_CMD1(SPI_CMD_RESET); -+ fmc_writel(host, FMC_CMD, reg); -+ FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START; -+ fmc_writel(host, FMC_OP, reg); -+ FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); -+ -+ FMC_CMD_WAIT_CPU_FINISH(host); -+ -+ FMC_PR(BT_DBG, "\t|*-End send cmd reset\n"); -+} -+ -+/*****************************************************************************/ -+static void fmc100_host_init(struct fmc_host *host) -+{ -+ unsigned int reg; -+ -+ FMC_PR(BT_DBG, "\t||*-Start SPI Nand host init\n"); -+ -+ reg = fmc_readl(host, FMC_CFG); -+ if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) { -+ reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL); -+ fmc_writel(host, FMC_CFG, reg); -+ FMC_PR(BT_DBG, "\t|||-Set CFG[%#x]%#x\n", FMC_CFG, reg); -+ } -+ -+ host->fmc_cfg = reg; -+ host->fmc_cfg_ecc0 = (reg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; -+ -+ reg = fmc_readl(host, FMC_GLOBAL_CFG); -+ if (reg & FMC_GLOBAL_CFG_WP_ENABLE) { -+ reg &= ~FMC_GLOBAL_CFG_WP_ENABLE; -+ fmc_writel(host, FMC_GLOBAL_CFG, reg); -+ } -+ -+ host->addr_cycle = 0; -+ host->addr_value[0] = 0; -+ host->addr_value[1] = 0; -+ host->cache_addr_value[0] = ~0; -+ host->cache_addr_value[1] = ~0; -+ -+ host->send_cmd_write = fmc100_send_cmd_write; -+ host->send_cmd_status = fmc100_send_cmd_status; -+ host->send_cmd_read = fmc100_send_cmd_read; -+ host->send_cmd_erase = fmc100_send_cmd_erase; -+ host->send_cmd_readid = fmc100_send_cmd_readid; -+ host->send_cmd_reset = fmc100_send_cmd_reset; -+#ifdef CONFIG_PM -+ host->suspend = fmc100_suspend; -+ host->resume = fmc100_resume; -+#endif -+ -+ reg = TIMING_CFG_TCSH(CS_HOLD_TIME) -+ | TIMING_CFG_TCSS(CS_SETUP_TIME) -+ | TIMING_CFG_TSHSL(CS_DESELECT_TIME); -+ fmc_writel(host, FMC_SPI_TIMING_CFG, reg); -+ -+ reg = ALL_BURST_ENABLE; -+ fmc_writel(host, FMC_DMA_AHB_CTRL, reg); -+ -+ FMC_PR(BT_DBG, "\t||*-End SPI Nand host init\n"); -+} -+ -+/*****************************************************************************/ -+static unsigned char fmc100_read_byte(struct mtd_info *mtd) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ unsigned char value, ret_val = 0; -+ -+ if (host->cmd_op.l_cmd == NAND_CMD_READID) { -+ value = fmc_readb(host->iobase + host->offset); -+ host->offset++; -+ if (host->cmd_op.data_no == host->offset) { -+ host->cmd_op.l_cmd = 0; -+ } -+ return value; -+ } -+ -+ if (host->cmd_op.cmd == NAND_CMD_STATUS) { -+ value = fmc_readl(host, FMC_STATUS); -+ if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) { -+ FMC_PR((ER_DBG || WR_DBG), "\t\tRead BP status:%#x\n", -+ value); -+ if (ANY_BP_ENABLE(value)) { -+ ret_val |= NAND_STATUS_WP; -+ } -+ -+ host->cmd_op.l_cmd = NAND_CMD_STATUS; -+ } -+ -+ if (!(value & STATUS_OIP_MASK)) { -+ ret_val |= NAND_STATUS_READY; -+ } -+ -+ if (value & STATUS_E_FAIL_MASK) { -+ FMC_PR(ER_DBG, "\t\tGet erase status: %#x\n", value); -+ ret_val |= NAND_STATUS_FAIL; -+ } -+ -+ if (value & STATUS_P_FAIL_MASK) { -+ FMC_PR(WR_DBG, "\t\tGet write status: %#x\n", value); -+ ret_val |= NAND_STATUS_FAIL; -+ } -+ -+ return ret_val; -+ } -+ -+ if (host->cmd_op.l_cmd == NAND_CMD_READOOB) { -+ value = fmc_readb(host->buffer + host->pagesize + host->offset); -+ host->offset++; -+ return value; -+ } -+ -+ host->offset++; -+ -+ return fmc_readb(host->buffer + host->column + host->offset - 1); -+} -+ -+/*****************************************************************************/ -+static unsigned short fmc100_read_word(struct mtd_info *mtd) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ -+ host->offset += 2; -+ return fmc_readw(host->buffer + host->column + host->offset - 2); -+} -+ -+/*****************************************************************************/ -+static void fmc100_write_buf(struct mtd_info *mtd, -+ const u_char *buf, int len) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ -+#ifdef FMC100_SPI_NAND_SUPPORT_REG_WRITE -+ if (buf == chip->oob_poi) { -+ memcpy((char *)host->iobase + host->pagesize, buf, len); -+ } else { -+ memcpy((char *)host->iobase, buf, len); -+ } -+#else -+ if (buf == chip->oob_poi) { -+ memcpy((char *)(host->buffer + host->pagesize), buf, len); -+ } else { -+ memcpy((char *)host->buffer, buf, len); -+ } -+#endif -+ return; -+} -+ -+/*****************************************************************************/ -+static void fmc100_read_buf(struct mtd_info *mtd, u_char *buf, int len) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ -+#ifdef FMC100_SPI_NAND_SUPPORT_REG_READ -+ if (buf == chip->oob_poi) { -+ memcpy(buf, (char *)host->iobase + host->pagesize, len); -+ } else { -+ memcpy(buf, (char *)host->iobase, len); -+ } -+#else -+ if (buf == chip->oob_poi) { -+ memcpy(buf, (char *)host->buffer + host->pagesize, len); -+ } else { -+ memcpy(buf, (char *)host->buffer, len); -+ } -+#endif -+ -+#ifdef CONFIG_GOKE_NAND_ECC_STATUS_REPORT -+ if (buf != chip->oob_poi) { -+ u_int reg, ecc_step = host->pagesize >> 10; -+ -+ reg = fmc_readl(host, FMC100_ECC_ERR_NUM0_BUF0); -+ while (ecc_step) { -+ u_char err_num; -+ -+ err_num = GET_ECC_ERR_NUM(--ecc_step, reg); -+ if (err_num == 0xff) { -+ mtd->ecc_stats.failed++; -+ } else { -+ mtd->ecc_stats.corrected += err_num; -+ } -+ } -+ } -+#endif -+ -+ return; -+} -+ -+/*****************************************************************************/ -+static void fmc100_select_chip(struct mtd_info *mtd, int chipselect) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ -+ if (chipselect < 0) { -+ mutex_unlock(&fmc_switch_mutex); -+ return; -+ } -+ -+ mutex_lock(&fmc_switch_mutex); -+ -+ if (chipselect > CONFIG_SPI_NAND_MAX_CHIP_NUM) { -+ DB_BUG("Error: Invalid chipselect: %d\n", chipselect); -+ } -+ -+ if (host->mtd != mtd) { -+ host->mtd = mtd; -+ host->cmd_op.cs = chipselect; -+ } -+ -+ if (!(chip->options & NAND_BROKEN_XD)) { -+ if ((chip->state == FL_ERASING) || (chip->state == FL_WRITING)) { -+ host->cmd_op.l_cmd = NAND_CMD_GET_FEATURES; -+ } -+ } -+} -+ -+/*****************************************************************************/ -+static void fmc100_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned ctrl) -+{ -+ unsigned char cmd; -+ int is_cache_invalid = 1; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ unsigned int udat = (unsigned int)dat; -+ -+ if (ctrl & NAND_ALE) { -+ unsigned int addr_value = 0; -+ unsigned int addr_offset = 0; -+ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ host->addr_cycle = 0x0; -+ host->addr_value[0] = 0x0; -+ host->addr_value[1] = 0x0; -+ } -+ addr_offset = host->addr_cycle << 3; -+ -+ if (host->addr_cycle >= FMC100_ADDR_CYCLE_MASK) { -+ addr_offset = (host->addr_cycle - -+ FMC100_ADDR_CYCLE_MASK) << 3; -+ addr_value = 1; -+ } -+ host->addr_value[addr_value] |= -+ ((udat & 0xff) << addr_offset); -+ -+ host->addr_cycle++; -+ } -+ -+ if ((ctrl & NAND_CLE) && (ctrl & NAND_CTRL_CHANGE)) { -+ cmd = udat & 0xff; -+ host->cmd_op.cmd = cmd; -+ switch (cmd) { -+ case NAND_CMD_PAGEPROG: -+ host->offset = 0; -+ host->send_cmd_write(host); -+ break; -+ -+ case NAND_CMD_READSTART: -+ is_cache_invalid = 0; -+ if (host->addr_value[0] == host->pagesize) { -+ host->cmd_op.l_cmd = NAND_CMD_READOOB; -+ } -+ host->send_cmd_read(host); -+ break; -+ -+ case NAND_CMD_ERASE2: -+ host->send_cmd_erase(host); -+ break; -+ -+ case NAND_CMD_READID: -+ memset((u_char *)(host->iobase), 0, -+ MAX_SPI_NAND_ID_LEN); -+ host->cmd_op.l_cmd = cmd; -+ host->cmd_op.data_no = MAX_SPI_NAND_ID_LEN; -+ host->send_cmd_readid(host); -+ break; -+ -+ case NAND_CMD_STATUS: -+ host->send_cmd_status(host); -+ break; -+ -+ case NAND_CMD_READ0: -+ host->cmd_op.l_cmd = cmd; -+ break; -+ -+ case NAND_CMD_RESET: -+ host->send_cmd_reset(host); -+ break; -+ -+ case NAND_CMD_SEQIN: -+ case NAND_CMD_ERASE1: -+ default: -+ break; -+ } -+ } -+ -+ if ((dat == NAND_CMD_NONE) && host->addr_cycle) { -+ if (host->cmd_op.cmd == NAND_CMD_SEQIN -+ || host->cmd_op.cmd == NAND_CMD_READ0 -+ || host->cmd_op.cmd == NAND_CMD_READID) { -+ host->offset = 0x0; -+ host->column = (host->addr_value[0] & 0xffff); -+ } -+ } -+ -+ if (is_cache_invalid) { -+ host->cache_addr_value[0] = ~0; -+ host->cache_addr_value[1] = ~0; -+ } -+} -+ -+/*****************************************************************************/ -+static int fmc100_dev_ready(struct mtd_info *mtd) -+{ -+ unsigned int reg; -+ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ -+ do { -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ -+ reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START; -+ fmc_writel(host, FMC_OP, reg); -+ -+ FMC_CMD_WAIT_CPU_FINISH(host); -+ -+ reg = fmc_readl(host, FMC_STATUS); -+ -+ if (!(reg & STATUS_OIP_MASK)) { -+ return NAND_STATUS_READY; -+ } -+ -+ cond_resched(); -+ -+ } while (!time_after_eq(jiffies, deadline)); -+ -+ if (!(chip->options & NAND_SCAN_SILENT_NODEV)) { -+ pr_warn("Wait SPI nand ready timeout, status: %#x\n", reg); -+ } -+ -+ return 0; -+} -+ -+/*****************************************************************************/ -+/* -+ * 'host->epm' only use the first oobfree[0] field, it looks very simple, But... -+ */ -+/* Default OOB area layout */ -+static int fmc_ooblayout_ecc_default(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) { -+ return -ERANGE; -+ } -+ -+ oobregion->length = 32; -+ oobregion->offset = 32; -+ -+ return 0; -+} -+ -+static int fmc_ooblayout_free_default(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) { -+ return -ERANGE; -+ } -+ -+ oobregion->length = 30; -+ oobregion->offset = 2; -+ -+ return 0; -+} -+ -+static struct mtd_ooblayout_ops fmc_ooblayout_default_ops = { -+ .ecc = fmc_ooblayout_ecc_default, -+ .free = fmc_ooblayout_free_default, -+}; -+ -+#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 -+static int fmc_ooblayout_ecc_4k16bit(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) { -+ return -ERANGE; -+ } -+ -+ oobregion->length = 14; -+ oobregion->offset = 14; -+ -+ return 0; -+} -+ -+static int fmc_ooblayout_free_4k16bit(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) { -+ return -ERANGE; -+ } -+ -+ oobregion->length = 14; -+ oobregion->offset = 2; -+ -+ return 0; -+} -+ -+static struct mtd_ooblayout_ops fmc_ooblayout_4k16bit_ops = { -+ .ecc = fmc_ooblayout_ecc_4k16bit, -+ .free = fmc_ooblayout_free_4k16bit, -+}; -+ -+static int fmc_ooblayout_ecc_2k16bit(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) { -+ return -ERANGE; -+ } -+ -+ oobregion->length = 6; -+ oobregion->offset = 6; -+ -+ return 0; -+} -+ -+static int fmc_ooblayout_free_2k16bit(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) { -+ return -ERANGE; -+ } -+ -+ oobregion->length = 6; -+ oobregion->offset = 2; -+ -+ return 0; -+} -+ -+static struct mtd_ooblayout_ops fmc_ooblayout_2k16bit_ops = { -+ .ecc = fmc_ooblayout_ecc_2k16bit, -+ .free = fmc_ooblayout_free_2k16bit, -+}; -+#endif -+ -+/*****************************************************************************/ -+static struct nand_config_info fmc_spi_nand_config_table[] = { -+ {NAND_PAGE_4K, NAND_ECC_24BIT, 24, 200, &fmc_ooblayout_default_ops}, -+#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 -+ {NAND_PAGE_4K, NAND_ECC_16BIT, 16, 128, &fmc_ooblayout_4k16bit_ops}, -+#endif -+ {NAND_PAGE_4K, NAND_ECC_8BIT, 8, 128, &fmc_ooblayout_default_ops}, -+ {NAND_PAGE_4K, NAND_ECC_0BIT, 0, 32, &fmc_ooblayout_default_ops}, -+ -+ {NAND_PAGE_2K, NAND_ECC_24BIT, 24, 128, &fmc_ooblayout_default_ops}, -+#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 -+ {NAND_PAGE_2K, NAND_ECC_16BIT, 16, 64, &fmc_ooblayout_2k16bit_ops}, -+#endif -+ {NAND_PAGE_2K, NAND_ECC_8BIT, 8, 64, &fmc_ooblayout_default_ops}, -+ {NAND_PAGE_2K, NAND_ECC_0BIT, 0, 32, &fmc_ooblayout_default_ops}, -+ -+ {0, 0, 0, 0, NULL}, -+}; -+ -+/* -+ * Auto-sensed the page size and ecc type value. driver will try each of page -+ * size and ecc type one by one till flash can be read and wrote accurately. -+ * so the page size and ecc type is match adaptively without switch on the board -+ */ -+static struct nand_config_info *fmc100_get_config_type_info( -+ struct mtd_info *mtd, struct nand_dev_t *nand_dev) -+{ -+ struct nand_config_info *best = NULL; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nand_config_info *info = fmc_spi_nand_config_table; -+ -+ nand_dev->start_type = "Auto"; -+ -+ for (; info->ooblayout_ops; info++) { -+ if (match_page_type_to_size(info->pagetype) != mtd->writesize) { -+ continue; -+ } -+ -+ if (mtd->oobsize < info->oobsize) { -+ continue; -+ } -+ -+ if (!best || (best->ecctype < info->ecctype)) { -+ best = info; -+ } -+ } -+ -+ /* All SPI NAND are small-page, SLC */ -+ chip->bits_per_cell = 1; -+ -+ return best; -+} -+ -+/*****************************************************************************/ -+static void fmc100_chip_init(struct nand_chip *chip) -+{ -+ chip->read_byte = fmc100_read_byte; -+ chip->read_word = fmc100_read_word; -+ chip->write_buf = fmc100_write_buf; -+ chip->read_buf = fmc100_read_buf; -+ -+ chip->select_chip = fmc100_select_chip; -+ -+ chip->cmd_ctrl = fmc100_cmd_ctrl; -+ chip->dev_ready = fmc100_dev_ready; -+ -+ chip->chip_delay = FMC_CHIP_DELAY; -+ -+ chip->options = NAND_SKIP_BBTSCAN | NAND_BROKEN_XD -+ | NAND_SCAN_SILENT_NODEV; -+ -+ chip->ecc.mode = NAND_ECC_NONE; -+} -+ -+/*****************************************************************************/ -+static void fmc100_set_oob_info(struct mtd_info *mtd, -+ struct nand_config_info *info, struct nand_dev_t *nand_dev) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ struct mtd_oob_region fmc_oobregion = {0, 0}; -+ -+ if (info->ecctype != NAND_ECC_0BIT) { -+ mtd->oobsize = info->oobsize; -+ } -+ -+ host->oobsize = mtd->oobsize; -+ nand_dev->oobsize = host->oobsize; -+ -+ host->dma_oob = host->dma_buffer + host->pagesize; -+ host->bbm = (u_char *)(host->buffer + host->pagesize -+ + FMC_BAD_BLOCK_POS); -+ -+ info->ooblayout_ops->free(mtd, 0, &fmc_oobregion); -+ -+ mtd_set_ooblayout(mtd, info->ooblayout_ops); -+ -+ /* EB bits locate in the bottom two of CTRL(30) */ -+ host->epm = (u_short *)(host->buffer + host->pagesize -+ + fmc_oobregion.offset + 28); -+ -+#ifdef CONFIG_GOKE_NAND_FS_MAY_NO_YAFFS2 -+ if (best->ecctype == NAND_ECC_16BIT) { -+ if (host->pagesize == _2K) { -+ /* EB bits locate in the bottom two of CTRL(4) */ -+ host->epm = (u_short *)(host->buffer + host->pagesize -+ + fmc_oobregion.offset + 4); -+ } else if (host->pagesize == _4K) { -+ /* EB bit locate in the bottom two of CTRL(14) */ -+ host->epm = (u_short *)(host->buffer + host->pagesize -+ + fmc_oobregion.offset + 12); -+ } -+ } -+#endif -+} -+ -+/*****************************************************************************/ -+static unsigned int fmc100_get_ecc_reg(struct fmc_host *host, -+ struct nand_config_info *info, struct nand_dev_t *nand_dev) -+{ -+ host->ecctype = info->ecctype; -+ nand_dev->ecctype = host->ecctype; -+ -+ return FMC_CFG_ECC_TYPE(match_ecc_type_to_reg(info->ecctype)); -+} -+ -+/*****************************************************************************/ -+static unsigned int fmc100_get_page_reg(struct fmc_host *host, -+ struct nand_config_info *info) -+{ -+ host->pagesize = match_page_type_to_size(info->pagetype); -+ -+ return FMC_CFG_PAGE_SIZE(match_page_type_to_reg(info->pagetype)); -+} -+ -+/*****************************************************************************/ -+static unsigned int fmc100_get_block_reg(struct fmc_host *host, -+ struct nand_config_info *info) -+{ -+ unsigned int block_reg = 0, page_per_block; -+ struct mtd_info *mtd = host->mtd; -+ -+ host->block_page_mask = ((mtd->erasesize / mtd->writesize) - 1); -+ page_per_block = mtd->erasesize / match_page_type_to_size(info->pagetype); -+ switch (page_per_block) { -+ case 64: -+ block_reg = BLOCK_SIZE_64_PAGE; -+ break; -+ case 128: -+ block_reg = BLOCK_SIZE_128_PAGE; -+ break; -+ case 256: -+ block_reg = BLOCK_SIZE_256_PAGE; -+ break; -+ case 512: -+ block_reg = BLOCK_SIZE_512_PAGE; -+ break; -+ default: -+ DB_MSG("Can't support block %#x and page %#x size\n", -+ mtd->erasesize, mtd->writesize); -+ } -+ -+ return FMC_CFG_BLOCK_SIZE(block_reg); -+} -+ -+/*****************************************************************************/ -+static void fmc100_set_fmc_cfg_reg(struct fmc_host *host, -+ struct nand_config_info *type_info, struct nand_dev_t *nand_dev) -+{ -+ unsigned int page_reg, ecc_reg, block_reg, reg_fmc_cfg; -+ -+ ecc_reg = fmc100_get_ecc_reg(host, type_info, nand_dev); -+ page_reg = fmc100_get_page_reg(host, type_info); -+ block_reg = fmc100_get_block_reg(host, type_info); -+ -+ reg_fmc_cfg = fmc_readl(host, FMC_CFG); -+ reg_fmc_cfg &= ~(PAGE_SIZE_MASK | ECC_TYPE_MASK | BLOCK_SIZE_MASK); -+ reg_fmc_cfg |= ecc_reg | page_reg | block_reg; -+ fmc_writel(host, FMC_CFG, reg_fmc_cfg); -+ -+ /* Save value of FMC_CFG and FMC_CFG_ECC0 to turn on/off ECC */ -+ host->fmc_cfg = reg_fmc_cfg; -+ host->fmc_cfg_ecc0 = (host->fmc_cfg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT; -+ FMC_PR(BT_DBG, "\t|-Save FMC_CFG[%#x]: %#x and FMC_CFG_ECC0: %#x\n", -+ FMC_CFG, host->fmc_cfg, host->fmc_cfg_ecc0); -+} -+ -+/*****************************************************************************/ -+static int fmc100_set_config_info(struct mtd_info *mtd, -+ struct nand_chip *chip, struct nand_dev_t *nand_dev) -+{ -+ struct fmc_host *host = chip->priv; -+ struct nand_config_info *type_info = NULL; -+ -+ FMC_PR(BT_DBG, "\t*-Start config Block Page OOB and Ecc\n"); -+ -+ type_info = fmc100_get_config_type_info(mtd, nand_dev); -+ BUG_ON(!type_info); -+ -+ FMC_PR(BT_DBG, "\t|-%s Config, PageSize %s EccType %s OOBSize %d\n", -+ nand_dev->start_type, nand_page_name(type_info->pagetype), -+ nand_ecc_name(type_info->ecctype), type_info->oobsize); -+ -+ /* Set the page_size, ecc_type, block_size of FMC_CFG[0x0] register */ -+ fmc100_set_fmc_cfg_reg(host, type_info, nand_dev); -+ -+ fmc100_set_oob_info(mtd, type_info, nand_dev); -+ -+ FMC_PR(BT_DBG, "\t*-End config Block Page Oob and Ecc\n"); -+ -+ return 0; -+} -+ -+/*****************************************************************************/ -+int fmc100_spi_nand_init(struct nand_chip *chip) -+{ -+ struct fmc_host *host = chip->priv; -+ -+ FMC_PR(BT_DBG, "\t|*-Start fmc100 SPI Nand init\n"); -+ -+ /* Set system clock and enable controller */ -+ clk_prepare_enable(host->clk); -+ -+ /* Switch SPI type to SPI nand */ -+ fmc100_switch_to_spi_nand(host); -+ -+ /* hold on STR mode */ -+ fmc100_set_str_mode(host); -+ -+ /* fmc host init */ -+ fmc100_host_init(host); -+ host->chip = chip; -+ -+ /* fmc nand_chip struct init */ -+ fmc100_chip_init(chip); -+ -+ fmc_spi_nand_ids_register(); -+ nfc_param_adjust = fmc100_set_config_info; -+ -+ FMC_PR(BT_DBG, "\t|*-End fmc100 SPI Nand init\n"); -+ -+ return 0; -+} -+#ifdef CONFIG_PM -+/*****************************************************************************/ -+int fmc100_suspend(struct platform_device *pltdev, pm_message_t state) -+{ -+ unsigned int ret; -+ struct fmc_host *host = platform_get_drvdata(pltdev); -+ struct fmc_spi *spi = host->spi; -+ -+ mutex_lock(host->lock); -+ fmc100_switch_to_spi_nand(host); -+ -+ ret = spi->driver->wait_ready(spi); -+ if (ret) -+ DB_MSG("Error: wait ready failed!"); -+ -+ clk_disable_unprepare(host->clk); -+ mutex_unlock(host->lock); -+ -+ return 0; -+} -+/*****************************************************************************/ -+int fmc100_resume(struct platform_device *pltdev) -+{ -+ int cs; -+ struct fmc_host *host = platform_get_drvdata(pltdev); -+ struct nand_chip *chip = host->chip; -+ -+ mutex_lock(host->lock); -+ fmc100_switch_to_spi_nand(host); -+ clk_prepare_enable(host->clk); -+ -+ for (cs = 0; cs < chip->numchips; cs++) { -+ host->send_cmd_reset(host); -+ } -+ -+ fmc100_spi_nand_config(host); -+ -+ mutex_unlock(host->lock); -+ return 0; -+} -+#endif -+ ---- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,375 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __FMC100_H__ -+#define __FMC100_H__ -+ -+/*****************************************************************************/ -+#include -+#include -+ -+/*****************************************************************************/ -+#define INFINITE (0xFFFFFFFF) -+ -+/*****************************************************************************/ -+#define SPI_IF_READ_STD (0x01) -+#define SPI_IF_READ_FAST (0x02) -+#define SPI_IF_READ_DUAL (0x04) -+#define SPI_IF_READ_DUAL_ADDR (0x08) -+#define SPI_IF_READ_QUAD (0x10) -+#define SPI_IF_READ_QUAD_ADDR (0x20) -+ -+#define SPI_IF_WRITE_STD (0x01) -+#define SPI_IF_WRITE_DUAL (0x02) -+#define SPI_IF_WRITE_DUAL_ADDR (0x04) -+#define SPI_IF_WRITE_QUAD (0x08) -+#define SPI_IF_WRITE_QUAD_ADDR (0x10) -+ -+#define SPI_IF_ERASE_SECTOR_4K (0x01) -+#define SPI_IF_ERASE_SECTOR_32K (0x02) -+#define SPI_IF_ERASE_SECTOR_64K (0x04) -+#define SPI_IF_ERASE_SECTOR_128K (0x08) -+#define SPI_IF_ERASE_SECTOR_256K (0x10) -+ -+/******************************************************************************/ -+#define FMC_SPI_NAND_SUPPORT_READ (SPI_IF_READ_STD \ -+ | SPI_IF_READ_FAST \ -+ | SPI_IF_READ_DUAL \ -+ | SPI_IF_READ_DUAL_ADDR \ -+ | SPI_IF_READ_QUAD \ -+ | SPI_IF_READ_QUAD_ADDR) -+ -+#define FMC_SPI_NAND_SUPPORT_WRITE (SPI_IF_WRITE_STD | SPI_IF_WRITE_QUAD) -+ -+#define FMC_SPI_NAND_SUPPORT_MAX_DUMMY 8 -+ -+/*****************************************************************************/ -+#define SPI_CMD_READ_STD 0x03 /* Standard read cache */ -+#define SPI_CMD_READ_FAST 0x0B /* Higher speed read cache */ -+#define SPI_CMD_READ_DUAL 0x3B /* 2 IO read cache only date */ -+#define SPI_CMD_READ_DUAL_ADDR 0xBB /* 2 IO read cache date&addr */ -+#define SPI_CMD_READ_QUAD 0x6B /* 4 IO read cache only date */ -+#define SPI_CMD_READ_QUAD_ADDR 0xEB /* 4 IO read cache date&addr */ -+ -+#define SPI_CMD_WRITE_STD 0x02 /* Standard page program */ -+#define SPI_CMD_WRITE_DUAL 0xA2 /* 2 IO program only date */ -+#define SPI_CMD_WRITE_DUAL_ADDR 0xD2 /* 2 IO program date&addr */ -+#define SPI_CMD_WRITE_QUAD 0x32 /* 4 IO program only date */ -+#define SPI_CMD_WRITE_QUAD_ADDR 0x12 /* 4 IO program date&addr */ -+ -+#define SPI_CMD_SE_4K 0x20 /* 4KB sector Erase */ -+#define SPI_CMD_SE_32K 0x52 /* 32KB sector Erase */ -+#define SPI_CMD_SE_64K 0xD8 /* 64KB sector Erase */ -+#define SPI_CMD_SE_128K 0xD8 /* 128KB sector Erase */ -+#define SPI_CMD_SE_256K 0xD8 /* 256KB sector Erase */ -+ -+/*****************************************************************************/ -+#define SET_READ_STD(_dummy_, _size_, _clk_) \ -+ static struct spi_op read_std_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_READ_STD, SPI_CMD_READ_STD, _dummy_, _size_, _clk_ } -+ -+#define SET_READ_FAST(_dummy_, _size_, _clk_) \ -+ static struct spi_op read_fast_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_READ_FAST, SPI_CMD_READ_FAST, _dummy_, _size_, _clk_ } -+ -+#define SET_READ_DUAL(_dummy_, _size_, _clk_) \ -+ static struct spi_op read_dual_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_READ_DUAL, SPI_CMD_READ_DUAL, _dummy_, _size_, _clk_ } -+ -+#define SET_READ_DUAL_ADDR(_dummy_, _size_, _clk_) \ -+ static struct spi_op read_dual_addr_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_READ_DUAL_ADDR, SPI_CMD_READ_DUAL_ADDR, _dummy_, _size_, _clk_ } -+ -+#define SET_READ_QUAD(_dummy_, _size_, _clk_) \ -+ static struct spi_op read_quad_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_READ_QUAD, SPI_CMD_READ_QUAD, _dummy_, _size_, _clk_ } -+ -+#define SET_READ_QUAD_ADDR(_dummy_, _size_, _clk_) \ -+ static struct spi_op read_quad_addr_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_READ_QUAD_ADDR, SPI_CMD_READ_QUAD_ADDR, _dummy_, _size_, _clk_ } -+ -+/*****************************************************************************/ -+#define SET_WRITE_STD(_dummy_, _size_, _clk_) \ -+ static struct spi_op write_std_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_WRITE_STD, SPI_CMD_WRITE_STD, _dummy_, _size_, _clk_ } -+ -+#define SET_WRITE_DUAL(_dummy_, _size_, _clk_) \ -+ static struct spi_op write_dual_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_WRITE_DUAL, SPI_CMD_WRITE_DUAL, _dummy_, _size_, _clk_ } -+ -+#define SET_WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \ -+ static struct spi_op write_dual_addr_##_dummy_##_size_##_clk_ = { \ -+SPI_IF_WRITE_DUAL_ADDR, SPI_CMD_WRITE_DUAL_ADDR, _dummy_, _size_, _clk_ } -+ -+#define SET_WRITE_QUAD(_dummy_, _size_, _clk_) \ -+ static struct spi_op write_quad_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_WRITE_QUAD, SPI_CMD_WRITE_QUAD, _dummy_, _size_, _clk_ } -+ -+#define SET_WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \ -+ static struct spi_op write_quad_addr_##_dummy_##_size_##_clk_ = { \ -+SPI_IF_WRITE_QUAD_ADDR, SPI_CMD_WRITE_QUAD_ADDR, _dummy_, _size_, _clk_ } -+ -+/*****************************************************************************/ -+#define SET_ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \ -+ static struct spi_op erase_sector_4k_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_ERASE_SECTOR_4K, SPI_CMD_SE_4K, _dummy_, _size_, _clk_ } -+ -+#define SET_ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \ -+ static struct spi_op erase_sector_32k_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_ERASE_SECTOR_32K, SPI_CMD_SE_32K, _dummy_, _size_, _clk_ } -+ -+#define SET_ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \ -+ static struct spi_op erase_sector_64k_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_ERASE_SECTOR_64K, SPI_CMD_SE_64K, _dummy_, _size_, _clk_ } -+ -+#define SET_ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \ -+ static struct spi_op erase_sector_128k_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_ERASE_SECTOR_128K, SPI_CMD_SE_128K, _dummy_, _size_, _clk_ } -+ -+#define SET_ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \ -+ static struct spi_op erase_sector_256k_##_dummy_##_size_##_clk_ = { \ -+ SPI_IF_ERASE_SECTOR_256K, SPI_CMD_SE_256K, _dummy_, _size_, _clk_ } -+ -+/*****************************************************************************/ -+#define READ_STD(_dummy_, _size_, _clk_) read_std_##_dummy_##_size_##_clk_ -+#define READ_FAST(_dummy_, _size_, _clk_) read_fast_##_dummy_##_size_##_clk_ -+#define READ_DUAL(_dummy_, _size_, _clk_) read_dual_##_dummy_##_size_##_clk_ -+#define READ_DUAL_ADDR(_dummy_, _size_, _clk_) \ -+ read_dual_addr_##_dummy_##_size_##_clk_ -+#define READ_QUAD(_dummy_, _size_, _clk_) read_quad_##_dummy_##_size_##_clk_ -+#define READ_QUAD_ADDR(_dummy_, _size_, _clk_) \ -+ read_quad_addr_##_dummy_##_size_##_clk_ -+ -+/*****************************************************************************/ -+#define WRITE_STD(_dummy_, _size_, _clk_) write_std_##_dummy_##_size_##_clk_ -+#define WRITE_DUAL(_dummy_, _size_, _clk_) write_dual_##_dummy_##_size_##_clk_ -+#define WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \ -+ write_dual_addr_##_dummy_##_size_##_clk_ -+#define WRITE_QUAD(_dummy_, _size_, _clk_) write_quad_##_dummy_##_size_##_clk_ -+#define WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \ -+ write_quad_addr_##_dummy_##_size_##_clk_ -+ -+/*****************************************************************************/ -+#define ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \ -+ erase_sector_4k_##_dummy_##_size_##_clk_ -+#define ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \ -+ erase_sector_32k_##_dummy_##_size_##_clk_ -+#define ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \ -+ erase_sector_64k_##_dummy_##_size_##_clk_ -+#define ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \ -+ erase_sector_128k_##_dummy_##_size_##_clk_ -+#define ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \ -+ erase_sector_256k_##_dummy_##_size_##_clk_ -+ -+/*****************************************************************************/ -+#define SPI_CMD_WREN 0x06 /* Write Enable */ -+#define SPI_CMD_WRDI 0x04 /* Write Disable */ -+ -+#define SPI_CMD_RDID 0x9F /* Read Identification */ -+ -+/*****************************************************************************/ -+#define SPI_CMD_GET_FEATURES 0x0F /* Get Features */ -+#define SPI_CMD_SET_FEATURE 0x1F /* Set Feature */ -+ -+#define SPI_CMD_PAGE_READ 0x13 /* Page Read to Cache */ -+ -+#define SPI_CMD_RESET 0xff /* Reset the device */ -+ -+/*****************************************************************************/ -+/* These macroes are for debug only, reg option is slower then dma option */ -+#undef FMC100_SPI_NAND_SUPPORT_REG_READ -+/* #define FMC100_SPI_NAND_SUPPORT_REG_READ */ -+ -+#undef FMC100_SPI_NAND_SUPPORT_REG_WRITE -+/* #define FMC100_SPI_NAND_SUPPORT_REG_WRITE */ -+ -+#ifdef CONFIG_GOKE_NAND_ECC_STATUS_REPORT -+/*****************************************************************************/ -+#define FMC100_ECC_ERR_NUM0_BUF0 0xc0 -+ -+#define GET_ECC_ERR_NUM(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) -+#endif -+/*****************************************************************************/ -+#define REG_CNT_HIGH_BLOCK_NUM_SHIFT 10 -+ -+#define REG_CNT_BLOCK_NUM_MASK 0x3ff -+#define REG_CNT_BLOCK_NUM_SHIFT 22 -+ -+#define REG_CNT_PAGE_NUM_MASK 0x3f -+#define REG_CNT_PAGE_NUM_SHIFT 16 -+ -+#define REG_CNT_WRAP_MASK 0xf -+#define REG_CNT_WRAP_SHIFT 12 -+ -+#define REG_CNT_ECC_OFFSET_MASK 0xfff -+#define REG_CNT_ECC_8BIT_OFFSET 1054 -+#define REG_CNT_ECC_16BIT_OFFSET 1056 -+#define REG_CNT_ECC_24BIT_OFFSET 1082 -+ -+#define ERR_STR_DRIVER "Driver does not support this configure " -+#define ERR_STR_CHECK "Please make sure the hardware configuration is correct" -+ -+/*****************************************************************************/ -+#define FMC100_ADDR_CYCLE_MASK 0x2 -+ -+/*****************************************************************************/ -+#define OP_STYPE_NONE 0x0 -+#define OP_STYPE_READ 0x01 -+#define OP_STYPE_WRITE 0x02 -+#define OP_STYPE_ERASE 0x04 -+#define CLK_FMC_TO_CRG_MHZ(_clk) ((_clk) * 2000000) -+ -+/*****************************************************************************/ -+#define MAX_SPI_OP 8 -+ -+/*****************************************************************************/ -+/* SPI general operation parameter */ -+struct spi_op { -+ unsigned char iftype; -+ unsigned char cmd; -+ unsigned char dummy; -+ unsigned int size; -+ unsigned int clock; -+}; -+ -+struct spi_drv; -+ -+/* SPI interface all operation */ -+struct fmc_spi { -+ char *name; -+ int chipselect; -+ unsigned long long chipsize; -+ unsigned int erasesize; -+#define SPI_NOR_3BYTE_ADDR_LEN 3 /* address len 3Bytes */ -+#define SPI_NOR_4BYTE_ADDR_LEN 4 /* address len 4Bytes for 32MB */ -+ unsigned int addrcycle; -+ -+ struct spi_op read[1]; -+ struct spi_op write[1]; -+ struct spi_op erase[MAX_SPI_OP]; -+ -+ void *host; -+ -+ struct spi_drv *driver; -+}; -+ -+/* SPI interface special operation function hook */ -+struct spi_drv { -+ int (*wait_ready)(struct fmc_spi *spi); -+ int (*write_enable)(struct fmc_spi *spi); -+ int (*qe_enable)(struct fmc_spi *spi); -+ int (*bus_prepare)(struct fmc_spi *spi, int op); -+ int (*entry_4addr)(struct fmc_spi *spi, int en); -+}; -+ -+struct spi_nand_info { -+ char *name; -+ unsigned char id[MAX_SPI_NAND_ID_LEN]; -+ unsigned char id_len; -+ unsigned long long chipsize; -+ unsigned int erasesize; -+ unsigned int pagesize; -+ unsigned int oobsize; -+#define BBP_LAST_PAGE 0x01 -+#define BBP_FIRST_PAGE 0x02 -+ unsigned int badblock_pos; -+ struct spi_op *read[MAX_SPI_OP]; -+ struct spi_op *write[MAX_SPI_OP]; -+ struct spi_op *erase[MAX_SPI_OP]; -+ struct spi_drv *driver; -+}; -+ -+/*****************************************************************************/ -+extern u_char spi_nand_feature_op(struct fmc_spi *spi, u_char op, u_char addr, -+ u_char val); -+ -+/*****************************************************************************/ -+struct fmc_host { -+ struct mtd_info *mtd; -+ struct nand_chip *chip; -+ struct fmc_spi spi[CONFIG_SPI_NAND_MAX_CHIP_NUM]; -+ struct fmc_cmd_op cmd_op; -+ -+ void __iomem *iobase; -+ void __iomem *regbase; -+ struct clk *clk; -+ u32 clkrate; -+ -+ unsigned int fmc_cfg; -+ unsigned int fmc_cfg_ecc0; -+ -+ unsigned int offset; -+ -+ struct device *dev; -+ struct mutex *lock; -+ -+ /* This is maybe an un-aligment address, only for malloc or free */ -+ char *buforg; -+ char *buffer; -+ -+#ifdef CONFIG_64BIT -+ unsigned long long dma_buffer; -+ unsigned long long dma_oob; -+#else -+ unsigned int dma_buffer; -+ unsigned int dma_oob; -+#endif -+ -+ unsigned int addr_cycle; -+ unsigned int addr_value[2]; -+ unsigned int cache_addr_value[2]; -+ -+ unsigned int column; -+ unsigned int block_page_mask; -+ -+ unsigned int ecctype; -+ unsigned int pagesize; -+ unsigned int oobsize; -+ -+ int add_partition; -+ -+ int need_rr_data; -+#define FMC100_READ_RETRY_DATA_LEN 128 -+ char rr_data[FMC100_READ_RETRY_DATA_LEN]; -+ struct read_retry_t *read_retry; -+ -+ int version; -+ -+ /* BOOTROM read two bytes to detect the bad block flag */ -+#define FMC_BAD_BLOCK_POS 0 -+ unsigned char *bbm; /* nand bad block mark */ -+ unsigned short *epm; /* nand empty page mark */ -+ -+ unsigned int uc_er; -+ -+ void (*send_cmd_write)(struct fmc_host *host); -+ void (*send_cmd_status)(struct fmc_host *host); -+ void (*send_cmd_read)(struct fmc_host *host); -+ void (*send_cmd_erase)(struct fmc_host *host); -+ void (*send_cmd_readid)(struct fmc_host *host); -+ void (*send_cmd_reset)(struct fmc_host *host); -+#ifdef CONFIG_PM -+ int (*suspend)(struct platform_device *pltdev, pm_message_t state); -+ int (*resume)(struct platform_device *pltdev); -+#endif -+}; -+ -+/*****************************************************************************/ -+void fmc100_ecc0_switch(struct fmc_host *host, unsigned char op); -+ -+int fmc100_spi_nand_init(struct nand_chip *chip); -+ -+/*****************************************************************************/ -+extern void fmc_spi_nand_ids_register(void); -+ -+extern void fmc_set_nand_system_clock(struct spi_op *op, int clk_en); -+ -+/*****************************************************************************/ -+#ifdef CONFIG_PM -+int fmc100_suspend(struct platform_device *pltdev, pm_message_t state); -+int fmc100_resume(struct platform_device *pltdev); -+void fmc100_spi_nand_config(struct fmc_host *host); -+#endif -+ -+#endif /* End of __FMC100_H__ */ ---- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100_os.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100_os.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,223 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../../mtdcore.h" -+#include "fmc100.h" -+ -+/*****************************************************************************/ -+static int fmc100_spi_nand_pre_probe(struct nand_chip *chip) -+{ -+ uint8_t nand_maf_id; -+ struct fmc_host *host = chip->priv; -+ -+ /* Reset the chip first */ -+ host->send_cmd_reset(host); -+ udelay(1000); -+ -+ /* Check the ID */ -+ host->offset = 0; -+ memset((unsigned char *)(chip->IO_ADDR_R), 0, 0x10); -+ host->send_cmd_readid(host); -+ nand_maf_id = fmc_readb(chip->IO_ADDR_R); -+ -+ if (nand_maf_id == 0x00 || nand_maf_id == 0xff) { -+ printk("Cannot found a valid SPI Nand Device\n"); -+ return 1; -+ } -+ -+ return 0; -+} -+/*****************************************************************************/ -+static int fmc_nand_scan(struct mtd_info *mtd) -+{ -+ int result = 0; -+ unsigned char cs, chip_num = CONFIG_SPI_NAND_MAX_CHIP_NUM; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ -+ for (cs = 0; chip_num && (cs < FMC_MAX_CHIP_NUM); cs++) { -+ if (fmc_cs_user[cs]) { -+ FMC_PR(BT_DBG, "\t\t*-Current CS(%d) is occupied.\n", -+ cs); -+ continue; -+ } -+ -+ host->cmd_op.cs = cs; -+ -+ if (fmc100_spi_nand_pre_probe(chip)) { -+ return -ENODEV; -+ } -+ -+ FMC_PR(BT_DBG, "\t\t*-Scan SPI nand flash on CS: %d\n", cs); -+ if (nand_scan(mtd, chip_num)) { -+ continue; -+ } -+ chip_num--; -+ } -+ -+ if (chip_num == CONFIG_SPI_NAND_MAX_CHIP_NUM) { -+ result = -ENXIO; -+ } else { -+ result = 0; -+ } -+ -+ return result; -+} -+ -+/*****************************************************************************/ -+static int bsp_spi_nand_probe(struct platform_device *pltdev) -+{ -+ int len, result = 0; -+ struct fmc_host *host = NULL; -+ struct nand_chip *chip = NULL; -+ struct mtd_info *mtd = NULL; -+ struct device *dev = &pltdev->dev; -+ struct device_node *np = NULL; -+ struct bsp_fmc *fmc = dev_get_drvdata(dev->parent); -+ -+ FMC_PR(BT_DBG, "\t*-Start SPI Nand flash driver probe\n"); -+ -+ if (!fmc) { -+ dev_err(dev, "get mfd fmc devices failed\n"); -+ return -ENXIO; -+ } -+ -+ len = sizeof(struct fmc_host) + sizeof(struct nand_chip) -+ + sizeof(struct mtd_info); -+ host = devm_kzalloc(dev, len, GFP_KERNEL); -+ if (!host) { -+ return -ENOMEM; -+ } -+ memset((char *)host, 0, len); -+ -+ platform_set_drvdata(pltdev, host); -+ host->dev = &pltdev->dev; -+ -+ host->chip = chip = (struct nand_chip *)&host[1]; -+ host->mtd = mtd = nand_to_mtd(chip); -+ -+ host->regbase = fmc->regbase; -+ host->iobase = fmc->iobase; -+ host->clk = fmc->clk; -+ host->lock = &fmc->lock; -+ host->buffer = fmc->buffer; -+ host->dma_buffer = fmc->dma_buffer; -+ -+ memset((char *)host->iobase, 0xff, fmc->dma_len); -+ chip->IO_ADDR_R = chip->IO_ADDR_W = host->iobase; -+ -+ chip->priv = host; -+ result = fmc100_spi_nand_init(chip); -+ if (result) { -+ FMC_PR(BT_DBG, "\t|-SPI Nand init failed, ret: %d\n", result); -+ result = -ENODEV; -+ goto fail; -+ } -+ -+ np = of_get_next_available_child(dev->of_node, NULL); -+ mtd->name = np->name; -+ mtd->type = MTD_NANDFLASH; -+ mtd->priv = chip; -+ mtd->owner = THIS_MODULE; -+ -+ result = of_property_read_u32(np, "spi-max-frequency", &host->clkrate); -+ if (result) { -+ goto fail; -+ } -+ -+ result = fmc_nand_scan(mtd); -+ if (result) { -+ FMC_PR(BT_DBG, "\t|-Scan SPI Nand failed.\n"); -+ goto fail; -+ } -+ -+ result = mtd_device_register(mtd, NULL, 0); -+ if (!result) { -+ FMC_PR(BT_DBG, "\t*-End driver probe !!\n"); -+ return 0; -+ } -+ -+ result = -ENODEV; -+fail: -+ clk_disable_unprepare(host->clk); -+ nand_release(mtd); -+ -+ DB_MSG("Error: driver probe, result: %d\n", result); -+ return result; -+} -+ -+/*****************************************************************************/ -+static int bsp_spi_nand_remove(struct platform_device *pltdev) -+{ -+ struct fmc_host *host = platform_get_drvdata(pltdev); -+ if (host == NULL){ -+ FMC_PR(BT_DBG, "\t*host is NULL ,remove err !!\n"); -+ return 0; -+ } -+ clk_disable_unprepare(host->clk); -+ nand_release(host->mtd); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+/*****************************************************************************/ -+static int fmc100_os_suspend(struct platform_device *pltdev, -+ pm_message_t state) -+{ -+ struct fmc_host *host = platform_get_drvdata(pltdev); -+ -+ if (host && host->suspend) { -+ return (host->suspend)(pltdev, state); -+ } -+ -+ return 0; -+} -+ -+/*****************************************************************************/ -+static int fmc100_os_resume(struct platform_device *pltdev) -+{ -+ struct fmc_host *host = platform_get_drvdata(pltdev); -+ -+ if (host && host->resume) { -+ return (host->resume)(pltdev); -+ } -+ -+ return 0; -+} -+#endif /* End of CONFIG_PM */ -+/*****************************************************************************/ -+static const struct of_device_id bsp_spi_nand_dt_ids[] = { -+ { .compatible = "goke,fmc-spi-nand"}, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, bsp_spi_nand_dt_ids); -+ -+static struct platform_driver bsp_spi_nand_driver = { -+ .driver = { -+ .name = "bsp_spi_nand", -+ .of_match_table = bsp_spi_nand_dt_ids, -+ }, -+ .probe = bsp_spi_nand_probe, -+ .remove = bsp_spi_nand_remove, -+#ifdef CONFIG_PM -+ .suspend = fmc100_os_suspend, -+ .resume = fmc100_os_resume, -+#endif -+}; -+module_platform_driver(bsp_spi_nand_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Goke Flash Memory Controller V100 SPI Nand Driver"); ---- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100_spi_general.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100_spi_general.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,246 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+/* -+ Send set/get features command to SPI Nand flash -+*/ -+u_char spi_nand_feature_op(struct fmc_spi *spi, u_char op, u_char addr, -+ u_char val) -+{ -+ unsigned int reg; -+ const char *str[] = {"Get", "Set"}; -+ struct fmc_host *host = (struct fmc_host *)spi->host; -+ -+ if ((op == GET_OP) && (STATUS_ADDR == addr)) { -+ if (SR_DBG) { -+ pr_info("\n"); -+ } -+ FMC_PR(SR_DBG, "\t\t|*-Start Get Status\n"); -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(SR_DBG, "\t\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START; -+ fmc_writel(host, FMC_OP, reg); -+ FMC_PR(SR_DBG, "\t\t||-Set OP[%#x]%#x\n", FMC_OP, reg); -+ -+ FMC_CMD_WAIT_CPU_FINISH(host); -+ -+ val = fmc_readl(host, FMC_STATUS); -+ FMC_PR(SR_DBG, "\t\t|*-End Get Status, result: %#x\n", val); -+ -+ return val; -+ } -+ -+ FMC_PR(FT_DBG, "\t|||*-Start %s feature, addr[%#x]\n", str[op], addr); -+ -+ fmc100_ecc0_switch(host, ENABLE); -+ -+ reg = FMC_CMD_CMD1(op ? SPI_CMD_SET_FEATURE : SPI_CMD_GET_FEATURES); -+ fmc_writel(host, FMC_CMD, reg); -+ FMC_PR(FT_DBG, "\t||||-Set CMD[%#x]%#x\n", FMC_CMD, reg); -+ -+ fmc_writel(host, FMC_ADDRL, addr); -+ FMC_PR(FT_DBG, "\t||||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, addr); -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) -+ | OP_CFG_ADDR_NUM(FEATURES_OP_ADDR_NUM) -+ | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(FT_DBG, "\t||||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ reg = FMC_DATA_NUM_CNT(FEATURES_DATA_LEN); -+ fmc_writel(host, FMC_DATA_NUM, reg); -+ FMC_PR(FT_DBG, "\t||||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg); -+ -+ reg = FMC_OP_CMD1_EN -+ | FMC_OP_ADDR_EN -+ | FMC_OP_REG_OP_START; -+ -+ if (op == SET_OP) { -+ reg |= FMC_OP_WRITE_DATA_EN; -+ fmc_writeb(val, host->iobase); -+ FMC_PR(FT_DBG, "\t||||-Write IO[%#lx]%#x\n", (long)host->iobase, -+ *(u_char *)host->iobase); -+ } else { -+ reg |= FMC_OP_READ_DATA_EN; -+ } -+ -+ fmc_writel(host, FMC_OP, reg); -+ FMC_PR(FT_DBG, "\t||||-Set OP[%#x]%#x\n", FMC_OP, reg); -+ -+ FMC_CMD_WAIT_CPU_FINISH(host); -+ -+ if (op == GET_OP) { -+ val = fmc_readb(host->iobase); -+ FMC_PR(FT_DBG, "\t||||-Read IO[%#lx]%#x\n", (long)host->iobase, -+ *(u_char *)host->iobase); -+ } -+ -+ fmc100_ecc0_switch(host, DISABLE); -+ -+ FMC_PR(FT_DBG, "\t|||*-End %s Feature[%#x]:%#x\n", str[op], addr, val); -+ -+ return val; -+} -+ -+/*****************************************************************************/ -+/* -+ Read status[C0H]:[0]bit OIP, judge whether the device is busy or not -+*/ -+static int spi_general_wait_ready(struct fmc_spi *spi) -+{ -+ unsigned char status; -+ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; -+ struct fmc_host *host = (struct fmc_host *)spi->host; -+ -+ do { -+ status = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, 0); -+ if (!(status & STATUS_OIP_MASK)) { -+ if ((host->cmd_op.l_cmd == NAND_CMD_ERASE2) -+ && (status & STATUS_E_FAIL_MASK)) { -+ return status; -+ } -+ if ((host->cmd_op.l_cmd == NAND_CMD_PAGEPROG) -+ && (status & STATUS_P_FAIL_MASK)) { -+ return status; -+ } -+ return 0; -+ } -+ -+ cond_resched(); -+ -+ } while (!time_after_eq(jiffies, deadline)); -+ -+ DB_MSG("Error: SPI Nand wait ready timeout, status: %#x\n", status); -+ -+ return 1; -+} -+ -+/*****************************************************************************/ -+/* -+ Send write enable cmd to SPI Nand, status[C0H]:[2]bit WEL must be set 1 -+*/ -+static int spi_general_write_enable(struct fmc_spi *spi) -+{ -+ unsigned int reg; -+ struct fmc_host *host = (struct fmc_host *)spi->host; -+ -+ if (WE_DBG) { -+ pr_info("\n"); -+ } -+ FMC_PR(WE_DBG, "\t|*-Start Write Enable\n"); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, 0); -+ if (reg & STATUS_WEL_MASK) { -+ FMC_PR(WE_DBG, "\t||-Write Enable was opened! reg: %#x\n", -+ reg); -+ return 0; -+ } -+ -+ reg = fmc_readl(host, FMC_GLOBAL_CFG); -+ FMC_PR(WE_DBG, "\t||-Get GLOBAL_CFG[%#x]%#x\n", FMC_GLOBAL_CFG, reg); -+ if (reg & FMC_GLOBAL_CFG_WP_ENABLE) { -+ reg &= ~FMC_GLOBAL_CFG_WP_ENABLE; -+ fmc_writel(host, FMC_GLOBAL_CFG, reg); -+ FMC_PR(WE_DBG, "\t||-Set GLOBAL_CFG[%#x]%#x\n", -+ FMC_GLOBAL_CFG, reg); -+ } -+ -+ reg = FMC_CMD_CMD1(SPI_CMD_WREN); -+ fmc_writel(host, FMC_CMD, reg); -+ FMC_PR(WE_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg); -+ -+ reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ FMC_PR(WE_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg); -+ -+ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START; -+ fmc_writel(host, FMC_OP, reg); -+ FMC_PR(WE_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg); -+ -+ FMC_CMD_WAIT_CPU_FINISH(host); -+ -+#if WE_DBG -+ spi->driver->wait_ready(spi); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, 0); -+ if (reg & STATUS_WEL_MASK) { -+ FMC_PR(WE_DBG, "\t||-Write Enable success. reg: %#x\n", reg); -+ } else { -+ DB_MSG("Error: Write Enable failed! reg: %#x\n", reg); -+ return reg; -+ } -+#endif -+ -+ FMC_PR(WE_DBG, "\t|*-End Write Enable\n"); -+ return 0; -+} -+ -+/*****************************************************************************/ -+/* -+ judge whether SPI Nand support QUAD read/write or not -+*/ -+static int spi_is_quad(struct fmc_spi *spi) -+{ -+ const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; -+ -+ FMC_PR(QE_DBG, "\t\t|||*-SPI read iftype: %s write iftype: %s\n", -+ if_str[spi->read->iftype], if_str[spi->write->iftype]); -+ -+ if ((spi->read->iftype == IF_TYPE_QUAD) -+ || (spi->read->iftype == IF_TYPE_QIO) -+ || (spi->write->iftype == IF_TYPE_QUAD) -+ || (spi->write->iftype == IF_TYPE_QIO)) { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/*****************************************************************************/ -+/* -+ Send set features cmd to SPI Nand, feature[B0H]:[0]bit QE would be set -+*/ -+static int spi_general_qe_enable(struct fmc_spi *spi) -+{ -+ unsigned int reg, op; -+ const char *str[] = {"Disable", "Enable"}; -+ -+ FMC_PR(QE_DBG, "\t||*-Start SPI Nand flash QE\n"); -+ -+ op = spi_is_quad(spi); -+ -+ FMC_PR(QE_DBG, "\t|||*-End Quad check, SPI Nand %s Quad.\n", str[op]); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); -+ FMC_PR(QE_DBG, "\t|||-Get [%#x]feature: %#x\n", FEATURE_ADDR, reg); -+ if ((reg & FEATURE_QE_ENABLE) == op) { -+ FMC_PR(QE_DBG, "\t||*-SPI Nand quad was %sd!\n", str[op]); -+ return op; -+ } -+ -+ if (op == ENABLE) { -+ reg |= FEATURE_QE_ENABLE; -+ } else { -+ reg &= ~FEATURE_QE_ENABLE; -+ } -+ -+ spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, reg); -+ FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad\n", str[op]); -+ -+ spi->driver->wait_ready(spi); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); -+ if ((reg & FEATURE_QE_ENABLE) == op) { -+ FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad succeed!\n", str[op]); -+ } else { -+ DB_MSG("Error: %s Quad failed! reg: %#x\n", str[op], reg); -+ } -+ -+ FMC_PR(QE_DBG, "\t||*-End SPI Nand %s Quad.\n", str[op]); -+ -+ return op; -+} ---- linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc_spi_nand_ids.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc_spi_nand_ids.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,2270 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../nfc_gen.h" -+#include "fmc100.h" -+ -+/*****************************************************************************/ -+SET_READ_STD(1, INFINITE, 24); -+ -+SET_READ_FAST(1, INFINITE, 80); -+SET_READ_FAST(1, INFINITE, 100); -+SET_READ_FAST(1, INFINITE, 104); -+SET_READ_FAST(1, INFINITE, 108); -+SET_READ_FAST(1, INFINITE, 120); -+SET_READ_FAST(1, INFINITE, 133); -+ -+SET_READ_DUAL(1, INFINITE, 80); -+SET_READ_DUAL(1, INFINITE, 100); -+SET_READ_DUAL(1, INFINITE, 104); -+SET_READ_DUAL(1, INFINITE, 108); -+SET_READ_DUAL(1, INFINITE, 120); -+SET_READ_DUAL(1, INFINITE, 133); -+ -+SET_READ_DUAL_ADDR(1, INFINITE, 40); -+SET_READ_DUAL_ADDR(1, INFINITE, 80); -+SET_READ_DUAL_ADDR(2, INFINITE, 80); -+SET_READ_DUAL_ADDR(1, INFINITE, 100); -+SET_READ_DUAL_ADDR(1, INFINITE, 104); -+SET_READ_DUAL_ADDR(1, INFINITE, 108); -+SET_READ_DUAL_ADDR(1, INFINITE, 120); -+SET_READ_DUAL_ADDR(2, INFINITE, 104); -+ -+SET_READ_QUAD(1, INFINITE, 80); -+SET_READ_QUAD(1, INFINITE, 100); -+SET_READ_QUAD(1, INFINITE, 104); -+SET_READ_QUAD(1, INFINITE, 108); -+SET_READ_QUAD(1, INFINITE, 120); -+SET_READ_QUAD(1, INFINITE, 133); -+ -+SET_READ_QUAD_ADDR(2, INFINITE, 40); -+SET_READ_QUAD_ADDR(1, INFINITE, 80); -+SET_READ_QUAD_ADDR(2, INFINITE, 80); -+SET_READ_QUAD_ADDR(4, INFINITE, 80); -+SET_READ_QUAD_ADDR(1, INFINITE, 100); -+SET_READ_QUAD_ADDR(1, INFINITE, 104); -+SET_READ_QUAD_ADDR(2, INFINITE, 104); -+SET_READ_QUAD_ADDR(1, INFINITE, 108); -+SET_READ_QUAD_ADDR(1, INFINITE, 120); -+SET_READ_QUAD_ADDR(4, INFINITE, 104); -+ -+/*****************************************************************************/ -+SET_WRITE_STD(0, 256, 24); -+SET_WRITE_STD(0, 256, 75); -+SET_WRITE_STD(0, 256, 80); -+SET_WRITE_STD(0, 256, 100); -+SET_WRITE_STD(0, 256, 104); -+SET_WRITE_STD(0, 256, 133); -+ -+SET_WRITE_QUAD(0, 256, 80); -+SET_WRITE_QUAD(0, 256, 100); -+SET_WRITE_QUAD(0, 256, 104); -+SET_WRITE_QUAD(0, 256, 108); -+SET_WRITE_QUAD(0, 256, 120); -+SET_WRITE_QUAD(0, 256, 133); -+ -+/*****************************************************************************/ -+SET_ERASE_SECTOR_128K(0, _128K, 24); -+SET_ERASE_SECTOR_128K(0, _128K, 75); -+SET_ERASE_SECTOR_128K(0, _128K, 80); -+SET_ERASE_SECTOR_128K(0, _128K, 104); -+SET_ERASE_SECTOR_128K(0, _128K, 133); -+ -+SET_ERASE_SECTOR_256K(0, _256K, 24); -+SET_ERASE_SECTOR_256K(0, _256K, 75); -+SET_ERASE_SECTOR_256K(0, _256K, 80); -+SET_ERASE_SECTOR_256K(0, _256K, 100); -+SET_ERASE_SECTOR_256K(0, _256K, 104); -+SET_ERASE_SECTOR_256K(0, _256K, 133); -+ -+/*****************************************************************************/ -+#include "fmc100_spi_general.c" -+static struct spi_drv spi_driver_general = { -+ .wait_ready = spi_general_wait_ready, -+ .write_enable = spi_general_write_enable, -+ .qe_enable = spi_general_qe_enable, -+}; -+ -+/* some spi nand flash default QUAD enable, needn't to set qe enable */ -+static struct spi_drv spi_driver_no_qe = { -+ .wait_ready = spi_general_wait_ready, -+ .write_enable = spi_general_write_enable, -+}; -+ -+/*****************************************************************************/ -+#define SPI_NAND_ID_TAB_VER "2.7" -+ -+/******* SPI Nand ID Table *************************************************** -+ * Version Manufacturer Chip Name Size Operation -+ * 1.0 ESMT F50L512M41A 64MB Add 5 chip -+ * GD 5F1GQ4UAYIG 128MB -+ * GD 5F2GQ4UAYIG 256MB -+ * GD GD5F2GQ5UEYIG 256MB -+ * GD 5F4GQ4UAYIG 512MB -+ * GD 5F4GQ4UBYIG 512MB -+ * GD 5F1GQ4RB9IG 128MB -+ * GD 5F1GQ4UEYIHY 128MB -+ * 1.1 ESMT F50L1G41A 128MB Add 2 chip -+ * Winbond W25N01GV 128MB -+ * Winbond W25N02JWZEIF 256MB -+ * 1.2 GD 5F1GQ4UBYIG 128MB Add 2 chip -+ * GD 5F2GQ4U9IGR/BYIG 256MB -+ * GD 1.8V 5F4GQ6RE9IG 512MB -+ * 1.3 ATO ATO25D1GA 128MB Add 1 chip -+ * 1.4 MXIC MX35LF1GE4AB 128MB Add 2 chip -+ * MXIC MX35LF2GE4AB 256MB (SOP-16Pin) -+ * 1.5 Paragon PN26G01A 128MB Add 1 chip -+ * 1.6 All-flash AFS1GQ4UAC 128MB Add 1 chip -+ * 1.7 TOSHIBA TC58CVG0S3H 128MB Add 2 chip -+ * TOSHIBA TC58CVG2S0H 512MB -+ * 1.8 ALL-flash AFS2GQ4UAD 256MB Add 2 chip -+ * Paragon PN26G02A 256MB -+ * 1.9 TOSHIBA TC58CVG1S3H 256MB Add 1 chip -+ * 2.0 HeYangTek HYF1GQ4UAACAE 128MB Add 3 chip -+ * HeYangTek HYF2GQ4UAACAE 256MB -+ * HeYangTek HYF4GQ4UAACBE 512MB -+ * 2.1 Micron MT29F1G01ABA 128MB Add 5 chip -+ TOSHIBA 1.8V TC58CYG0S3H 128MB -+ TOSHIBA 1.8V TC58CYG1S3H 256MB -+ TOSHIBA 1.8V TC58CYG2S0H 512MB -+ Winbond 1.8V W25N01GWZEIG 128MB -+ * 2.2 Micron MT29F2G01ABA 256MB Add 1 chip -+ * 2.3 MXIC MX35LF2G14AC 256MB Add 1 chip -+ * 2.4 GD 1.8V 5F4GQ4RAYIG 512MB Add 1 chip -+ * 2.5 GD 1.8V 5F2GQ4RB9IGR 256MB Add 1 chip -+ * 2.6 MXIC 1.8V MX35UF1G14AC 128MB Add 4 chip -+ * MXIC 1.8V MX35UF2G14AC 256MB -+ * Micron 1.8V MT29F1G01ABB 128MB -+ * Micron 1.8V MT29F2G01ABB 256MB -+ * 2.7 Dosilicon DS35Q1GA-IB 128MB Add 2 chip -+ * Dosilicon DS35Q2GA-IB 256MB -+ * GD 5F1GQ4RB9IGR 128MB -+ * Micron MT29F4G01ADAG 512MB 3.3V Add 1 chip -+ * GD 1.8V 5F4GQ4RBYIG 512MB Add 1 chip -+ * Etron 1.8V EM78D044VCF-H 256MB -+ * Etron 3.3V EM73C044VCC-H 128MB -+ * XTX 3.3V XT26G01B 1Gbit 128MB -+ * Micron MT29F4G01ABBFDW 512MB 1.8V -+ * FM FM25S01-DND-A-G 128MB 3.3V -+ * FM FM25S01A 128MB 3.3V -+ ******************************************************************************/ -+struct spi_nand_info fmc_spi_nand_flash_table[] = { -+ /* Micron MT29F1G01ABA 1GBit */ -+ { -+ .name = "MT29F1G01ABA", -+ .id = {0x2C, 0x14}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(2, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* Micron MT29F1G01ABB 1GBit 1.8V */ -+ { -+ .name = "MT29F1G01ABB", -+ .id = {0x2C, 0x15}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(2, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* Micron MT29F2G01ABA 2GBit */ -+ { -+ .name = "MT29F2G01ABA", -+ .id = {0x2C, 0x24}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 108), -+ &READ_DUAL(1, INFINITE, 108), -+ &READ_DUAL_ADDR(1, INFINITE, 108), -+ &READ_QUAD(1, INFINITE, 108), -+ &READ_QUAD_ADDR(2, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 108), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* Micron MT29F2G01ABB 2GBit 1.8V */ -+ { -+ .name = "MT29F2G01ABB", -+ .id = {0x2C, 0x25}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(2, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* Micron MT29F4G01ADAG 4GBit 3.3V */ -+ { -+ .name = "MT29F4G01ADAG", -+ .id = {0x2C, 0x36}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 108), -+ &READ_DUAL(1, INFINITE, 108), -+ &READ_DUAL_ADDR(1, INFINITE, 108), -+ &READ_QUAD(1, INFINITE, 108), -+ &READ_QUAD_ADDR(2, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 108), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* ESMT F50L512M41A 512Mbit */ -+ { -+ .name = "F50L512M41A", -+ .id = {0xC8, 0x20}, -+ .id_len = 2, -+ .chipsize = _64M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* ESMT F50L1G41A 1Gbit */ -+ { -+ .name = "F50L1G41A", -+ .id = {0xC8, 0x21}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* ESMT F50L1G41LB-104YG2ME 1Gbit */ -+ { -+ .name = "F50L1G41LB-104YG2ME", -+ .id = {0xC8, 0x01, 0X7F}, -+ .id_len = 3, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* GD 3.3v GD5F1GQ4UAYIG 1Gbit */ -+ { -+ .name = "GD5F1GQ4UAYIG", -+ .id = {0xc8, 0xf1}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 3.3v GD5F1GQ4UEYIHY 1Gbit */ -+ { -+ .name = "GD5F1GQ4UEYIHY", -+ .id = {0xc8, 0xd9}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 1.8v GD5F1GQ4RB9IG 1Gbit */ -+ { -+ .name = "GD5F1GQ4RB9IG", -+ .id = {0xc8, 0xc1}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 3.3v GD5F1GQ4UBYIG 1Gbit */ -+ { -+ .name = "GD5F1GQ4UBYIG", -+ .id = {0xc8, 0xd1}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 3.3v GD5F2GQ4UAYIG 2Gbit */ -+ { -+ .name = "GD5F2GQ4UAYIG", -+ .id = {0xc8, 0xf2}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 3.3v GD5F2GQ4U9IGR/BYIG 2Gbit */ -+ { -+ .name = "GD5F2GQ4U9IGR/BYIG", -+ .id = {0xc8, 0xd2}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ /* GD 3.3v GD5F2GQ5UEYIG 2Gbit */ -+ { -+ .name = "GD5F2GQ5UEYIG", -+ .id = {0xc8, 0x52}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_DUAL_ADDR(2, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ &READ_QUAD_ADDR(4, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 3.3v GD5F4GQ4UAYIG 4Gbit */ -+ { -+ .name = "GD5F4GQ4UAYIG", -+ .id = {0xc8, 0xf4}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 3.3v GD5F4GQ4UBYIG 4Gbit */ -+ { -+ .name = "GD5F4GQ4UBYIG", -+ .id = {0xc8, 0xd4}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 3.3v GD5F4GQ6UEYIG 4Gbit */ -+ { -+ .name = "GD5F4GQ6UEYIG", -+ .id = {0xc8, 0x55}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), /* 24MHz */ -+ &READ_FAST(1, INFINITE, 104), /* 104MHz */ -+ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ -+ &READ_DUAL_ADDR(2, INFINITE, 104), /* 104MHz */ -+ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ -+ &READ_QUAD_ADDR(4, INFINITE, 104), /* 104MHz */ -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), /* 24MHz */ -+ &WRITE_QUAD(0, 256, 104), /* 104MHz */ -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 1.8V GD5F1GQ4RB9IGR 1Gbit */ -+ { -+ .name = "GD5F1GQ4RB9IGR", -+ .id = {0xc8, 0xc1}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_DUAL_ADDR(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ &READ_QUAD_ADDR(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 1.8V GD5F2GQ4RB9IGR 2Gbit */ -+ { -+ .name = "GD5F2GQ4RB9IGR", -+ .id = {0xc8, 0xc2}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_DUAL_ADDR(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ &READ_QUAD_ADDR(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ /* GD 1.8V 5F4GQ6RE9IG 4Gbit */ -+ { -+ .name = "GD5F4GQ6RE9IG", -+ .id = {0xc8, 0x45}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(2, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(4, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ /* GD 1.8V GD5F4GQ4RAYIG 4Gbit */ -+ { -+ .name = "GD5F4GQ4RAYIG", -+ .id = {0xc8, 0xe4}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_DUAL_ADDR(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ &READ_QUAD_ADDR(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Winbond 1.8V W25N02JWZEIF 2Gbit */ -+ { -+ .name = "W25N02JWZEIF", -+ .id = {0xef, 0xbf, 0x22}, -+ .id_len = 3, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(2, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* GD 1.8V 5F4GQ4RBYIG 4Gbit */ -+ { -+ .name = "5F4GQ4RBYIG", -+ .id = {0xc8, 0xc4}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Winbond W25N01GV 1Gbit 3.3V */ -+ { -+ .name = "W25N01GV", -+ .id = {0xef, 0xaa, 0x21}, -+ .id_len = 3, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_DUAL_ADDR(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ &READ_QUAD_ADDR(2, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* Winbond W25N01GWZEIG 1Gbit 1.8V */ -+ { -+ .name = "W25N01GWZEIG", -+ .id = {0xef, 0xba, 0x21}, -+ .id_len = 3, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_DUAL_ADDR(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ &READ_QUAD_ADDR(2, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* ATO ATO25D1GA 1Gbit */ -+ { -+ .name = "ATO25D1GA", -+ .id = {0x9b, 0x12}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* MXIC MX35LF1GE4AB 1Gbit */ -+ { -+ .name = "MX35LF1GE4AB", -+ .id = {0xc2, 0x12}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* MXIC MX35UF1G14AC 1Gbit 1.8V */ -+ { -+ .name = "MX35UF1G14AC", -+ .id = {0xc2, 0x90}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* MXIC MX35LF2GE4AB 2Gbit SOP-16Pin */ -+ { -+ .name = "MX35LF2GE4AB", -+ .id = {0xc2, 0x22}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* MXIC MX35LF2G14AC 2GBit */ -+ { -+ .name = "MX35LF2G14AC", -+ .id = {0xc2, 0x20}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* MXIC MX35UF2G14AC 2Gbit 1.8V */ -+ { -+ .name = "MX35UF2G14AC", -+ .id = {0xc2, 0xa0}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Paragon PN26G01A 1Gbit */ -+ { -+ .name = "PN26G01A", -+ .id = {0xa1, 0xe1}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 108), -+ &READ_DUAL(1, INFINITE, 108), -+ &READ_DUAL_ADDR(1, INFINITE, 108), -+ &READ_QUAD(1, INFINITE, 108), -+ &READ_QUAD_ADDR(1, INFINITE, 108), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 108), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Paragon PN26G02A 2Gbit */ -+ { -+ .name = "PN26G02A", -+ .id = {0xa1, 0xe2}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 108), -+ &READ_DUAL(1, INFINITE, 108), -+ &READ_DUAL_ADDR(1, INFINITE, 108), -+ &READ_QUAD(1, INFINITE, 108), -+ &READ_QUAD_ADDR(1, INFINITE, 108), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 108), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* All-flash AFS1GQ4UAC 1Gbit */ -+ { -+ .name = "AFS1GQ4UAC", -+ .id = {0xc1, 0x51}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(1, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* All-flash AFS2GQ4UAD 2Gbit */ -+ { -+ .name = "AFS2GQ4UAD", -+ .id = {0xc1, 0x52}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(1, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 24), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 24), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* TOSHIBA TC58CVG0S3H 1Gbit */ -+ { -+ .name = "TC58CVG0S3H", -+ .id = {0x98, 0xc2}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CVG0S3HRAIJ 1Gbit */ -+ { -+ .name = "TC58CVG0S3HRAIJ", -+ .id = {0x98, 0xe2, 0x40}, -+ .id_len = 3, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 133), -+ &READ_DUAL(1, INFINITE, 133), -+ &READ_QUAD(1, INFINITE, 133), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 133), -+ &WRITE_QUAD(0, 256, 133), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 133), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CYG0S3H 1.8V 1Gbit */ -+ { -+ .name = "TC58CYG0S3H", -+ .id = {0x98, 0xb2}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CYG0S3HRAIJ 1.8V 1Gbit */ -+ { -+ .name = "TC58CYG0S3HRAIJ", -+ .id = {0x98, 0xD2, 0x40}, -+ .id_len = 3, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 133), -+ &READ_DUAL(1, INFINITE, 133), -+ &READ_QUAD(1, INFINITE, 133), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 133), -+ &WRITE_QUAD(0, 256, 133), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 133), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CVG1S3H 2Gbit */ -+ { -+ .name = "TC58CVG1S3H", -+ .id = {0x98, 0xcb}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CVG1S3HRAIJ 2Gbit */ -+ { -+ .name = "TC58CVG1S3HRAIJ", -+ .id = {0x98, 0xeb, 0x40}, -+ .id_len = 3, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 133), -+ &READ_DUAL(1, INFINITE, 133), -+ &READ_QUAD(1, INFINITE, 133), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 133), -+ &WRITE_QUAD(0, 256, 133), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 133), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CYG1S3H 1.8V 2Gbit */ -+ { -+ .name = "TC58CYG1S3H", -+ .id = {0x98, 0xbb}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 75), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 75), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CVG2S0H 4Gbit */ -+ { -+ .name = "TC58CVG2S0H", -+ .id = {0x98, 0xcd}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CVG2S0HRAIJ 4Gbit */ -+ { -+ .name = "TC58CVG2S0HRAIJ", -+ .id = {0x98, 0xed, 0x51}, -+ .id_len = 3, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 133), -+ &READ_DUAL(1, INFINITE, 133), -+ &READ_QUAD(1, INFINITE, 133), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 133), -+ &WRITE_QUAD(0, 256, 133), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 133), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* TOSHIBA TC58CYG2S0H 1.8V 4Gbit */ -+ { -+ .name = "TC58CYG2S0H", -+ .id = {0x98, 0xbd}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 75), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 75), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* KIOXIA TC58CYG2S0HRAIJ 1.8V 4Gbit */ -+ { -+ .name = "TC58CYG2S0HRAIJ", -+ .id = {0x98, 0xdd, 0x51}, -+ .id_len = 3, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), /* 24MHz */ -+ &READ_FAST(1, INFINITE, 133), /* 133MHz */ -+ &READ_DUAL(1, INFINITE, 133), /* 133MHz */ -+ &READ_QUAD(1, INFINITE, 133), /* 133MHz */ -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 133), /* 133MHz */ -+ &WRITE_QUAD(0, 256, 133), /* 133MHz */ -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */ -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ /* KIOXIA TH58CYG3S0H 1.8V 8Gbit */ -+ { -+ .name = "TH58CYG3S0H", -+ .id = {0x98, 0xd4, 0x51}, -+ .id_len = 3, -+ .chipsize = _1G, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), /* 24MHz */ -+ &READ_FAST(1, INFINITE, 133), /* 133MHz */ -+ &READ_DUAL(1, INFINITE, 133), /* 133MHz */ -+ &READ_QUAD(1, INFINITE, 133), /* 133MHz */ -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 133), /* 133MHz */ -+ &WRITE_QUAD(0, 256, 133), /* 133MHz */ -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */ -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* HeYangTek HYF1GQ4UAACAE 1Gbit */ -+ { -+ .name = "HYF1GQ4UAACAE", -+ .id = {0xc9, 0x51}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(1, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* HeYangTek HYF2GQ4UAACAE 2Gbit */ -+ { -+ .name = "HYF2GQ4UAACAE", -+ .id = {0xc9, 0x52}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(1, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* HeYangTek HYF4GQ4UAACBE 4Gbit */ -+ { -+ .name = "HYF4GQ4UAACBE", -+ .id = {0xc9, 0xd4}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(1, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Dosilicon 3.3V DS35Q1GA-IB 1Gbit */ -+ { -+ .name = "DS35Q1GA-IB", -+ .id = {0xe5, 0x71}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* XTX 3.3V XT26G01B 1Gbit */ -+ { -+ .name = "XT26G01B", -+ .id = {0x0B, 0xF1}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_DUAL_ADDR(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ &READ_QUAD_ADDR(1, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Etron 1.8V EM78F044VCA-H 8Gbit */ -+ { -+ .name = "EM78F044VCA-H", -+ .id = {0xD5, 0x8D}, -+ .id_len = 2, -+ .chipsize = _512M*2, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 100), -+ &READ_DUAL(1, INFINITE, 100), -+ &READ_DUAL_ADDR(1, INFINITE, 100), -+ &READ_QUAD(1, INFINITE, 100), -+ &READ_QUAD_ADDR(1, INFINITE, 100), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 100), -+ &WRITE_QUAD(0, 256, 100), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 100), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Etron 1.8V EM78E044VCA-H 4Gbit */ -+ { -+ .name = "EM78E044VCA-H", -+ .id = {0xD5, 0x8C}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 100), -+ &READ_DUAL(1, INFINITE, 100), -+ &READ_DUAL_ADDR(1, INFINITE, 100), -+ &READ_QUAD(1, INFINITE, 100), -+ &READ_QUAD_ADDR(1, INFINITE, 100), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 100), -+ &WRITE_QUAD(0, 256, 100), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 100), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Etron 1.8V EM78D044VCF-H 2Gbit */ -+ { -+ .name = "EM78D044VCF-H", -+ .id = {0xd5, 0x81}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_DUAL_ADDR(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ &READ_QUAD_ADDR(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Etron 3.3V EM73C044VCC-H 1Gbit */ -+ { -+ .name = "EM73C044VCC-H", -+ .id = {0xd5, 0x22}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 120), -+ &READ_DUAL(1, INFINITE, 120), -+ &READ_DUAL_ADDR(1, INFINITE, 120), -+ &READ_QUAD(1, INFINITE, 120), -+ &READ_QUAD_ADDR(1, INFINITE, 120), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), -+ &WRITE_QUAD(0, 256, 120), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* Micron MT29F4G01ABBFDWB 4GBit 1.8V */ -+ { -+ .name = "MT29F4G01ABBFDWB", -+ .id = {0x2C, 0x35}, -+ .id_len = 2, -+ .chipsize = _512M, -+ .erasesize = _256K, -+ .pagesize = _4K, -+ .oobsize = 256, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 80), -+ &READ_DUAL(1, INFINITE, 80), -+ &READ_QUAD(1, INFINITE, 80), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 80), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_256K(0, _256K, 80), -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* Dosilicon 3.3V DS35Q2GA-IB 1Gb */ -+ { -+ .name = "DS35Q2GA-IB", -+ .id = {0xe5, 0x72}, -+ .id_len = 2, -+ .chipsize = _256M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), -+ &READ_FAST(1, INFINITE, 104), -+ &READ_DUAL(1, INFINITE, 104), -+ &READ_QUAD(1, INFINITE, 104), -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 80), -+ &WRITE_QUAD(0, 256, 104), -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), -+ 0 -+ }, -+ .driver = &spi_driver_general, -+ }, -+ -+ /* FM 3.3v FM25S01-DND-A-G 1Gbit */ -+ { -+ .name = "FM25S01-DND-A-G", -+ .id = {0xa1, 0xa1}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 128, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), /* 24MHz */ -+ &READ_FAST(1, INFINITE, 104), /* 104MHz */ -+ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ -+ &READ_DUAL_ADDR(1, INFINITE, 40), /* 40MHz */ -+ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ -+ &READ_QUAD_ADDR(2, INFINITE, 40), /* 40MHz */ -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), /* 104MHz */ -+ &WRITE_QUAD(0, 256, 104), /* 104MHz */ -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ /* FM 3.3v FM25S01A 1Gbit */ -+ { -+ .name = "FM25S01A", -+ .id = {0xa1, 0xe4}, -+ .id_len = 2, -+ .chipsize = _128M, -+ .erasesize = _128K, -+ .pagesize = _2K, -+ .oobsize = 64, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .read = { -+ &READ_STD(1, INFINITE, 24), /* 104MHz */ -+ &READ_FAST(1, INFINITE, 104), /* 104MHz */ -+ &READ_DUAL(1, INFINITE, 104), /* 104MHz */ -+ &READ_DUAL_ADDR(1, INFINITE, 40), /* 70MHz */ -+ &READ_QUAD(1, INFINITE, 104), /* 104MHz */ -+ &READ_QUAD_ADDR(2, INFINITE, 40), /* 70MHz */ -+ 0 -+ }, -+ .write = { -+ &WRITE_STD(0, 256, 104), /* 104MHz */ -+ &WRITE_QUAD(0, 256, 104), /* 104MHz */ -+ 0 -+ }, -+ .erase = { -+ &ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */ -+ 0 -+ }, -+ .driver = &spi_driver_no_qe, -+ }, -+ -+ { .id_len = 0, }, -+}; -+ -+/*****************************************************************************/ -+static void fmc100_spi_nand_search_rw(struct spi_nand_info *spiinfo, -+ struct spi_op *spiop_rw, u_int iftype, u_int max_dummy, int rw_type) -+{ -+ int ix = 0; -+ struct spi_op **spiop, **fitspiop; -+ -+ for (fitspiop = spiop = (rw_type ? spiinfo->write : spiinfo->read); -+ (*spiop) && ix < MAX_SPI_OP; spiop++, ix++) { -+ if (((*spiop)->iftype & iftype) -+ && ((*spiop)->dummy <= max_dummy) -+ && (*fitspiop)->iftype < (*spiop)->iftype) { -+ fitspiop = spiop; -+ } -+ } -+ memcpy(spiop_rw, (*fitspiop), sizeof(struct spi_op)); -+} -+ -+/*****************************************************************************/ -+static void fmc100_spi_nand_get_erase(struct spi_nand_info *spiinfo, -+ struct spi_op *spiop_erase) -+{ -+ int ix; -+ -+ spiop_erase->size = 0; -+ for (ix = 0; ix < MAX_SPI_OP; ix++) { -+ if (spiinfo->erase[ix] == NULL) { -+ break; -+ } -+ if (spiinfo->erasesize == spiinfo->erase[ix]->size) { -+ memcpy(&spiop_erase[ix], spiinfo->erase[ix], -+ sizeof(struct spi_op)); -+ break; -+ } -+ } -+} -+ -+/*****************************************************************************/ -+static void fmc100_map_spi_op(struct fmc_spi *spi) -+{ -+ unsigned char ix; -+ const int iftype_read[] = { -+ SPI_IF_READ_STD, IF_TYPE_STD, -+ SPI_IF_READ_FAST, IF_TYPE_STD, -+ SPI_IF_READ_DUAL, IF_TYPE_DUAL, -+ SPI_IF_READ_DUAL_ADDR, IF_TYPE_DIO, -+ SPI_IF_READ_QUAD, IF_TYPE_QUAD, -+ SPI_IF_READ_QUAD_ADDR, IF_TYPE_QIO, -+ 0, 0, -+ }; -+ const int iftype_write[] = { -+ SPI_IF_WRITE_STD, IF_TYPE_STD, -+ SPI_IF_WRITE_QUAD, IF_TYPE_QUAD, -+ 0, 0, -+ }; -+ const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; -+ -+ FMC_PR(BT_DBG, "\t||*-Start Get SPI operation iftype\n"); -+ -+ for (ix = 0; iftype_write[ix]; ix += 2) { -+ if (spi->write->iftype == iftype_write[ix]) { -+ spi->write->iftype = iftype_write[ix + 1]; -+ break; -+ } -+ } -+ FMC_PR(BT_DBG, "\t|||-Get best write iftype: %s \n", -+ if_str[spi->write->iftype]); -+ -+ for (ix = 0; iftype_read[ix]; ix += 2) { -+ if (spi->read->iftype == iftype_read[ix]) { -+ spi->read->iftype = iftype_read[ix + 1]; -+ break; -+ } -+ } -+ FMC_PR(BT_DBG, "\t|||-Get best read iftype: %s \n", -+ if_str[spi->read->iftype]); -+ -+ spi->erase->iftype = IF_TYPE_STD; -+ FMC_PR(BT_DBG, "\t|||-Get best erase iftype: %s \n", -+ if_str[spi->erase->iftype]); -+ -+ FMC_PR(BT_DBG, "\t||*-End Get SPI operation iftype \n"); -+} -+ -+/*****************************************************************************/ -+static void fmc100_spi_ids_probe(struct mtd_info *mtd, -+ struct spi_nand_info *spi_dev) -+{ -+ unsigned int reg; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ struct fmc_spi *spi = host->spi; -+ -+ FMC_PR(BT_DBG, "\t|*-Start match SPI operation & chip init\n"); -+ -+ spi->host = host; -+ spi->name = spi_dev->name; -+ spi->driver = spi_dev->driver; -+ -+ fmc100_spi_nand_search_rw(spi_dev, spi->read, -+ FMC_SPI_NAND_SUPPORT_READ, -+ FMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_READ); -+ FMC_PR(BT_DBG, "\t||-Save spi->read op cmd:%#x\n", spi->read->cmd); -+ -+ fmc100_spi_nand_search_rw(spi_dev, spi->write, -+ FMC_SPI_NAND_SUPPORT_WRITE, -+ FMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_WRITE); -+ FMC_PR(BT_DBG, "\t||-Save spi->write op cmd:%#x\n", spi->write->cmd); -+ -+ fmc100_spi_nand_get_erase(spi_dev, spi->erase); -+ FMC_PR(BT_DBG, "\t||-Save spi->erase op cmd:%#x\n", spi->erase->cmd); -+ -+ fmc100_map_spi_op(spi); -+ -+ if (spi->driver->qe_enable) { -+ spi->driver->qe_enable(spi); -+ } -+ -+ /* Disable write protection */ -+ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); -+ FMC_PR(BT_DBG, "\t||-Get protect status[%#x]: %#x\n", PROTECT_ADDR, -+ reg); -+ if (ANY_BP_ENABLE(reg)) { -+ reg &= ~ALL_BP_MASK; -+ spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, reg); -+ FMC_PR(BT_DBG, "\t||-Set [%#x]FT %#x\n", PROTECT_ADDR, reg); -+ -+ spi->driver->wait_ready(spi); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); -+ FMC_PR(BT_DBG, "\t||-Check BP disable result: %#x\n", reg); -+ if (ANY_BP_ENABLE(reg)) { -+ DB_MSG("Error: Write protection disable failed!\n"); -+ } -+ } -+ -+ /* Disable chip internal ECC */ -+ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); -+ FMC_PR(BT_DBG, "\t||-Get feature status[%#x]: %#x\n", FEATURE_ADDR, -+ reg); -+ if (reg & FEATURE_ECC_ENABLE) { -+ reg &= ~FEATURE_ECC_ENABLE; -+ spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, reg); -+ FMC_PR(BT_DBG, "\t||-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg); -+ -+ spi->driver->wait_ready(spi); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); -+ FMC_PR(BT_DBG, "\t||-Check internal ECC disable result: %#x\n", -+ reg); -+ if (reg & FEATURE_ECC_ENABLE) { -+ DB_MSG("Error: Chip internal ECC disable failed!\n"); -+ } -+ } -+ -+ fmc_cs_user[host->cmd_op.cs]++; -+ -+ FMC_PR(BT_DBG, "\t|*-End match SPI operation & chip init\n"); -+} -+ -+static struct nand_flash_dev spi_nand_dev; -+/*****************************************************************************/ -+static struct nand_flash_dev *spi_nand_get_flash_info(struct mtd_info *mtd, -+ unsigned char *id) -+{ -+ unsigned char ix, len = 0; -+ char buffer[100]; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct fmc_host *host = chip->priv; -+ struct spi_nand_info *spi_dev = fmc_spi_nand_flash_table; -+ struct nand_flash_dev *type = &spi_nand_dev; -+ -+ FMC_PR(BT_DBG, "\t*-Start find SPI Nand flash\n"); -+ -+ len = sprintf(buffer, "SPI Nand(cs %d) ID: %#x %#x", -+ host->cmd_op.cs, id[0], id[1]); -+ -+ for (; spi_dev->id_len; spi_dev++) { -+ if (memcmp(id, spi_dev->id, spi_dev->id_len)) { -+ continue; -+ } -+ -+ for (ix = 2; ix < spi_dev->id_len; ix++) { -+ len += sprintf(buffer + len, " %#x", id[ix]); -+ } -+ pr_info("%s\n", buffer); -+ -+ FMC_PR(BT_DBG, "\t||-CS(%d) found SPI Nand: %s\n", -+ host->cmd_op.cs, spi_dev->name); -+ -+ type->name = spi_dev->name; -+ memcpy(type->id, spi_dev->id, spi_dev->id_len); -+ type->pagesize = spi_dev->pagesize; -+ type->chipsize = spi_dev->chipsize >> 20; -+ type->erasesize = spi_dev->erasesize; -+ type->id_len = spi_dev->id_len; -+ type->oobsize = spi_dev->oobsize; -+ FMC_PR(BT_DBG, "\t|-Save struct nand_flash_dev info\n"); -+ -+ mtd->oobsize = spi_dev->oobsize; -+ mtd->erasesize = spi_dev->erasesize; -+ mtd->writesize = spi_dev->pagesize; -+ chip->chipsize = spi_dev->chipsize; -+ -+ fmc100_spi_ids_probe(mtd, spi_dev); -+ -+ FMC_PR(BT_DBG, "\t*-Found SPI nand: %s\n", spi_dev->name); -+ -+ return type; -+ } -+ -+ FMC_PR(BT_DBG, "\t*-Not found SPI nand flash, %s\n", buffer); -+ -+ return NULL; -+} -+ -+/*****************************************************************************/ -+void fmc_spi_nand_ids_register(void) -+{ -+ pr_info("SPI Nand ID Table Version %s\n", SPI_NAND_ID_TAB_VER); -+ get_spi_nand_flash_type_hook = spi_nand_get_flash_info; -+} -+ -+#ifdef CONFIG_PM -+/*****************************************************************************/ -+void fmc100_spi_nand_config(struct fmc_host *host) -+{ -+ unsigned int reg; -+ struct fmc_spi *spi = host->spi; -+ static const char *str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; -+ -+ /* judge whether support QUAD read/write or not, set it if yes */ -+ FMC_PR(PM_DBG, "\t|-SPI read iftype: %s write iftype: %s\n", -+ str[spi->read->iftype], str[spi->write->iftype]); -+ -+ if (spi->driver->qe_enable) { -+ spi->driver->qe_enable(spi); -+ } -+ -+ /* Disable write protection */ -+ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); -+ FMC_PR(PM_DBG, "\t|-Get protect status[%#x]: %#x\n", PROTECT_ADDR, -+ reg); -+ if (ANY_BP_ENABLE(reg)) { -+ reg &= ~ALL_BP_MASK; -+ spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, reg); -+ FMC_PR(PM_DBG, "\t|-Set [%#x]FT %#x\n", PROTECT_ADDR, reg); -+ -+ spi->driver->wait_ready(spi); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, 0); -+ FMC_PR(PM_DBG, "\t|-Check BP disable result: %#x\n", reg); -+ if (ANY_BP_ENABLE(reg)) { -+ DB_MSG("Error: Write protection disable failed!\n"); -+ } -+ } -+ -+ /* Disable chip internal ECC */ -+ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); -+ FMC_PR(PM_DBG, "\t|-Get feature status[%#x]: %#x\n", FEATURE_ADDR, -+ reg); -+ if (reg & FEATURE_ECC_ENABLE) { -+ reg &= ~FEATURE_ECC_ENABLE; -+ spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, reg); -+ FMC_PR(PM_DBG, "\t|-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg); -+ -+ spi->driver->wait_ready(spi); -+ -+ reg = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, 0); -+ FMC_PR(PM_DBG, "\t|-Check internal ECC disable result: %#x\n", -+ reg); -+ if (reg & FEATURE_ECC_ENABLE) { -+ DB_MSG("Error: Chip internal ECC disable failed!\n"); -+ } -+ } -+} -+/*****************************************************************************/ -+#endif /* CONFIG_PM */ ---- linux-4.9.37/drivers/mtd/nand/gkfmc100/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/gkfmc100/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,17 @@ -+# -+# goke flash memory controller SPI nand device driver version 100 -+# drivers/mtd/nand/gkfmc100/Kconfig -+# add by goke 2017.8.7 -+# -+ -+config MTD_SPI_NAND_FMC100 -+ bool "Goke Flash Memory Controller v100 SPI Nand devices support" -+ depends on MFD_GOKE_FMC && MTD_SPI_NAND_GOKE -+ select MISC_FILESYSTEMS -+ select MTD_BLOCK -+ select YAFFS_FS -+ select YAFFS_YAFFS2 -+ help -+ Goke Flash Memory Controller version 100 is called fmc100 for -+ short. The controller driver support registers and DMA transfers -+ while reading or writing the SPI nand flash. ---- linux-4.9.37/drivers/mtd/nand/gkfmc100/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/gkfmc100/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,26 @@ -+# -+# The Flash Memory Controller v100 Device Driver for goke -+# -+# Copyright (c) 2016-2017 Goke Technologies Co., Ltd. -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 2 of the License, or (at your -+# option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+# -+# -+ -+# -+# drivers/mtd/nand/gkfmc100/Makefile -+# -+ -+obj-y += fmc_spi_nand_ids.o -+obj-y += fmc100.o fmc100_os.o ---- linux-4.9.37/drivers/mtd/nand/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -569,4 +569,28 @@ - Enables support for NAND controller on MTK SoCs. - This controller is found on mt27xx, mt81xx, mt65xx SoCs. - -+config MTD_SPI_NAND_GOKE -+ tristate "Support for SPI NAND controller on Goke SoCs" -+ depends on MTD_NAND -+ help -+ Enables support for the SPI NAND device drivers. -+ -+config GOKE_NAND_ECC_STATUS_REPORT -+ tristate "Report the ecc status to MTD for Goke Nand Driver" -+ depends on MTD_NAND && ARCH_GOKE -+ default n -+ help -+ Flash Memory Controller reports the ecc status include ECC error -+ and ECC corrected to MTD to monitor the aging of devices. -+ -+config GOKE_NAND_FS_MAY_NO_YAFFS2 -+ bool "Remove the restraintion of 16bit ecc type on yaffs2 to Goke" -+ depends on MFD_GOKE_FMC -+ default n -+ help -+ The ecc type: 16bit is limited by the Goke flash memory controller, -+ as the yaffs2 tag of goke rootfs limits the min size of CTRL len is 28. -+ -+source "drivers/mtd/nand/gkfmc100/Kconfig" -+ - endif # MTD_NAND ---- linux-4.9.37/drivers/mtd/nand/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -8,6 +8,7 @@ - obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o - obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o - -+obj-$(CONFIG_MTD_SPI_NAND_FMC100) += gkfmc100/ - obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o - obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o - obj-$(CONFIG_MTD_NAND_DENALI) += denali.o -@@ -59,4 +60,4 @@ - obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o - obj-$(CONFIG_MTD_NAND_MTK) += mtk_nand.o mtk_ecc.o - --nand-objs := nand_base.o nand_bbt.o nand_timings.o -+nand-objs := nand_base.o nand_bbt.o nand_timings.o nfc_gen.o nfc_spl_ids.o match_table.o ---- linux-4.9.37/drivers/mtd/nand/match_table.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/match_table.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,99 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include "match_table.h" -+ -+/*****************************************************************************/ -+int reg2type(struct match_reg_type *table, int length, int reg, int def) -+{ -+ while (length-- > 0) { -+ if (table->reg == reg) { -+ return table->type; -+ } -+ table++; -+ } -+ return def; -+} -+ -+int type2reg(struct match_reg_type *table, int length, int type, int def) -+{ -+ while (length-- > 0) { -+ if (table->type == type) { -+ return table->reg; -+ } -+ table++; -+ } -+ return def; -+} -+ -+int str2type(struct match_type_str *table, int length, const char *str, -+ int size, int def) -+{ -+ while (length-- > 0) { -+ if (!strncmp(table->str, str, size)) { -+ return table->type; -+ } -+ table++; -+ } -+ return def; -+} -+ -+const char *type2str(struct match_type_str *table, int length, int type, -+ const char *def) -+{ -+ while (length-- > 0) { -+ if (table->type == type) { -+ return table->str; -+ } -+ table++; -+ } -+ return def; -+} -+ -+int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def) -+{ -+ while (nr_table-- > 0) { -+ if (table->reg == reg) { -+ return table->type; -+ } -+ table++; -+ } -+ return def; -+} -+ -+int match_type_to_reg(struct match_t *table, int nr_table, int type, int def) -+{ -+ while (nr_table-- > 0) { -+ if (table->type == type) { -+ return table->reg; -+ } -+ table++; -+ } -+ return def; -+} -+ -+int match_data_to_type(struct match_t *table, int nr_table,const char *data, -+ int size, int def) -+{ -+ while (nr_table-- > 0) { -+ if (!memcmp(table->data, data, size)) { -+ return table->type; -+ } -+ table++; -+ } -+ return def; -+} -+ -+void *match_type_to_data(struct match_t *table, int nr_table, int type, -+ const void *def) -+{ -+ while (nr_table-- > 0) { -+ if (table->type == type) { -+ return table->data; -+ } -+ table++; -+ } -+ return (void *)def; -+} ---- linux-4.9.37/drivers/mtd/nand/match_table.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/match_table.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,53 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __MATCH_TABLE_H__ -+#define __MATCH_TABLE_H__ -+ -+/*****************************************************************************/ -+struct match_reg_type { -+ int reg; -+ int type; -+}; -+ -+struct match_type_str { -+ int type; -+ const char *str; -+}; -+ -+struct match_t { -+ int type; -+ int reg; -+ void *data; -+}; -+ -+/*****************************************************************************/ -+#define MATCH_SET_TYPE_REG(_type, _reg) {(_type), (_reg), (void *)0} -+#define MATCH_SET_TYPE_DATA(_type, _data) {(_type), 0, (void *)(_data)} -+#define MATCH_SET(_type, _reg, _data) {(_type), (_reg), (void *)(_data)} -+ -+/*****************************************************************************/ -+int reg2type(struct match_reg_type *table, int length, int reg, int def); -+ -+int type2reg(struct match_reg_type *table, int length, int type, int def); -+ -+int str2type(struct match_type_str *table, int length, const char *str, -+ int size, int def); -+ -+const char *type2str(struct match_type_str *table, int length, int type, -+ const char *def); -+ -+int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def); -+ -+int match_type_to_reg(struct match_t *table, int nr_table, int type, int def); -+ -+int match_data_to_type(struct match_t *table, int nr_table,const char *data, -+ int size, int def); -+ -+void *match_type_to_data(struct match_t *table, int nr_table, int type, -+ const void *def); -+ -+/*****************************************************************************/ -+ -+#endif /* End of __MATCH_TABLE_H__ */ ---- linux-4.9.37/drivers/mtd/nand/nand_base.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/nand_base.c 2021-06-07 13:01:33.000000000 +0300 -@@ -47,6 +47,8 @@ - #include - #include - -+#include "nfc_gen.h" -+ - static int nand_get_device(struct mtd_info *mtd, int new_state); - - static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, -@@ -2808,6 +2810,10 @@ - int ret; - int oob_required = oob ? 1 : 0; - -+#ifdef CONFIG_ARCH_GOKE -+ oob_required = 1; -+#endif -+ - ops->retlen = 0; - if (!writelen) - return 0; -@@ -4058,7 +4064,7 @@ - int *maf_id, int *dev_id, - struct nand_flash_dev *type) - { -- int busw; -+ int busw = 0; - int i, maf_idx; - u8 id_data[8]; - -@@ -4097,6 +4103,30 @@ - return ERR_PTR(-ENODEV); - } - -+#ifdef CONFIG_ARCH_GOKE -+ -+#ifndef CONFIG_MTD_SPI_NAND_GOKE -+ /* Parallel Nand Flash */ -+ -+ /* The 3rd id byte holds MLC / multichip data */ -+ chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]); -+#endif -+ -+ if (get_spi_nand_flash_type_hook) -+ type = get_spi_nand_flash_type_hook(mtd, id_data); -+ -+ if (type) -+ goto ident_done; -+#ifdef CONFIG_MTD_SPI_NAND_GOKE -+ else { -+ pr_info("This device[%02x,%02x] cannot found in spi nand id table!!\n", -+ *maf_id, *dev_id); -+ return ERR_PTR(-ENODEV); -+ } -+#endif -+ -+#endif /* endif CONFIG_ARCH_GOKE */ -+ - if (!type) - type = nand_flash_ids; - -@@ -4144,6 +4174,9 @@ - if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) - chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; - ident_done: -+#ifdef CONFIG_ARCH_GOKE -+ nfc_nand_param_adjust(mtd, chip); -+#endif - - /* Try to identify manufacturer */ - for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { -@@ -4205,9 +4238,13 @@ - pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, - type->name); - -- pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", -+ pr_info("%dMiB, %s, page size: %d\n", - (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", -- mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); -+ mtd->writesize); -+ -+ /* Print ecc type and ecc mode about goke flash controller */ -+ nfc_show_info(mtd, nand_manuf_ids[maf_idx].name, type->name); -+ - return type; - } - -@@ -4727,7 +4764,7 @@ - break; - - case NAND_ECC_NONE: -- pr_warn("NAND_ECC_NONE selected by board driver. This is not recommended!\n"); -+ pr_warn(" ECC provided by Flash Memory Controller\n"); - ecc->read_page = nand_read_page_raw; - ecc->write_page = nand_write_page_raw; - ecc->read_oob = nand_read_oob_std; -@@ -4814,8 +4851,13 @@ - break; - } - -+#ifdef CONFIG_MTD_UBI -+ /* mtd->type = MTD_MLCNANDFLASH isn't support by mtd_util ubi tools jet */ -+ mtd->type = MTD_NANDFLASH; -+#else - /* Fill in remaining MTD driver data */ - mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH; -+#endif - mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : - MTD_CAP_NANDFLASH; - mtd->_erase = nand_erase; ---- linux-4.9.37/drivers/mtd/nand/nand_ids.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/nand_ids.c 2021-06-07 13:01:33.000000000 +0300 -@@ -168,7 +168,7 @@ - /* Manufacturer IDs */ - struct nand_manufacturers nand_manuf_ids[] = { - {NAND_MFR_TOSHIBA, "Toshiba"}, -- {NAND_MFR_ESMT, "ESMT"}, -+ {NAND_MFR_GD_ESMT, "GD/ESMT"}, - {NAND_MFR_SAMSUNG, "Samsung"}, - {NAND_MFR_FUJITSU, "Fujitsu"}, - {NAND_MFR_NATIONAL, "National"}, -@@ -179,9 +179,17 @@ - {NAND_MFR_AMD, "AMD/Spansion"}, - {NAND_MFR_MACRONIX, "Macronix"}, - {NAND_MFR_EON, "Eon"}, -+ {NAND_MFR_WINBOND, "Winbond"}, -+ {NAND_MFR_ATO, "ATO"}, -+ {NAND_MFR_MXIC, "MXIC"}, -+ {NAND_MFR_ALL_FLASH, "All-flash"}, -+ {NAND_MFR_PARAGON, "Paragon"}, - {NAND_MFR_SANDISK, "SanDisk"}, - {NAND_MFR_INTEL, "Intel"}, - {NAND_MFR_ATO, "ATO"}, -+ {NAND_MFR_HEYANGTEK, "HeYangTek"}, -+ {NAND_MFR_DOSILICON, "Dosilicon"}, -+ {NAND_MFR_FIDELIX, "Fidelix/Dosi"}, /* Fidelix was purchased by Dosilicon */ - {0x0, "Unknown"} - }; - ---- linux-4.9.37/drivers/mtd/nand/nfc_gen.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/nfc_gen.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,233 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include "match_table.h" -+#include "nfc_gen.h" -+ -+/*****************************************************************************/ -+struct nand_flash_dev *(*get_spi_nand_flash_type_hook)(struct mtd_info *mtd, -+ unsigned char *id) = NULL; -+ -+/*****************************************************************************/ -+static struct match_t match_ecc[] = { -+ MATCH_SET_TYPE_DATA(NAND_ECC_NONE, "none"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_0BIT, "none"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_1BIT_512, "1bit/512"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_4BIT, "4bit/512"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_4BIT_512, "4bit/512"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_4BYTE, "4byte/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_8BIT, "4bit/512"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_8BIT_512, "8bit/512"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_8BYTE, "8byte/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_13BIT, "13bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_16BIT, "8bit/512"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_18BIT, "18bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_24BIT, "24bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_27BIT, "27bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_32BIT, "32bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_40BIT, "40bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_41BIT, "41bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_48BIT, "48bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_60BIT, "60bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_72BIT, "72bit/1k"), -+ MATCH_SET_TYPE_DATA(NAND_ECC_80BIT, "80bit/1k"), -+}; -+ -+const char *nand_ecc_name(int type) -+{ -+ return (char *)match_type_to_data(match_ecc, ARRAY_SIZE(match_ecc), -+ type, "unknown"); -+} -+ -+char *get_ecctype_str(enum ecc_type ecctype) -+{ -+ static char *ecctype_string[] = { -+ "None", "1bit/512Byte", "4bits/512Byte", "8bits/512Byte", -+ "24bits/1K", "40bits/1K", "unknown", "unknown" -+ }; -+ return ecctype_string[((unsigned int)ecctype & 0x07)]; -+} -+ -+/*****************************************************************************/ -+static struct match_type_str page2name[] = { -+ { NAND_PAGE_512B, "512" }, -+ { NAND_PAGE_2K, "2K" }, -+ { NAND_PAGE_4K, "4K" }, -+ { NAND_PAGE_8K, "8K" }, -+ { NAND_PAGE_16K, "16K" }, -+ { NAND_PAGE_32K, "32K" }, -+}; -+ -+const char *nand_page_name(int type) -+{ -+ return type2str(page2name, ARRAY_SIZE(page2name), type, "unknown"); -+} -+ -+char *get_pagesize_str(enum page_type pagetype) -+{ -+ static char *pagesize_str[] = { -+ "512", "2K", "4K", "8K", "16K", "unknown", -+ "unknown", "unknown" -+ }; -+ return pagesize_str[((unsigned int)pagetype & 0x07)]; -+} -+ -+/*****************************************************************************/ -+static struct match_reg_type page2size[] = { -+ { _512B, NAND_PAGE_512B }, -+ { _2K, NAND_PAGE_2K }, -+ { _4K, NAND_PAGE_4K }, -+ { _8K, NAND_PAGE_8K }, -+ { _16K, NAND_PAGE_16K }, -+ { _32K, NAND_PAGE_32K }, -+}; -+ -+unsigned int get_pagesize(enum page_type pagetype) -+{ -+ unsigned int pagesize[] = { -+ _512B, _2K, _4K, _8K, _16K, 0, 0, 0 -+ }; -+ return pagesize[((unsigned int)pagetype & 0x07)]; -+} -+ -+int nandpage_size2type(int size) -+{ -+ return reg2type(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K); -+} -+ -+int nandpage_type2size(int size) -+{ -+ return type2reg(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K); -+} -+ -+char *nand_dbgfs_options; -+ -+static int __init dbgfs_options_setup(char *s) -+{ -+ nand_dbgfs_options = s; -+ return 1; -+} -+__setup("nanddbgfs=", dbgfs_options_setup); -+ -+/*****************************************************************************/ -+ -+int get_bits(unsigned int n) -+{ -+ int loop; -+ int ret = 0; -+ -+ if (!n) -+ return 0; -+ -+ if (n > 0xFFFF) -+ loop = n > 0xFFFFFF ? 32 : 24; -+ else -+ loop = n > 0xFF ? 16 : 8; -+ -+ while (loop-- > 0 && n) { -+ if (n & 1) -+ ret++; -+ n >>= 1; -+ } -+ return ret; -+} -+ -+/*****************************************************************************/ -+#define et_ecc_none 0x00 -+#define et_ecc_4bit 0x02 -+#define et_ecc_8bit 0x03 -+#define et_ecc_24bit1k 0x04 -+#define et_ecc_40bit1k 0x05 -+#define et_ecc_64bit1k 0x06 -+ -+static struct match_reg_type ecc_yaffs_type_t[] = { -+ {et_ecc_none, NAND_ECC_0BIT}, -+ {et_ecc_4bit, NAND_ECC_8BIT}, -+ {et_ecc_8bit, NAND_ECC_16BIT}, -+ {et_ecc_24bit1k, NAND_ECC_24BIT}, -+ {et_ecc_40bit1k, NAND_ECC_40BIT}, -+ {et_ecc_64bit1k, NAND_ECC_64BIT} -+}; -+ -+unsigned char match_ecc_type_to_yaffs(unsigned char type) -+{ -+ return type2reg(ecc_yaffs_type_t, ARRAY_SIZE(ecc_yaffs_type_t), type, -+ et_ecc_4bit); -+} -+ -+/*****************************************************************************/ -+static struct match_t page_table[] = { -+ {NAND_PAGE_2K, PAGE_SIZE_2KB, "2K"}, -+ {NAND_PAGE_4K, PAGE_SIZE_4KB, "4K"}, -+ {NAND_PAGE_8K, PAGE_SIZE_8KB, "8K"}, -+ {NAND_PAGE_16K, PAGE_SIZE_16KB, "16K"}, -+}; -+ -+unsigned char match_page_reg_to_type(unsigned char reg) -+{ -+ return match_reg_to_type(page_table, ARRAY_SIZE(page_table), reg, -+ NAND_PAGE_2K); -+} -+ -+unsigned char match_page_type_to_reg(unsigned char type) -+{ -+ return match_type_to_reg(page_table, ARRAY_SIZE(page_table), type, -+ PAGE_SIZE_2KB); -+} -+ -+const char *match_page_type_to_str(unsigned char type) -+{ -+ return match_type_to_data(page_table, ARRAY_SIZE(page_table), type, -+ "unknown"); -+} -+ -+/*****************************************************************************/ -+static struct match_t ecc_table[] = { -+ {NAND_ECC_0BIT, ECC_TYPE_0BIT, "none"}, -+ {NAND_ECC_8BIT, ECC_TYPE_8BIT, "4bit/512"}, -+ {NAND_ECC_16BIT, ECC_TYPE_16BIT, "8bit/512"}, -+ {NAND_ECC_24BIT, ECC_TYPE_24BIT, "24bit/1K"}, -+ {NAND_ECC_28BIT, ECC_TYPE_28BIT, "28bit/1K"}, -+ {NAND_ECC_40BIT, ECC_TYPE_40BIT, "40bit/1K"}, -+ {NAND_ECC_64BIT, ECC_TYPE_64BIT, "64bit/1K"}, -+}; -+ -+unsigned char match_ecc_reg_to_type(unsigned char reg) -+{ -+ return match_reg_to_type(ecc_table, ARRAY_SIZE(ecc_table), reg, -+ NAND_ECC_8BIT); -+} -+ -+unsigned char match_ecc_type_to_reg(unsigned char type) -+{ -+ return match_type_to_reg(ecc_table, ARRAY_SIZE(ecc_table), type, -+ ECC_TYPE_8BIT); -+} -+ -+const char *match_ecc_type_to_str(unsigned char type) -+{ -+ return match_type_to_data(ecc_table, ARRAY_SIZE(ecc_table), type, -+ "unknown"); -+} -+ -+/*****************************************************************************/ -+static struct match_t page_type_size_table[] = { -+ {NAND_PAGE_2K, _2K, NULL}, -+ {NAND_PAGE_4K, _4K, NULL}, -+ {NAND_PAGE_8K, _8K, NULL}, -+ {NAND_PAGE_16K, _16K, NULL}, -+}; -+ -+unsigned char match_page_size_to_type(unsigned int size) -+{ -+ return match_reg_to_type(page_type_size_table, -+ ARRAY_SIZE(page_type_size_table), size, NAND_PAGE_2K); -+} -+ -+unsigned int match_page_type_to_size(unsigned char type) -+{ -+ return match_type_to_reg(page_type_size_table, -+ ARRAY_SIZE(page_type_size_table), type, _2K); -+} ---- linux-4.9.37/drivers/mtd/nand/nfc_gen.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/nfc_gen.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,280 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __NFC_GEN_H__ -+#define __NFC_GEN_H__ -+ -+/*****************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+ -+/*****************************************************************************/ -+#define NFC_VER_300 (0x300) -+#define NFC_VER_301 (0x301) -+#define NFC_VER_310 (0x310) -+#define NFC_VER_504 (0x504) -+#define NFC_VER_505 (0x505) -+#define NFC_VER_600 (0x600) -+#define NFC_VER_610 (0x610) -+#define NFC_VER_620 (0x620) -+ -+#define SNFC_VER_100 (0x400) -+ -+/*****************************************************************************/ -+#define NAND_PAGE_512B 0 -+#define NAND_PAGE_1K 1 -+#define NAND_PAGE_2K 2 -+#define NAND_PAGE_4K 3 -+#define NAND_PAGE_8K 4 -+#define NAND_PAGE_16K 5 -+#define NAND_PAGE_32K 6 -+ -+/*****************************************************************************/ -+#define NAND_ECC_NONE 0 -+#define NAND_ECC_0BIT 0 -+#define NAND_ECC_1BIT 1 -+#define NAND_ECC_1BIT_512 1 -+#define NAND_ECC_4BIT 2 -+#define NAND_ECC_4BIT_512 2 -+#define NAND_ECC_4BYTE 2 -+#define NAND_ECC_8BIT 2 -+#define NAND_ECC_8BIT_512 3 -+#define NAND_ECC_8BYTE 3 -+#define NAND_ECC_13BIT 4 -+#define NAND_ECC_16BIT 5 -+#define NAND_ECC_18BIT 6 -+#define NAND_ECC_24BIT 7 -+#define NAND_ECC_27BIT 8 -+#define NAND_ECC_28BIT 9 -+#define NAND_ECC_32BIT 10 -+#define NAND_ECC_40BIT 11 -+#define NAND_ECC_41BIT 12 -+#define NAND_ECC_42BIT 13 -+#define NAND_ECC_48BIT 14 -+#define NAND_ECC_60BIT 15 -+#define NAND_ECC_64BIT 16 -+#define NAND_ECC_72BIT 17 -+#define NAND_ECC_80BIT 18 -+ -+enum ecc_type { -+ et_ecc_none = 0x00, -+ et_ecc_1bit = 0x01, -+ et_ecc_4bit = 0x02, -+ et_ecc_8bit = 0x03, -+ et_ecc_24bit1k = 0x04, -+ et_ecc_40bit1k = 0x05, -+ et_ecc_64bit1k = 0x06, -+}; -+ -+enum page_type { -+ pt_pagesize_512 = 0x00, -+ pt_pagesize_2K = 0x01, -+ pt_pagesize_4K = 0x02, -+ pt_pagesize_8K = 0x03, -+ pt_pagesize_16K = 0x04, -+}; -+ -+/*****************************************************************************/ -+struct nand_config_info { -+ unsigned int pagetype; -+ unsigned int ecctype; -+ unsigned int ecc_strength; -+ unsigned int oobsize; -+ struct mtd_ooblayout_ops *ooblayout_ops; -+}; -+ -+struct nfc_host; -+ -+struct nand_sync { -+ -+#define SET_NAND_SYNC_TYPE(_mfr, _onfi, _version) \ -+ ((((_mfr) & 0xFF) << 16) | (((_version) & 0xFF) << 8) \ -+ | ((_onfi) & 0xFF)) -+ -+#define GET_NAND_SYNC_TYPE_MFR(_type) (((_type) >> 16) & 0xFF) -+#define GET_NAND_SYNC_TYPE_VER(_type) (((_type) >> 8) & 0xFF) -+#define GET_NAND_SYNC_TYPE_INF(_type) ((_type) & 0xFF) -+ -+#define NAND_TYPE_ONFI_23_MICRON \ -+ SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x23) -+#define NAND_TYPE_ONFI_30_MICRON \ -+ SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x30) -+#define NAND_TYPE_TOGGLE_TOSHIBA \ -+ SET_NAND_SYNC_TYPE(NAND_MFR_TOSHIBA, 0, 0) -+#define NAND_TYPE_TOGGLE_SAMSUNG \ -+ SET_NAND_SYNC_TYPE(NAND_MFR_SAMSUNG, 0, 0) -+ -+#define NAND_TYPE_TOGGLE_10 SET_NAND_SYNC_TYPE(0, 0, 0x10) -+#define NAND_TYPE_ONFI_30 SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x30) -+#define NAND_TYPE_ONFI_23 SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x23) -+ -+ int type; -+ int (*enable)(struct nand_chip *chip); -+ int (*disable)(struct nand_chip *chip); -+}; -+ -+struct read_retry_t { -+ int type; -+ int count; -+ int (*set_rr_param)(struct nfc_host *host, int param); -+ int (*get_rr_param)(struct nfc_host *host); -+ int (*reset_rr_param)(struct nfc_host *host); -+}; -+ -+struct ecc_info_t { -+ int pagesize; -+ int ecctype; -+ int threshold; -+ int section; -+ void (*dump)(struct nfc_host *host, unsigned char ecc[], -+ int *max_bitsflag); -+}; -+ -+struct nand_dev_t { -+ struct nand_flash_dev flash_dev; -+ -+ char *start_type; -+ unsigned char ids[8]; -+ int oobsize; -+ int ecctype; -+ -+ /* (Controller) support ecc/page detect, driver don't need detect */ -+#define NANDC_HW_AUTO 0x01 -+ /* (Controller) support ecc/page detect, -+ * and current ecc/page config finish */ -+#define NANDC_CONFIG_DONE 0x02 -+ /* (Controller) is sync, default is async */ -+#define NANDC_IS_SYNC_BOOT 0x04 -+ -+ /* (NAND) need randomizer */ -+#define NAND_RANDOMIZER 0x10 -+ /* (NAND) is ONFI interface, combine with sync/async symble */ -+#define NAND_IS_ONFI 0x20 -+ /* (NAND) support async and sync, such micron onfi, toshiba toggle 1.0 */ -+#define NAND_MODE_SYNC_ASYNC 0x40 -+ /* (NAND) support only sync, such samsung sync. */ -+#define NAND_MODE_ONLY_SYNC 0x80 -+ -+#define NAND_CHIP_MICRON (NAND_MODE_SYNC_ASYNC | NAND_IS_ONFI) -+ /* This NAND is async, or sync/async, default is async mode, -+ * toggle1.0 interface */ -+#define NAND_CHIP_TOSHIBA_TOGGLE_10 (NAND_MODE_SYNC_ASYNC) -+ /* This NAND is only sync mode, toggle2.0 interface */ -+#define NAND_CHIP_TOSHIBA_TOGGLE_20 (NAND_MODE_ONLY_SYNC) -+ /* This NAND is only sync mode */ -+#define NAND_CHIP_SAMSUNG (NAND_MODE_ONLY_SYNC) -+ -+ unsigned int flags; -+ -+#define NAND_RR_NONE 0x00 -+#define NAND_RR_HYNIX_BG_BDIE 0x10 -+#define NAND_RR_HYNIX_BG_CDIE 0x11 -+#define NAND_RR_HYNIX_CG_ADIE 0x12 -+#define NAND_RR_MICRON 0x20 -+#define NAND_RR_SAMSUNG 0x30 -+#define NAND_RR_TOSHIBA_24nm 0x40 -+#define NAND_RR_TOSHIBA_19nm 0x41 -+ int read_retry_type; -+}; -+ -+/*****************************************************************************/ -+ -+#define IS_NANDC_HW_AUTO(_host) ((_host)->flags & NANDC_HW_AUTO) -+#define IS_NANDC_CONFIG_DONE(_host) ((_host)->flags & NANDC_CONFIG_DONE) -+#define IS_NANDC_SYNC_BOOT(_host) ((_host)->flags & NANDC_IS_SYNC_BOOT) -+ -+#define IS_NAND_RANDOM(_dev) ((_dev)->flags & NAND_RANDOMIZER) -+#define IS_NAND_ONLY_SYNC(_dev) ((_dev)->flags & NAND_MODE_ONLY_SYNC) -+#define IS_NAND_SYNC_ASYNC(_dev) ((_dev)->flags & NAND_MODE_SYNC_ASYNC) -+#define IS_NAND_ONFI(_dev) ((_dev)->flags & NAND_IS_ONFI) -+ -+#define ERSTR_HARDWARE "Hardware configuration error. " -+#define ERSTR_DRIVER "Driver does not support. " -+ -+#define ENABLE 1 -+#define DISABLE 0 -+ -+/*****************************************************************************/ -+ -+char *get_ecctype_str(enum ecc_type ecctype); -+ -+char *get_pagesize_str(enum page_type pagetype); -+ -+unsigned int get_pagesize(enum page_type pagetype); -+ -+const char *nand_ecc_name(int type); -+ -+const char *nand_page_name(int type); -+ -+int nandpage_size2type(int size); -+ -+int nandpage_type2size(int size); -+ -+/*****************************************************************************/ -+extern int (*nfc_param_adjust)(struct mtd_info *mtd, struct nand_chip *chip, -+ struct nand_dev_t *nand_dev); -+ -+extern struct nand_flash_dev *(*nand_get_flash_type_func)(struct mtd_info *mtd, -+ struct nand_chip *chip, struct nand_dev_t *spinand_dev_t); -+ -+extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook) -+(struct mtd_info *mtd, unsigned char *id); -+ -+extern int (*nfc_param_adjust)(struct mtd_info *, -+ struct nand_chip *, struct nand_dev_t *); -+ -+/*****************************************************************************/ -+struct nand_flash_dev *nfc_get_flash_type(struct mtd_info *mtd, -+ struct nand_chip *chip, u8 *id_data, int *busw); -+ -+extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook) -+(struct mtd_info *mtd, unsigned char *id); -+ -+void nfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip); -+ -+void nfc_show_info(struct mtd_info *mtd, char *goke, char *chipname); -+ -+void nfc_show_chipsize(struct nand_chip *chip); -+ -+int get_bits(unsigned int n); -+ -+/*****************************************************************************/ -+#define nfc_pr_msg(_fmt, arg...) printk(_fmt, ##arg) -+ -+#define nfc_pr_bug(fmt, args...) do { \ -+ printk("%s(%d): bug " fmt, __FILE__, __LINE__, ##args); \ -+ while (1) \ -+ ; \ -+} while (0) -+ -+#define PR_MSG(_fmt, arg...) \ -+ printk(_fmt, ##arg) -+ -+extern char *nand_dbgfs_options; -+/*****************************************************************************/ -+extern unsigned char match_page_reg_to_type(unsigned char reg); -+ -+extern unsigned char match_page_type_to_reg(unsigned char type); -+ -+extern const char *match_page_type_to_str(unsigned char type); -+ -+/*****************************************************************************/ -+extern unsigned char match_ecc_reg_to_type(unsigned char reg); -+ -+extern unsigned char match_ecc_type_to_reg(unsigned char type); -+ -+extern const char *match_ecc_type_to_str(unsigned char type); -+ -+/*****************************************************************************/ -+extern unsigned char match_page_size_to_type(unsigned int size); -+ -+extern unsigned int match_page_type_to_size(unsigned char type); -+ -+const char *nand_ecc_name(int type); -+/*****************************************************************************/ -+ -+#endif /* End of __NFC_GEN_H__ */ ---- linux-4.9.37/drivers/mtd/nand/nfc_spl_ids.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/nand/nfc_spl_ids.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,966 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include "nfc_gen.h" -+ -+/*****************************************************************************/ -+ -+struct nand_flash_special_dev { -+ unsigned char id[8]; -+ int length; /* length of id. */ -+ unsigned long long chipsize; -+ struct nand_flash_dev *(*probe)(struct nand_dev_t *nand_dev); -+ char *name; -+ -+ unsigned long pagesize; -+ unsigned long erasesize; -+ unsigned long oobsize; -+ unsigned long options; -+ unsigned int read_retry_type; -+ -+#define BBP_LAST_PAGE 0x01 -+#define BBP_FIRST_PAGE 0x02 -+ unsigned int badblock_pos; -+ unsigned int flags; -+}; -+ -+/*****************************************************************************/ -+/* this is nand probe function. */ -+/*****************************************************************************/ -+ -+static struct nand_flash_dev *hynix_probe_v02( -+ struct nand_dev_t *nand_dev) -+{ -+ unsigned char *id = nand_dev->ids; -+ struct nand_flash_dev *type = &nand_dev->flash_dev; -+ -+ int pagesizes[] = {SZ_2K, SZ_4K, SZ_8K, 0}; -+ int oobsizes[] = {128, 224, 448, 0, 0, 0, 0, 0}; -+ int blocksizes[] = {SZ_128K, SZ_256K, SZ_512K, -+ (SZ_256K + SZ_512K), SZ_1M, SZ_2M, 0, 0 -+ }; -+ -+ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); -+ int oobtype = (((id[3] >> 2) & 0x03) | ((id[3] >> 4) & 0x04)); -+ -+ type->options = 0; -+ type->pagesize = pagesizes[(id[3] & 0x03)]; -+ type->erasesize = blocksizes[blocktype]; -+ nand_dev->oobsize = oobsizes[oobtype]; -+ -+ return type; -+} -+/*****************************************************************************/ -+ -+static struct nand_flash_dev *samsung_probe_v02( -+ struct nand_dev_t *nand_dev) -+{ -+ unsigned char *id = nand_dev->ids; -+ struct nand_flash_dev *type = &nand_dev->flash_dev; -+ -+ int pagesizes[] = {SZ_2K, SZ_4K, SZ_8K, 0}; -+ int oobsizes[] = {0, 128, 218, 400, 436, 0, 0, 0}; -+ int blocksizes[] = {SZ_128K, SZ_256K, SZ_512K, SZ_1M, 0, 0, 0, 0}; -+ -+ int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03)); -+ int oobtype = (((id[3] >> 4) & 0x04) | ((id[3] >> 2) & 0x03)); -+ -+ type->options = 0; -+ type->pagesize = pagesizes[(id[3] & 0x03)]; -+ type->erasesize = blocksizes[blocktype]; -+ nand_dev->oobsize = oobsizes[oobtype]; -+ -+ return type; -+} -+/*****************************************************************************/ -+ -+#define DRV_VERSION "1.38" -+ -+/*****************************************************************************/ -+/* -+ * samsung: 27nm need randomizer, 21nm need read retry; -+ * micron: 25nm need read retry, datasheet will explain read retry. -+ * toshaba 32nm need randomizer, 24nm need read retry. -+ * hynix: 2xnm need read retry. -+ * -+ * The special nand flash ID table version 1.37 -+ * -+ * manufactory | type | name | ecc_type | version_tag -+ * Micron | MLC | MT29F64G08CBABA | 40bit/1k | 1.36 -+ * Micron | MLC | MT29F32G08CBADA | 40bit/1k | -+ * Micron | SLC | MT29F8G08ABxBA | 4bit/512 | -+ * Micron | MLC | MT29F16G08CBABx | 12bit/512 | -+ * Micron | MLC | MT29F16G08CBACA | 24bit/1k | -+ * Micron | MLC | MT29F32G08CBACA | 24bit/1k | -+ * Micron | MLC | MT29F64G08CxxAA | 24bit/1k | -+ * Micron | MLC | MT29F256G08CJAAA | 24bit/1k | 2CE -+ * Micron | MLC | MT29F256G08CMCBB | 24bit/1k | -+ * Micron | SLC | MT29F8G08ABACA | 8bit/512 | -+ * Micron | SLC | MT29F4G08ABAEA | 8bit/512 | -+ * Micron | SLC | MT29F2G08ABAFA | 8bit/512 | -+ * Micron | SLC | MT29F16G08ABACA | 8bit/512 | -+ * Toshiba | MLC | TC58NVG4D2FTA00 | 24bit/1k | -+ * Toshiba | MLC | TH58NVG6D2FTA20 | 24bit/1k | 2CE -+ * Toshiba | MLC | TC58NVG5D2HTA00 | 40bit/1k | -+ * Toshiba | MLC | TC58NVG6D2GTA00 | 40bit/1k | -+ * Toshiba | MLC | TC58NVG6DCJTA00 | | -+ * Toshiba | MLC | TC58TEG5DCJTA00 | | -+ * Toshiba | SLC | TC58NVG0S3HTA00 | 8bit/512 | -+ * Toshiba | SLC | TC58NVG1S3HTA00 | 8bit/512 | -+ * Toshiba | SLC | TC58NVG1S3ETA00 | 4bit/512 | -+ * Toshiba | SLC | TC58NVG3S0FTA00 | 4bit/512 | -+ * Toshiba | SLC | TC58NVG2S0FTA00 | 4bit/512 | -+ * Toshiba | SLC | TH58NVG2S3HTA00 | 4bit/512 | -+ * Toshiba | TLC | TC58NVG5T2JTA00 | 60bit/1k | -+ * Toshiba | TLC | TC58TEG5DCKTAx0 | 60bit/1k | -+ * Toshiba | MLC | Tx58TEGxDDKTAx0 | | -+ * Samsung | MLC | K9LB(HC/PD/MD)G08U0(1)D | 8bit/512B | -+ * Samsung | MLC | K9GAG08U0E | 24bit/1KB | -+ * Samsung | MLC | K9LBG08U0E | 24bit/1KB | -+ * Samsung | MLC | K9G8G08U0C | 24bit/1KB | -+ * Samsung | MLC | K9GAG08U0F | 24bit/1KB | -+ * Samsung | MLC | K9LBG08U0M | | -+ * Samsung | MLC | K9GBG08U0A | 24bit/1KB | -+ * Samsung | MLC | K9GBG08U0B | 40bit/1KB | -+ * Hynix | MLC | H27UAG8T2A | | -+ * Hynix | MLC | H27UAG8T2B | | -+ * Hynix | MLC | H27UBG8T2A | | -+ * Hynix | MLC | H27UBG8T2BTR | 24bit/1KB | -+ * Hynix | MLC | H27UCG8T2A | 40bit/1KB | -+ * Hynix | MLC | H27UBG8T2C | 40bit/1KB | -+ * MISC | MLC | P1UAGA30AT-GCA | 8bit/512 | -+ * MISC | MLC | PSU8GA30AT-GIA/ASU8GA30IT-G30CA | 4bit/512 | -+ * MISC | SLC | PSU2GA30AT | 1bit/512 | 1.36 -+ * Toshiba | SLC | TC58NVG2S0HTA00 | 24bit/1K | 1.37 -+ * Toshiba | SLC | TC58NVG3S0HTA00 | 24bit/1K | 1.37 -+ * Micron | SLC | MT29F2G08ABAEA | 4bit/512 | -+ * Spansion | SLC | S34ML02G200TFI000 | 24bit/1K | -+ * Spansion | SLC | S34ML04G200TFI000 | 24bit/1K | 1.38 -+ * -+ */ -+ -+static struct nand_flash_special_dev nand_flash_special_dev[] = { -+ -+ /****************************** Spansion *******************************/ -+ -+ { /* SLC S34ML02G200TFI000 */ -+ .name = "S34ML02G200TFI000", -+ .id = {0x01, 0xDA, 0x90, 0x95, 0x46, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = _256M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 128, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ -+ { /* SLC S34ML04G200TFI000 */ -+ .name = "S34ML04G200TFI000", -+ .id = {0x01, 0xDC, 0x90, 0x95, 0x56, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = _512M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 128, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ -+ /****************************** Micron *******************************/ -+ { /* MLC 40bit/1k */ -+ .name = "MT29F64G08CBABA", -+ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = _8G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 744, -+ .options = 0, -+ .read_retry_type = NAND_RR_MICRON, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = NAND_RANDOMIZER | NAND_CHIP_MICRON, -+ }, -+ { /* MLC 40bit/1k */ -+ .name = "MT29F32G08CBADA", -+ .id = {0x2C, 0x44, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 744, -+ .options = 0, -+ .read_retry_type = NAND_RR_MICRON, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { /* SLC 4bit/512 */ -+ .name = "MT29F8G08ABxBA", -+ .id = {0x2C, 0x38, 0x00, 0x26, 0x85, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = SZ_1G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_512K, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 12bit/512 */ -+ .name = "MT29F16G08CBABx", -+ .id = {0x2C, 0x48, 0x04, 0x46, 0x85, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = SZ_2G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_1M, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1k */ -+ .name = "MT29F16G08CBACA", -+ .id = {0x2C, 0x48, 0x04, 0x4A, 0xA5, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = SZ_2G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_1M, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1k */ -+ .name = "MT29F32G08CBACA", -+ .id = {0x2C, 0x68, 0x04, 0x4A, 0xA9, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_1M, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1k */ -+ .name = "MT29F64G08CxxAA", -+ .id = {0x2C, 0x88, 0x04, 0x4B, 0xA9, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = _8G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 448, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1k 2CE */ -+ .name = "MT29F256G08CJAAA", -+ .id = {0x2C, 0xA8, 0x05, 0xCB, 0xA9, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = _16G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 448, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 40bit/1k */ -+ .name = "MT29F256G08CMCBB", -+ .id = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00}, -+ .length = 8, -+ .chipsize = _8G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 744, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 8bit/512 */ -+ .name = "MT29F8G08ABACA", -+ .id = {0x2C, 0xD3, 0x90, 0xA6, 0x64, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = SZ_1G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_256K, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 8bit/512 */ -+ .name = "MT29F4G08ABAEA", -+ .id = {0x2C, 0xDC, 0x90, 0xA6, 0x54, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = SZ_512M, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_256K, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 8bit/512 */ -+ .name = "MT29F2G08ABAFA", -+ .id = {0x2C, 0xDA, 0x90, 0x95, 0x04, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = SZ_256M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC MT29F2G08ABAEA */ -+ .name = "MT29F2G08ABAEA", -+ .id = {0x2C, 0xDA, 0x90, 0x95, 0x06, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = _256M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 64, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 8bit/512 */ -+ .name = "MT29F16G08ABACA", -+ .id = {0x2C, 0x48, 0x00, 0x26, 0xA9, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = SZ_2G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_512K, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ -+ /****************************** Toshaba *******************************/ -+ -+ { /* MLC 24bit/1k 32nm */ -+ .name = "TC58NVG4D2FTA00", -+ .id = {0x98, 0xD5, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = SZ_2G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_1M, -+ .oobsize = 448, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1k 32nm 2CE*/ -+ .name = "TH58NVG6D2FTA20", -+ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_1M, -+ .oobsize = 448, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 40bit/1k 24nm */ -+ .name = "TC58NVG5D2HTA00 24nm", -+ .id = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x56, 0x08, 0x00}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_1M, -+ .oobsize = 640, -+ .options = 0, -+ .read_retry_type = NAND_RR_TOSHIBA_24nm, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { /* MLC 40bit/1k */ -+ .name = "TC58NVG6D2GTA00", -+ .id = {0x98, 0xDE, 0x94, 0x82, 0x76, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = _8G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 640, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 19nm */ -+ .name = "TC58NVG6DCJTA00 19nm", -+ .id = {0x98, 0xDE, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, -+ .length = 8, -+ .chipsize = _8G, -+ .probe = NULL, -+ .pagesize = SZ_16K, -+ .erasesize = SZ_4M, -+ .oobsize = 1280, -+ .options = 0, -+ .read_retry_type = NAND_RR_TOSHIBA_24nm, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { /* MLC 19nm */ -+ .name = "TC58TEG5DCJTA00 19nm", -+ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_16K, -+ .erasesize = SZ_4M, -+ .oobsize = 1280, -+ .options = 0, -+ .read_retry_type = NAND_RR_TOSHIBA_24nm, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER | NAND_CHIP_TOSHIBA_TOGGLE_10, -+ }, -+ { /* SLC 8bit/512 */ -+ .name = "TC58NVG0S3HTA00", -+ .id = {0x98, 0xF1, 0x80, 0x15, 0x72, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = SZ_128M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 128, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ /* -+ * Datasheet: read one column of any page in each block. If the -+ * data of the column is 00 (Hex), define the block as a bad -+ * block. -+ */ -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 8bit/512 */ -+ .name = "TC58NVG1S3HTA00", -+ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x16, 0x08, 0x00}, -+ .length = 7, -+ .chipsize = SZ_256M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 128, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 4bit/512 */ -+ .name = "TC58NVG1S3ETA00", -+ .id = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x14, 0x03, 0x00}, -+ .length = 7, -+ .chipsize = SZ_256M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 64, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 4bit/512 */ -+ .name = "TC58NVG3S0FTA00", -+ .id = {0x98, 0xD3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08}, -+ .length = 8, -+ .chipsize = SZ_1G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_256K, -+ .oobsize = 232, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 4bit/512 */ -+ .name = "TC58NVG3S0HTA00", -+ .id = {0x98, 0xD3, 0x91, 0x26, 0x76, 0x16, 0x08, 0x00}, -+ .length = 8, -+ .chipsize = SZ_1G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_256K, -+ .oobsize = 256, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 24bit/1k */ -+ .name = "TC58NVG2S0HTA00", -+ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00}, -+ .length = 8, -+ .chipsize = SZ_512M, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_256K, -+ .oobsize = 256, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 4bit/512 */ -+ .name = "TC58NVG2S0FTA00", -+ .id = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08}, -+ .length = 8, -+ .chipsize = SZ_512M, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_256K, -+ .oobsize = 224, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 4bit/512 */ -+ .name = "TH58NVG2S3HTA00", -+ .id = {0x98, 0xDC, 0x91, 0x15, 0x76}, -+ .length = 5, -+ .chipsize = SZ_512M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 128, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE, -+ .flags = 0, -+ }, -+ { /* TLC 60bit/1k 19nm */ -+ .name = "TC58NVG5T2JTA00 19nm TLC", -+ .id = {0x98, 0xD7, 0x98, 0x92, 0x72, 0x57, 0x08, 0x10}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_4M, -+ .oobsize = 1024, -+ .options = 0, -+ .read_retry_type = NAND_RR_TOSHIBA_24nm, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { /* TLC 60bit/1k 19nm */ -+ .name = "TC58TEG5DCKTAx0 19nm MLC", -+ /* datasheet says 6 ids id data, but really has 8 ids. */ -+ .id = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x50, 0x08, 0x04}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_16K, -+ .erasesize = SZ_4M, -+ .oobsize = 1280, -+ .options = 0, -+ .read_retry_type = NAND_RR_TOSHIBA_19nm, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { -+ .name = "Tx58TEGxDDKTAx0 19nm MLC", -+ .id = {0x98, 0xDE, 0x94, 0x93, 0x76, 0x50}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_16K, -+ .erasesize = SZ_4M, -+ .oobsize = 1280, -+ .options = 0, -+ .read_retry_type = NAND_RR_TOSHIBA_19nm, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ /******************************* Samsung ******************************/ -+ { /* MLC 8bit/512B */ -+ .name = "K9LB(HC/PD/MD)G08U0(1)D", -+ .id = {0xEC, 0xD7, 0xD5, 0x29, 0x38, 0x41, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = samsung_probe_v02, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1KB */ -+ .name = "K9GAG08U0E", -+ .id = {0xEC, 0xD5, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = SZ_2G, -+ .probe = samsung_probe_v02, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1KB */ -+ .name = "K9LBG08U0E", -+ .id = {0xEC, 0xD7, 0xC5, 0x72, 0x54, 0x42, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = samsung_probe_v02, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1KB */ -+ .name = "K9G8G08U0C", -+ .id = {0xEC, 0xD3, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = SZ_1G, -+ .probe = samsung_probe_v02, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1k */ -+ .name = "K9GAG08U0F", -+ .id = {0xEC, 0xD5, 0x94, 0x76, 0x54, 0x43, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = SZ_2G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_1M, -+ .oobsize = 512, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC */ -+ .name = "K9LBG08U0M", -+ .id = {0xEC, 0xD7, 0x55, 0xB6, 0x78, 0x00, 0x00, 0x00}, -+ .length = 5, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_512K, -+ .oobsize = 128, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1k */ -+ .name = "K9GBG08U0A 20nm", -+ .id = {0xEC, 0xD7, 0x94, 0x7A, 0x54, 0x43, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_1M, -+ .oobsize = 640, -+ .options = 0, -+ .read_retry_type = NAND_RR_SAMSUNG, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { /* MLC 40bit/1k */ -+ .name = "K9GBG08U0B", -+ .id = {0xEC, 0xD7, 0x94, 0x7E, 0x64, 0x44, 0x00, 0x00}, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_1M, -+ .oobsize = 1024, -+ .options = 0, -+ .read_retry_type = NAND_RR_SAMSUNG, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ -+ /*********************************** Hynix ****************************/ -+ { /* MLC */ -+ .name = "H27UAG8T2A", -+ .id = {0xAD, 0xD5, 0x94, 0x25, 0x44, 0x41, }, -+ .length = 6, -+ .chipsize = SZ_2G, -+ .probe = hynix_probe_v02, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC */ -+ .name = "H27UAG8T2B", -+ .id = {0xAD, 0xD5, 0x94, 0x9A, 0x74, 0x42, }, -+ .length = 6, -+ .chipsize = SZ_2G, -+ .probe = hynix_probe_v02, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC */ -+ .name = "H27UBG8T2A", -+ .id = {0xAD, 0xD7, 0x94, 0x9A, 0x74, 0x42, }, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = hynix_probe_v02, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 24bit/1K, 26nm TODO: Need read retry, chip is EOS */ -+ .name = "H27UBG8T2BTR 26nm", -+ .id = {0xAD, 0xD7, 0x94, 0xDA, 0x74, 0xC3, }, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 640, -+ .options = 0, -+ .read_retry_type = NAND_RR_HYNIX_BG_BDIE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { /* MLC 40bit/1k */ -+ .name = "H27UCG8T2A", -+ .id = {0xAD, 0xDE, 0x94, 0xDA, 0x74, 0xC4, }, -+ .length = 6, -+ .chipsize = _8G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 640, -+ .options = 0, -+ .read_retry_type = NAND_RR_HYNIX_CG_ADIE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ { /* MLC 40bit/1k */ -+ .name = "H27UBG8T2C", -+ .id = {0xAD, 0xD7, 0x94, 0x91, 0x60, 0x44, }, -+ .length = 6, -+ .chipsize = _4G, -+ .probe = NULL, -+ .pagesize = SZ_8K, -+ .erasesize = SZ_2M, -+ .oobsize = 640, -+ .options = 0, -+ .read_retry_type = NAND_RR_HYNIX_BG_CDIE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = NAND_RANDOMIZER, -+ }, -+ -+ /********************** MISC ******************************************/ -+ { /* MLC 8bit/512 */ -+ .name = "P1UAGA30AT-GCA", -+ .id = {0xC8, 0xD5, 0x14, 0x29, 0x34, 0x01, }, -+ .length = 6, -+ .chipsize = SZ_2G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_512K, -+ .oobsize = 218, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* MLC 4bit/512 */ -+ /* -+ * PowerFlash ASU8GA30IT-G30CA ID and MIRA PSU8GA30AT-GIA ID are -+ * the same ID -+ */ -+ .name = "PSU8GA30AT-GIA/ASU8GA30IT-G30CA", -+ .id = {0xC8, 0xD3, 0x90, 0x19, 0x34, 0x01, }, -+ .length = 6, -+ .chipsize = SZ_1G, -+ .probe = NULL, -+ .pagesize = SZ_4K, -+ .erasesize = SZ_256K, -+ .oobsize = 218, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ { /* SLC 1bit/512 */ -+ .name = "PSU2GA30AT", -+ .id = {0x7F, 0x7F, 0x7F, 0x7F, 0xC8, 0xDA, 0x00, 0x15, }, -+ .length = 8, -+ .chipsize = SZ_256M, -+ .probe = NULL, -+ .pagesize = SZ_2K, -+ .erasesize = SZ_128K, -+ .oobsize = 64, -+ .options = 0, -+ .read_retry_type = NAND_RR_NONE, -+ .badblock_pos = BBP_FIRST_PAGE | BBP_LAST_PAGE, -+ .flags = 0, -+ }, -+ {{0}, 0, 0, 0, 0, 0, 0, 0, 0}, -+}; -+ -+#define NUM_OF_SPECIAL_DEVICE \ -+ (sizeof(nand_flash_special_dev)/sizeof(struct nand_flash_special_dev)) -+ -+int (*nfc_param_adjust)(struct mtd_info *, struct nand_chip *, -+ struct nand_dev_t *) = NULL; -+ -+static struct nand_dev_t __nand_dev; -+/*****************************************************************************/ -+ -+static struct nand_flash_dev *nfc_nand_probe(struct mtd_info *mtd, -+ struct nand_chip *chip, -+ struct nand_dev_t *nand_dev) -+{ -+ struct nand_flash_special_dev *spl_dev = NULL; -+ unsigned char *byte = nand_dev->ids; -+ struct nand_flash_dev *type = &nand_dev->flash_dev; -+ -+ nfc_pr_msg("Nand ID: 0x%02X 0x%02X 0x%02X 0x%02X", -+ byte[0], byte[1], byte[2], byte[3]); -+ nfc_pr_msg(" 0x%02X 0x%02X 0x%02X 0x%02X\n", -+ byte[4], byte[5], byte[6], byte[7]); -+ -+ for (spl_dev = nand_flash_special_dev; spl_dev->length; spl_dev++) { -+ if (memcmp(byte, spl_dev->id, spl_dev->length)) -+ continue; -+ -+ nfc_pr_msg("The Special NAND id table Version: %s\n", DRV_VERSION); -+ -+ if (spl_dev->probe) { -+ type = spl_dev->probe(nand_dev); -+ } else { -+ type->options = spl_dev->options; -+ type->pagesize = spl_dev->pagesize; -+ type->erasesize = spl_dev->erasesize; -+ nand_dev->oobsize = spl_dev->oobsize; -+ } -+ -+ nand_dev->read_retry_type = spl_dev->read_retry_type; -+ nand_dev->flags = spl_dev->flags; -+ -+ type->id[1] = byte[1]; -+ type->chipsize = (unsigned long)(spl_dev->chipsize >> 20); -+ type->name = spl_dev->name; -+ return type; -+ } -+ nand_dev->read_retry_type = NAND_RR_NONE; -+ -+ return NULL; -+} -+/*****************************************************************************/ -+ -+struct nand_flash_dev *nfc_get_flash_type(struct mtd_info *mtd, -+ struct nand_chip *chip, -+ u8 *id_data, int *busw) -+{ -+ struct nand_flash_dev *type = NULL; -+ struct nand_dev_t *nand_dev = &__nand_dev; -+ -+ memset(nand_dev, 0, sizeof(struct nand_dev_t)); -+ memcpy(nand_dev->ids, id_data, 8); -+ -+ if (!nfc_nand_probe(mtd, chip, nand_dev)) -+ return NULL; -+ -+ type = &nand_dev->flash_dev; -+ -+ if (!mtd->name) -+ mtd->name = type->name; -+ -+ chip->chipsize = (uint64_t)type->chipsize << 20; -+ mtd->erasesize = type->erasesize; -+ mtd->writesize = type->pagesize; -+ mtd->oobsize = nand_dev->oobsize; -+ *busw = (type->options & NAND_BUSWIDTH_16); -+ -+ return type; -+} -+/*****************************************************************************/ -+ -+void nfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip) -+{ -+ struct nand_dev_t *nand_dev = &__nand_dev; -+ -+ if (!nand_dev->oobsize) -+ nand_dev->oobsize = mtd->oobsize; -+ -+ if (nfc_param_adjust) -+ nfc_param_adjust(mtd, chip, nand_dev); -+} -+/*****************************************************************************/ -+ -+void nfc_show_info(struct mtd_info *mtd, char *goke, char *chipname) -+{ -+ /* char buf[20]; */ -+ struct nand_dev_t *nand_dev = &__nand_dev; -+ -+ /* nfc_pr_msg("Nand: %s %s ", goke, chipname); */ -+ -+ if (IS_NAND_RANDOM(nand_dev)) -+ nfc_pr_msg("Randomizer \n"); -+ -+ if (nand_dev->read_retry_type != NAND_RR_NONE) -+ nfc_pr_msg("Read-Retry \n"); -+ -+ if (nand_dev->start_type) -+ nfc_pr_msg("Nand(%s): ", nand_dev->start_type); -+ else -+ nfc_pr_msg("Nand: "); -+ -+ nfc_pr_msg("OOB:%dB ", nand_dev->oobsize); -+ nfc_pr_msg("ECC:%s ", nand_ecc_name(nand_dev->ecctype)); -+} -+/*****************************************************************************/ -+ -+void nfc_show_chipsize(struct nand_chip *chip) -+{ -+ /*char buf[20];*/ -+ -+ /*nfc_pr_msg("Chip:%sB*%d\n", -+ ultohstr(chip->chipsize, buf, sizeof(buf)), -+ chip->numchips);*/ -+} ---- linux-4.9.37/drivers/mtd/spi-nor/goke-sfc.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/spi-nor/goke-sfc.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,592 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../mtdcore.h" -+ -+#define FMC_OP_DMA 0x68 -+ -+struct fmc_priv { -+ u32 chipselect; -+ u32 clkrate; -+ struct fmc_host *host; -+}; -+ -+struct fmc_host { -+ struct device *dev; -+ struct mutex *lock; -+ -+ void __iomem *regbase; -+ void __iomem *iobase; -+ struct clk *clk; -+ void *buffer; -+ dma_addr_t dma_buffer; -+ -+ struct spi_nor *nor[FMC_MAX_CHIP_NUM]; -+ struct fmc_priv priv[FMC_MAX_CHIP_NUM]; -+ u32 num_chip; -+ unsigned int dma_len; -+}; -+ -+/******************************************************************************/ -+static inline int wait_op_finish(struct fmc_host *host) -+{ -+ u32 reg; -+ -+ return readl_poll_timeout(host->regbase + FMC_INT, reg, -+ (reg & FMC_INT_OP_DONE), 0, FMC_WAIT_TIMEOUT); -+} -+ -+static int get_if_type(enum spi_nor_protocol mode) -+{ -+ enum fmc_iftype if_type; -+ -+ switch (mode) { -+ case SNOR_PROTO_1_1_2: -+ if_type = IF_TYPE_DUAL; -+ break; -+ case SNOR_PROTO_1_2_2: -+ if_type = IF_TYPE_DIO; -+ break; -+ case SNOR_PROTO_1_1_4: -+ if_type = IF_TYPE_QUAD; -+ break; -+ case SNOR_PROTO_1_4_4: -+ if_type = IF_TYPE_QIO; -+ break; -+ case SNOR_PROTO_1_1_1: -+ default: -+ if_type = IF_TYPE_STD; -+ break; -+ } -+ -+ return if_type; -+} -+ -+/******************************************************************************/ -+static void spi_nor_switch_spi_type(struct fmc_host *host) -+{ -+ unsigned int reg; -+ -+ reg = fmc_readl(host, FMC_CFG); -+ reg &= ~FLASH_TYPE_SEL_MASK; -+ reg |= FMC_CFG_FLASH_SEL(0); -+ fmc_writel(host, FMC_CFG, reg); -+} -+ -+/******************************************************************************/ -+static void bsp_spi_nor_init(struct fmc_host *host) -+{ -+ unsigned int reg; -+ -+ /* switch the flash type to spi nor */ -+ spi_nor_switch_spi_type(host); -+ -+ /* set the boot mode to normal */ -+ reg = fmc_readl(host, FMC_CFG); -+ if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) { -+ reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL); -+ fmc_writel(host, FMC_CFG, reg); -+ } -+ -+ /* hold on STR mode */ -+ reg = fmc_readl(host, FMC_GLOBAL_CFG); -+ reg &= (~FMC_GLOBAL_CFG_DTR_MODE); -+ fmc_writel(host, FMC_GLOBAL_CFG, reg); -+ -+ /* set timming */ -+ reg = TIMING_CFG_TCSH(CS_HOLD_TIME) -+ | TIMING_CFG_TCSS(CS_SETUP_TIME) -+ | TIMING_CFG_TSHSL(CS_DESELECT_TIME); -+ fmc_writel(host, FMC_SPI_TIMING_CFG, reg); -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_prep(struct spi_nor *nor, enum spi_nor_ops ops) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ u32 clkrate; -+ int ret; -+ -+ mutex_lock(&fmc_switch_mutex); -+ mutex_lock(host->lock); -+ -+ clkrate = min_t(u32, priv->clkrate, nor->clkrate); -+ ret = clk_set_rate(host->clk, clkrate); -+ if (ret) -+ goto out; -+ -+ ret = clk_prepare_enable(host->clk); -+ if (ret) -+ goto out; -+ -+ spi_nor_switch_spi_type(host); -+ -+ return 0; -+ -+out: -+ mutex_unlock(host->lock); -+ return ret; -+} -+ -+/******************************************************************************/ -+static void bsp_spi_nor_unprep(struct spi_nor *nor, enum spi_nor_ops ops) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ -+ clk_disable_unprepare(host->clk); -+ mutex_unlock(host->lock); -+ mutex_unlock(&fmc_switch_mutex); -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_op_reg(struct spi_nor *nor, -+ u8 opcode, u32 len, u8 optype) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ u32 reg; -+ -+ reg = FMC_CMD_CMD1(opcode); -+ fmc_writel(host, FMC_CMD, reg); -+ -+ reg = FMC_DATA_NUM_CNT(len); -+ fmc_writel(host, FMC_DATA_NUM, reg); -+ -+ reg = OP_CFG_FM_CS(priv->chipselect) | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ -+ fmc_writel(host, FMC_INT_CLR, 0xff); -+ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START | optype; -+ fmc_writel(host, FMC_OP, reg); -+ -+ return wait_op_finish(host); -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, -+ int len) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ int ret; -+ -+ ret = bsp_spi_nor_op_reg(nor, opcode, len, FMC_OP_READ_DATA_EN); -+ if (ret) -+ return ret; -+ -+ memcpy_fromio(buf, host->iobase, len); -+ return 0; -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_write_reg(struct spi_nor *nor, u8 opcode, -+ u8 *buf, int len) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ -+ if (len) -+ memcpy_toio(host->iobase, buf, len); -+ -+ return bsp_spi_nor_op_reg(nor, opcode, len, FMC_OP_WRITE_DATA_EN); -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_dma_transfer(struct spi_nor *nor, loff_t start_off, -+ dma_addr_t dma_buf, size_t len, u8 op_type) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ u8 if_type = 0, dummy = 0; -+ u32 reg; -+ -+ reg = fmc_readl(host, FMC_CFG); -+ reg &= ~(FMC_CFG_OP_MODE_MASK | SPI_NOR_ADDR_MODE_MASK); -+ reg |= FMC_CFG_OP_MODE_NORMAL; -+ reg |= (nor->addr_width == 4) ? SPI_NOR_ADDR_MODE_4BYTES -+ : SPI_NOR_ADDR_MODE_3BYTES; -+ fmc_writel(host, FMC_CFG, reg); -+ -+ fmc_writel(host, FMC_ADDRL, start_off); -+ -+ reg = (unsigned int)dma_buf; -+ fmc_writel(host, FMC_DMA_SADDR_D0, reg); -+ -+#ifdef CONFIG_64BIT -+ reg = (dma_buf & FMC_DMA_SADDRH_MASK) >> 32; -+ fmc_writel(host, FMC_DMA_SADDRH_D0, reg); -+#endif -+ -+ fmc_writel(host, FMC_DMA_LEN, FMC_DMA_LEN_SET(len)); -+ -+ reg = OP_CFG_FM_CS(priv->chipselect); -+ if (op_type == FMC_OP_READ) { -+ if_type = get_if_type(nor->read_proto); -+ dummy = nor->read_dummy >> 3; -+ } else { -+ if_type = get_if_type(nor->write_proto); -+ } -+ reg |= OP_CFG_MEM_IF_TYPE(if_type) -+ | OP_CFG_DUMMY_NUM(dummy) -+ | OP_CFG_OEN_EN; -+ fmc_writel(host, FMC_OP_CFG, reg); -+ -+ fmc_writel(host, FMC_INT_CLR, 0xff); -+ reg = OP_CTRL_RW_OP(op_type) | OP_CTRL_DMA_OP_READY; -+ reg |= (op_type == FMC_OP_READ) -+ ? OP_CTRL_RD_OPCODE(nor->read_opcode) -+ : OP_CTRL_WR_OPCODE(nor->program_opcode); -+ fmc_writel(host, FMC_OP_DMA, reg); -+ -+ return wait_op_finish(host); -+} -+ -+static ssize_t bsp_spi_nor_read(struct spi_nor *nor, loff_t from, size_t len, -+ u_char *read_buf) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ size_t offset; -+ int ret; -+ -+ for (offset = 0; offset < len; offset += host->dma_len) { -+ size_t trans = min_t(size_t, host->dma_len, len - offset); -+ -+ ret = bsp_spi_nor_dma_transfer(nor, -+ from + offset, host->dma_buffer, trans, FMC_OP_READ); -+ if (ret) { -+ dev_warn(nor->dev, "DMA read timeout\n"); -+ return ret; -+ } -+ memcpy(read_buf + offset, host->buffer, trans); -+ } -+ -+ return len; -+} -+ -+static ssize_t bsp_spi_nor_write(struct spi_nor *nor, loff_t to, -+ size_t len, const u_char *write_buf) -+{ -+ struct fmc_priv *priv = nor->priv; -+ struct fmc_host *host = priv->host; -+ size_t offset; -+ int ret; -+ -+ for (offset = 0; offset < len; offset += host->dma_len) { -+ size_t trans = min_t(size_t, host->dma_len, len - offset); -+ -+ memcpy(host->buffer, write_buf + offset, trans); -+ ret = bsp_spi_nor_dma_transfer(nor, -+ to + offset, host->dma_buffer, trans, FMC_OP_WRITE); -+ if (ret) { -+ dev_warn(nor->dev, "DMA write timeout\n"); -+ return ret; -+ } -+ } -+ -+ return len; -+} -+ -+/** -+ * parse partitions info and register spi flash device as mtd device. -+ */ -+static int bsp_snor_device_register(struct mtd_info *mtd) -+{ -+ int ret; -+ struct mtd_partitions parsed; -+ -+ /* -+ * We do not add the whole spi flash as a mtdblock device, -+ * To avoid the number of nand partition +1. -+ */ -+ memset(&parsed, 0, sizeof(parsed)); -+ ret = parse_mtd_partitions(mtd, NULL, &parsed, NULL); -+ if (ret) -+ return ret; -+ -+ return parsed.nr_parts ? mtd_device_register(mtd, NULL, 0) : parsed.nr_parts; -+} -+ -+/** -+ * Get spi flash device information and register it as a mtd device. -+ */ -+static int bsp_spi_nor_register(struct device_node *np, -+ struct fmc_host *host) -+{ -+ struct device *dev = host->dev; -+ struct spi_nor *nor; -+ struct fmc_priv *priv = &host->priv[host->num_chip]; -+ struct mtd_info *mtd; -+ int ret; -+ struct spi_nor_modes modes = { -+ .rd_modes = SNOR_MODE_SLOW, -+ .wr_modes = SNOR_MODE_1_1_1, -+ }; -+ -+ nor = devm_kzalloc(dev, sizeof(*nor), GFP_KERNEL); -+ if (!nor) -+ return -ENOMEM; -+ -+ nor->dev = dev; -+ spi_nor_set_flash_node(nor, np); -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ ret = of_property_read_u32(np, "reg", &priv->chipselect); -+ if (ret) { -+ dev_err(dev, "There's no reg property for %s\n", -+ np->full_name); -+ return ret; -+ } -+ -+ if (priv->chipselect != host->num_chip) { -+ dev_warn(dev, " The CS: %d states in device trees isn't real " \ -+ "chipselect on board\n, using CS: %d instead. ", -+ priv->chipselect, host->num_chip); -+ priv->chipselect = host->num_chip; -+ } -+ -+ ret = of_property_read_u32(np, "spi-max-frequency", -+ &priv->clkrate); -+ if (ret) { -+ dev_err(dev, "There's no spi-max-frequency property for %s\n", -+ np->full_name); -+ return ret; -+ } -+ priv->host = host; -+ nor->priv = priv; -+ -+ nor->prepare = bsp_spi_nor_prep; -+ nor->unprepare = bsp_spi_nor_unprep; -+ nor->read_reg = bsp_spi_nor_read_reg; -+ nor->write_reg = bsp_spi_nor_write_reg; -+ nor->read = bsp_spi_nor_read; -+ nor->write = bsp_spi_nor_write; -+ -+ modes.rd_modes |= SNOR_MODE_1_1_1 -+ | SNOR_MODE_1_1_2 -+ | SNOR_MODE_1_2_2; -+#ifndef CONFIG_CLOSE_SPI_8PIN_4IO -+ modes.rd_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; -+ modes.wr_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; -+#endif -+ ret = spi_nor_scan(nor, NULL, &modes); -+ if (ret) -+ return ret; -+ -+ mtd = &nor->mtd; -+ mtd->name = np->name; -+ ret = bsp_snor_device_register(mtd); -+ if (ret) -+ return ret; -+ -+ /* current chipselect has scanned, to detect next chipselect */ -+ fmc_cs_user[host->num_chip]++; -+ host->nor[host->num_chip] = nor; -+ return 0; -+} -+ -+static void bsp_spi_nor_unregister_all(struct fmc_host *host) -+{ -+ int i; -+ -+ for (i = 0; i < host->num_chip; i++) -+ mtd_device_unregister(&host->nor[i]->mtd); -+} -+ -+static int bsp_spi_nor_register_all(struct fmc_host *host) -+{ -+ struct device *dev = host->dev; -+ struct device_node *np = NULL; -+ int ret; -+ -+ for_each_available_child_of_node(dev->of_node, np) { -+ if (fmc_cs_user[host->num_chip]) { -+ dev_warn(dev, "Current CS(%d) is occupied.\n", -+ host->num_chip); -+ continue; -+ } -+ ret = bsp_spi_nor_register(np, host); -+ if (ret) -+ goto fail; -+ -+ if (host->num_chip == FMC_MAX_CHIP_NUM) { -+ dev_warn(dev, "Flash device number exceeds the " -+ "maximum chipselect number\n"); -+ break; -+ } -+ -+ host->num_chip++; -+ -+ } -+ -+ return 0; -+ -+fail: -+ bsp_spi_nor_unregister_all(host); -+ return ret; -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct bsp_fmc *fmc = dev_get_drvdata(dev->parent); -+ struct fmc_host *host; -+ int ret; -+ -+ if (!fmc) { -+ dev_err(&pdev->dev, "get mfd fmc devices failed\n"); -+ return -ENXIO; -+ } -+ -+ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); -+ if (!host) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, host); -+ host->dev = dev; -+ -+ host->regbase = fmc->regbase; -+ host->iobase = fmc->iobase; -+ host->clk = fmc->clk; -+ host->lock = &fmc->lock; -+ host->buffer = fmc->buffer; -+ host->dma_buffer = fmc->dma_buffer; -+ host->dma_len = fmc->dma_len; -+ -+ clk_prepare_enable(host->clk); -+ bsp_spi_nor_init(host); -+ ret = bsp_spi_nor_register_all(host); -+ if (ret) -+ dev_warn(dev, "spi nor register fail!\n"); -+ -+ clk_disable_unprepare(host->clk); -+ -+ return ret; -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_remove(struct platform_device *pdev) -+{ -+ struct fmc_host *host = platform_get_drvdata(pdev); -+ if (host == NULL){ -+ dev_err(&pdev->dev, "host is NULL ,remove err !!\n"); -+ return 0; -+ } -+ -+ bsp_spi_nor_unregister_all(host); -+ clk_disable_unprepare(host->clk); -+ return 0; -+} -+ -+/******************************************************************************/ -+static void bsp_spi_nor_driver_shutdown(struct platform_device *pdev) -+{ -+ int i; -+ struct fmc_host *host = platform_get_drvdata(pdev); -+ -+ if (!host) -+ return; -+ -+ mutex_lock(host->lock); -+ clk_prepare_enable(host->clk); -+ -+ spi_nor_switch_spi_type(host); -+ for (i = 0; i < host->num_chip; i++) -+ spi_nor_driver_shutdown(host->nor[i]); -+ -+ clk_disable_unprepare(host->clk); -+ mutex_unlock(host->lock); -+ dev_dbg(host->dev, "End of driver shutdown\n"); -+} -+ -+#ifdef CONFIG_PM -+/******************************************************************************/ -+static int bsp_spi_nor_driver_suspend(struct platform_device *pdev, -+ pm_message_t state) -+{ -+ int i; -+ struct fmc_host *host = platform_get_drvdata(pdev); -+ -+ if (!host) -+ return 0; -+ -+ mutex_lock(host->lock); -+ clk_prepare_enable(host->clk); -+ -+ spi_nor_switch_spi_type(host); -+ for (i = 0; i < host->num_chip; i++) -+ spi_nor_suspend(host->nor[i], state); -+ -+ clk_disable_unprepare(host->clk); -+ mutex_unlock(host->lock); -+ dev_dbg(host->dev, "End of suspend\n"); -+ -+ return 0; -+} -+ -+/******************************************************************************/ -+static int bsp_spi_nor_driver_resume(struct platform_device *pdev) -+{ -+ int i; -+ struct fmc_host *host = platform_get_drvdata(pdev); -+ -+ if (!host) -+ return 0; -+ -+ mutex_lock(host->lock); -+ clk_prepare_enable(host->clk); -+ -+ spi_nor_switch_spi_type(host); -+ for (i = 0; i < host->num_chip; i++) -+ spi_nor_resume(host->nor[i]); -+ -+ mutex_unlock(host->lock); -+ dev_dbg(host->dev, "End of resume\n"); -+ -+ return 0; -+} -+#endif /* End of CONFIG_PM */ -+ -+/******************************************************************************/ -+static const struct of_device_id bsp_spi_nor_dt_ids[] = { -+ { .compatible = "goke,fmc-spi-nor"}, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, bsp_spi_nor_dt_ids); -+ -+/******************************************************************************/ -+static struct platform_driver bsp_spi_nor_driver = { -+ .driver = { -+ .name = "bsp-sfc", -+ .of_match_table = bsp_spi_nor_dt_ids, -+ }, -+ .probe = bsp_spi_nor_probe, -+ .remove = bsp_spi_nor_remove, -+ .shutdown = bsp_spi_nor_driver_shutdown, -+#ifdef CONFIG_PM -+ .suspend = bsp_spi_nor_driver_suspend, -+ .resume = bsp_spi_nor_driver_resume, -+#endif -+}; -+module_platform_driver(bsp_spi_nor_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("Goke SPI Nor Flash Controller Driver"); ---- linux-4.9.37/drivers/mtd/spi-nor/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/spi-nor/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -65,6 +65,34 @@ - help - This enables support for hisilicon SPI-NOR flash controller. - -+config SPI_GOKE_SFC -+ tristate "Goke FMCV100 SPI-NOR Flash Controller(SFC)" -+ depends on ARCH_GOKE || ARCH_GOKE || COMPILE_TEST -+ depends on HAS_IOMEM && HAS_DMA -+ help -+ This enables support for goke flash memory contrller ver100 -+ (FMCV100)- SPI-NOR flash controller. -+ -+config CLOSE_SPI_8PIN_4IO -+ bool "Close SPI device Quad SPI mode for some 8PIN chip" -+ default y if ARCH_GOKE -+ help -+ fmcv100 and sfcv350 support Quad SPI mode and Quad&addr SPI mode. -+ But some 8PIN chip does not support this mode when HOLD/IO3 PIN -+ was used by reset operation. -+ Usually, your should not config this option. -+ -+config GOKE_SPI_BLOCK_PROTECT -+ bool "Goke Spi Nor Device BP(Block Protect) Support" -+ depends on SPI_GOKE_SFC -+ default y if SPI_GOKE_SFC -+ help -+ GOKE SFC supports BP(Block Protect) feature to preestablish a series -+ area to avoid writing and erasing, except to reading. With this macro -+ definition we can get the BP info which was setted before. The -+ BOTTOM/TOP bit is setted to BOTTOM, it means the lock area starts -+ from 0 address. -+ - config SPI_NXP_SPIFI - tristate "NXP SPI Flash Interface (SPIFI)" - depends on OF && (ARCH_LPC18XX || COMPILE_TEST) ---- linux-4.9.37/drivers/mtd/spi-nor/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/spi-nor/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -2,6 +2,7 @@ - obj-$(CONFIG_SPI_ATMEL_QUADSPI) += atmel-quadspi.o - obj-$(CONFIG_SPI_CADENCE_QUADSPI) += cadence-quadspi.o - obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o -+obj-$(CONFIG_SPI_GOKE_SFC) += goke-sfc.o - obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o - obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o - obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o ---- linux-4.9.37/drivers/mtd/spi-nor/spi-nor.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/mtd/spi-nor/spi-nor.c 2021-06-07 13:01:33.000000000 +0300 -@@ -75,6 +75,13 @@ - * bit. Must be used with - * SPI_NOR_HAS_LOCK. - */ -+#define SPI_NOR_4B_OPCODES BIT(10) /* -+ * Use dedicated 4byte address op codes -+ * to support memory size above 128Mib. -+ */ -+ -+ const struct spi_nor_basic_flash_parameter *params; -+ u32 clkrate; - }; - - #define JEDEC_MFR(info) ((info)->id[0]) -@@ -139,31 +146,24 @@ - } - - /* -- * Dummy Cycle calculation for different type of read. -- * It can be used to support more commands with -- * different dummy cycle requirements. -+ * Write status register 1 byte -+ * Returns negative if error occurred. - */ --static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor) -+static inline int write_sr(struct spi_nor *nor, u8 val) - { -- switch (nor->flash_read) { -- case SPI_NOR_FAST: -- case SPI_NOR_DUAL: -- case SPI_NOR_QUAD: -- return 8; -- case SPI_NOR_NORMAL: -- return 0; -- } -- return 0; -+ nor->cmd_buf[0] = val; -+ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1); - } - -+ - /* -- * Write status register 1 byte -+ * Write status register-2 1 byte - * Returns negative if error occurred. - */ --static inline int write_sr(struct spi_nor *nor, u8 val) -+static inline int write_sr2(struct spi_nor *nor, u8 val) - { - nor->cmd_buf[0] = val; -- return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1); -+ return nor->write_reg(nor, SPINOR_OP_WRSR2, nor->cmd_buf, 1); - } - - /* -@@ -188,9 +188,83 @@ - return mtd->priv; - } - -+struct spi_nor_address_entry { -+ u8 src_opcode; -+ u8 dst_opcode; -+}; -+ -+static u8 spi_nor_convert_opcode(u8 opcode, -+ const struct spi_nor_address_entry *entries, -+ size_t num_entries) -+{ -+ unsigned int min, max; -+ -+ min = 0; -+ max = num_entries - 1; -+ while (min <= max) { -+ int mid = (min + max) >> 1; -+ const struct spi_nor_address_entry *entry = &entries[mid]; -+ -+ if (opcode == entry->src_opcode) -+ return entry->dst_opcode; -+ -+ if (opcode < entry->src_opcode) -+ max = mid - 1; -+ else -+ min = mid + 1; -+ } -+ -+ /* No conversion found */ -+ return opcode; -+} -+ -+static u8 spi_nor_3to4_opcode(u8 opcode) -+{ -+ /* MUST be sorted by 3byte opcode */ -+#define ENTRY_3TO4(_opcode) { _opcode, _opcode##_4B } -+ static const struct spi_nor_address_entry spi_nor_3to4_table[] = { -+ ENTRY_3TO4(SPINOR_OP_PP), /* 0x02 */ -+ ENTRY_3TO4(SPINOR_OP_READ), /* 0x03 */ -+ ENTRY_3TO4(SPINOR_OP_READ_FAST), /* 0x0b */ -+ ENTRY_3TO4(SPINOR_OP_BE_4K), /* 0x20 */ -+ ENTRY_3TO4(SPINOR_OP_PP_1_1_4), /* 0x32 */ -+ ENTRY_3TO4(SPINOR_OP_PP_1_4_4), /* 0x38 */ -+ ENTRY_3TO4(SPINOR_OP_READ_1_1_2), /* 0x3b */ -+ ENTRY_3TO4(SPINOR_OP_BE_32K), /* 0x52 */ -+ ENTRY_3TO4(SPINOR_OP_READ_1_1_4), /* 0x6b */ -+ ENTRY_3TO4(SPINOR_OP_READ_1_2_2), /* 0xbb */ -+ ENTRY_3TO4(SPINOR_OP_SE), /* 0xd8 */ -+ ENTRY_3TO4(SPINOR_OP_READ_1_4_4), /* 0xeb */ -+ }; -+#undef ENTRY_3TO4 -+ -+ return spi_nor_convert_opcode(opcode, spi_nor_3to4_table, -+ ARRAY_SIZE(spi_nor_3to4_table)); -+} -+ -+static void spi_nor_set_4byte_opcodes(struct spi_nor *nor, -+ const struct flash_info *info) -+{ -+ /* Do some manufacturer fixups first */ -+ switch (JEDEC_MFR(info)) { -+ case SNOR_MFR_SPANSION: -+ /* No small sector erase for 4-byte command set */ -+ nor->erase_opcode = SPINOR_OP_SE; -+ nor->mtd.erasesize = info->sector_size; -+ break; -+ -+ default: -+ break; -+ } -+ -+ nor->read_opcode = spi_nor_3to4_opcode(nor->read_opcode); -+ nor->program_opcode = spi_nor_3to4_opcode(nor->program_opcode); -+ nor->erase_opcode = spi_nor_3to4_opcode(nor->erase_opcode); -+} -+ - /* Enable/disable 4-byte addressing mode. */ - static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info, -- int enable) -+ u32 enable) - { - int status; - bool need_wren = false; -@@ -201,16 +275,26 @@ - /* Some Micron need WREN command; all will accept it */ - need_wren = true; - case SNOR_MFR_MACRONIX: -- case SNOR_MFR_WINBOND: - if (need_wren) - write_enable(nor); - - cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B; - status = nor->write_reg(nor, cmd, NULL, 0); -+ - if (need_wren) - write_disable(nor); - - return status; -+ case SNOR_MFR_WINBOND: -+ if (enable) -+ return nor->write_reg(nor, SPINOR_OP_EN4B, NULL, 0); -+ else { -+ /* w25q256fvfg must send reset to disable 4 byte mode */ -+ nor->write_reg(nor, SPINOR_ENABLE_RESET, NULL, 0); -+ nor->write_reg(nor, SPINOR_OP_RESET, NULL, 0); -+ udelay(30); -+ } -+ return 0; - default: - /* Spansion style */ - nor->cmd_buf[0] = enable << 7; -@@ -220,24 +304,28 @@ - static inline int spi_nor_sr_ready(struct spi_nor *nor) - { - int sr = read_sr(nor); -+ - if (sr < 0) - return sr; - else -- return !(sr & SR_WIP); -+ return !((unsigned int)sr & SR_WIP); - } - --static inline int spi_nor_fsr_ready(struct spi_nor *nor) -+static inline unsigned int spi_nor_fsr_ready(struct spi_nor *nor) - { - int fsr = read_fsr(nor); -+ unsigned int ufsr = (unsigned int)fsr; -+ - if (fsr < 0) - return fsr; - else -- return fsr & FSR_READY; -+ return ufsr & FSR_READY; - } - - static int spi_nor_ready(struct spi_nor *nor) - { - int sr, fsr; -+ - sr = spi_nor_sr_ready(nor); - if (sr < 0) - return sr; -@@ -282,7 +370,31 @@ - return spi_nor_wait_till_ready_with_timeout(nor, - DEFAULT_READY_WAIT_JIFFIES); - } -+static int issi_spi_nor_wait_till_ready(struct spi_nor *nor) -+{ -+ unsigned long deadline; -+ int timeout = 0; -+ int ret; - -+ deadline = jiffies + DEFAULT_READY_WAIT_JIFFIES; -+ -+ while (!timeout) { -+ if (time_after_eq(jiffies, deadline)) -+ timeout = 1; -+ -+ ret = spi_nor_sr_ready(nor); -+ if (ret < 0) -+ return ret; -+ if (ret) -+ return 0; -+ -+ cond_resched(); -+ } -+ -+ dev_err(nor->dev, "flash operation timed out\n"); -+ -+ return -ETIMEDOUT; -+} - /* - * Erase the whole flash memory - * -@@ -367,6 +479,12 @@ - if (ret) - return ret; - -+#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT -+ if ((nor->level) && (addr < nor->end_addr)) { -+ dev_err(nor->dev, "Error: The erase area was locked\n"); -+ return -EINVAL; -+ } -+#endif - /* whole-chip erase? */ - if (len == mtd->size) { - unsigned long timeout; -@@ -745,6 +863,280 @@ - return ret; - } - -+#define SNOR_RD_MODES \ -+ (SNOR_MODE_SLOW | \ -+ SNOR_MODE_1_1_1 | \ -+ SNOR_MODE_1_1_2 | \ -+ SNOR_MODE_1_2_2 | \ -+ SNOR_MODE_1_1_4 | \ -+ SNOR_MODE_1_4_4) -+ -+#define SNOR_WR_MODES \ -+ (SNOR_MODE_1_1_1 | \ -+ SNOR_MODE_1_1_4) -+ -+static int spansion_quad_enable(struct spi_nor *nor); -+static int macronix_quad_enable(struct spi_nor *nor); -+static int gd_quad_enable(struct spi_nor *nor); -+static int xtx_quad_enable(struct spi_nor *nor); -+static int issi_quad_enable(struct spi_nor *nor); -+static int puya_quad_enable(struct spi_nor *nor); -+static int puya_quad_enable(struct spi_nor *nor); -+ -+#define SNOR_EON_RD_MODES \ -+ (SNOR_MODE_SLOW | \ -+ SNOR_MODE_1_1_1 | \ -+ SNOR_MODE_1_1_2 | \ -+ SNOR_MODE_1_2_2) -+ -+#define SNOR_EON_WR_MODES \ -+ (SNOR_MODE_1_1_1) -+ -+static const struct spi_nor_basic_flash_parameter eon_params = { -+ .rd_modes = SNOR_EON_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_EON_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter esmt_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = macronix_quad_enable, -+ -+}; -+ -+#define SNOR_PARAGON_WR_MODES \ -+ (SNOR_MODE_1_1_1) -+ -+static const struct spi_nor_basic_flash_parameter paragon_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_PARAGON_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = spansion_quad_enable, -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter gd_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = gd_quad_enable, -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter winbond_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = spansion_quad_enable, -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter spansion_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = spansion_quad_enable, -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter issi_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = issi_quad_enable, -+ -+}; -+ -+#define SNOR_MXIC_WR_MODES \ -+ (SNOR_MODE_1_1_1 | \ -+ SNOR_MODE_1_4_4) -+ -+static const struct spi_nor_basic_flash_parameter mxic_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_MXIC_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_4_4] = SPINOR_OP_PP_1_4_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = macronix_quad_enable, -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter xmc_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter micron_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(8, 8, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(0, 40, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter micron_4k_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(1, 9, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ .erase_types[1] = SNOR_OP_ERASE_4K(SPINOR_OP_BE_4K), -+}; -+ -+static const struct spi_nor_basic_flash_parameter xtx_params = { -+ .rd_modes = SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW] = SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4] = SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes = SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1] = SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4] = SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0] = SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = xtx_quad_enable, -+ -+}; -+ -+static const struct spi_nor_basic_flash_parameter puya_params = { -+ .rd_modes= SNOR_RD_MODES, -+ .reads[SNOR_MIDX_SLOW]= SNOR_OP_READ(0, 0, SPINOR_OP_READ), -+ .reads[SNOR_MIDX_1_1_1]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST), -+ .reads[SNOR_MIDX_1_1_2]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2), -+ .reads[SNOR_MIDX_1_2_2]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2), -+ .reads[SNOR_MIDX_1_1_4]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4), -+ .reads[SNOR_MIDX_1_4_4]= SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4), -+ -+ .wr_modes= SNOR_WR_MODES, -+ .page_programs[SNOR_MIDX_1_1_1]= SPINOR_OP_PP, -+ .page_programs[SNOR_MIDX_1_1_4]= SPINOR_OP_PP_1_1_4, -+ -+ .erase_types[0]= SNOR_OP_ERASE_64K(SPINOR_OP_SE), -+ -+ .enable_quad_io = puya_quad_enable, -+}; -+ -+#define PARAMS(_name) .params = &_name##_params -+ - /* Used when the "_ext_id" is two bytes at most */ - #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ -@@ -758,7 +1150,7 @@ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ -- .flags = (_flags), -+ .flags = (_flags) - - #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ -@@ -782,6 +1174,10 @@ - .addr_width = (_addr_width), \ - .flags = (_flags), - -+/* Different from spi-max-frequency in DTS, the clk here stands for the clock -+ * rate on SPI interface, it is half of the FMC CRG configuration */ -+#define CLK_MHZ_2X(clk) .clkrate = (clk * 2000000), -+ - /* NOTE: double check command sets and memory organization when you add - * more nor chips. This current list focusses on newer chips, which - * have been converging on command sets which including JEDEC ID. -@@ -793,6 +1189,63 @@ - * For historical (and compatibility) reasons (before we got above config) some - * old entries may be missing 4K flag. - */ -+#define SPI_NOR_IDS_VER "1.2" -+ -+/******* SPI Nor ID Table ************************************************************************ -+ * Version Manufacturer Chip Name Chipsize Block Vol Operation -+ * Macronix/MXIC MX25V1635F 2M 64K 3V3 -+ * 1.0 Macronix/MXIC MX25L1606E 2M 64K 3V3 -+ * Macronix/MXIC MX25L6436F 8M 64K 3V3 -+ * Macronix/MXIC MX25R6435F 8M 64K 1V8/3V3 Add 14chips -+ * Macronix/MXIC MX25U6435F 8M 64K 1V8 -+ * Macronix/MXIC MX25U12835F 16M 64K 1V8 -+ * Macronix/MXIC MX25F128XXX 16M 64K 3V3 -+ * Macronix/MXIC MX25U25635F/45G 32M 64K 1V8 25645G-DTR -+ * Macronix/MXIC MX25L(256/257) 32M 64K 3V3 25645G-DTR -+ * Macronix/MXIC MX25U51245G 64M 64K 1V8 51245G-DTR -+ * Macronix/MXIC MX25L51245G 64M 64K 3V3 -+ * Macronix/MXIC MX66U1G45GM 128M 64K 1V8 -+ * Spansion S25FL129P1 16M 64K 3V3 -+ * Spansion S25FL256S 32M 64K 3V3 -+ * Micron N25Q064A 8M 64K 3V3 -+ * Micron N25QL064A 8M 64K 3V3 -+ * Micron N25Q128A11/MT25QU128AB 16M 64K 1V8 -+ * Micron N25QL128A 16M 64K 3V3 -+ * Micron MT25QU256A 32M 64K 1V8 -+ * Micron MT25QL256A 32M 64K 3V3 -+ * Winbond W25Q16(B/C)V/S25FL016K 2M 64K 3V3 -+ * Winbond W25Q32(B/F)V 4M 64K 3V3 -+ * Winbond W25Q32FW 4M 64K 1V8 -+ * Winbond W25Q64FW 8M 64K 1V8 -+ * Winbond W25Q64FV(SPI)/W25Q64JV_IQ 8M 64K 3V3 -+ * Winbond W25Q128FW 16M 64K 1V8 -+ * Winbond W25Q128(B/F)V 16M 64K 3V3 -+ * Winbond W25Q128JV_IM 16M 64K 3V3 DTR -+ * Winbond W25Q256JWEIQ 32M 64K 1V8 -+ * Winbond W25Q256JWFIM 32M 64K 1V8 -+ * ESMT/CFEON EN25Q32B 4M 64K 3V3 -+ * ESMT/CFEON EN25Q64 8M 64K 3V3 -+ * ESMT/CFEON EN25Q128 16M 64K 3V3 -+ * ESMT/CFEON F25L64QA 8M 64K 3V3 -+ * GD GD25Q16C 2M 64K 3V3 -+ * GD GD25Q64 8M 64K 3V3 -+ * GD GD25LQ128 16M 64K 1V8 -+ * GD GD25Q128 16M 64K 3V3 -+ * GD GD25Q256 32M 64K 3V3 -+ * GD GD25LQ64C 8M 64K 1V8 -+ * GD GD25Q32 4M 64K 3V3 -+ * Paragon PN25F16S 2M 64K 3V3 -+ * Paragon PN25F32S 4M 64K 3V3 -+ * 1.1 ESMT/CFEON EN25QH64A 8M 64K 3V3 -+ * 1.2 XMC XM25QH64AHIG 8M 64K 3V3 -+ * XMC XM25QH128A 16M 64K 3V3 -+ * XMC XM25QH128B 16M 64K 3V3 -+ * Puya P25Q128H-SUH-IT 16M 64K 3V3 -+ * FM FM25Q64-SOB-T-G 8M 64K 3V3 -+ * FM FM25Q128-SOB-T-G 16M 64K 3V3 -+ * HUAHONG H25S64 8M 64K 3V3 -+ * HUAHONG H25S128 16M 64K 3V3 -+ ********************************************************************************************/ - static const struct flash_info spi_nor_ids[] = { - /* Atmel -- some are (confusingly) marketed as "DataFlash" */ - { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, -@@ -812,44 +1265,55 @@ - /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, -- { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, -+ { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, -+ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, -- { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, -+ { "en25qh32b-104hip2b", INFO(0x1c7016, 0, 64 * 1024, 64, -+ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(133) }, -+ { "en25qh64a", INFO(0x1c7017, 0, 64 * 1024, 128, -+ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, -+ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, -+ { "en25qh128a", INFO(0x1c7018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(eon), CLK_MHZ_2X(104) }, - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, - { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, - - /* ESMT */ - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "f25l64qa", INFO(0x8c4117, 0, 64 * 1024, 128, -+ SPI_NOR_QUAD_READ), PARAMS(esmt), CLK_MHZ_2X(84) }, - - /* Everspin */ -- { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -- { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { "mr25h256", CAT25_INFO(32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE -+ | SPI_NOR_NO_FR) }, -+ { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE -+ | SPI_NOR_NO_FR) }, - - /* Fujitsu */ - { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, - -- /* GigaDevice */ -- { -- "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, -- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -- }, -- { -- "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, -- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -- }, -- { -- "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128, -- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -- }, -- { -- "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, -- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -- }, -+ /* GigaDevice 3.3V */ -+ { "gd25q16c", INFO(0xc84015, 0, 64 * 1024, 32, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(120) }, -+ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(120) }, -+ { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(120) }, -+ { "gd25q128/gd25q127", INFO(0xc84018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(80) }, -+ { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512, -+ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(gd), CLK_MHZ_2X(80) }, -+ /* GigaDevice 1.8V */ -+ { "gd25lq16c", INFO(0xc86015, 0, 64 * 1024, 32, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(104) }, -+ { "gd25lq64", INFO(0xc86017, 0, 64 * 1024, 128, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(133) }, -+ { "gd25lq128", INFO(0xc86018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(gd), CLK_MHZ_2X(133) }, - - /* Intel/Numonyx -- xxxs33b */ - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, -@@ -859,68 +1323,132 @@ - /* ISSI */ - { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, - -- /* Macronix */ -+ { "IS25WP512M-RMLA3", INFO(0x9d701a, 0, 64 * 1024, 1024, -+ SPI_NOR_QUAD_READ), PARAMS(issi), CLK_MHZ_2X(80) }, -+ -+ /* Macronix/MXIC 3.3V */ - { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, - { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, - { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, -- { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, -- { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K -+ | SPI_NOR_DUAL_READ), CLK_MHZ_2X(80) }, -+ { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, -- { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, -- { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, -- { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, -+ { "mx25l6436f", INFO(0xc22017, 0, 64 * 1024, 128, -+ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(133) }, -+ { "mx25l12835f", INFO(0xc22018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(84) }, - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, -- { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, -+ { "mx25l25635f", INFO(0xc22019, 0, 64 * 1024, 512, -+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(84) }, -+ { "mx25l25673g", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_QUAD_READ -+ | SPI_NOR_4B_OPCODES) }, - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, -- { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, -- { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, -- -- /* Micron */ -- { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, -- { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, -- { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, -- { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, -- { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, -- { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, -- { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, -- { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -- { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -- { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, -+ { "mx66l51235l/mx25l51245g", INFO(0xc2201a, 0, 64 * 1024, 1024, -+ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(133)}, -+ { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ)}, -+ { "mx25v1635f", INFO(0xc22315, 0, 64 * 1024, 32 , -+ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(80) }, -+ /* Macronix/MXIC Wide Voltage Range 1.65~3.6V */ -+ { "mx25r6435f", INFO(0xc22817, 0, 64 * 1024, 128, -+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ), CLK_MHZ_2X(80) }, -+ /* Macronix/MXIC 1.8V */ -+ { "mx25u1633f", INFO(0xc22535, 0, 64 * 1024, 32, -+ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(80) }, -+ { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(84) }, -+ { "mx25u12835f/mx25u12832f", INFO(0xc22538, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(mxic), CLK_MHZ_2X(84) }, -+ { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, -+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(84) }, -+ { "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024, -+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(166) }, -+ { "mx66u1g45gm", INFO(0xc2253b, 0, 64 * 1024, 2048, -+ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(mxic), CLK_MHZ_2X(133) }, -+ -+ /* Micron 3.3V */ -+ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ), -+ PARAMS(micron), CLK_MHZ_2X(84) }, -+ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), -+ PARAMS(micron_4k), CLK_MHZ_2X(108) }, -+ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), -+ PARAMS(micron), CLK_MHZ_2X(108) }, -+ { "mt25ql256a", INFO(0x20ba19, 0x1044, 64 * 1024, 512, SPI_NOR_QUAD_READ), -+ PARAMS(micron), CLK_MHZ_2X(108) }, -+ { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR), -+ PARAMS(micron_4k) }, -+ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR | SPI_NOR_QUAD_READ), -+ PARAMS(micron_4k), CLK_MHZ_2X(80) }, -+ /* Micron 1.8V */ -+ { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ), -+ PARAMS(micron), CLK_MHZ_2X(108) }, -+ { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), -+ PARAMS(micron), CLK_MHZ_2X(108) }, -+ { "mt25qu128a/n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), -+ PARAMS(micron), CLK_MHZ_2X(108) }, -+ { "mt25qu256a", INFO(0x20bb19, 0, 64 * 1024, 512, -+ SPI_NOR_4B_OPCODES | SPI_NOR_QUAD_READ), PARAMS(micron), CLK_MHZ_2X(108) }, -+ { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, USE_FSR | SPI_NOR_QUAD_READ), -+ PARAMS(micron_4k), CLK_MHZ_2X(80) }, -+ -+ /* XMC */ -+ { "xm25qh64a", INFO(0x207017, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), -+ PARAMS(xmc), CLK_MHZ_2X(104) }, -+ { "xm25qh64b", INFO(0x206017, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ), -+ PARAMS(xmc), CLK_MHZ_2X(104) }, -+ { "xm25qh128a", INFO(0x207018, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), -+ PARAMS(xmc), CLK_MHZ_2X(104) }, -+ { "xm25qh128b", INFO(0x206018, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ), -+ PARAMS(xmc), CLK_MHZ_2X(104) }, - - /* PMC */ -- { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, -- { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, -- { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, -+ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, -+ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, -+ { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, - - /* Spansion -- single (large) sector size only, at least - * for the chips listed here (without boot sectors). - */ -- { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, -+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, -+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, -- { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, -+ { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, -+ SPI_NOR_4B_OPCODES | SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(104) }, -+ { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, -+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, -+ { "s25fl127s/129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(108) }, - { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, - { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, -- { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, -- { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, -- { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, -- { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, -- { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, -- { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, -- { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, -- { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -- { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, -- { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, -- { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, -+ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SECT_4K -+ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl128lagmfi010z", INFO(0x016018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ)}, -+ { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, -+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, -+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, -+ { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, -+ { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, -+ { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, -+ { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, -+ { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K -+ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K -+ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "w25Q16jv-iq/s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(84) }, -+ /* { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K -+ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, */ -+ { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K -+ | SPI_NOR_DUAL_READ) }, - - /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, -@@ -972,43 +1500,101 @@ - { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, - { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, - -- /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ -+ /* Winbond 3.3V-- w25x "blocks" are 64K, "sectors" are 4KiB */ - { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, - { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, - { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, - { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, -- { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, -+ { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K -+ | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, -- { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, -- { -- "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, -- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -- }, -+ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, - { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, -- { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, -- { -- "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, -- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -- }, -- { -- "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, -- SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -- SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -- }, -+ { "w25q64fv(spi)/w25q64jv_iq", INFO(0xef4017, 0, 64 * 1024, 128, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, - { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, -- { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, -- { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, -+ { "w25q128(b/f)v", INFO(0xef4018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(104) }, -+ { "w25q128jv_im", INFO(0xef7018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, -+#ifdef CONFIG_AUTOMOTIVE_GRADE -+ { "w25q256(f/j)v", INFO(0xef4019, 0, 64 * 1024, 512, -+ SECT_4K | SPI_NOR_QUAD_READ), PARAMS(winbond), CLK_MHZ_2X(80) }, -+#else -+ { "w25q256(f/j)v", INFO(0xef4019, 0, 64 * 1024, 512, -+ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES), PARAMS(winbond), CLK_MHZ_2X(80) }, -+#endif -+ /* Winbond 1.8V */ -+ { "w25q32fw", INFO(0xef6016, 0, 64 * 1024, 64, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB), PARAMS(winbond), CLK_MHZ_2X(80) }, -+ { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB), PARAMS(winbond), CLK_MHZ_2X(80) }, -+ { "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB), PARAMS(winbond), CLK_MHZ_2X(80) }, -+ { "w25q256jw-im", INFO(0xef8019, 0, 64 * 1024, 512, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES), -+ PARAMS(winbond), CLK_MHZ_2X(80) }, -+ { "w25q256jw-iq", INFO(0xef6019, 0, 64 * 1024, 512, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES), -+ PARAMS(winbond), CLK_MHZ_2X(133) }, - - /* Catalyst / On Semiconductor -- non-JEDEC */ -- { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -- { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -- { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -- { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -- { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, -+ { "cat25c11", CAT25_INFO(16, 8, 16, 1, SPI_NOR_NO_ERASE -+ | SPI_NOR_NO_FR) }, -+ { "cat25c03", CAT25_INFO(32, 8, 16, 2, SPI_NOR_NO_ERASE -+ | SPI_NOR_NO_FR) }, -+ { "cat25c09", CAT25_INFO(28, 8, 32, 2, SPI_NOR_NO_ERASE -+ | SPI_NOR_NO_FR) }, -+ { "cat25c17", CAT25_INFO(256, 8, 32, 2, SPI_NOR_NO_ERASE -+ | SPI_NOR_NO_FR) }, -+ { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE -+ | SPI_NOR_NO_FR) }, -+ /* Paragon 3.3V */ -+ { "pn25f16s", INFO(0xe04015, 0, 64 * 1024, 32, -+ SPI_NOR_QUAD_READ), PARAMS(paragon), CLK_MHZ_2X(80) }, -+ { "pn25f32s", INFO(0xe04016, 0, 64 * 1024, 64, -+ SPI_NOR_QUAD_READ), PARAMS(paragon), CLK_MHZ_2X(80) }, -+ -+ /* XTX */ -+ { "xt25f16bssigu", INFO(0x0b4015, 0, 64 * 1024, 32, -+ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(120) }, -+ -+ { "xt25f32bssigu-s", INFO(0x0b4016, 0, 64 * 1024, 64, -+ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(120) }, -+ -+ { "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(70) }, -+ -+ { "xt25f64b", INFO(0x0b4017, 0, 64 * 1024, 128, -+ SPI_NOR_QUAD_READ), PARAMS(xtx), CLK_MHZ_2X(70) }, -+ -+ /*puya 3.3V */ -+ {"p25q128h", INFO(0x856018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(puya), CLK_MHZ_2X(104) }, -+ -+ /* FM 3.3v */ -+ { "FM25Q64-SOB-T-G",INFO(0xa14017, 0, 64 * 1024, 128, -+ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, -+ { "FM25Q128-SOB-T-G",INFO(0xa14018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, -+ -+ /* HUAHONG 3.3v */ -+ { "H25S64",INFO(0x684017, 0, 64 * 1024, 128, -+ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, -+ -+ { "H25S128",INFO(0x684018, 0, 64 * 1024, 256, -+ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(80) }, -+ -+ { "ZB25VQ64A",INFO(0x5e4017, 0, 64 * 1024, 128, -+ SPI_NOR_QUAD_READ), PARAMS(spansion), CLK_MHZ_2X(104) }, - { }, - }; - -@@ -1024,6 +1610,11 @@ - return ERR_PTR(tmp); - } - -+ if ((id[0] == 0xff) || (id[0] == 0x00)) { -+ dev_err(nor->dev, "unrecognized Manufacturer ID\n"); -+ return ERR_PTR(-ENODEV); -+ } -+ - for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { - info = &spi_nor_ids[tmp]; - if (info->id_len) { -@@ -1036,6 +1627,36 @@ - return ERR_PTR(-ENODEV); - } - -+static int puya_quad_enable(struct spi_nor *nor) -+{ -+ int ret; -+ u8 val; -+ -+ ret = read_cr(nor); -+ if ((unsigned int)ret & CR_QUAD_EN_SPAN) -+ return 0; -+ -+ val = (((unsigned int)ret & 0xff) | CR_QUAD_EN_SPAN); -+ write_enable(nor); -+ -+ ret = write_sr2(nor, val); -+ if (ret < 0) { -+ dev_err(nor->dev, -+ "error while writing status register-2\n"); -+ return -EINVAL; -+ } -+ -+ if (spi_nor_wait_till_ready(nor)) -+ return 1; -+ -+ /* read back and check it */ -+ ret = read_cr(nor); -+ if ((unsigned int)ret & CR_QUAD_EN_SPAN) -+ return 0; -+ else -+ return 1; -+} -+ - static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) - { -@@ -1167,14 +1788,22 @@ - ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_WRITE); - if (ret) - return ret; -+#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT -+ if (nor->level && (to < nor->end_addr)) { -+ dev_err(nor->dev, "Error: The DMA write area was locked\n"); -+ return -EINVAL; -+ } -+#endif - - for (i = 0; i < len; ) { - ssize_t written; - - page_offset = (to + i) & (nor->page_size - 1); -+#ifndef CONFIG_SPI_GOKE_SFC - WARN_ONCE(page_offset, - "Writing at offset %zu into a NOR page. Writing partial pages may decrease reliability and increase wear of NOR flash.", - page_offset); -+#endif - /* the size of data remaining on the first page */ - page_remain = min_t(size_t, - nor->page_size - page_offset, len - i); -@@ -1211,15 +1840,22 @@ - val = read_sr(nor); - if (val < 0) - return val; -+ -+ if ((unsigned int)val & SR_QUAD_EN_MX) -+ return 0; -+ -+ /* Update the Quad Enable bit. */ -+ dev_dbg(nor->dev, "setting Macronix Quad Enable (non-volatile) bit\n"); -+ - write_enable(nor); - -- write_sr(nor, val | SR_QUAD_EN_MX); -+ write_sr(nor, (u8)val | SR_QUAD_EN_MX); - - if (spi_nor_wait_till_ready(nor)) - return 1; - - ret = read_sr(nor); -- if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) { -+ if (!(ret > 0 && ((unsigned int)ret & SR_QUAD_EN_MX))) { - dev_err(nor->dev, "Macronix Quad bit not set\n"); - return -EINVAL; - } -@@ -1227,6 +1863,41 @@ - return 0; - } - -+static int xtx_quad_enable(struct spi_nor *nor) -+{ -+ u8 ret, val_h,val_l; -+ /* read SR high 8bit*/ -+ val_h = read_cr(nor); -+ if (val_h < 0) -+ return val_h; -+ -+ if (val_h & SR_QUAD_EN_XTX) -+ return 0; -+ -+ /* Update the Quad Enable bit. */ -+ dev_dbg(nor->dev, "setting xtx Quad Enable (non-volatile) bit\n"); -+ -+ write_enable(nor); -+ -+ /* read SR low 8bit*/ -+ val_l = read_sr(nor); -+ -+ /* write SR */ -+ nor->cmd_buf[0] = val_l; -+ nor->cmd_buf[1] = val_h; -+ nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2); -+ -+ if (spi_nor_wait_till_ready(nor)) -+ return 1; -+ -+ ret = read_cr(nor); -+ if (!(ret > 0 && (ret & SR_QUAD_EN_XTX))) { -+ dev_err(nor->dev, "xtx Quad bit not set\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} - /* - * Write status Register and configuration register with 2 bytes - * The first byte will be written to the status register, while the -@@ -1243,29 +1914,168 @@ - - static int spansion_quad_enable(struct spi_nor *nor) - { -- int ret; -- int quad_en = CR_QUAD_EN_SPAN << 8; -+ unsigned int ret; -+ u16 val; -+ -+ ret = read_cr(nor); -+ if (ret & CR_QUAD_EN_SPAN) -+ return 0; -+ -+ /* Update the Quad Enable bit. */ -+ dev_dbg(nor->dev, "setting Quad Enable (non-volatile) bit\n"); -+ -+ val = ((ret & 0xff) | CR_QUAD_EN_SPAN) << 8; -+ -+ ret = read_sr(nor); -+ val |= (ret & 0xff); -+ -+ write_enable(nor); -+ -+ ret = write_sr_cr(nor, val); -+ if (ret < 0) { -+ dev_err(nor->dev, -+ "error while writing configuration register\n"); -+ return -EINVAL; -+ } -+ -+ if (spi_nor_wait_till_ready(nor)) -+ return 1; -+ -+ /* read back and check it */ -+ ret = read_cr(nor); -+ if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { -+ dev_err(nor->dev, "Spansion Quad bit not set\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int issi_quad_enable(struct spi_nor *nor) -+{ -+ unsigned int ret; -+ u16 val; -+ -+ ret = read_sr(nor); -+ if (ret & QUAD_EN_ISSI) -+ return 0; -+ -+ /* Update the Quad Enable bit. */ -+ dev_dbg(nor->dev, "setting Quad Enable (non-volatile) bit\n"); -+ -+ val = ((ret & 0xff) | QUAD_EN_ISSI); - - write_enable(nor); - -- ret = write_sr_cr(nor, quad_en); -+ ret = write_sr(nor, val); - if (ret < 0) { - dev_err(nor->dev, - "error while writing configuration register\n"); - return -EINVAL; - } - -+ if (issi_spi_nor_wait_till_ready(nor)) -+ return 1; -+ -+ /* read back and check it */ -+ ret = read_sr(nor); -+ if (!(ret > 0 && (ret & QUAD_EN_ISSI))) { -+ dev_err(nor->dev, "ISSI Quad bit not set\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int micron_quad_enable(struct spi_nor *nor) -+{ -+ int ret; -+ u8 val; -+ -+ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error %d reading EVCR\n", ret); -+ return ret; -+ } -+ -+ write_enable(nor); -+ -+ /* set EVCR, enable quad I/O */ -+ nor->cmd_buf[0] = val & ~EVCR_QUAD_EN_MICRON; -+ ret = nor->write_reg(nor, SPINOR_OP_WD_EVCR, nor->cmd_buf, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error while writing EVCR register\n"); -+ return ret; -+ } -+ - ret = spi_nor_wait_till_ready(nor); -- if (ret) { -+ if (ret) -+ return ret; -+ -+ /* read EVCR and check it */ -+ ret = nor->read_reg(nor, SPINOR_OP_RD_EVCR, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error %d reading EVCR\n", ret); -+ return ret; -+ } -+ if (val & EVCR_QUAD_EN_MICRON) { -+ dev_err(nor->dev, "Micron EVCR Quad bit not clear\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int gd_quad_enable(struct spi_nor *nor) -+{ -+ int ret; -+ u16 val; -+ -+ /* First, Quad Enable for 16-Pin GD flash, use WRSR[01h] cmd */ -+ ret = read_cr(nor); -+ val = (((unsigned int)ret & 0xff) | CR_QUAD_EN_SPAN) << 8; -+ -+ ret = read_sr(nor); -+ val |= ((unsigned int)ret & 0xff); -+ -+ write_enable(nor); -+ -+ ret = write_sr_cr(nor, val); -+ if (ret < 0) { - dev_err(nor->dev, -- "timeout while writing configuration register\n"); -+ "error while writing config and status register\n"); -+ return -EINVAL; -+ } -+ -+ if (spi_nor_wait_till_ready(nor)) -+ return 1; -+ -+ /* read back and check it */ -+ ret = read_cr(nor); -+ if ((unsigned int)ret & CR_QUAD_EN_SPAN) -+ return 0; -+ -+ /* Second, Quad Enable for 8-Pin GD flash, use WRCR[31h] cmd */ -+ ret = read_sr(nor); -+ if (!((unsigned int)ret & SR_WEL)) -+ write_enable(nor); -+ -+ ret = read_cr(nor); -+ nor->cmd_buf[0] = ((unsigned int)ret & 0xff) | CR_QUAD_EN_SPAN; -+ -+ ret = nor->write_reg(nor, SPINOR_OP_WRCR, nor->cmd_buf, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error while writing config register\n"); - return ret; - } - -+ if (spi_nor_wait_till_ready(nor)) -+ return 1; -+ - /* read back and check it */ - ret = read_cr(nor); -- if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { -- dev_err(nor->dev, "Spansion Quad bit not set\n"); -+ if (!(ret > 0 && ((unsigned int)ret & CR_QUAD_EN_SPAN))) { -+ dev_err(nor->dev, "GigaDevice Quad bit not set\n"); - return -EINVAL; - } - -@@ -1277,6 +2087,7 @@ - int status; - - switch (JEDEC_MFR(info)) { -+ case SNOR_MFR_ESMT: - case SNOR_MFR_MACRONIX: - status = macronix_quad_enable(nor); - if (status) { -@@ -1285,7 +2096,40 @@ - } - return status; - case SNOR_MFR_MICRON: -- return 0; -+ status = micron_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "Micron quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; -+ case SNOR_MFR_GD: -+ status = gd_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "GD quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; -+ case SNOR_MFR_XTX: -+ status = xtx_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "xtx quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; -+ case SNOR_MFR_PUYA: -+ status = puya_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "puya quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; -+ case SNOR_MFR_ISSI: -+ status = issi_quad_enable(nor); -+ if (status) { -+ dev_err(nor->dev, "puya quad-read not enabled\n"); -+ return -EINVAL; -+ } -+ return status; - default: - status = spansion_quad_enable(nor); - if (status) { -@@ -1307,8 +2151,375 @@ - return 0; - } - --int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) -+#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT -+static void spi_lock_update_address(struct spi_nor *nor, const struct flash_info *info) -+{ -+ unsigned int lock_level_max, sectorsize, chipsize; -+ -+ if (!nor->level) { -+ nor->end_addr = 0; -+ dev_warn(nor->dev, "all blocks is unlocked.\n"); -+ return; -+ } -+ -+ sectorsize = info->sector_size; -+ chipsize = sectorsize * info->n_sectors; -+ lock_level_max = nor->lock_level_max; -+ -+ switch (JEDEC_MFR(info)) { -+ case SNOR_MFR_MACRONIX: -+ if (chipsize == _2M) { -+ if ((nor->level != lock_level_max) -+ && (nor->level != 1)) -+ nor->end_addr = chipsize - (sectorsize << -+ (lock_level_max - nor->level - 1)); -+ else -+ nor->end_addr = chipsize; -+ return; -+ } -+ -+ if (chipsize != _8M) -+ break; -+ case SNOR_MFR_ESMT: -+ /* this case is for ESMT and MXIC 8M devices */ -+ if (nor->level != lock_level_max) -+ nor->end_addr = chipsize - (sectorsize -+ << (lock_level_max - nor->level)); -+ else -+ nor->end_addr = chipsize; -+ return; -+ case SNOR_MFR_EON: -+ if (nor->level != lock_level_max) -+ nor->end_addr = chipsize - (sectorsize -+ << (nor->level - 1)); -+ else -+ nor->end_addr = chipsize; -+ return; -+ default: -+ break; -+ } -+ -+ /* general case */ -+ nor->end_addr = chipsize >> (lock_level_max - nor->level); -+} -+ -+static unsigned char bsp_bp_to_level(struct spi_nor *nor, -+ const struct flash_info *info, unsigned int bp_num) -+{ -+ int ret; -+ unsigned char val; -+ unsigned char level; -+ unsigned int chipsize; -+ -+ ret = spi_nor_wait_till_ready(nor); -+ BUG_ON(ret); -+ -+ ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error %d reading SR\n", ret); -+ return ret; -+ } -+ -+ if (bp_num == BP_NUM_3) -+ level = (val & SPI_NOR_SR_BP_MASK_3) >> SPI_NOR_SR_BP0_SHIFT; -+ else -+ level = (val & SPI_NOR_SR_BP_MASK_4) >> SPI_NOR_SR_BP0_SHIFT; -+ -+ dev_dbg(nor->dev, "the current level[%d]\n", level); -+ -+ if (bp_num == BP_NUM_4) { -+ nor->lock_level_max = LOCK_LEVEL_MAX(bp_num) - 5; -+ chipsize = info->sector_size * info->n_sectors; -+ if ((JEDEC_MFR(info) == SNOR_MFR_MACRONIX) -+ && (chipsize == _16M)) -+ nor->lock_level_max--; -+ } else -+ nor->lock_level_max = LOCK_LEVEL_MAX(bp_num); -+ dev_dbg(nor->dev, "Get the max bp level: [%d]\n", -+ nor->lock_level_max); -+ -+ return level; -+} -+ -+static void bsp_get_spi_lock_info(struct spi_nor *nor, const struct flash_info *info) -+{ -+ unsigned int chipsize; -+ struct device *dev = nor->dev; -+ -+ chipsize = info->sector_size * info->n_sectors; -+ -+ /* read the BP bit in RDSR to check whether nor is lock or not */ -+ switch (JEDEC_MFR(info)) { -+ case SNOR_MFR_GD: -+ case SNOR_MFR_ESMT: -+ case SNOR_MFR_EON: -+ case SNOR_MFR_SPANSION: -+ /* BP bit convert to lock level */ -+ nor->level = bsp_bp_to_level(nor, info, BP_NUM_3); -+ break; -+ case SNOR_MFR_WINBOND: -+ /* BP bit convert to lock level */ -+ if (chipsize <= _16M) -+ nor->level = bsp_bp_to_level(nor, info, BP_NUM_3); -+ else -+ nor->level = bsp_bp_to_level(nor, info, BP_NUM_4); -+ break; -+ case SNOR_MFR_MACRONIX: -+ /* BP bit convert to lock level */ -+ if (chipsize <= _8M) -+ nor->level = bsp_bp_to_level(nor, info, BP_NUM_3); -+ else -+ nor->level = bsp_bp_to_level(nor, info, BP_NUM_4); -+ break; -+ default: -+ goto usage; -+ } -+ -+ spi_lock_update_address(nor, info); -+ if (nor->end_addr) -+ dev_info(dev, "Address range [0 => %#x] is locked.\n", -+ nor->end_addr); -+ return; -+usage: -+ dev_err(dev, "The ID: %#x isn't in the BP table," -+ " Current device can't not protect\n", -+ JEDEC_MFR(info)); -+} -+#endif/* CONFIG_GOKE_SPI_BLOCK_PROTECT */ -+ -+static int spi_nor_midx2proto(int midx, enum spi_nor_protocol *proto) -+{ -+ switch (midx) { -+ case SNOR_MIDX_SLOW: -+ case SNOR_MIDX_1_1_1: -+ *proto = SNOR_PROTO_1_1_1; -+ break; -+ -+ case SNOR_MIDX_1_1_2: -+ *proto = SNOR_PROTO_1_1_2; -+ break; -+ -+ case SNOR_MIDX_1_2_2: -+ *proto = SNOR_PROTO_1_2_2; -+ break; -+ case SNOR_MIDX_1_1_4: -+ *proto = SNOR_PROTO_1_1_4; -+ break; -+ -+ case SNOR_MIDX_1_4_4: -+ *proto = SNOR_PROTO_1_4_4; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int spi_nor_sr3_to_reset(struct spi_nor *nor) - { -+ int ret; -+ unsigned char val; -+ -+ ret = nor->read_reg(nor, SPINOR_OP_RDSR3, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error %d reading Status Reg 3.\n", ret); -+ return ret; -+ } -+ -+ if (SPI_NOR_GET_RST(val)) { -+ dev_dbg(nor->dev, "Device has worked on RESET#.\n"); -+ return 0; -+ } -+ -+ dev_dbg(nor->dev, "Start to enable RESET# function.\n"); -+ val = SPI_NOR_SET_RST(val); -+ -+ nor->write_reg(nor, SPINOR_OP_WRSR3, &val, 1); -+ if (ret < 0) { -+ dev_err(nor->dev, "error while writing Status Reg 3.\n"); -+ return ret; -+ } -+ -+ dev_dbg(nor->dev, "Enable RESET# function success.\n"); -+ -+ return 0; -+} -+ -+static int spi_nor_reset_pin_enable(struct spi_nor *nor, -+ const struct flash_info *info) -+{ -+ switch (JEDEC_MFR(info)) { -+ case SNOR_MFR_WINBOND: -+ case SNOR_MFR_GD: -+ return spi_nor_sr3_to_reset(nor); -+ default: -+ return 0; -+ } -+} -+ -+static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, -+ const struct spi_nor_basic_flash_parameter *params, -+ const struct spi_nor_modes *modes) -+{ -+ bool enable_quad_io; -+ u32 rd_modes, wr_modes; -+ const struct spi_nor_erase_type *erase_type; -+ const struct spi_nor_read_op *read; -+ int rd_midx, wr_midx, err = 0; -+#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS -+ int i = 0; -+#endif -+ rd_modes = modes->rd_modes; -+ wr_modes = modes->wr_modes; -+ -+ /* Setup read operation. */ -+ rd_midx = fls(params->rd_modes & rd_modes) - 1; -+ if (spi_nor_midx2proto(rd_midx, &nor->read_proto)) { -+ dev_err(nor->dev, "invalid (fast) read\n"); -+ return -EINVAL; -+ } -+ read = ¶ms->reads[rd_midx]; -+ nor->read_opcode = read->opcode; -+ nor->read_dummy = read->num_mode_clocks + read->num_wait_states; -+ -+ /* Set page program op code and protocol. */ -+ wr_midx = fls(params->wr_modes & wr_modes) - 1; -+ if (spi_nor_midx2proto(wr_midx, &nor->write_proto)) { -+ dev_err(nor->dev, "invalid page program\n"); -+ return -EINVAL; -+ } -+ nor->program_opcode = params->page_programs[wr_midx]; -+ -+ /* Set sector erase op code and size. */ -+ erase_type = ¶ms->erase_types[0]; -+#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS -+ for (i = 1; i < SNOR_MAX_ERASE_TYPES; ++i) -+ if (params->erase_types[i].size == 0x0c) -+ erase_type = ¶ms->erase_types[i]; -+#endif -+ nor->erase_opcode = erase_type->opcode; -+ nor->mtd.erasesize = (1 << erase_type->size); -+ -+ enable_quad_io = (SNOR_PROTO_DATA_FROM_PROTO(nor->read_proto) == 4 || -+ SNOR_PROTO_DATA_FROM_PROTO(nor->write_proto) == 4); -+ -+ /* Enable Quad I/O if needed. */ -+ if (enable_quad_io && params->enable_quad_io) { -+ err = params->enable_quad_io(nor); -+ if (err) { -+ dev_err(nor->dev, -+ "failed to enable the Quad I/O mode\n"); -+ return err; -+ } -+ } -+ -+ /* -+ * Fix erase protocol if needed, read and write protocols should -+ * already be valid. -+ */ -+ nor->erase_proto = SNOR_PROTO_1_1_1; -+ -+ dev_dbg(nor->dev, -+ "(Fast) Read: opcode=%02Xh, protocol=%03x, mode=%u, wait=%u\n", -+ nor->read_opcode, nor->read_proto, -+ read->num_mode_clocks, read->num_wait_states); -+ dev_dbg(nor->dev, -+ "Page Program: opcode=%02Xh, protocol=%03x\n", -+ nor->program_opcode, nor->write_proto); -+ dev_dbg(nor->dev, -+ "Sector Erase: opcode=%02Xh, protocol=%03x, sector size=%zu\n", -+ nor->erase_opcode, nor->erase_proto, (size_t)nor->mtd.erasesize); -+ -+ return 0; -+} -+ -+static int spi_nor_config(struct spi_nor *nor, const struct flash_info *info, -+ const struct spi_nor_basic_flash_parameter *params, -+ struct spi_nor_modes *modes) -+{ -+ int ret; -+ unsigned char cval,val; -+ -+ if (JEDEC_MFR(info) == SNOR_MFR_MACRONIX){ -+ val = read_sr(nor); -+ if (val < 0) -+ return val; -+ -+ /* read Configuration Register for macronix's spi nor flash */ -+ ret = nor->read_reg(nor, SPINOR_OP_RDSR3, &cval, 1); -+ if(ret < 0){ -+ dev_err(nor->dev, "error %d reading config Reg.\n", ret); -+ return ret; -+ } -+ -+ /* check the bit[6:7] whether is set in uboot when use DTR mode;if it was set and clear it. */ -+ /* pay attention to sequence of issuing WRSR instruction */ -+ if (cval & CR_DUMMY_CYCLE){ -+ write_enable(nor); -+ nor->cmd_buf[0]=val; -+ nor->cmd_buf[1]=(cval & (~CR_DUMMY_CYCLE)); -+ ret = nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 2); -+ } -+ } -+ -+ if (params) { -+ ret = spi_nor_setup(nor, info, params, modes); -+ if (ret) -+ return ret; -+ } else if (modes->rd_modes & SNOR_MODE_1_1_4 && -+ info->flags & SPI_NOR_QUAD_READ) { -+ /* -+ * This branch is spcially for some devices which can -+ * not be stated by params, but only SPI_NOR_QUAD_READ, -+ * it just supports the protocol 1_1_4. -+ */ -+ if (spi_nor_wait_till_ready(nor)) -+ return 1; -+ -+ ret = set_quad_mode(nor, info); -+ if (ret) { -+ dev_err(nor->dev, "quad mode not supported\n"); -+ return ret; -+ } -+ nor->read_proto = SNOR_PROTO_1_1_4; -+ nor->read_opcode = SPINOR_OP_READ_1_1_4; -+ nor->read_dummy = 8; -+ } else if (modes->rd_modes & SNOR_MODE_1_1_2 && -+ info->flags & SPI_NOR_DUAL_READ) { -+ /* -+ * This branch is spcially for some devices which can -+ * not be stated by params, but only SPI_NOR_DUAL_READ, -+ * it just supports the protocol 1_1_2. -+ */ -+ nor->read_proto = SNOR_PROTO_1_1_2; -+ nor->read_opcode = SPINOR_OP_READ_1_1_2; -+ nor->read_dummy = 8; -+ } else { -+ if (modes->rd_modes & SNOR_MODE_1_1_1) { -+ nor->read_opcode = SPINOR_OP_READ_FAST; -+ nor->read_dummy = 8; -+ } else { -+ nor->read_opcode = SPINOR_OP_READ; -+ nor->read_dummy = 0; -+ } -+ } -+ -+ if (!(modes->rd_modes & (SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4))) { -+ ret = spi_nor_reset_pin_enable(nor, info); -+ if (ret < 0) { -+ dev_err(nor->dev, "Enable RESET# fail.\n"); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+int spi_nor_scan(struct spi_nor *nor, const char *name, -+ struct spi_nor_modes *modes) -+{ -+ const struct spi_nor_basic_flash_parameter *params = NULL; - const struct flash_info *info = NULL; - struct device *dev = nor->dev; - struct mtd_info *mtd = &nor->mtd; -@@ -1320,11 +2531,19 @@ - if (ret) - return ret; - -+ /* Reset SPI protocol for all commands */ -+ nor->erase_proto = SNOR_PROTO_1_1_1; -+ nor->read_proto = SNOR_PROTO_1_1_1; -+ nor->write_proto = SNOR_PROTO_1_1_1; -+ - if (name) - info = spi_nor_match_id(name); - /* Try to auto-detect if chip name wasn't specified or not found */ -- if (!info) -+ if (!info) { -+ dev_info(dev, "SPI Nor ID Table Version %s\n", SPI_NOR_IDS_VER); - info = spi_nor_read_id(nor); -+ } -+ - if (IS_ERR_OR_NULL(info)) - return -ENOENT; - -@@ -1351,9 +2570,15 @@ - info = jinfo; - } - } -+ if (info->params) -+ params = info->params; - - mutex_init(&nor->lock); - -+#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT -+ /* NOR block protection support */ -+ bsp_get_spi_lock_info(nor, info); -+#else - /* - * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up - * with the software protection bits set -@@ -1367,6 +2592,7 @@ - write_sr(nor, 0); - spi_nor_wait_till_ready(nor); - } -+#endif - - if (!mtd->name) - mtd->name = dev_name(dev); -@@ -1380,7 +2606,8 @@ - - /* NOR protection support for STmicro/Micron chips and similar */ - if (JEDEC_MFR(info) == SNOR_MFR_MICRON || -- info->flags & SPI_NOR_HAS_LOCK) { -+ JEDEC_MFR(info) == SNOR_MFR_WINBOND || -+ info->flags & SPI_NOR_HAS_LOCK) { - nor->flash_lock = stm_lock; - nor->flash_unlock = stm_unlock; - nor->flash_is_locked = stm_is_locked; -@@ -1428,92 +2655,61 @@ - if (np) { - /* If we were instantiated by DT, use it */ - if (of_property_read_bool(np, "m25p,fast-read")) -- nor->flash_read = SPI_NOR_FAST; -+ modes->rd_modes |= SNOR_MODE_1_1_1; - else -- nor->flash_read = SPI_NOR_NORMAL; -+ modes->rd_modes &= ~SNOR_MODE_1_1_1; - } else { - /* If we weren't instantiated by DT, default to fast-read */ -- nor->flash_read = SPI_NOR_FAST; -+ modes->rd_modes |= SNOR_MODE_1_1_1; - } - - /* Some devices cannot do fast-read, no matter what DT tells us */ - if (info->flags & SPI_NOR_NO_FR) -- nor->flash_read = SPI_NOR_NORMAL; -- -- /* Quad/Dual-read mode takes precedence over fast/normal */ -- if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) { -- ret = set_quad_mode(nor, info); -- if (ret) { -- dev_err(dev, "quad mode not supported\n"); -- return ret; -- } -- nor->flash_read = SPI_NOR_QUAD; -- } else if (mode == SPI_NOR_DUAL && info->flags & SPI_NOR_DUAL_READ) { -- nor->flash_read = SPI_NOR_DUAL; -- } -- -- /* Default commands */ -- switch (nor->flash_read) { -- case SPI_NOR_QUAD: -- nor->read_opcode = SPINOR_OP_READ_1_1_4; -- break; -- case SPI_NOR_DUAL: -- nor->read_opcode = SPINOR_OP_READ_1_1_2; -- break; -- case SPI_NOR_FAST: -- nor->read_opcode = SPINOR_OP_READ_FAST; -- break; -- case SPI_NOR_NORMAL: -- nor->read_opcode = SPINOR_OP_READ; -- break; -- default: -- dev_err(dev, "No Read opcode defined\n"); -- return -EINVAL; -- } -+ modes->rd_modes &= ~SNOR_MODE_1_1_1; - - nor->program_opcode = SPINOR_OP_PP; - -+ /* -+ * Configure the SPI memory: -+ * - select op codes for (Fast) Read, Page Program and Sector Erase. -+ * - set the number of dummy cycles (mode cycles + wait states). -+ * - set the SPI protocols for register and memory accesses. -+ * - set the Quad Enable bit if needed (required by SPI x-y-4 protos). -+ */ -+ ret = spi_nor_config(nor, info, params, modes); -+ if (ret) -+ return ret; -+ - if (info->addr_width) - nor->addr_width = info->addr_width; - else if (mtd->size > 0x1000000) { - /* enable 4-byte addressing if the device exceeds 16MiB */ - nor->addr_width = 4; -- if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) { -- /* Dedicated 4-byte command set */ -- switch (nor->flash_read) { -- case SPI_NOR_QUAD: -- nor->read_opcode = SPINOR_OP_READ4_1_1_4; -- break; -- case SPI_NOR_DUAL: -- nor->read_opcode = SPINOR_OP_READ4_1_1_2; -- break; -- case SPI_NOR_FAST: -- nor->read_opcode = SPINOR_OP_READ4_FAST; -- break; -- case SPI_NOR_NORMAL: -- nor->read_opcode = SPINOR_OP_READ4; -- break; -- } -- nor->program_opcode = SPINOR_OP_PP_4B; -- /* No small sector erase for 4-byte command set */ -- nor->erase_opcode = SPINOR_OP_SE_4B; -- mtd->erasesize = info->sector_size; -- } else -+ if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || -+ info->flags & SPI_NOR_4B_OPCODES) -+ spi_nor_set_4byte_opcodes(nor, info); -+ else - set_4byte(nor, info, 1); - } else { - nor->addr_width = 3; - } - -+ /* choose the suitable clockrate */ -+ if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) /* device supports dual or quad */ -+ && (modes->rd_modes & (~SNOR_MODE_SLOW)) /* controller supports fast mode */ -+ && info->clkrate) -+ nor->clkrate = info->clkrate; -+ else -+ nor->clkrate = 24000000; -+ - if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) { - dev_err(dev, "address width is too large: %u\n", - nor->addr_width); - return -EINVAL; - } - -- nor->read_dummy = spi_nor_read_dummy_cycles(nor); -- -- dev_info(dev, "%s (%lld Kbytes)\n", info->name, -- (long long)mtd->size >> 10); -+ dev_info(dev, "%s (Chipsize %lld Mbytes, Blocksize %uKiB)\n", -+ info->name, (long long)mtd->size >> 20, mtd->erasesize / 1024); - - dev_dbg(dev, - "mtd .name = %s, .size = 0x%llx (%lldMiB), " -@@ -1547,6 +2743,64 @@ - return NULL; - } - -+/******************************************************************************/ -+void spi_nor_driver_shutdown(struct spi_nor *nor) -+{ -+ /* disable 4-byte addressing if the device exceeds 16MiB */ -+ if (nor->addr_width == 4) { -+ const struct flash_info *info = NULL; -+ -+ info = spi_nor_read_id(nor); -+ set_4byte(nor, info, 0); -+ } -+ return; -+} -+ -+#ifdef CONFIG_PM -+/******************************************************************************/ -+int spi_nor_suspend(struct spi_nor *nor, pm_message_t state) -+{ -+ return spi_nor_wait_till_ready(nor); -+} -+ -+/******************************************************************************/ -+int spi_nor_resume(struct spi_nor *nor) -+{ -+ int ret; -+ const struct flash_info *info = NULL; -+ const struct spi_nor_basic_flash_parameter *params = NULL; -+ struct spi_nor_modes modes = { -+ .rd_modes = SNOR_MODE_SLOW, -+ .wr_modes = SNOR_MODE_1_1_1, -+ }; -+ -+ modes.rd_modes |= SNOR_MODE_1_1_1 -+ | SNOR_MODE_1_1_2 -+ | SNOR_MODE_1_2_2; -+#ifndef CONFIG_CLOSE_SPI_8PIN_4IO -+ modes.rd_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; -+ modes.wr_modes |= SNOR_MODE_1_1_4 | SNOR_MODE_1_4_4; -+#endif -+ -+ if (!info) -+ info = spi_nor_read_id(nor); -+ -+ /* Quad mode takes precedence over fast/normal */ -+ if (info->params) -+ params = info->params; -+ -+ ret = spi_nor_config(nor, info, params, &modes); -+ if (ret) -+ return ret; -+ -+ /* enable 4-byte addressing if the device exceeds 16MiB */ -+ if (nor->addr_width == 4 && JEDEC_MFR(info) != SNOR_MFR_SPANSION) -+ set_4byte(nor, info, 1); -+ -+ return 0; -+} -+#endif /* End of CONFIG_PM */ -+ - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Huang Shijie "); - MODULE_AUTHOR("Mike Lavender"); ---- linux-4.9.37/drivers/net/ethernet/goke/femac/femac.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/femac.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,1560 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "phy_fix.h" -+#include "femac.h" -+#include "util.h" -+ -+static void femac_irq_enable(const struct femac_priv *priv, u32 irqs) -+{ -+ u32 val; -+ -+ val = readl(priv->glb_base + GLB_IRQ_ENA); -+ writel(val | irqs, priv->glb_base + GLB_IRQ_ENA); -+} -+ -+static void femac_irq_disable(const struct femac_priv *priv, u32 irqs) -+{ -+ u32 val; -+ -+ val = readl(priv->glb_base + GLB_IRQ_ENA); -+ writel(val & (~irqs), priv->glb_base + GLB_IRQ_ENA); -+} -+ -+#ifdef CONFIG_FEPHY_OPT -+static u32 highflag = 0; -+static u32 lowflag = 0; -+static void femac_trim_phy(struct phy_device *phy_dev, u32 val) -+{ -+ u32 val1; -+ /* 32 pieces of data */ -+ int table[32] = {0x11, 0x10, 0x10, 0xf, 0xe, 0xd, 0xd, 0xc, -+ 0xb, 0xa, 0xa, 0x9, 0x8, 0x7, 0x7, 0x6, -+ 0x5, 0x5, 0x4, 0x3, 0x2, 0x2, 0x1, 0x0, -+ 0x3f, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a -+ }; -+ -+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE); -+ phy_write(phy_dev, MII_EXPMD, val); -+ val &= 0x1f; -+ val1 = table[val]; -+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE); -+ val = phy_read(phy_dev, MII_EXPMD); -+ val = (val1 << 2) | (val & 0x3); /* shift left 2 bits */ -+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE); -+ phy_write(phy_dev, MII_EXPMD, val); -+} -+ -+static void femac_trim(struct net_device *dev) -+{ -+ struct phy_device *phy_dev = NULL; -+ int temp; -+ u32 val; -+ -+ phy_dev = dev->phydev; -+ if (phy_dev == NULL) { -+ pr_err("get phy device failed \n"); -+ return; -+ } -+ -+ phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE); -+ val = phy_read(phy_dev, MII_EXPMD); -+ temp = regval_to_temp(val); -+ if ((temp > HIGH_TEMP) && (highflag == 0)) { -+ highflag = 1; -+ if ((val & 0x1f) > 1) -+ val = (val & 0xe0) | ((val & 0x1f) - 1); -+ else -+ return; -+ femac_trim_phy(phy_dev, val); -+ } -+ if ((temp < NORMAL_TEMP1) && (highflag == 1)) { -+ highflag = 0; -+ if ((val & 0x1f) < 0x1f) -+ val = (val & 0xe0) | ((val & 0x1f) + 1); -+ else -+ return; -+ femac_trim_phy(phy_dev, val); -+ } -+ if ((temp > NORMAL_TEMP2) && (lowflag == 0)) { -+ lowflag = 1; -+ if ((val & 0x1f) > 1) -+ val = (val & 0xe0) | ((val & 0x1f) - 1); -+ else -+ return; -+ femac_trim_phy(phy_dev, val); -+ } -+ if ((temp < LOW_TEMP) && (lowflag == 1)) { -+ lowflag = 0; -+ if ((val & 0x1f) < 0x1f) -+ val = (val & 0xe0) | ((val & 0x1f) + 1); -+ else -+ return; -+ femac_trim_phy(phy_dev, val); -+ } -+} -+ -+static void femac_watchdog(struct work_struct *work) -+{ -+ struct delayed_work *dwork = to_delayed_work(work); -+ struct femac_priv *priv = container_of(dwork, struct femac_priv, watchdog_queue); -+ void __iomem *sys_reg_addr; -+ struct net_device *dev = NULL; -+ u32 val; -+ -+ dev = priv->ndev; -+ if (dev == NULL) { -+ pr_err("get net device failed \n"); -+ return; -+ } -+ -+ sys_reg_addr = (void __iomem *)ioremap_nocache(SYS_REG_ADDR, 0x100); -+ if (!sys_reg_addr) { -+ pr_err("iomap failed \n"); -+ return; -+ } -+ val = readl(sys_reg_addr + MISC_CTRL45); -+ if ((val >> 30) != 0x3) { /* bit[30 31] */ -+ val |= TSENSOR_EN; -+ writel(val, sys_reg_addr + MISC_CTRL45); -+ mdelay(10); /* wait 10ms */ -+ } -+ val = readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT0; -+ /* high 16bit */ -+ val += (readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT1) >> 16; -+ val += readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT2; -+ /* high 16bit */ -+ val += (readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT3) >> 16; -+ val = val / 4; /* average value of the 4 values */ -+ if (val < LOW_TEM_VALUE || val > HIGH_TEM_VALUE) { -+ goto out; -+ } -+ femac_trim(dev); -+out: -+ iounmap(sys_reg_addr); -+ schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER); -+} -+#endif -+ -+static void femac_tx_sg_dma_unmap(const struct femac_priv *priv, -+ const struct sk_buff *skb, unsigned int pos) -+{ -+ struct tx_desc *desc_cur; -+ dma_addr_t addr; -+ u32 len; -+ int i; -+ -+ desc_cur = priv->tx_ring.desc + pos; -+ -+ addr = desc_cur->linear_addr; -+ len = desc_cur->linear_len; -+ dma_unmap_single(priv->dev, addr, len, DMA_TO_DEVICE); -+ -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -+ addr = desc_cur->frags[i].addr; -+ len = desc_cur->frags[i].size; -+ dma_unmap_page(priv->dev, addr, len, DMA_TO_DEVICE); -+ } -+} -+ -+static void femac_tx_dma_unmap(const struct femac_priv *priv, -+ const struct sk_buff *skb, unsigned int pos) -+{ -+ if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) { -+ dma_addr_t dma_addr; -+ -+ dma_addr = priv->txq.dma_phys[pos]; -+ dma_unmap_single(priv->dev, dma_addr, skb->len, DMA_TO_DEVICE); -+ } else { -+ femac_tx_sg_dma_unmap(priv, skb, pos); -+ } -+} -+ -+static void femac_xmit_reclaim(struct net_device *dev) -+{ -+ struct sk_buff *skb = NULL; -+ struct femac_priv *priv = netdev_priv(dev); -+ struct femac_queue *txq = &priv->txq; -+ unsigned int bytes_compl = 0; -+ unsigned int pkts_compl = 0; -+ u32 val; -+ -+ netif_tx_lock(dev); -+ -+ val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK; -+ while (val < priv->tx_fifo_used_cnt) { -+ skb = txq->skb[txq->tail]; -+ if (unlikely(skb == NULL)) { -+ netdev_err(dev, "xmitq_cnt_inuse=%d, tx_fifo_used=%d\n", -+ val, priv->tx_fifo_used_cnt); -+ break; -+ } -+ femac_tx_dma_unmap(priv, skb, txq->tail); -+ pkts_compl++; -+ bytes_compl += skb->len; -+ dev_kfree_skb_any(skb); -+ -+ priv->tx_fifo_used_cnt--; -+ -+ val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK; -+ txq->skb[txq->tail] = NULL; -+ txq->tail = (txq->tail + 1) % txq->num; -+ } -+ -+ netdev_completed_queue(dev, pkts_compl, bytes_compl); -+ -+ if (unlikely(netif_queue_stopped(dev)) && pkts_compl) -+ netif_wake_queue(dev); -+ -+ netif_tx_unlock(dev); -+} -+ -+static void femac_get_tso_err_info(const struct femac_priv *priv) -+{ -+ unsigned int reg_addr, reg_tx_info, reg_tx_err; -+ unsigned int sg_index; -+ struct tx_desc *sg_desc = NULL; -+ int *sg_word = NULL; -+ int i; -+ -+ reg_addr = readl(priv->port_base + TSO_DBG_ADDR); -+ reg_tx_info = readl(priv->port_base + TSO_DBG_TX_INFO); -+ reg_tx_err = readl(priv->port_base + TSO_DBG_TX_ERR); -+ -+ WARN(1, "tx err=0x%x, tx_info=0x%x, addr=0x%x\n", -+ reg_tx_err, reg_tx_info, reg_addr); -+ -+ sg_index = (reg_addr - priv->tx_ring.dma_phys) / sizeof(struct tx_desc); -+ sg_desc = priv->tx_ring.desc + sg_index; -+ sg_word = (int *)sg_desc; -+ for (i = 0; i < sizeof(struct tx_desc) / sizeof(int); i++) -+ pr_err("%s,%d: sg_desc word[%d]=0x%x\n", -+ __func__, __LINE__, i, sg_word[i]); -+ -+ /* restart MAC to transmit next packet */ -+ femac_irq_disable(priv, INT_TX_ERR); -+ /* -+ * If we need allow netcard transmit packet again. -+ * we should readl TSO_DBG_STATE and enable irq. -+ */ -+} -+ -+static netdev_tx_t femac_net_xmit(struct sk_buff *skb, -+ struct net_device *dev); -+ -+static netdev_tx_t femac_sw_gso(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ struct sk_buff *segs = NULL; -+ struct sk_buff *curr_skb = NULL; -+ netdev_features_t features = dev->features; -+ -+ features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO); -+ segs = skb_gso_segment(skb, features); -+ if (IS_ERR_OR_NULL(segs)) { -+ goto drop; -+ } -+ -+ do { -+ curr_skb = segs; -+ segs = segs->next; -+ curr_skb->next = NULL; -+ if (femac_net_xmit(curr_skb, dev)) { -+ dev_kfree_skb(curr_skb); -+ while (segs != NULL) { -+ curr_skb = segs; -+ segs = segs->next; -+ curr_skb->next = NULL; -+ dev_kfree_skb_any(curr_skb); -+ } -+ goto drop; -+ } -+ } while (segs != NULL); -+ -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+ -+drop: -+ dev_kfree_skb_any(skb); -+ dev->stats.tx_dropped++; -+ return NETDEV_TX_OK; -+} -+ -+static int femac_fill_sg_desc(const struct femac_priv *priv, -+ const struct sk_buff *skb, unsigned int pos) -+{ -+ struct tx_desc *desc_cur; -+ dma_addr_t addr; -+ int ret; -+ int i; -+ -+ desc_cur = priv->tx_ring.desc + pos; -+ -+ desc_cur->ipv6_id = ntohl(skb_shinfo(skb)->ip6_frag_id); -+ -+ desc_cur->total_len = skb->len; -+ addr = dma_map_single(priv->dev, skb->data, skb_headlen(skb), -+ DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(priv->dev, addr))) { -+ return -EINVAL; -+ } -+ desc_cur->linear_addr = addr; -+ desc_cur->linear_len = skb_headlen(skb); -+ -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -+ int len = frag->size; -+ -+ addr = skb_frag_dma_map(priv->dev, frag, 0, len, DMA_TO_DEVICE); -+ ret = dma_mapping_error(priv->dev, addr); -+ if (unlikely(ret)) { -+ return -EINVAL; -+ } -+ desc_cur->frags[i].addr = addr; -+ desc_cur->frags[i].size = len; -+ } -+ -+ return 0; -+} -+ -+static void femac_adjust_link(struct net_device *dev) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct phy_device *phy = dev->phydev; -+ u32 status = 0; -+ -+ if (phy->link) -+ status |= MAC_PORTSET_LINKED; -+ if (phy->duplex == DUPLEX_FULL) -+ status |= MAC_PORTSET_DUPLEX_FULL; -+ if (phy->speed == SPEED_100) -+ status |= MAC_PORTSET_SPEED_100M; -+ -+ if ((status != priv->link_status) && -+ ((status | priv->link_status) & MAC_PORTSET_LINKED)) { -+ writel(status, priv->port_base + MAC_PORTSET); -+ priv->link_status = status; -+ phy_print_status(phy); -+ -+ priv->tx_pause_en = phy->pause; -+ femac_set_flow_ctrl(priv); -+ } -+} -+ -+static void femac_rx_refill(struct femac_priv *priv) -+{ -+ struct femac_queue *rxq = &priv->rxq; -+ struct sk_buff *skb = NULL; -+ u32 pos; -+ u32 len; -+ dma_addr_t addr; -+ u32 alloc_rxbuf_align; -+ int reserve_room; -+ -+ pos = rxq->head; -+ while (readl(priv->port_base + ADDRQ_STAT) & BIT_RX_READY) { -+ if (!CIRC_SPACE(pos, rxq->tail, rxq->num)) { -+ break; -+ } -+ if (unlikely(rxq->skb[pos])) { -+ netdev_err(priv->ndev, "err skb[%d]=%p\n", -+ pos, rxq->skb[pos]); -+ break; -+ } -+ len = MAX_FRAME_SIZE + RXBUF_ADDR_ALIGN_SIZE; -+ skb = netdev_alloc_skb_ip_align(priv->ndev, len); -+ if (unlikely(skb == NULL)) { -+ break; -+ } -+ -+ alloc_rxbuf_align = ((uintptr_t)skb->data - NET_IP_ALIGN) & -+ (RXBUF_ADDR_ALIGN_SIZE - 1); -+ if (alloc_rxbuf_align) { -+ reserve_room = RXBUF_ADDR_ALIGN_SIZE - -+ alloc_rxbuf_align; -+ len -= reserve_room; -+ skb_reserve(skb, reserve_room); -+ } -+ -+ addr = dma_map_single(priv->dev, skb->data, len, -+ DMA_FROM_DEVICE); -+ if (dma_mapping_error(priv->dev, addr)) { -+ dev_kfree_skb_any(skb); -+ break; -+ } -+ rxq->dma_phys[pos] = addr; -+ rxq->skb[pos] = skb; -+ writel(addr, priv->port_base + IQ_ADDR); -+ pos = (pos + 1) % rxq->num; -+ } -+ rxq->head = pos; -+} -+ -+#ifdef FEMAC_RX_REFILL_IN_IRQ -+static void femac_recv_queue(struct net_device *dev, struct sk_buff *skb, -+ u32 rx_pkt_info) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ int hdr_csum_done, hdr_csum_err; -+ int payload_csum_done, payload_csum_err; -+ -+ skb->ip_summed = CHECKSUM_NONE; -+ if (dev->features & NETIF_F_RXCSUM) { -+ hdr_csum_done = -+ (rx_pkt_info >> BITS_HEADER_DONE_OFFSET) & -+ BITS_HEADER_DONE_MASK; -+ payload_csum_done = -+ (rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) & -+ BITS_PAYLOAD_DONE_MASK; -+ hdr_csum_err = -+ (rx_pkt_info >> BITS_HEADER_ERR_OFFSET) & -+ BITS_HEADER_ERR_MASK; -+ payload_csum_err = -+ (rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) & -+ BITS_PAYLOAD_ERR_MASK; -+ -+ if (hdr_csum_done && payload_csum_done) { -+ if (unlikely(hdr_csum_err)) { -+ dev->stats.rx_errors++; -+ dev->stats.rx_crc_errors++; -+ dev_kfree_skb_any(skb); -+ return; -+ } else if (!payload_csum_err) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ } -+ } -+ } -+ skb_queue_tail(&priv->rx_head, skb); -+} -+ -+static void femac_pre_receive(struct net_device *dev) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct femac_queue *rxq = &priv->rxq; -+ struct sk_buff *skb = NULL; -+ u32 rx_pkt_info, pos, len; -+ unsigned long rxflags; -+ -+ spin_lock_irqsave(&priv->rxlock, rxflags); -+ pos = rxq->tail; -+ while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) { -+ rx_pkt_info = readl(priv->port_base + IQFRM_DES); -+ len = rx_pkt_info & RX_FRAME_LEN_MASK; -+ len -= ETH_FCS_LEN; -+ -+ /* tell hardware we will deal with this packet */ -+ writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW); -+ -+ skb = rxq->skb[pos]; -+ if (unlikely(skb == NULL)) { -+ netdev_err(dev, "rx skb NULL. pos=%d\n", pos); -+ break; -+ } -+ rxq->skb[pos] = NULL; -+ -+ dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE, -+ DMA_FROM_DEVICE); -+ skb_put(skb, len); -+ if (unlikely(skb->len > MAX_FRAME_SIZE)) { -+ netdev_err(dev, "rcv len err, len = %d\n", skb->len); -+ dev->stats.rx_errors++; -+ dev->stats.rx_length_errors++; -+ dev_kfree_skb_any(skb); -+ goto next; -+ } -+ -+ femac_recv_queue(dev, skb, rx_pkt_info); -+next: -+ pos = (pos + 1) % rxq->num; -+ } -+ rxq->tail = pos; -+ -+ femac_rx_refill(priv); -+ spin_unlock_irqrestore(&priv->rxlock, rxflags); -+} -+ -+static u32 femac_rx(struct net_device *dev, int limit) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct sk_buff *skb = skb_dequeue(&priv->rx_head); -+ u32 rx_pkts_num = 0; -+ -+ while (skb != NULL) { -+ skb->protocol = eth_type_trans(skb, dev); -+ napi_gro_receive(&priv->napi, skb); -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += skb->len; -+ rx_pkts_num++; -+ -+ if (rx_pkts_num >= limit) { -+ break; -+ } -+ skb = skb_dequeue(&priv->rx_head); -+ } -+ -+ return rx_pkts_num; -+} -+#else -+static int femac_recv_queue(struct net_device *dev, struct sk_buff *skb, -+ u32 rx_pkt_info) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ int hdr_csum_done, hdr_csum_err; -+ int payload_csum_done, payload_csum_err; -+ -+ skb->ip_summed = CHECKSUM_NONE; -+ if (dev->features & NETIF_F_RXCSUM) { -+ hdr_csum_done = -+ (rx_pkt_info >> BITS_HEADER_DONE_OFFSET) & -+ BITS_HEADER_DONE_MASK; -+ payload_csum_done = -+ (rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) & -+ BITS_PAYLOAD_DONE_MASK; -+ hdr_csum_err = -+ (rx_pkt_info >> BITS_HEADER_ERR_OFFSET) & -+ BITS_HEADER_ERR_MASK; -+ payload_csum_err = -+ (rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) & -+ BITS_PAYLOAD_ERR_MASK; -+ -+ if (hdr_csum_done && payload_csum_done) { -+ if (unlikely(hdr_csum_err)) { -+ dev->stats.rx_errors++; -+ dev->stats.rx_crc_errors++; -+ dev_kfree_skb_any(skb); -+ return -1; -+ } else if (!payload_csum_err) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ } -+ } -+ } -+ return 0; -+} -+ -+static u32 femac_rx(struct net_device *dev, int limit) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct femac_queue *rxq = &priv->rxq; -+ struct sk_buff *skb; -+ u32 rx_pkt_info, pos, len; -+ u32 rx_pkts_num = 0; -+ -+ pos = rxq->tail; -+ while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) { -+ rx_pkt_info = readl(priv->port_base + IQFRM_DES); -+ len = rx_pkt_info & RX_FRAME_LEN_MASK; -+ len -= ETH_FCS_LEN; -+ -+ /* tell hardware we will deal with this packet */ -+ writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW); -+ -+ rx_pkts_num++; -+ -+ skb = rxq->skb[pos]; -+ if (unlikely(!skb)) { -+ netdev_err(dev, "rx skb NULL. pos=%d\n", pos); -+ break; -+ } -+ rxq->skb[pos] = NULL; -+ -+ dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE, -+ DMA_FROM_DEVICE); -+ skb_put(skb, len); -+ if (unlikely(skb->len > MAX_FRAME_SIZE)) { -+ netdev_err(dev, "rcv len err, len = %d\n", skb->len); -+ dev->stats.rx_errors++; -+ dev->stats.rx_length_errors++; -+ dev_kfree_skb_any(skb); -+ goto next; -+ } -+ -+ if (femac_recv_queue(dev, skb, rx_pkt_info) < 0) -+ goto next; -+ -+ skb->protocol = eth_type_trans(skb, dev); -+ napi_gro_receive(&priv->napi, skb); -+ dev->stats.rx_packets++; -+ dev->stats.rx_bytes += len; -+next: -+ pos = (pos + 1) % rxq->num; -+ if (rx_pkts_num >= limit) { -+ break; -+ } -+ } -+ rxq->tail = pos; -+ -+ femac_rx_refill(priv); -+ -+ return rx_pkts_num; -+} -+#endif -+ -+static int femac_poll(struct napi_struct *napi, int budget) -+{ -+ struct femac_priv *priv = container_of(napi, -+ struct femac_priv, napi); -+ struct net_device *dev = priv->ndev; -+ int work_done = 0; -+ int task = budget; -+ u32 ints, num; -+ -+ do { -+#ifdef FEMAC_RX_REFILL_IN_IRQ -+ femac_pre_receive(dev); -+#endif -+ femac_xmit_reclaim(dev); -+ num = femac_rx(dev, task); -+ work_done += num; -+ task -= num; -+ if (work_done >= budget) { -+ break; -+ } -+ -+ ints = readl(priv->glb_base + GLB_IRQ_RAW); -+ writel(ints & DEF_INT_MASK, -+ priv->glb_base + GLB_IRQ_RAW); -+ } while (ints & DEF_INT_MASK); -+ -+ if (work_done < budget) { -+ napi_complete(napi); -+ femac_irq_enable(priv, DEF_INT_MASK & -+ (~IRQ_INT_TX_PER_PACKET)); -+ } -+ -+ return work_done; -+} -+ -+static irqreturn_t femac_interrupt(int irq, void *dev_id) -+{ -+ u32 ints; -+ struct net_device *dev = (struct net_device *)dev_id; -+ struct femac_priv *priv = netdev_priv(dev); -+ -+ ints = readl(priv->glb_base + GLB_IRQ_RAW); -+ if (likely(ints & DEF_INT_MASK)) { -+#ifdef FEMAC_RX_REFILL_IN_IRQ -+ femac_pre_receive(dev); -+#endif -+ writel(ints & DEF_INT_MASK, -+ priv->glb_base + GLB_IRQ_RAW); -+ femac_irq_disable(priv, DEF_INT_MASK); -+ napi_schedule(&priv->napi); -+ } -+ -+ if (has_tso_cap(priv->hw_cap) && unlikely(ints & INT_TX_ERR)) -+ femac_get_tso_err_info(priv); -+ -+ return IRQ_HANDLED; -+} -+ -+static int femac_init_tx_descriptor_ring(struct femac_priv *priv) -+{ -+ priv->tx_ring.desc = (struct tx_desc *)dma_zalloc_coherent(priv->dev, -+ TXQ_NUM * sizeof(struct tx_desc), &priv->tx_ring.dma_phys, GFP_KERNEL); -+ if (!priv->tx_ring.desc) { -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static void femac_destroy_tx_descriptor_ring(struct femac_priv *priv) -+{ -+ if (priv->tx_ring.desc) -+ dma_free_coherent(priv->dev, TXQ_NUM * sizeof(struct tx_desc), -+ priv->tx_ring.desc, priv->tx_ring.dma_phys); -+ priv->tx_ring.desc = NULL; -+} -+ -+static int femac_init_queue(struct device *dev, -+ struct femac_queue *queue, unsigned int num) -+{ -+ queue->skb = devm_kcalloc(dev, num, sizeof(struct sk_buff *), GFP_KERNEL); -+ if (queue->skb == NULL) { -+ return -ENOMEM; -+ } -+ -+ queue->dma_phys = devm_kcalloc(dev, num, sizeof(dma_addr_t), GFP_KERNEL); -+ if (queue->dma_phys == NULL) { -+ return -ENOMEM; -+ } -+ -+ queue->num = num; -+ queue->head = 0; -+ queue->tail = 0; -+ -+ return 0; -+} -+ -+static int femac_init_tx_and_rx_queues(struct femac_priv *priv) -+{ -+ int ret; -+ -+ ret = femac_init_queue(priv->dev, &priv->txq, TXQ_NUM); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = femac_init_queue(priv->dev, &priv->rxq, RXQ_NUM); -+ if (ret) { -+ return ret; -+ } -+ -+ priv->tx_fifo_used_cnt = 0; -+ -+ return 0; -+} -+ -+static void femac_free_skb_rings(struct femac_priv *priv) -+{ -+ struct femac_queue *txq = &priv->txq; -+ struct femac_queue *rxq = &priv->rxq; -+ struct sk_buff *skb = NULL; -+ dma_addr_t dma_addr; -+ u32 pos; -+ -+ pos = rxq->tail; -+ while (pos != rxq->head) { -+ skb = rxq->skb[pos]; -+ if (unlikely(skb == NULL)) { -+ netdev_err(priv->ndev, "NULL rx skb. pos=%d, head=%d\n", -+ pos, rxq->head); -+ pos = (pos + 1) % rxq->num; -+ continue; -+ } -+ -+ dma_addr = rxq->dma_phys[pos]; -+ dma_unmap_single(priv->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE); -+ -+ dev_kfree_skb_any(skb); -+ rxq->skb[pos] = NULL; -+ pos = (pos + 1) % rxq->num; -+ } -+ rxq->tail = pos; -+ -+ pos = txq->tail; -+ while (pos != txq->head) { -+ skb = txq->skb[pos]; -+ if (unlikely(skb == NULL)) { -+ netdev_err(priv->ndev, "NULL tx skb. pos=%d, head=%d\n", -+ pos, txq->head); -+ pos = (pos + 1) % txq->num; -+ continue; -+ } -+ femac_tx_dma_unmap(priv, skb, pos); -+ dev_kfree_skb_any(skb); -+ txq->skb[pos] = NULL; -+ pos = (pos + 1) % txq->num; -+ } -+ txq->tail = pos; -+ priv->tx_fifo_used_cnt = 0; -+} -+ -+static int femac_set_hw_mac_addr(const struct femac_priv *priv, -+ const unsigned char *mac) -+{ -+ u32 reg; -+ -+ reg = mac[1] | (mac[0] << 8); /* mac0 is high 8 bits */ -+ writel(reg, priv->glb_base + GLB_HOSTMAC_H16); -+ /* addr2 [24 31] addr3 [16 23] addr4 [8 15] addr5 [0 7] */ -+ reg = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24); -+ writel(reg, priv->glb_base + GLB_HOSTMAC_L32); -+ -+ return 0; -+} -+ -+static int femac_port_reset(const struct femac_priv *priv) -+{ -+ u32 val; -+ -+ val = readl(priv->glb_base + GLB_SOFT_RESET); -+ val |= SOFT_RESET_ALL; -+ writel(val, priv->glb_base + GLB_SOFT_RESET); -+ -+ usleep_range(500, 800); /* wait 500-800us */ -+ -+ val &= ~SOFT_RESET_ALL; -+ writel(val, priv->glb_base + GLB_SOFT_RESET); -+ -+ return 0; -+} -+ -+static int femac_net_open(struct net_device *dev) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ -+ femac_set_hw_mac_addr(priv, dev->dev_addr); -+ /* -+ * clear interrupts will drop the first packet MAC have received, -+ * so do it before refill the rx free skbs. -+ */ -+ writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW); -+ femac_rx_refill(priv); -+ -+ netif_carrier_off(dev); -+ netdev_reset_queue(dev); -+ netif_start_queue(dev); -+ napi_enable(&priv->napi); -+ -+ priv->link_status = 0; -+ if (dev->phydev) -+ phy_start(dev->phydev); -+ -+ femac_irq_enable(priv, IRQ_ENA_ALL | IRQ_ENA_PORT0 | DEF_INT_MASK); -+ if (has_tso_cap(priv->hw_cap)) -+ femac_irq_enable(priv, INT_TX_ERR); -+ -+ return 0; -+} -+ -+static void femac_port_init(struct femac_priv *priv); -+ -+static int femac_net_close(struct net_device *dev) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ -+ femac_irq_disable(priv, IRQ_ENA_PORT0); -+ -+ if (dev->phydev) -+ phy_stop(dev->phydev); -+ -+ netif_stop_queue(dev); -+ napi_disable(&priv->napi); -+ -+ /* -+ * reset MAC port first before free skb rings -+ * to prevent potential risk of use-after-free. -+ */ -+ femac_port_reset(priv); -+ femac_port_init(priv); -+ -+ priv->tx_pause_en = false; -+ femac_set_flow_ctrl(priv); -+ femac_free_skb_rings(priv); -+#ifdef FEMAC_RX_REFILL_IN_IRQ -+ skb_queue_purge(&priv->rx_head); -+#endif -+ -+ return 0; -+} -+ -+static bool femac_net_isready(struct net_device *dev) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct femac_queue *txq = &priv->txq; -+ u32 val; -+ -+ val = readl(priv->port_base + ADDRQ_STAT); -+ val &= BIT_TX_READY; -+ if (!val) { -+ femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET); -+ dev->stats.tx_dropped++; -+ dev->stats.tx_fifo_errors++; -+ netif_stop_queue(dev); -+ return false; -+ } -+ -+ if (unlikely(!CIRC_SPACE(txq->head, txq->tail, -+ txq->num))) { -+ femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET); -+ dev->stats.tx_dropped++; -+ dev->stats.tx_fifo_errors++; -+ netif_stop_queue(dev); -+ return false; -+ } -+ -+ return true; -+} -+ -+static netdev_tx_t femac_net_xmit(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct femac_queue *txq = &priv->txq; -+ dma_addr_t addr; -+ int ret; -+ u32 pkt_info; -+ -+ if (!femac_net_isready(dev)) -+ return NETDEV_TX_BUSY; -+ -+ ret = femac_check_hw_capability(skb); -+ if (unlikely(ret)) { -+ if (ret == -ENOTSUPP) -+ return femac_sw_gso(skb, dev); -+ -+ dev_kfree_skb_any(skb); -+ dev->stats.tx_dropped++; -+ return NETDEV_TX_OK; -+ } -+ -+ pkt_info = femac_get_pkt_info(skb); -+ -+ if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) { -+ addr = dma_map_single(priv->dev, skb->data, -+ skb->len, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(priv->dev, addr))) { -+ dev_kfree_skb_any(skb); -+ dev->stats.tx_dropped++; -+ return NETDEV_TX_OK; -+ } -+ } else { -+ ret = femac_fill_sg_desc(priv, skb, txq->head); -+ if (unlikely(ret)) { -+ dev_kfree_skb_any(skb); -+ dev->stats.tx_dropped++; -+ return NETDEV_TX_OK; -+ } -+ -+ addr = priv->tx_ring.dma_phys + -+ txq->head * sizeof(struct tx_desc); -+ -+ /* Ensure desc info writen to memory before config hardware */ -+ wmb(); -+ } -+ txq->dma_phys[txq->head] = addr; -+ -+ skb_tx_timestamp(skb); -+ -+ txq->skb[txq->head] = skb; -+ txq->head = (txq->head + 1) % txq->num; -+ -+ writel(addr, priv->port_base + EQ_ADDR); -+ writel(pkt_info, priv->port_base + EQFRM_LEN); -+ -+ priv->tx_fifo_used_cnt++; -+ -+ dev->stats.tx_packets++; -+ dev->stats.tx_bytes += skb->len; -+ netdev_sent_queue(dev, skb->len); -+ -+ return NETDEV_TX_OK; -+} -+ -+static int femac_set_mac_address(struct net_device *dev, void *p) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct sockaddr *skaddr = p; -+ -+ if (!is_valid_ether_addr(skaddr->sa_data)) { -+ return -EADDRNOTAVAIL; -+ } -+ -+ memcpy(dev->dev_addr, skaddr->sa_data, dev->addr_len); -+ dev->addr_assign_type &= ~NET_ADDR_RANDOM; -+ -+ femac_set_hw_mac_addr(priv, dev->dev_addr); -+ -+ return 0; -+} -+ -+static void femac_enable_hw_addr_filter(const struct femac_priv *priv, -+ unsigned int reg_n, bool enable) -+{ -+ u32 val; -+ -+ val = readl(priv->glb_base + glb_mac_h16(reg_n)); -+ if (enable) { -+ val |= BIT_MACFLT_ENA; -+ } else { -+ val &= ~BIT_MACFLT_ENA; -+ } -+ writel(val, priv->glb_base + glb_mac_h16(reg_n)); -+} -+ -+static void femac_set_hw_addr_filter(const struct femac_priv *priv, -+ const unsigned char *addr, unsigned int reg_n) -+{ -+ unsigned int high, low; -+ u32 val; -+ -+ high = glb_mac_h16(reg_n); -+ low = glb_mac_l32(reg_n); -+ /* addr2 [24 31] addr3 [16 23] addr4 [8 15] addr5 [0 7] */ -+ val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; -+ writel(val, priv->glb_base + low); -+ -+ val = readl(priv->glb_base + high); -+ val &= ~MACFLT_HI16_MASK; -+ val |= ((addr[0] << 8) | addr[1]); /* addr0 is high 8 bits */ -+ val |= (BIT_MACFLT_ENA | BIT_MACFLT_FW2CPU); -+ writel(val, priv->glb_base + high); -+} -+ -+static void femac_set_promisc_mode(const struct femac_priv *priv, -+ bool promisc_mode) -+{ -+ u32 val; -+ -+ val = readl(priv->glb_base + GLB_FWCTRL); -+ if (promisc_mode) { -+ val |= FWCTRL_FWALL2CPU; -+ } else { -+ val &= ~FWCTRL_FWALL2CPU; -+ } -+ writel(val, priv->glb_base + GLB_FWCTRL); -+} -+ -+/* Handle multiple multicast addresses (perfect filtering) */ -+static void femac_set_mc_addr_filter(const struct femac_priv *priv) -+{ -+ struct net_device *dev = priv->ndev; -+ u32 val; -+ -+ val = readl(priv->glb_base + GLB_MACTCTRL); -+ if ((netdev_mc_count(dev) > MAX_MULTICAST_ADDRESSES) || -+ (dev->flags & IFF_ALLMULTI)) { -+ val |= MACTCTRL_MULTI2CPU; -+ } else { -+ int reg = MAX_UNICAST_ADDRESSES; -+ int i; -+ struct netdev_hw_addr *ha = NULL; -+ -+ for (i = reg; i < MAX_MAC_FILTER_NUM; i++) -+ femac_enable_hw_addr_filter(priv, i, false); -+ -+ netdev_for_each_mc_addr(ha, dev) -+ { -+ femac_set_hw_addr_filter(priv, ha->addr, reg); -+ reg++; -+ } -+ val &= ~MACTCTRL_MULTI2CPU; -+ } -+ writel(val, priv->glb_base + GLB_MACTCTRL); -+} -+ -+/* Handle multiple unicast addresses (perfect filtering) */ -+static void femac_set_uc_addr_filter(const struct femac_priv *priv) -+{ -+ struct net_device *dev = priv->ndev; -+ u32 val; -+ -+ val = readl(priv->glb_base + GLB_MACTCTRL); -+ if (netdev_uc_count(dev) > MAX_UNICAST_ADDRESSES) { -+ val |= MACTCTRL_UNI2CPU; -+ } else { -+ int reg = 0; -+ int i; -+ struct netdev_hw_addr *ha = NULL; -+ -+ for (i = reg; i < MAX_UNICAST_ADDRESSES; i++) -+ femac_enable_hw_addr_filter(priv, i, false); -+ -+ netdev_for_each_uc_addr(ha, dev) -+ { -+ femac_set_hw_addr_filter(priv, ha->addr, reg); -+ reg++; -+ } -+ val &= ~MACTCTRL_UNI2CPU; -+ } -+ writel(val, priv->glb_base + GLB_MACTCTRL); -+} -+ -+static void femac_net_set_rx_mode(struct net_device *dev) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ -+ if (dev->flags & IFF_PROMISC) { -+ femac_set_promisc_mode(priv, true); -+ } else { -+ femac_set_promisc_mode(priv, false); -+ femac_set_mc_addr_filter(priv); -+ femac_set_uc_addr_filter(priv); -+ } -+} -+ -+static int femac_net_ioctl(struct net_device *dev, -+ struct ifreq *ifreq, int cmd) -+{ -+ if (!netif_running(dev)) { -+ return -EINVAL; -+ } -+ -+ if (!dev->phydev) { -+ return -EINVAL; -+ } -+ -+ return phy_mii_ioctl(dev->phydev, ifreq, cmd); -+} -+ -+static const struct ethtool_ops femac_ethtools_ops = { -+ .get_link = ethtool_op_get_link, -+ .get_link_ksettings = phy_ethtool_get_link_ksettings, -+ .set_link_ksettings = phy_ethtool_set_link_ksettings, -+ .get_pauseparam = femac_get_pauseparam, -+ .set_pauseparam = femac_set_pauseparam, -+ .get_ts_info = ethtool_op_get_ts_info, -+}; -+ -+static const struct net_device_ops femac_netdev_ops = { -+ .ndo_open = femac_net_open, -+ .ndo_stop = femac_net_close, -+ .ndo_start_xmit = femac_net_xmit, -+ .ndo_do_ioctl = femac_net_ioctl, -+ .ndo_set_mac_address = femac_set_mac_address, -+ .ndo_set_rx_mode = femac_net_set_rx_mode, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_set_features = femac_set_features, -+}; -+ -+static void femac_verify_flow_ctrl_args(struct femac_priv *priv) -+{ -+ if (priv->tx_pause_active_thresh < FC_ACTIVE_MIN || -+ priv->tx_pause_active_thresh > FC_ACTIVE_MAX) -+ priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT; -+ -+ if (priv->tx_pause_deactive_thresh < FC_DEACTIVE_MIN || -+ priv->tx_pause_deactive_thresh > FC_DEACTIVE_MAX) -+ priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT; -+ -+ if (priv->tx_pause_active_thresh >= priv->tx_pause_deactive_thresh) { -+ priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT; -+ priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT; -+ } -+} -+ -+static void femac_core_reset(const struct femac_priv *priv) -+{ -+ reset_control_assert(priv->mac_rst); -+ reset_control_deassert(priv->mac_rst); -+} -+ -+static void femac_phy_reset(const struct femac_priv *priv) -+{ -+ /* -+ * To make sure PHY hardware reset success, -+ * we must keep PHY in deassert state first and -+ * then complete the hardware reset operation -+ */ -+ reset_control_deassert(priv->phy_rst); -+ femac_sleep_us(priv->phy_reset_delays[PRE_DELAY]); -+ -+ reset_control_assert(priv->phy_rst); -+ /* -+ * delay some time to ensure reset ok, -+ * this depends on PHY hardware feature -+ */ -+ femac_sleep_us(priv->phy_reset_delays[PULSE]); -+ reset_control_deassert(priv->phy_rst); -+ /* delay some time to ensure later MDIO access */ -+ femac_sleep_us(priv->phy_reset_delays[POST_DELAY]); -+} -+ -+static void femac_port_init(struct femac_priv *priv) -+{ -+ u32 val; -+ -+ /* MAC gets link status info and phy mode by software config */ -+ val = MAC_PORTSEL_STAT_CPU; -+ if (priv->ndev->phydev->interface == PHY_INTERFACE_MODE_RMII) -+ val |= MAC_PORTSEL_RMII; -+ writel(val, priv->port_base + MAC_PORTSEL); -+ -+ /* clear all interrupt status */ -+ writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW); -+ femac_irq_disable(priv, IRQ_ENA_PORT0_MASK | IRQ_ENA_PORT0); -+ -+ if (has_tso_cap(priv->hw_cap)) { -+ /* enable TSO debug for error handle */ -+ val = readl(priv->port_base + TSO_DBG_EN); -+ val |= BITS_TSO_DBG_EN; -+ writel(val, priv->port_base + TSO_DBG_EN); -+ } -+ -+ val = readl(priv->glb_base + GLB_FWCTRL); -+ val &= ~(FWCTRL_VLAN_ENABLE | FWCTRL_FWALL2CPU); -+ val |= FWCTRL_FW2CPU_ENA; -+ writel(val, priv->glb_base + GLB_FWCTRL); -+ -+ val = readl(priv->glb_base + GLB_MACTCTRL); -+ val |= (MACTCTRL_BROAD2CPU | MACTCTRL_MACT_ENA); -+ writel(val, priv->glb_base + GLB_MACTCTRL); -+ -+ val = readl(priv->port_base + MAC_SET); -+ val &= ~MAX_FRAME_SIZE_MASK; -+ val |= MAX_FRAME_SIZE; -+ writel(val, priv->port_base + MAC_SET); -+ -+ val = RX_COALESCED_TIMER | -+ (RX_COALESCED_FRAMES << RX_COALESCED_FRAME_OFFSET); -+ writel(val, priv->port_base + RX_COALESCE_SET); -+ -+ val = (HW_RX_FIFO_DEPTH << RX_DEPTH_OFFSET) | HW_TX_FIFO_DEPTH; -+ writel(val, priv->port_base + QLEN_SET); -+ -+ femac_set_flow_ctrl(priv); -+} -+ -+static int femac_drv_res(struct platform_device *pdev, -+ struct femac_priv *priv) -+{ -+ struct resource *res = NULL; -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ int ret; -+ -+ if (of_device_is_compatible(node, "goke,femac-v2")) -+ priv->hw_cap |= HW_CAP_TSO | HW_CAP_RXCSUM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ priv->port_base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(priv->port_base)) { -+ ret = PTR_ERR(priv->port_base); -+ return ret; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ priv->glb_base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(priv->glb_base)) { -+ ret = PTR_ERR(priv->glb_base); -+ return ret; -+ } -+ -+ priv->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(priv->clk)) { -+ dev_err(dev, "failed to get clk\n"); -+ ret = -ENODEV; -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(priv->clk); -+ if (ret) { -+ dev_err(dev, "failed to enable clk %d\n", ret); -+ return ret; -+ } -+ return 0; -+} -+ -+static int femac_drv_mac(struct platform_device *pdev, -+ struct femac_priv *priv) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ const char *mac_addr = NULL; -+ struct net_device *ndev = priv->ndev; -+ -+ priv->mac_rst = devm_reset_control_get(dev, "mac"); -+ if (IS_ERR(priv->mac_rst)) -+ return PTR_ERR(priv->mac_rst); -+ -+ femac_core_reset(priv); -+ -+ mac_addr = of_get_mac_address(node); -+ if (mac_addr != NULL) -+ ether_addr_copy(ndev->dev_addr, mac_addr); -+ if (!is_valid_ether_addr(ndev->dev_addr)) { -+ eth_hw_addr_random(ndev); -+ dev_warn(dev, "using random MAC address %pM\n", -+ ndev->dev_addr); -+ } -+ return 0; -+} -+ -+static struct phy_device* femac_drv_phy(struct platform_device *pdev, -+ struct femac_priv *priv, int *ret) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct phy_device* phy = NULL; -+ -+ priv->phy_rst = devm_reset_control_get(dev, "phy"); -+ if (IS_ERR(priv->phy_rst)) { -+ priv->phy_rst = NULL; -+ } else { -+ *ret = of_property_read_u32_array(node, PHY_RESET_DELAYS_PROPERTY, -+ priv->phy_reset_delays, DELAYS_NUM); -+ if (*ret) -+ return phy; -+ femac_phy_reset(priv); -+ } -+ -+ phy_register_fixups(); -+ -+ phy = of_phy_get_and_connect(priv->ndev, node, femac_adjust_link); -+ if (phy == NULL) { -+ /* check if a fixed-link is defined in device-tree */ -+ if (of_phy_is_fixed_link(node)) { -+ *ret = of_phy_register_fixed_link(node); -+ if (*ret < 0) { -+ dev_err(dev, "cannot regitster fixed link phy %d \n", *ret); -+ return phy; -+ } -+ /* -+ * In case of a fixed link phy, the DT node associated -+ * to the phy is the Ethernet MAC DT node. -+ */ -+ phy = of_phy_connect(priv->ndev, of_node_get(node), &femac_adjust_link, 0, of_get_phy_mode(node)); -+ if (phy == NULL) { -+ dev_err(dev, "fixed_link didnot connect successfully.\n"); -+ return phy; -+ } -+ } else { -+ dev_err(dev, "connect to PHY failed!\n"); -+ *ret = -ENODEV; -+ return phy; -+ } -+ } -+ -+ phy->advertising |= ADVERTISED_Pause; -+ phy->supported |= ADVERTISED_Pause; -+ phy->advertising &= ~(ADVERTISED_1000baseT_Full | -+ ADVERTISED_1000baseT_Half); -+ -+ phy_attached_print(phy, "phy_id=0x%.8lx, phy_mode=%s\n", -+ (unsigned long)phy->phy_id, phy_modes(phy->interface)); -+ -+ return phy; -+} -+ -+static void femac_drv_napi(struct platform_device *pdev, -+ struct femac_priv *priv) -+{ -+ struct net_device *ndev = priv->ndev; -+ -+ ndev->watchdog_timeo = 6 * HZ; /* 6HZ */ -+ ndev->priv_flags |= IFF_UNICAST_FLT; -+ ndev->netdev_ops = &femac_netdev_ops; -+ ndev->ethtool_ops = &femac_ethtools_ops; -+ netif_napi_add(ndev, &priv->napi, femac_poll, FEMAC_POLL_WEIGHT); -+ -+#ifdef CONFIG_FEPHY_OPT -+ INIT_DELAYED_WORK(&priv->watchdog_queue, femac_watchdog); -+ schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER); -+#endif -+ -+ if (has_tso_cap(priv->hw_cap)) -+ ndev->hw_features |= NETIF_F_SG | -+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -+ NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO; -+ -+ if (has_rxcsum_cap(priv->hw_cap)) -+ ndev->hw_features |= NETIF_F_RXCSUM; -+ ndev->features |= ndev->hw_features; -+ ndev->vlan_features |= ndev->features; -+ -+ device_set_wakeup_capable(priv->dev, true); -+ device_set_wakeup_enable(priv->dev, true); -+ -+ priv->tx_pause_en = true; -+ priv->tx_pause_active_thresh = TX_FLOW_CTRL_ACTIVE_THRESHOLD; -+ priv->tx_pause_deactive_thresh = TX_FLOW_CTRL_DEACTIVE_THRESHOLD; -+ -+ femac_verify_flow_ctrl_args(priv); -+ -+ femac_port_init(priv); -+ -+ if (has_rxcsum_cap(priv->hw_cap)) -+ femac_enable_rxcsum_drop(priv, true); -+} -+ -+static int femac_drv_queues(struct platform_device *pdev, -+ struct femac_priv *priv) -+{ -+ int ret; -+ -+#ifdef FEMAC_RX_REFILL_IN_IRQ -+ skb_queue_head_init(&priv->rx_head); -+ spin_lock_init(&priv->rxlock); -+#endif -+ ret = femac_init_tx_and_rx_queues(priv); -+ if (ret) -+ return ret; -+ -+ if (has_tso_cap(priv->hw_cap)) { -+ ret = femac_init_tx_descriptor_ring(priv); -+ if (ret) -+ return ret; -+ } -+ return 0; -+} -+ -+static int femac_drv_register(struct platform_device *pdev, -+ struct femac_priv *priv) -+{ -+ struct device *dev = &pdev->dev; -+ struct net_device *ndev = priv->ndev; -+ int ret; -+ -+ ndev->irq = platform_get_irq(pdev, 0); -+ if (ndev->irq <= 0) { -+ dev_err(dev, "No irq resource\n"); -+ ret = -ENODEV; -+ return ret; -+ } -+ -+ ret = devm_request_irq(dev, ndev->irq, femac_interrupt, -+ IRQF_SHARED, pdev->name, ndev); -+ if (ret) { -+ dev_err(dev, "devm_request_irq %d failed!\n", ndev->irq); -+ return ret;; -+ } -+ -+ ret = register_netdev(ndev); -+ if (ret) { -+ dev_err(dev, "register_netdev failed!\n"); -+ return ret;; -+ } -+ return 0; -+} -+ -+static int femac_drv_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct net_device *ndev = NULL; -+ struct femac_priv *priv = NULL; -+ struct phy_device *phy = NULL; -+ int ret; -+ -+ ndev = alloc_etherdev(sizeof(*priv)); -+ if (ndev == NULL) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, ndev); -+ SET_NETDEV_DEV(ndev, &pdev->dev); -+ -+ priv = netdev_priv(ndev); -+ priv->dev = dev; -+ priv->ndev = ndev; -+ -+ ret = femac_drv_res(pdev, priv); -+ if (ret) -+ goto out_free_netdev; -+ -+ ret = femac_drv_mac(pdev, priv); -+ if (ret) -+ goto out_disable_clk; -+ -+ phy = femac_drv_phy(pdev, priv, &ret); -+ if (phy == NULL) -+ goto out_disable_clk; -+ -+ femac_drv_napi(pdev, priv); -+ -+ ret = femac_drv_queues(pdev, priv); -+ if (ret) -+ goto out_disconnect_phy; -+ -+ ret = femac_drv_register(pdev, priv); -+ if (ret) -+ goto out_destroy_descriptor; -+ -+ return ret; -+ -+out_destroy_descriptor: -+ if (has_tso_cap(priv->hw_cap)) -+ femac_destroy_tx_descriptor_ring(priv); -+out_disconnect_phy: -+ netif_napi_del(&priv->napi); -+ phy_disconnect(phy); -+out_disable_clk: -+ clk_disable_unprepare(priv->clk); -+out_free_netdev: -+ free_netdev(ndev); -+ -+ return ret; -+} -+ -+static int femac_drv_remove(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct femac_priv *priv = netdev_priv(ndev); -+ -+ netif_napi_del(&priv->napi); -+ unregister_netdev(ndev); -+ if (has_tso_cap(priv->hw_cap)) -+ femac_destroy_tx_descriptor_ring(priv); -+ -+ phy_disconnect(ndev->phydev); -+#ifdef CONFIG_FEPHY_OPT -+ cancel_delayed_work_sync(&priv->watchdog_queue); -+#endif -+ clk_disable_unprepare(priv->clk); -+ free_netdev(ndev); -+ -+ phy_unregister_fixups(); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int femac_drv_suspend(struct platform_device *pdev, -+ pm_message_t state) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct femac_priv *priv = netdev_priv(ndev); -+ -+ disable_irq(ndev->irq); -+ if (netif_running(ndev)) { -+ femac_net_close(ndev); -+ netif_device_detach(ndev); -+ } -+ -+ clk_disable_unprepare(priv->clk); -+ -+ return 0; -+} -+ -+static int femac_drv_resume(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ struct femac_priv *priv = netdev_priv(ndev); -+ -+ clk_prepare_enable(priv->clk); -+ if (priv->phy_rst != NULL) -+ femac_phy_reset(priv); -+ -+ if (netif_running(ndev)) { -+ femac_port_init(priv); -+ femac_net_open(ndev); -+ netif_device_attach(ndev); -+ } -+ enable_irq(ndev->irq); -+ -+ return 0; -+} -+#endif -+ -+static const struct of_device_id femac_match[] = { -+ { -+ .compatible = "goke,femac", -+ }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, femac_match); -+ -+static struct platform_driver femac_driver = { -+ .driver = { -+ .name = "femac", -+ .of_match_table = femac_match, -+ }, -+ .probe = femac_drv_probe, -+ .remove = femac_drv_remove, -+#ifdef CONFIG_PM -+ .suspend = femac_drv_suspend, -+ .resume = femac_drv_resume, -+#endif -+}; -+ -+module_platform_driver(femac_driver); -+ -+MODULE_DESCRIPTION("Goke Fast Ethernet MAC driver"); -+MODULE_AUTHOR("Goke"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:femac"); ---- linux-4.9.37/drivers/net/ethernet/goke/femac/femac.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/femac.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,262 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __ETH_GOKE_FEMAC_H__ -+#define __ETH_GOKE_FEMAC_H__ -+ -+/* MAC control register list */ -+#define MAC_PORTSEL 0x0200 -+#define MAC_PORTSEL_STAT_CPU BIT(0) -+#define MAC_PORTSEL_RMII BIT(1) -+#define MAC_PORTSET 0x0208 -+#define MAC_PORTSET_DUPLEX_FULL BIT(0) -+#define MAC_PORTSET_LINKED BIT(1) -+#define MAC_PORTSET_SPEED_100M BIT(2) -+#define MAC_SET 0x0210 -+#define MAX_FRAME_SIZE 1600 -+#define MAX_FRAME_SIZE_MASK GENMASK(10, 0) -+#define BIT_PAUSE_EN BIT(18) -+#define RX_COALESCE_SET 0x0340 -+#define RX_COALESCED_FRAME_OFFSET 24 -+#define RX_COALESCED_FRAMES 8 -+#define RX_COALESCED_TIMER 0x74 -+#define QLEN_SET 0x0344 -+#define RX_DEPTH_OFFSET 8 -+#define MAX_HW_FIFO_DEPTH 64 -+#define HW_TX_FIFO_DEPTH 12 -+#define HW_RX_FIFO_DEPTH (MAX_HW_FIFO_DEPTH - HW_TX_FIFO_DEPTH) -+#define FC_LEVEL 0x0348 -+#define BITS_FC_ACTIVE_THR_OFFSET 8 -+#define FC_DEACTIVE_THR_MASK GENMASK(5, 0) -+#define FC_ACTIVE_THR_MASK GENMASK(13, 8) -+#define BIT_FC_EN BIT(14) -+#define IQFRM_DES 0x0354 -+#define RX_FRAME_LEN_MASK GENMASK(11, 0) -+#define BITS_PAYLOAD_ERR_OFFSET 28 -+#define BITS_PAYLOAD_ERR_MASK 0x1 -+#define BITS_HEADER_ERR_OFFSET 29 -+#define BITS_HEADER_ERR_MASK 0x1 -+#define BITS_PAYLOAD_DONE_OFFSET 30 -+#define BITS_PAYLOAD_DONE_MASK 0x1 -+#define BITS_HEADER_DONE_OFFSET 31 -+#define BITS_HEADER_DONE_MASK 0x1 -+#define IQ_ADDR 0x0358 -+#define EQ_ADDR 0x0360 -+#define EQFRM_LEN 0x0364 -+#define ADDRQ_STAT 0x036C -+#define TX_CNT_INUSE_MASK GENMASK(5, 0) -+#define BIT_TX_READY BIT(24) -+#define BIT_RX_READY BIT(25) -+#define RX_COE_CTRL 0x0380 -+#define BIT_COE_IPV6_UDP_ZERO_DROP BIT(13) -+#define BIT_COE_PAYLOAD_DROP BIT(14) -+#define BIT_COE_IPHDR_DROP BIT(15) -+#define COE_ERR_DROP (BIT_COE_IPHDR_DROP | \ -+ BIT_COE_PAYLOAD_DROP | \ -+ BIT_COE_IPV6_UDP_ZERO_DROP) -+#define TSO_DBG_EN 0x03A4 -+#define BITS_TSO_DBG_EN BIT(31) -+#define TSO_DBG_STATE 0x03A8 -+#define TSO_DBG_ADDR 0x03AC -+#define TSO_DBG_TX_INFO 0x03B0 -+#define TSO_DBG_TX_ERR 0x03B4 -+/* global control register list */ -+#define GLB_HOSTMAC_L32 0x0000 -+#define GLB_HOSTMAC_H16 0x0004 -+#define GLB_SOFT_RESET 0x0008 -+#define SOFT_RESET_ALL BIT(0) -+#define GLB_FWCTRL 0x0010 -+#define FWCTRL_VLAN_ENABLE BIT(0) -+#define FWCTRL_FW2CPU_ENA BIT(5) -+#define FWCTRL_FWALL2CPU BIT(7) -+#define GLB_MACTCTRL 0x0014 -+#define MACTCTRL_UNI2CPU BIT(1) -+#define MACTCTRL_MULTI2CPU BIT(3) -+#define MACTCTRL_BROAD2CPU BIT(5) -+#define MACTCTRL_MACT_ENA BIT(7) -+#define GLB_IRQ_STAT 0x0030 -+#define GLB_IRQ_ENA 0x0034 -+#define IRQ_ENA_PORT0_MASK GENMASK(7, 0) -+#define IRQ_ENA_PORT0 BIT(18) -+#define IRQ_ENA_ALL BIT(19) -+#define GLB_IRQ_RAW 0x0038 -+#define IRQ_INT_RX_RDY BIT(0) -+#define IRQ_INT_TX_PER_PACKET BIT(1) -+#define IRQ_INT_TX_FIFO_EMPTY BIT(6) -+#define IRQ_INT_MULTI_RXRDY BIT(7) -+#define INT_TX_ERR BIT(8) -+#define DEF_INT_MASK (IRQ_INT_MULTI_RXRDY | \ -+ IRQ_INT_TX_PER_PACKET | \ -+ IRQ_INT_TX_FIFO_EMPTY) -+#define GLB_MAC_L32_BASE 0x0100 -+#define GLB_MAC_H16_BASE 0x0104 -+#define MACFLT_HI16_MASK GENMASK(15, 0) -+#define BIT_MACFLT_ENA BIT(17) -+#define BIT_MACFLT_FW2CPU BIT(21) -+#define glb_mac_h16(reg) (GLB_MAC_H16_BASE + ((reg) * 0x8)) -+#define glb_mac_l32(reg) (GLB_MAC_L32_BASE + ((reg) * 0x8)) -+#define MAX_MAC_FILTER_NUM 8 -+#define MAX_UNICAST_ADDRESSES 2 -+#define MAX_MULTICAST_ADDRESSES (MAX_MAC_FILTER_NUM - MAX_UNICAST_ADDRESSES) -+/* software tx and rx queue number, should be power of 2 */ -+#define TXQ_NUM 64 -+#define RXQ_NUM 128 -+#define FEMAC_POLL_WEIGHT 64 -+#define HW_CAP_TSO BIT(0) -+#define HW_CAP_RXCSUM BIT(1) -+#define has_tso_cap(hw_cap) ((hw_cap) & HW_CAP_TSO) -+#define has_rxcsum_cap(hw_cap) ((hw_cap) & HW_CAP_RXCSUM) -+#define RXBUF_ADDR_ALIGN_SIZE 64UL -+/* UDP header len is 2 word */ -+#define UDP_HDR_LEN 2 -+/* IPv6 header len is 10 word */ -+#define IPV6_HDR_LEN 10 -+#define WORD_TO_BYTE 4 -+ -+#define BIT_OFFSET_NFRAGS_NUM 11 -+#define BIT_OFFSET_PROT_HEADER_LEN 16 -+#define BIT_OFFSET_IP_HEADER_LEN 20 -+#define BIT_FLAG_SG BIT(26) -+#define BIT_FLAG_TXCSUM BIT(27) -+#define BIT_FLAG_UDP BIT(28) -+#define BIT_FLAG_IPV6 BIT(29) -+#define BIT_FLAG_VLAN BIT(30) -+#define BIT_FLAG_TSO BIT(31) -+ -+#define PHY_RESET_DELAYS_PROPERTY "goke,phy-reset-delays-us" -+ -+/* -+ * The threshold for activing tx flow ctrl. -+ * When the left amount of receive queue descriptors is below this threshold, -+ * hardware will send pause frame immediately. -+ * We advise this value is set between 1 and 10. -+ * Too bigger is not a good choice. -+ * This value must be smaller than tx flow ctrl deactive threshold. -+ */ -+#define TX_FLOW_CTRL_ACTIVE_THRESHOLD 3 -+/* -+ * The threshold for deactiving tx flow ctrl. -+ * When the left amount of receive queue descriptors is -+ * above or equal with this threshold, -+ * hardware will exit flow control state. -+ * We advise this value is set between 1 and 10. -+ * Too bigger is not a good choice. -+ * This value must be larger than tx flow ctrl active threshold. -+ */ -+#define TX_FLOW_CTRL_DEACTIVE_THRESHOLD 5 -+#define FC_ACTIVE_MIN 1 -+#define FC_ACTIVE_DEFAULT 3 -+#define FC_ACTIVE_MAX 31 -+#define FC_DEACTIVE_MIN 1 -+#define FC_DEACTIVE_DEFAULT 5 -+#define FC_DEACTIVE_MAX 31 -+ -+#ifdef CONFIG_FEPHY_OPT -+/* FEPHY register list */ -+ -+#define SYS_REG_ADDR 0x12028000 -+#define FEPHY_TRIM_CACHE 0x3022 -+#define FEPHY_TRIM_VALUE 0x20a1 -+#define LOW_TEM_VALUE 117 -+#define HIGH_TEM_VALUE 915 -+#define LINK_STATUS 0x4 -+#define IS_LINK 0X4 -+#define SPEED_STATUS 0x18 -+#define SPEED_100M 0x8 -+#define LINK_AN_SR 0x11 -+#define MISC_CTRL45 0x00B4 -+#define MISC_CTRL47 0x00BC -+#define MISC_CTRL48 0x00C0 -+#define TSENSOR_RESULT0 0x3ff -+#define TSENSOR_RESULT1 0x3ff0000 -+#define TSENSOR_RESULT2 0x3ff -+#define TSENSOR_RESULT3 0x3ff0000 -+#define TSENSOR_EN 0xc3200000 -+#define HIGH_TEMP 100 -+#define NORMAL_TEMP1 90 -+#define NORMAL_TEMP2 20 -+#define LOW_TEMP 10 -+#define TSENSOR_LIMIT 0xfffff -+#define regval_to_temp(val) ((val - 117) * 165 / 798 - 40) -+#define FEPHY_OPT_TIMER (30 * HZ) -+#endif -+ -+enum phy_reset_delays { -+ PRE_DELAY, -+ PULSE, -+ POST_DELAY, -+ DELAYS_NUM, -+}; -+ -+struct femac_queue { -+ struct sk_buff **skb; -+ dma_addr_t *dma_phys; -+ unsigned int num; -+ unsigned int head; -+ unsigned int tail; -+}; -+ -+struct femac_tx_desc_ring { -+ struct tx_desc *desc; -+ dma_addr_t dma_phys; -+}; -+ -+#define FEMAC_RX_REFILL_IN_IRQ -+ -+struct femac_priv { -+ void __iomem *port_base; -+ void __iomem *glb_base; -+ struct clk *clk; -+ struct reset_control *mac_rst; -+ struct reset_control *phy_rst; -+ u32 phy_reset_delays[DELAYS_NUM]; -+ u32 link_status; -+ -+#ifdef CONFIG_FEPHY_OPT -+ struct delayed_work watchdog_queue; -+#endif -+ struct device *dev; -+ struct net_device *ndev; -+ -+ u32 hw_cap; -+ struct femac_queue txq; -+ struct femac_queue rxq; -+#ifdef FEMAC_RX_REFILL_IN_IRQ -+ struct sk_buff_head rx_head; -+ spinlock_t rxlock; -+#endif -+ struct femac_tx_desc_ring tx_ring; -+ u32 tx_fifo_used_cnt; -+ struct napi_struct napi; -+ -+ /* 802.3x flow control */ -+ bool tx_pause_en; -+ u32 tx_pause_active_thresh; -+ u32 tx_pause_deactive_thresh; -+}; -+ -+struct frags_info { -+ /* Word(2*i+2) */ -+ u32 addr; -+ /* Word(2*i+3) */ -+ u32 size : 16; -+ u32 reserved : 16; -+}; -+ -+struct tx_desc { -+ /* Word0 */ -+ u32 total_len : 17; -+ u32 reserv : 15; -+ /* Word1 */ -+ u32 ipv6_id; -+ /* Word2 */ -+ u32 linear_addr; -+ /* Word3 */ -+ u32 linear_len : 16; -+ u32 reserv3 : 16; -+ /* MAX_SKB_FRAGS is 30 */ -+ struct frags_info frags[30]; -+}; -+ -+#endif ---- linux-4.9.37/drivers/net/ethernet/goke/femac/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,5 @@ -+# -+# Makefile for the Fast Ethernet network device drivers. -+# -+ -+obj-$(CONFIG_GOKE_FEMAC) += femac.o phy_fix.o util.o ---- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_fix.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_fix.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,83 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include "phy_fix.h" -+ -+static const u32 phy_v2_fix_param[] = { -+#include "phy_v2.h" -+}; -+ -+static const u32 phy_v1_fix_param[] = { -+#include "phy_v1.h" -+}; -+ -+static int phy_expanded_write_bulk(struct phy_device *phy_dev, -+ const u32 reg_and_val[], int count) -+{ -+ int i, v; -+ u32 reg_addr; -+ u16 val; -+ -+ v = phy_read(phy_dev, MII_BMCR); -+ v = (u32)v | BMCR_PDOWN; -+ phy_write(phy_dev, MII_BMCR, v); -+ -+ for (i = 0; i < count; i += 2) { /* Process 2 data at a time. */ -+ reg_addr = reg_and_val[i]; -+ val = (u16)reg_and_val[i + 1]; -+ phy_write(phy_dev, MII_EXPMA, reg_addr); -+ phy_write(phy_dev, MII_EXPMD, val); -+ } -+ -+ v = phy_read(phy_dev, MII_BMCR); -+ v = (u32)v & (~BMCR_PDOWN); -+ phy_write(phy_dev, MII_BMCR, v); -+ -+ return 0; -+} -+ -+static int goke_fephy_v272_fix(struct phy_device *phy_dev) -+{ -+ int count; -+ -+ count = ARRAY_SIZE(phy_v2_fix_param); -+ if (count % 2) /* must be an even number, mod 2 */ -+ pr_warn("internal FEPHY fix register count is not right.\n"); -+ phy_expanded_write_bulk(phy_dev, phy_v2_fix_param, count); -+ -+ return 0; -+} -+ -+static int goke_fephy_v115_fix(struct phy_device *phy_dev) -+{ -+ int count; -+ -+ count = ARRAY_SIZE(phy_v1_fix_param); -+ if (count % 2) /* must be an even number, mod 2 */ -+ pr_warn("internal FEPHY fix register count is not right.\n"); -+ phy_expanded_write_bulk(phy_dev, phy_v1_fix_param, count); -+ -+ return 0; -+} -+ -+void phy_register_fixups(void) -+{ -+ phy_register_fixup_for_uid(GOKE_PHY_ID_V272, -+ GOKE_PHY_MASK, -+ goke_fephy_v272_fix); -+ -+ phy_register_fixup_for_uid(GOKE_PHY_ID_V115, -+ GOKE_PHY_MASK, -+ goke_fephy_v115_fix); -+} -+ -+void phy_unregister_fixups(void) -+{ -+ phy_unregister_fixup_for_uid(GOKE_PHY_ID_V272, -+ GOKE_PHY_MASK); -+ -+ phy_unregister_fixup_for_uid(GOKE_PHY_ID_V115, -+ GOKE_PHY_MASK); -+} ---- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_fix.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_fix.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,18 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __ETH_PHY_FIX_H__ -+#define __ETH_PHY_FIX_H__ -+ -+#define GOKE_PHY_ID_V272 0x20669901 -+#define GOKE_PHY_ID_V115 0x20669903 -+#define GOKE_PHY_MASK 0xffffffff -+ -+#define MII_EXPMD 0x1d -+#define MII_EXPMA 0x1e -+ -+void phy_register_fixups(void); -+void phy_unregister_fixups(void); -+ -+#endif ---- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_v1.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_v1.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,188 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __ETH_PHY_S28V115_2C02_H__ -+#define __ETH_PHY__S28V115_2C02_H__ -+ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, -+ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, -+ 0x3402, 0x2C, 0x3403, 0x02, 0x3404, 0xFD, -+ 0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0xF6, -+ 0x3408, 0x36, 0x3409, 0x18, 0x340A, 0x26, -+ 0x340B, 0x05, 0x340C, 0xC6, 0x340D, 0x01, -+ 0x340E, 0xF7, 0x340F, 0x36, 0x3410, 0x18, -+ 0x3411, 0xCC, 0x3412, 0x35, 0x3413, 0x9F, -+ 0x3414, 0x1A, 0x3415, 0xB3, 0x3416, 0x00, -+ 0x3417, 0xD2, 0x3418, 0x27, 0x3419, 0x09, -+ 0x341A, 0xFD, 0x341B, 0x00, 0x341C, 0xD2, -+ 0x341D, 0x7F, 0x341E, 0x01, 0x341F, 0xBF, -+ 0x3420, 0x7F, 0x3421, 0x01, 0x3422, 0xB1, -+ 0x3423, 0x39, 0x3424, 0x3C, 0x3425, 0x3C, -+ 0x3426, 0x30, 0x3427, 0xF6, 0x3428, 0x30, -+ 0x3429, 0x55, 0x342A, 0xC0, 0x342B, 0x07, -+ 0x342C, 0x18, 0x342D, 0xFE, 0x342E, 0x30, -+ 0x342F, 0x4C, 0x3430, 0x18, 0x3431, 0x3A, -+ 0x3432, 0x18, 0x3433, 0xE6, 0x3434, 0x00, -+ 0x3435, 0x5C, 0x3436, 0xE7, 0x3437, 0x01, -+ 0x3438, 0xC1, 0x3439, 0x07, 0x343A, 0x23, -+ 0x343B, 0x04, 0x343C, 0xC6, 0x343D, 0x07, -+ 0x343E, 0xE7, 0x343F, 0x01, 0x3440, 0x58, -+ 0x3441, 0x58, 0x3442, 0x58, 0x3443, 0x58, -+ 0x3444, 0x58, 0x3445, 0xE7, 0x3446, 0x00, -+ 0x3447, 0xF6, 0x3448, 0x20, 0x3449, 0x04, -+ 0x344A, 0xC4, 0x344B, 0x1F, 0x344C, 0xEA, -+ 0x344D, 0x00, 0x344E, 0xF7, 0x344F, 0x20, -+ 0x3450, 0x04, 0x3451, 0x38, 0x3452, 0x38, -+ 0x3453, 0x39, 0x3454, 0x3C, 0x3455, 0x37, -+ 0x3456, 0x36, 0x3457, 0x30, 0x3458, 0x1A, -+ 0x3459, 0xEE, 0x345A, 0x00, 0x345B, 0x18, -+ 0x345C, 0xE6, 0x345D, 0x00, 0x345E, 0x26, -+ 0x345F, 0x1C, 0x3460, 0xF6, 0x3461, 0x00, -+ 0x3462, 0x5C, 0x3463, 0xC5, 0x3464, 0x04, -+ 0x3465, 0x27, 0x3466, 0x06, 0x3467, 0xCC, -+ 0x3468, 0x36, 0x3469, 0x12, 0x346A, 0xBD, -+ 0x346B, 0xF0, 0x346C, 0xA5, 0x346D, 0xF6, -+ 0x346E, 0x00, 0x346F, 0x47, 0x3470, 0xC4, -+ 0x3471, 0xF3, 0x3472, 0xF7, 0x3473, 0x00, -+ 0x3474, 0x47, 0x3475, 0xC6, 0x3476, 0x01, -+ 0x3477, 0x1A, 0x3478, 0xEE, 0x3479, 0x00, -+ 0x347A, 0x20, 0x347B, 0x10, 0x347C, 0x5A, -+ 0x347D, 0x26, 0x347E, 0x14, 0x347F, 0xF6, -+ 0x3480, 0x00, 0x3481, 0x46, 0x3482, 0x4F, -+ 0x3483, 0xC4, 0x3484, 0x0C, 0x3485, 0x83, -+ 0x3486, 0x00, 0x3487, 0x08, 0x3488, 0x26, -+ 0x3489, 0x05, 0x348A, 0xC6, 0x348B, 0x02, -+ 0x348C, 0x18, 0x348D, 0xE7, 0x348E, 0x00, -+ 0x348F, 0x5F, 0x3490, 0x38, 0x3491, 0x38, -+ 0x3492, 0x39, 0x3493, 0xF6, 0x3494, 0x00, -+ 0x3495, 0x5C, 0x3496, 0xC5, 0x3497, 0x04, -+ 0x3498, 0x27, 0x3499, 0x06, 0x349A, 0xCC, -+ 0x349B, 0x36, 0x349C, 0x08, 0x349D, 0xBD, -+ 0x349E, 0xF0, 0x349F, 0xA5, 0x34A0, 0xF6, -+ 0x34A1, 0x00, 0x34A2, 0x47, 0x34A3, 0xC4, -+ 0x34A4, 0xF3, 0x34A5, 0xCA, 0x34A6, 0x08, -+ 0x34A7, 0xF7, 0x34A8, 0x00, 0x34A9, 0x47, -+ 0x34AA, 0x18, 0x34AB, 0xFE, 0x34AC, 0x00, -+ 0x34AD, 0xB6, 0x34AE, 0x18, 0x34AF, 0xAD, -+ 0x34B0, 0x00, 0x34B1, 0xBD, 0x34B2, 0x34, -+ 0x34B3, 0x24, 0x34B4, 0xF6, 0x34B5, 0x1E, -+ 0x34B6, 0x05, 0x34B7, 0xC5, 0x34B8, 0x02, -+ 0x34B9, 0x27, 0x34BA, 0x0A, 0x34BB, 0xF6, -+ 0x34BC, 0x1E, 0x34BD, 0x07, 0x34BE, 0xC5, -+ 0x34BF, 0x02, 0x34C0, 0x27, 0x34C1, 0x03, -+ 0x34C2, 0xBD, 0x34C3, 0xC0, 0x34C4, 0x33, -+ 0x34C5, 0xF6, 0x34C6, 0x31, 0x34C7, 0x1F, -+ 0x34C8, 0x37, 0x34C9, 0xC6, 0x34CA, 0x52, -+ 0x34CB, 0xBD, 0x34CC, 0xDC, 0x34CD, 0x53, -+ 0x34CE, 0x31, 0x34CF, 0xF6, 0x34D0, 0x00, -+ 0x34D1, 0x41, 0x34D2, 0xC5, 0x34D3, 0x10, -+ 0x34D4, 0x26, 0x34D5, 0x04, 0x34D6, 0x13, -+ 0x34D7, 0x23, 0x34D8, 0x40, 0x34D9, 0x0D, -+ 0x34DA, 0xBD, 0x34DB, 0x93, 0x34DC, 0xCE, -+ 0x34DD, 0x1A, 0x34DE, 0xEE, 0x34DF, 0x00, -+ 0x34E0, 0x18, 0x34E1, 0x6F, 0x34E2, 0x00, -+ 0x34E3, 0xC6, 0x34E4, 0x04, 0x34E5, 0x20, -+ 0x34E6, 0xA9, 0x34E7, 0x1A, 0x34E8, 0xEE, -+ 0x34E9, 0x00, 0x34EA, 0x18, 0x34EB, 0x6F, -+ 0x34EC, 0x00, 0x34ED, 0xC6, 0x34EE, 0x01, -+ 0x34EF, 0x20, 0x34F0, 0x9F, 0x34F1, 0x3C, -+ 0x34F2, 0x37, 0x34F3, 0x36, 0x34F4, 0x30, -+ 0x34F5, 0x1A, 0x34F6, 0xEE, 0x34F7, 0x00, -+ 0x34F8, 0x18, 0x34F9, 0xE6, 0x34FA, 0x00, -+ 0x34FB, 0x26, 0x34FC, 0x49, 0x34FD, 0xF6, -+ 0x34FE, 0x00, 0x34FF, 0x5C, 0x3500, 0xC5, -+ 0x3501, 0x04, 0x3502, 0x27, 0x3503, 0x06, -+ 0x3504, 0xCC, 0x3505, 0x35, 0x3506, 0xFC, -+ 0x3507, 0xBD, 0x3508, 0xF0, 0x3509, 0xA5, -+ 0x350A, 0xC6, 0x350B, 0x52, 0x350C, 0xBD, -+ 0x350D, 0xDC, 0x350E, 0xF3, 0x350F, 0x5D, -+ 0x3510, 0x27, 0x3511, 0x03, 0x3512, 0xBD, -+ 0x3513, 0xC0, 0x3514, 0x22, 0x3515, 0xF6, -+ 0x3516, 0x00, 0x3517, 0x46, 0x3518, 0xC5, -+ 0x3519, 0x0C, 0x351A, 0x26, 0x351B, 0x0A, -+ 0x351C, 0x1A, 0x351D, 0xEE, 0x351E, 0x00, -+ 0x351F, 0x18, 0x3520, 0x6F, 0x3521, 0x00, -+ 0x3522, 0xC6, 0x3523, 0x07, 0x3524, 0x20, -+ 0x3525, 0x1D, 0x3526, 0xFC, 0x3527, 0x30, -+ 0x3528, 0x0C, 0x3529, 0xBD, 0x352A, 0x93, -+ 0x352B, 0x19, 0x352C, 0xBD, 0x352D, 0x9F, -+ 0x352E, 0x0B, 0x352F, 0xC6, 0x3530, 0x02, -+ 0x3531, 0x37, 0x3532, 0xC6, 0x3533, 0x51, -+ 0x3534, 0xBD, 0x3535, 0xDC, 0x3536, 0x53, -+ 0x3537, 0x31, 0x3538, 0x7F, 0x3539, 0x02, -+ 0x353A, 0x07, 0x353B, 0xC6, 0x353C, 0x02, -+ 0x353D, 0x1A, 0x353E, 0xEE, 0x353F, 0x00, -+ 0x3540, 0x18, 0x3541, 0xE7, 0x3542, 0x00, -+ 0x3543, 0x38, 0x3544, 0x38, 0x3545, 0x39, -+ 0x3546, 0xC6, 0x3547, 0x52, 0x3548, 0xBD, -+ 0x3549, 0xDC, 0x354A, 0xF3, 0x354B, 0x5D, -+ 0x354C, 0x27, 0x354D, 0x03, 0x354E, 0xBD, -+ 0x354F, 0xC0, 0x3550, 0x22, 0x3551, 0xF6, -+ 0x3552, 0x00, 0x3553, 0x46, 0x3554, 0xC5, -+ 0x3555, 0x0C, 0x3556, 0x26, 0x3557, 0x0A, -+ 0x3558, 0x1A, 0x3559, 0xEE, 0x355A, 0x00, -+ 0x355B, 0x18, 0x355C, 0x6F, 0x355D, 0x00, -+ 0x355E, 0xC6, 0x355F, 0x07, 0x3560, 0x20, -+ 0x3561, 0xE1, 0x3562, 0xC6, 0x3563, 0x51, -+ 0x3564, 0xBD, 0x3565, 0xDC, 0x3566, 0xF3, -+ 0x3567, 0x5D, 0x3568, 0x26, 0x3569, 0x04, -+ 0x356A, 0xC6, 0x356B, 0x02, 0x356C, 0x20, -+ 0x356D, 0xD5, 0x356E, 0xF6, 0x356F, 0x00, -+ 0x3570, 0x41, 0x3571, 0xC5, 0x3572, 0x10, -+ 0x3573, 0x26, 0x3574, 0x20, 0x3575, 0xF6, -+ 0x3576, 0x02, 0x3577, 0x07, 0x3578, 0xC1, -+ 0x3579, 0x02, 0x357A, 0x24, 0x357B, 0x19, -+ 0x357C, 0x18, 0x357D, 0xFE, 0x357E, 0x02, -+ 0x357F, 0x08, 0x3580, 0x18, 0x3581, 0xAD, -+ 0x3582, 0x00, 0x3583, 0xF6, 0x3584, 0x02, -+ 0x3585, 0x06, 0x3586, 0x27, 0x3587, 0x0D, -+ 0x3588, 0xC6, 0x3589, 0x02, 0x358A, 0x37, -+ 0x358B, 0xC6, 0x358C, 0x51, 0x358D, 0xBD, -+ 0x358E, 0xDC, 0x358F, 0x53, 0x3590, 0x31, -+ 0x3591, 0xC6, 0x3592, 0x02, 0x3593, 0x20, -+ 0x3594, 0xAE, 0x3595, 0x1A, 0x3596, 0xEE, -+ 0x3597, 0x00, 0x3598, 0x18, 0x3599, 0x6F, -+ 0x359A, 0x00, 0x359B, 0xC6, 0x359C, 0x03, -+ 0x359D, 0x20, 0x359E, 0xA4, 0x359F, 0xF6, -+ 0x35A0, 0x01, 0x35A1, 0xBF, 0x35A2, 0xC1, -+ 0x35A3, 0x08, 0x35A4, 0x24, 0x35A5, 0x55, -+ 0x35A6, 0xBD, 0x35A7, 0xF6, 0x35A8, 0xD3, -+ 0x35A9, 0x35, 0x35AA, 0xBA, 0x35AB, 0x35, -+ 0x35AC, 0xC2, 0x35AD, 0x35, 0x35AE, 0xCA, -+ 0x35AF, 0x35, 0x35B0, 0xD2, 0x35B1, 0x35, -+ 0x35B2, 0xDA, 0x35B3, 0x35, 0x35B4, 0xE2, -+ 0x35B5, 0x35, 0x35B6, 0xEA, 0x35B7, 0x35, -+ 0x35B8, 0xF2, 0x35B9, 0x39, 0x35BA, 0xCC, -+ 0x35BB, 0x01, 0x35BC, 0xB1, 0x35BD, 0xBD, -+ 0x35BE, 0x34, 0x35BF, 0x54, 0x35C0, 0x20, -+ 0x35C1, 0x36, 0x35C2, 0xCC, 0x35C3, 0x01, -+ 0x35C4, 0xB1, 0x35C5, 0xBD, 0x35C6, 0xC1, -+ 0x35C7, 0x52, 0x35C8, 0x20, 0x35C9, 0x2E, -+ 0x35CA, 0xCC, 0x35CB, 0x01, 0x35CC, 0xB1, -+ 0x35CD, 0xBD, 0x35CE, 0x34, 0x35CF, 0xF1, -+ 0x35D0, 0x20, 0x35D1, 0x26, 0x35D2, 0xCC, -+ 0x35D3, 0x01, 0x35D4, 0xB1, 0x35D5, 0xBD, -+ 0x35D6, 0xC3, 0x35D7, 0x9A, 0x35D8, 0x20, -+ 0x35D9, 0x1E, 0x35DA, 0xCC, 0x35DB, 0x01, -+ 0x35DC, 0xB1, 0x35DD, 0xBD, 0x35DE, 0xC4, -+ 0x35DF, 0x39, 0x35E0, 0x20, 0x35E1, 0x16, -+ 0x35E2, 0xCC, 0x35E3, 0x01, 0x35E4, 0xB1, -+ 0x35E5, 0xBD, 0x35E6, 0xC5, 0x35E7, 0x0B, -+ 0x35E8, 0x20, 0x35E9, 0x0E, 0x35EA, 0xCC, -+ 0x35EB, 0x01, 0x35EC, 0xB1, 0x35ED, 0xBD, -+ 0x35EE, 0xC6, 0x35EF, 0x3A, 0x35F0, 0x20, -+ 0x35F1, 0x06, 0x35F2, 0xCC, 0x35F3, 0x01, -+ 0x35F4, 0xB1, 0x35F5, 0xBD, 0x35F6, 0xC7, -+ 0x35F7, 0xC2, 0x35F8, 0xF7, 0x35F9, 0x01, -+ 0x35FA, 0xBF, 0x35FB, 0x39, 0x35FC, 0x43, -+ 0x35FD, 0x3A, 0x35FE, 0x41, 0x35FF, 0x44, -+ 0x3600, 0x54, 0x3601, 0x5F, 0x3602, 0x41, -+ 0x3603, 0x54, 0x3604, 0x4E, 0x3605, 0x0A, -+ 0x3606, 0x0D, 0x3607, 0x00, 0x3608, 0x43, -+ 0x3609, 0x3A, 0x360A, 0x45, 0x360B, 0x6E, -+ 0x360C, 0x5F, 0x360D, 0x53, 0x360E, 0x74, -+ 0x360F, 0x0A, 0x3610, 0x0D, 0x3611, 0x00, -+ 0x3612, 0x43, 0x3613, 0x3A, 0x3614, 0x49, -+ 0x3615, 0x0A, 0x3616, 0x0D, 0x3617, 0x00, -+ 0x3618, 0x00, 0x3400, 0x01, 0x33f8, 0x01 -+#endif -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/net/ethernet/goke/femac/phy_v2.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/phy_v2.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __ETH_PHY_V272_2723_H__ -+#define __ETH_PHY_V272_2723_H__ -+ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, -+ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, -+ 0x3402, 0x27, 0x3403, 0x23, 0x3404, 0xFD, -+ 0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0x20, -+ 0x3408, 0x00, 0x3409, 0x3C, 0x340A, 0x3C, -+ 0x340B, 0x30, 0x340C, 0xF6, 0x340D, 0x00, -+ 0x340E, 0x4A, 0x340F, 0xC4, 0x3410, 0x7F, -+ 0x3411, 0xE7, 0x3412, 0x01, 0x3413, 0xF6, -+ 0x3414, 0x01, 0x3415, 0xBE, 0x3416, 0xC1, -+ 0x3417, 0x02, 0x3418, 0x27, 0x3419, 0x0E, -+ 0x341A, 0xE6, 0x341B, 0x01, 0x341C, 0xC1, -+ 0x341D, 0x14, 0x341E, 0x27, 0x341F, 0x08, -+ 0x3420, 0xC1, 0x3421, 0x18, 0x3422, 0x25, -+ 0x3423, 0x09, 0x3424, 0xC1, 0x3425, 0x1B, -+ 0x3426, 0x22, 0x3427, 0x05, 0x3428, 0xC6, -+ 0x3429, 0x5C, 0x342A, 0xF7, 0x342B, 0x20, -+ 0x342C, 0xA1, 0x342D, 0xF6, 0x342E, 0x01, -+ 0x342F, 0xBF, 0x3430, 0xC1, 0x3431, 0x01, -+ 0x3432, 0x26, 0x3433, 0x29, 0x3434, 0xF6, -+ 0x3435, 0x30, 0x3436, 0x55, 0x3437, 0xC0, -+ 0x3438, 0x05, 0x3439, 0xE7, 0x343A, 0x01, -+ 0x343B, 0xC1, 0x343C, 0x13, 0x343D, 0x23, -+ 0x343E, 0x04, 0x343F, 0xC6, 0x3440, 0x13, -+ 0x3441, 0xE7, 0x3442, 0x01, 0x3443, 0x18, -+ 0x3444, 0xFE, 0x3445, 0x30, 0x3446, 0x4C, -+ 0x3447, 0x18, 0x3448, 0x3A, 0x3449, 0x18, -+ 0x344A, 0xE6, 0x344B, 0x00, 0x344C, 0x58, -+ 0x344D, 0x58, 0x344E, 0x58, 0x344F, 0x58, -+ 0x3450, 0x58, 0x3451, 0xE7, 0x3452, 0x00, -+ 0x3453, 0xF6, 0x3454, 0x20, 0x3455, 0x04, -+ 0x3456, 0xC4, 0x3457, 0x1F, 0x3458, 0xEA, -+ 0x3459, 0x00, 0x345A, 0xF7, 0x345B, 0x20, -+ 0x345C, 0x04, 0x345D, 0x38, 0x345E, 0x38, -+ 0x345F, 0x39, 0x3400, 0x01, 0x33f8, 0x01 -+#endif -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/net/ethernet/goke/femac/util.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/util.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,292 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+ -+#include "util.h" -+ -+static void femac_do_udp_checksum(struct sk_buff *skb) -+{ -+ int offset; -+ __wsum csum; -+ __sum16 udp_csum; -+ -+ offset = skb_checksum_start_offset(skb); -+ WARN_ON(offset >= skb_headlen(skb)); -+ csum = skb_checksum(skb, offset, skb->len - offset, 0); -+ -+ offset += skb->csum_offset; -+ WARN_ON(offset + sizeof(__sum16) > skb_headlen(skb)); -+ -+ udp_csum = csum_fold(csum); -+ if (udp_csum == 0) -+ udp_csum = CSUM_MANGLED_0; -+ -+ *(__sum16 *)(skb->data + offset) = udp_csum; -+ -+ skb->ip_summed = CHECKSUM_NONE; -+} -+ -+static __be16 femac_get_l3_proto(struct sk_buff *skb) -+{ -+ __be16 l3_proto; -+ -+ l3_proto = skb->protocol; -+ if (skb->protocol == htons(ETH_P_8021Q)) -+ l3_proto = vlan_get_protocol(skb); -+ -+ return l3_proto; -+} -+ -+static inline bool femac_skb_is_ipv6(struct sk_buff *skb) -+{ -+ return (femac_get_l3_proto(skb) == htons(ETH_P_IPV6)); -+} -+ -+static int femac_check_hw_capability_for_ipv6(struct sk_buff *skb) -+{ -+ unsigned int l4_proto; -+ -+ l4_proto = ipv6_hdr(skb)->nexthdr; -+ if ((l4_proto != IPPROTO_TCP) && (l4_proto != IPPROTO_UDP)) { -+ /* -+ * when IPv6 next header is not tcp or udp, -+ * it means that IPv6 next header is extension header. -+ * Hardware can't deal with this case, -+ * so do checksumming by software or do GSO by software. -+ */ -+ if (skb_is_gso(skb)) { -+ return -ENOTSUPP; -+ } -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL && -+ skb_checksum_help(skb)) { -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+int femac_check_hw_capability(struct sk_buff *skb) -+{ -+ /* -+ * if tcp_mtu_probe() use (2 * tp->mss_cache) as probe_size, -+ * the linear data length will be larger than 2048, -+ * the MAC can't handle it, so let the software do it. -+ */ -+ if (skb_is_gso(skb) && (skb_headlen(skb) > 2048)) { /* max is 2048 */ -+ return -ENOTSUPP; -+ } -+ -+ if (femac_skb_is_ipv6(skb)) { -+ return femac_check_hw_capability_for_ipv6(skb); -+ } -+ -+ return 0; -+} -+ -+static unsigned int femac_get_pkt_info_gso(struct sk_buff *skb, -+ bool txcsum, unsigned int max_mss, unsigned int l4_proto) -+{ -+ u32 pkt_info = 0; -+ bool do_txcsum = txcsum; -+ -+ /* -+ * Although netcard support UFO feature, it can't deal with -+ * UDP header checksum. -+ * So the driver will do UDP header checksum and netcard will just -+ * fragment the packet. -+ */ -+ if (do_txcsum && skb_is_gso(skb) && (l4_proto == IPPROTO_UDP)) { -+ femac_do_udp_checksum(skb); -+ do_txcsum = false; -+ } -+ -+ if (do_txcsum) -+ pkt_info |= BIT_FLAG_TXCSUM; -+ -+ if (skb_is_gso(skb)) { -+ pkt_info |= (BIT_FLAG_SG | BIT_FLAG_TSO); -+ } else if (skb_shinfo(skb)->nr_frags) { -+ pkt_info |= BIT_FLAG_SG; -+ } -+ -+ pkt_info |= (skb_shinfo(skb)->nr_frags << BIT_OFFSET_NFRAGS_NUM); -+ pkt_info |= (skb_is_gso(skb) ? ((skb_shinfo(skb)->gso_size > max_mss) ? max_mss : skb_shinfo(skb)->gso_size) : -+ (skb->len + ETH_FCS_LEN)); -+ return pkt_info; -+} -+ -+u32 femac_get_pkt_info(struct sk_buff *skb) -+{ -+ __be16 l3_proto; -+ unsigned int l4_proto = IPPROTO_MAX; -+ bool do_txcsum = false; -+ int max_data_len = skb->len - ETH_HLEN; -+ unsigned int max_mss = ETH_DATA_LEN; -+ u32 pkt_info = 0; -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) -+ do_txcsum = true; -+ -+ l3_proto = skb->protocol; -+ if (skb->protocol == htons(ETH_P_8021Q)) { -+ l3_proto = vlan_get_protocol(skb); -+ max_data_len -= VLAN_HLEN; -+ pkt_info |= BIT_FLAG_VLAN; -+ } -+ -+ if (l3_proto == htons(ETH_P_IP)) { -+ struct iphdr *iph = ip_hdr(skb); -+ -+ if ((max_data_len >= GSO_MAX_SIZE) && -+ (ntohs(iph->tot_len) <= (iph->ihl << 2))) /* trans 2 bytes */ -+ iph->tot_len = htons(GSO_MAX_SIZE - 1); -+ -+ max_mss -= iph->ihl * WORD_TO_BYTE; -+ pkt_info |= (iph->ihl << BIT_OFFSET_IP_HEADER_LEN); -+ l4_proto = iph->protocol; -+ } else if (l3_proto == htons(ETH_P_IPV6)) { -+ max_mss -= IPV6_HDR_LEN * WORD_TO_BYTE; -+ pkt_info |= BIT_FLAG_IPV6; -+ pkt_info |= (IPV6_HDR_LEN << BIT_OFFSET_IP_HEADER_LEN); -+ l4_proto = ipv6_hdr(skb)->nexthdr; -+ } else { -+ do_txcsum = false; -+ } -+ -+ if (l4_proto == IPPROTO_TCP) { -+ max_mss -= tcp_hdr(skb)->doff * WORD_TO_BYTE; -+ pkt_info |= (tcp_hdr(skb)->doff << BIT_OFFSET_PROT_HEADER_LEN); -+ } else if (l4_proto == IPPROTO_UDP) { -+ if (l3_proto == htons(ETH_P_IPV6)) -+ max_mss -= sizeof(struct frag_hdr); -+ pkt_info |= (BIT_FLAG_UDP | -+ (UDP_HDR_LEN << BIT_OFFSET_PROT_HEADER_LEN)); -+ } else { -+ do_txcsum = false; -+ } -+ -+ pkt_info |= femac_get_pkt_info_gso(skb, do_txcsum, max_mss, l4_proto); -+ -+ return pkt_info; -+} -+ -+void femac_sleep_us(u32 time_us) -+{ -+ u32 time_ms; -+ -+ if (!time_us) { -+ return; -+ } -+ -+ time_ms = DIV_ROUND_UP(time_us, 1000); /* add 1000us, round up */ -+ if (time_ms < 20) { /* less than 20 ms */ -+ usleep_range(time_us, time_us + 500); /* add maximum 500us */ -+ } else { -+ msleep(time_ms); -+ } -+} -+ -+void femac_set_flow_ctrl(const struct femac_priv *priv) -+{ -+ unsigned int pause_en; -+ unsigned int tx_flow_ctrl; -+ -+ tx_flow_ctrl = readl(priv->port_base + FC_LEVEL); -+ tx_flow_ctrl &= ~FC_DEACTIVE_THR_MASK; -+ tx_flow_ctrl |= priv->tx_pause_deactive_thresh; -+ tx_flow_ctrl &= ~FC_ACTIVE_THR_MASK; -+ tx_flow_ctrl |= priv->tx_pause_active_thresh << BITS_FC_ACTIVE_THR_OFFSET; -+ -+ pause_en = readl(priv->port_base + MAC_SET); -+ -+ if (priv->tx_pause_en) { -+ tx_flow_ctrl |= BIT_FC_EN; -+ pause_en |= BIT_PAUSE_EN; -+ } else { -+ tx_flow_ctrl &= ~BIT_FC_EN; -+ pause_en &= ~BIT_PAUSE_EN; -+ } -+ -+ writel(tx_flow_ctrl, priv->port_base + FC_LEVEL); -+ -+ writel(pause_en, priv->port_base + MAC_SET); -+} -+ -+void femac_get_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ -+ pause->autoneg = dev->phydev->autoneg; -+ pause->rx_pause = 1; -+ if (priv->tx_pause_en) -+ pause->tx_pause = 1; -+} -+ -+int femac_set_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ struct phy_device *phy = dev->phydev; -+ int ret = 0; -+ -+ if (pause->rx_pause == 0) { -+ return -EINVAL; -+ } -+ -+ if (pause->tx_pause != priv->tx_pause_en) { -+ priv->tx_pause_en = pause->tx_pause; -+ femac_set_flow_ctrl(priv); -+ } -+ -+ if (phy->autoneg) { -+ if (netif_running(dev)) { -+ struct ethtool_cmd cmd; -+ /* auto-negotiation automatically restarted */ -+ cmd.cmd = ETHTOOL_NWAY_RST; -+ cmd.supported = phy->supported; -+ cmd.advertising = phy->advertising; -+ cmd.autoneg = phy->autoneg; -+ cmd.speed = phy->speed; -+ cmd.duplex = phy->duplex; -+ cmd.phy_address = phy->mdio.addr; -+ ret = phy_ethtool_sset(phy, &cmd); -+ } -+ } -+ -+ return ret; -+} -+ -+void femac_enable_rxcsum_drop(const struct femac_priv *priv, -+ bool drop) -+{ -+ unsigned int val; -+ -+ val = readl(priv->port_base + RX_COE_CTRL); -+ val &= ~COE_ERR_DROP; -+ if (drop) -+ val |= (BIT_COE_IPHDR_DROP | BIT_COE_IPV6_UDP_ZERO_DROP); -+ writel(val, priv->port_base + RX_COE_CTRL); -+} -+ -+int femac_set_features(struct net_device *dev, netdev_features_t features) -+{ -+ struct femac_priv *priv = netdev_priv(dev); -+ netdev_features_t changed = dev->features ^ features; -+ -+ if (changed & NETIF_F_RXCSUM) { -+ if (features & NETIF_F_RXCSUM) { -+ femac_enable_rxcsum_drop(priv, true); -+ } else { -+ femac_enable_rxcsum_drop(priv, false); -+ } -+ } -+ -+ return 0; -+} -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/net/ethernet/goke/femac/util.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/femac/util.h 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __ETH_UTIL_H__ -+#define __ETH_UTIL_H__ -+ -+#include "femac.h" -+ -+int femac_check_hw_capability(struct sk_buff *skb); -+u32 femac_get_pkt_info(struct sk_buff *skb); -+void femac_sleep_us(u32 time_us); -+void femac_set_flow_ctrl(const struct femac_priv *priv); -+void femac_get_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause); -+int femac_set_pauseparam(struct net_device *dev, -+ struct ethtool_pauseparam *pause); -+void femac_enable_rxcsum_drop(const struct femac_priv *priv, -+ bool drop); -+int femac_set_features(struct net_device *dev, netdev_features_t features); -+ -+#endif -\ В конце файла нет новой строки ---- linux-4.9.37/drivers/net/ethernet/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,32 @@ -+# -+# Goke device configuration -+# -+ -+config NET_VENDOR_GOKE -+ bool "Goke devices" -+ default y -+ depends on (OF || ACPI) && HAS_DMA -+ depends on ARM || ARM64 || COMPILE_TEST -+ ---help--- -+ If you have a network (Ethernet) card belonging to this class, say Y. -+ -+ Note that the answer to this question doesn't directly affect the -+ kernel: saying N will just cause the configurator to skip all -+ the questions about Goke devices. If you say Y, you will be asked -+ for your specific card in the following questions. -+ -+if NET_VENDOR_GOKE -+ -+config GOKE_FEMAC -+ tristate "Goke Fast Ethernet MAC device support" -+ depends on HAS_IOMEM -+ select PHYLIB -+ select RESET_CONTROLLER -+ help -+ This selects the Goke Fast Ethernet MAC device(FEMAC). -+ The FEMAC receives and transmits data over Ethernet -+ ports at 10/100 Mbps in full-duplex or half-duplex mode. -+ The FEMAC exchanges data with the CPU, and supports -+ the energy efficient Ethernet (EEE). -+ -+endif # NET_VENDOR_GOKE ---- linux-4.9.37/drivers/net/ethernet/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/goke/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,5 @@ -+# -+# Makefile for the network device drivers. -+# -+ -+obj-$(CONFIG_GOKE_FEMAC) += femac/ ---- linux-4.9.37/drivers/net/ethernet/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -75,6 +75,7 @@ - source "drivers/net/ethernet/freescale/Kconfig" - source "drivers/net/ethernet/fujitsu/Kconfig" - source "drivers/net/ethernet/hisilicon/Kconfig" -+source "drivers/net/ethernet/goke/Kconfig" - source "drivers/net/ethernet/hp/Kconfig" - source "drivers/net/ethernet/ibm/Kconfig" - source "drivers/net/ethernet/intel/Kconfig" ---- linux-4.9.37/drivers/net/ethernet/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/net/ethernet/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -38,6 +38,7 @@ - obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/ - obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/ - obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/ -+obj-$(CONFIG_NET_VENDOR_GOKE) += goke/ - obj-$(CONFIG_NET_VENDOR_HP) += hp/ - obj-$(CONFIG_NET_VENDOR_IBM) += ibm/ - obj-$(CONFIG_NET_VENDOR_INTEL) += intel/ ---- linux-4.9.37/drivers/net/phy/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/net/phy/Kconfig 2021-06-07 13:01:33.000000000 +0300 -@@ -89,6 +89,13 @@ - config MDIO_CAVIUM - tristate - -+config MDIO_GOKE_FEMAC -+ tristate "Goke femac MDIO buses" -+ depends on HAS_IOMEM && OF_MDIO -+ help -+ This module provides a driver for the MDIO busses found in the -+ Goke SoC that have an Fast Ethernet. -+ - config MDIO_GPIO - tristate "GPIO lib-based bitbanged MDIO buses" - depends on MDIO_BITBANG && GPIOLIB ---- linux-4.9.37/drivers/net/phy/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/net/phy/Makefile 2021-06-07 13:01:33.000000000 +0300 -@@ -13,6 +13,7 @@ - obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o - obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) += mdio-mux-mmioreg.o - obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium.o -+obj-$(CONFIG_MDIO_GOKE_FEMAC) += mdio-goke-femac.o - obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o - obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o - obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o ---- linux-4.9.37/drivers/net/phy/mdio-goke-femac.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/net/phy/mdio-goke-femac.c 2021-06-07 13:01:33.000000000 +0300 -@@ -0,0 +1,450 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MDIO_RWCTRL 0x00 -+#define MDIO_RO_DATA 0x04 -+#define MDIO_WRITE BIT(13) -+#define MDIO_RW_FINISH BIT(15) -+#define BIT_PHY_ADDR_OFFSET 8 -+#define BIT_WR_DATA_OFFSET 16 -+ -+#define BIT_MASK_FEPHY_ADDR GENMASK(4, 0) -+#define BIT_FEPHY_SEL BIT(5) -+ -+#if defined(CONFIG_ARCH_CJ104V100) -+#define BIT_OFFSET_LD_SET 0 -+#define BIT_OFFSET_LDO_SET 5 -+#define BIT_OFFSET_R_TUNING 8 -+#else -+#define BIT_OFFSET_LD_SET 25 -+#define BIT_OFFSET_LDO_SET 22 -+#define BIT_OFFSET_R_TUNING 16 -+#endif -+#define MII_EXPMD 0x1d -+#define MII_EXPMA 0x1e -+ -+#define REG_LD_AM 0x3050 -+#define BIT_MASK_LD_SET GENMASK(4, 0) -+#define REG_LDO_AM 0x3051 -+#define BIT_MASK_LDO_SET GENMASK(2, 0) -+#define REG_R_TUNING 0x3052 -+#define BIT_MASK_R_TUNING GENMASK(5, 0) -+#define REG_WR_DONE 0x3053 -+#define BIT_CFG_DONE BIT(0) -+#define BIT_CFG_ACK BIT(1) -+#define REG_DEF_ATE 0x3057 -+#define BIT_AUTOTRIM_DONE BIT(0) -+ -+#define PHY_RESET_DELAYS_PROPERTY "goke,phy-reset-delays-us" -+ -+enum phy_reset_delays { -+ PRE_DELAY, -+ PULSE, -+ POST_DELAY, -+ DELAYS_NUM, -+}; -+ -+struct femac_mdio_data { -+ struct clk *clk; -+ struct clk *fephy_clk; -+ struct reset_control *phy_rst; -+ struct reset_control *fephy_rst; -+ u32 phy_reset_delays[DELAYS_NUM]; -+ void __iomem *membase; -+ void __iomem *fephy_iobase; -+ void __iomem *fephy_trim_iobase; -+ struct mii_bus *bus; -+ u32 phy_addr; -+}; -+ -+static int femac_mdio_wait_ready(struct femac_mdio_data *data) -+{ -+ u32 val; -+ -+ return readl_poll_timeout_atomic(data->membase + MDIO_RWCTRL, -+ val, val & MDIO_RW_FINISH, 20, 10000); -+} -+ -+static int femac_mdio_read(struct mii_bus *bus, int mii_id, int regnum) -+{ -+ struct femac_mdio_data *data = bus->priv; -+ int ret; -+ -+ ret = femac_mdio_wait_ready(data); -+ if (ret) -+ return ret; -+ -+ writel(((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum), -+ data->membase + MDIO_RWCTRL); -+ -+ ret = femac_mdio_wait_ready(data); -+ if (ret) -+ return ret; -+ -+ return readl(data->membase + MDIO_RO_DATA) & 0xFFFF; -+} -+ -+static int femac_mdio_write(struct mii_bus *bus, int mii_id, int regnum, -+ u16 value) -+{ -+ struct femac_mdio_data *data = bus->priv; -+ int ret; -+ -+ ret = femac_mdio_wait_ready(data); -+ if (ret) -+ return ret; -+ -+ writel(MDIO_WRITE | (value << BIT_WR_DATA_OFFSET) | -+ ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum), -+ data->membase + MDIO_RWCTRL); -+ -+ return femac_mdio_wait_ready(data); -+} -+ -+static void femac_sleep_us(u32 time_us) -+{ -+ u32 time_ms; -+ -+ if (!time_us) -+ return; -+ -+ time_ms = DIV_ROUND_UP(time_us, 1000); -+ if (time_ms < 20) -+ usleep_range(time_us, time_us + 500); -+ else -+ msleep(time_ms); -+} -+ -+static void femac_phy_reset(const struct femac_mdio_data *data) -+{ -+ /* To make sure PHY hardware reset success, -+ * we must keep PHY in deassert state first and -+ * then complete the hardware reset operation -+ */ -+ reset_control_deassert(data->phy_rst); -+ femac_sleep_us(data->phy_reset_delays[PRE_DELAY]); -+ -+ reset_control_assert(data->phy_rst); -+ /* delay some time to ensure reset ok, -+ * this depends on PHY hardware feature -+ */ -+ femac_sleep_us(data->phy_reset_delays[PULSE]); -+ reset_control_deassert(data->phy_rst); -+ /* delay some time to ensure later MDIO access */ -+ femac_sleep_us(data->phy_reset_delays[POST_DELAY]); -+} -+ -+static void femac_get_phy_addr(struct femac_mdio_data *data, -+ struct device_node *np) -+{ -+ struct device_node *child = NULL; -+ int addr; -+ -+ child = of_get_next_available_child(np, NULL); -+ if (!child) { -+ pr_err("%s: No valid PHY device node!\n", __func__); -+ return; -+ } -+ -+ addr = of_mdio_parse_addr(&data->bus->dev, child); -+ if (addr < 0) { -+ pr_err("%s: get PHY address failed!\n", __func__); -+ return; -+ } -+ -+ data->phy_addr = addr; -+} -+ -+static inline bool femac_use_fephy(struct femac_mdio_data *data) -+{ -+ /*return false;*/ -+ return (data->fephy_iobase ? -+ !(readl(data->fephy_iobase) & BIT_FEPHY_SEL) : false); -+} -+ -+static void femac_fephy_reset(struct femac_mdio_data *data) -+{ -+ u32 val; -+ -+ /* disable MDCK clock to make sure FEPHY reset success */ -+ clk_disable_unprepare(data->clk); -+ -+ val = readl(data->fephy_iobase); -+ val &= ~BIT_MASK_FEPHY_ADDR; -+ val |= data->phy_addr; -+ writel(val, data->fephy_iobase); -+ -+ clk_prepare_enable(data->fephy_clk); -+ udelay(10); -+ -+ reset_control_assert(data->fephy_rst); -+ udelay(10); -+ reset_control_deassert(data->fephy_rst); -+ /* delay at least 15ms for MDIO operation */ -+ msleep(20); -+ -+ clk_prepare_enable(data->clk); -+ /* delay 5ms after enable MDCK to make sure FEPHY trim safe */ -+ mdelay(5); -+} -+ -+static inline int fephy_expanded_read(struct mii_bus *bus, int phy_addr, -+ u32 reg_addr) -+{ -+ int ret; -+ -+ femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); -+ ret = femac_mdio_read(bus, phy_addr, MII_EXPMD); -+ -+ return ret; -+} -+ -+static inline int fephy_expanded_write(struct mii_bus *bus, int phy_addr, -+ u32 reg_addr, u16 val) -+{ -+ int ret; -+ -+ femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); -+ ret = femac_mdio_write(bus, phy_addr, MII_EXPMD, val); -+ -+ return ret; -+} -+ -+void femac_fephy_use_default_trim(struct femac_mdio_data *data) -+{ -+ unsigned short val; -+ int timeout = 3; -+ -+ pr_info("No OTP data, internal PHY use default ATE parameters!\n"); -+ -+ do { -+ msleep(250); -+ val = fephy_expanded_read(data->bus, data->phy_addr, -+ REG_DEF_ATE); -+ val &= BIT_AUTOTRIM_DONE; -+ } while (!val && --timeout); -+ -+ if (!timeout) -+ pr_err("femac PHY wait autotrim done timeout!\n"); -+ -+ mdelay(5); -+} -+ -+static void femac_fephy_trim(struct femac_mdio_data *data) -+{ -+ struct mii_bus *bus = data->bus; -+ u32 phy_addr = data->phy_addr; -+ int timeout = 3000; -+ u32 val; -+ u8 ld_set; -+ u8 ldo_set; -+ u8 r_tuning; -+ -+ val = readl(data->fephy_iobase); -+ ld_set = (val >> BIT_OFFSET_LD_SET) & BIT_MASK_LD_SET; -+ ldo_set = (val >> BIT_OFFSET_LDO_SET) & BIT_MASK_LDO_SET; -+ r_tuning = (val >> BIT_OFFSET_R_TUNING) & BIT_MASK_R_TUNING; -+ -+ if (!ld_set && !ldo_set && !r_tuning) { -+ femac_fephy_use_default_trim(data); -+ return; -+ } -+ -+ val = fephy_expanded_read(bus, phy_addr, REG_LD_AM); -+ val = (val & ~BIT_MASK_LD_SET) | (ld_set & BIT_MASK_LD_SET); -+ fephy_expanded_write(bus, phy_addr, REG_LD_AM, val); -+ -+ val = fephy_expanded_read(bus, phy_addr, REG_LDO_AM); -+ val = (val & ~BIT_MASK_LDO_SET) | (ldo_set & BIT_MASK_LDO_SET); -+ fephy_expanded_write(bus, phy_addr, REG_LDO_AM, val); -+ -+ val = fephy_expanded_read(bus, phy_addr, REG_R_TUNING); -+ val = (val & ~BIT_MASK_R_TUNING) | (r_tuning & BIT_MASK_R_TUNING); -+ fephy_expanded_write(bus, phy_addr, REG_R_TUNING, val); -+ -+ val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE); -+ if (val & BIT_CFG_ACK) -+ pr_err("femac PHY 0x3053 bit CFG_ACK value: 1\n"); -+ val = val | BIT_CFG_DONE; -+ fephy_expanded_write(bus, phy_addr, REG_WR_DONE, val); -+ -+ do { -+ usleep_range(100, 150); -+ val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE); -+ val &= BIT_CFG_ACK; -+ } while (!val && --timeout); -+ if (!timeout) -+ pr_err("femac PHY 0x3053 wait bit CFG_ACK timeout!\n"); -+ -+ mdelay(5); -+ -+ pr_info("FEPHY:addr=%d, la_am=0x%x, ldo_am=0x%x, r_tuning=0x%x\n", -+ phy_addr, -+ fephy_expanded_read(bus, phy_addr, REG_LD_AM), -+ fephy_expanded_read(bus, phy_addr, REG_LDO_AM), -+ fephy_expanded_read(bus, phy_addr, REG_R_TUNING)); -+} -+ -+static void femac_fephy_reset_and_trim(struct femac_mdio_data *data) -+{ -+ femac_fephy_reset(data); -+ femac_fephy_trim(data); -+} -+ -+static void femac_fephy_set_phy_addr(struct femac_mdio_data *data) -+{ -+ u32 val; -+ -+ if (!data->fephy_iobase) -+ return; -+ -+ val = readl(data->fephy_iobase); -+ val &= ~BIT_MASK_FEPHY_ADDR; -+ val |= (data->phy_addr + 1); -+ writel(val, data->fephy_iobase); -+} -+ -+static int femac_mdio_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct mii_bus *bus; -+ struct femac_mdio_data *data; -+ struct resource *res; -+ int ret; -+ -+ bus = mdiobus_alloc_size(sizeof(*data)); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->name = "femac_mii_bus"; -+ bus->read = &femac_mdio_read; -+ bus->write = &femac_mdio_write; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); -+ bus->parent = &pdev->dev; -+ -+ data = bus->priv; -+ data->bus = bus; -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ data->membase = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(data->membase)) { -+ ret = PTR_ERR(data->membase); -+ goto err_out_free_mdiobus; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (res) { -+ data->fephy_iobase = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(data->fephy_iobase)) { -+ ret = PTR_ERR(data->fephy_iobase); -+ goto err_out_free_mdiobus; -+ } -+ } else { -+ data->fephy_iobase = NULL; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); -+ if (res) { -+ data->fephy_trim_iobase = devm_ioremap_resource(&pdev->dev, -+ res); -+ if (IS_ERR(data->fephy_trim_iobase)) { -+ ret = PTR_ERR(data->fephy_trim_iobase); -+ goto err_out_free_mdiobus; -+ } -+ } else { -+ data->fephy_trim_iobase = NULL; -+ } -+ -+ data->clk = devm_clk_get(&pdev->dev, "mdio"); -+ if (IS_ERR(data->clk)) { -+ ret = PTR_ERR(data->clk); -+ goto err_out_free_mdiobus; -+ } -+ -+ data->fephy_clk = devm_clk_get(&pdev->dev, "phy"); -+ if (IS_ERR(data->fephy_clk)) -+ data->fephy_clk = NULL; -+ -+ ret = clk_prepare_enable(data->clk); -+ if (ret) -+ goto err_out_free_mdiobus; -+ -+ data->phy_rst = devm_reset_control_get(&pdev->dev, "external-phy"); -+ if (IS_ERR(data->phy_rst)) { -+ data->phy_rst = NULL; -+ } else { -+ ret = of_property_read_u32_array(np, -+ PHY_RESET_DELAYS_PROPERTY, -+ data->phy_reset_delays, -+ DELAYS_NUM); -+ if (ret) -+ goto err_out_disable_clk; -+ femac_phy_reset(data); -+ } -+ -+ data->fephy_rst = devm_reset_control_get(&pdev->dev, "internal-phy"); -+ if (IS_ERR(data->fephy_rst)) -+ data->fephy_rst = NULL; -+ -+ femac_get_phy_addr(data, np); -+ if (femac_use_fephy(data)) -+ femac_fephy_reset_and_trim(data); -+ else -+ femac_fephy_set_phy_addr(data); -+ -+ ret = of_mdiobus_register(bus, np); -+ if (ret) -+ goto err_out_disable_clk; -+ -+ platform_set_drvdata(pdev, bus); -+ -+ return 0; -+ -+err_out_disable_clk: -+ clk_disable_unprepare(data->fephy_clk); -+ clk_disable_unprepare(data->clk); -+err_out_free_mdiobus: -+ mdiobus_free(bus); -+ return ret; -+} -+ -+static int femac_mdio_remove(struct platform_device *pdev) -+{ -+ struct mii_bus *bus = platform_get_drvdata(pdev); -+ struct femac_mdio_data *data = bus->priv; -+ -+ mdiobus_unregister(bus); -+ clk_disable_unprepare(data->clk); -+ mdiobus_free(bus); -+ -+ return 0; -+} -+ -+static const struct of_device_id femac_mdio_dt_ids[] = { -+ { .compatible = "goke,femac-mdio" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, femac_mdio_dt_ids); -+ -+static struct platform_driver femac_mdio_driver = { -+ .probe = femac_mdio_probe, -+ .remove = femac_mdio_remove, -+ .driver = { -+ .name = "femac-mdio", -+ .of_match_table = femac_mdio_dt_ids, -+ }, -+}; -+ -+module_platform_driver(femac_mdio_driver); -+ -+MODULE_DESCRIPTION("Goke Fast Ethernet MAC MDIO interface driver"); -+MODULE_LICENSE("GPL v2"); ---- linux-4.9.37/drivers/net/phy/phy_device.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/net/phy/phy_device.c 2021-06-07 13:01:33.000000000 +0300 -@@ -234,6 +234,53 @@ - } - EXPORT_SYMBOL(phy_register_fixup_for_id); - -+/** -+ * phy_unregister_fixup - remove a phy_fixup from the list -+ * @bus_id: A string matches fixup->bus_id (or PHY_ANY_ID) in phy_fixup_list -+ * @phy_uid: A phy id matches fixup->phy_id (or PHY_ANY_UID) in phy_fixup_list -+ * @phy_uid_mask: Applied to phy_uid and fixup->phy_uid before comparison -+ */ -+int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask) -+{ -+ struct list_head *pos, *n; -+ struct phy_fixup *fixup; -+ int ret; -+ -+ ret = -ENODEV; -+ -+ mutex_lock(&phy_fixup_lock); -+ list_for_each_safe(pos, n, &phy_fixup_list) { -+ fixup = list_entry(pos, struct phy_fixup, list); -+ -+ if ((!strcmp(fixup->bus_id, bus_id)) && -+ ((fixup->phy_uid & phy_uid_mask) == -+ (phy_uid & phy_uid_mask))) { -+ list_del(&fixup->list); -+ kfree(fixup); -+ ret = 0; -+ break; -+ } -+ } -+ mutex_unlock(&phy_fixup_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL(phy_unregister_fixup); -+ -+/* Unregisters a fixup of any PHY with the UID in phy_uid */ -+int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask) -+{ -+ return phy_unregister_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask); -+} -+EXPORT_SYMBOL(phy_unregister_fixup_for_uid); -+ -+/* Unregisters a fixup of the PHY with id string bus_id */ -+int phy_unregister_fixup_for_id(const char *bus_id) -+{ -+ return phy_unregister_fixup(bus_id, PHY_ANY_UID, 0xffffffff); -+} -+EXPORT_SYMBOL(phy_unregister_fixup_for_id); -+ - /* Returns 1 if fixup matches phydev in bus_id and phy_uid. - * Fixups can be set to match any in one or more fields. - */ ---- linux-4.9.37/drivers/net/usb/cdc_ether.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/net/usb/cdc_ether.c 2021-06-07 13:01:33.000000000 +0300 -@@ -310,6 +310,26 @@ - return -ENODEV; - } - -+ return 0; -+ -+bad_desc: -+ dev_info(&dev->udev->dev, "bad CDC descriptors\n"); -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind); -+ -+ -+/* like usbnet_generic_cdc_bind() but handles filter initialization -+ * correctly -+ */ -+int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf) -+{ -+ int rv; -+ -+ rv = usbnet_generic_cdc_bind(dev, intf); -+ if (rv < 0) -+ goto bail_out; -+ - /* Some devices don't initialise properly. In particular - * the packet filter is not reset. There are devices that - * don't do reset all the way. So the packet filter should -@@ -317,13 +337,10 @@ - */ - usbnet_cdc_update_filter(dev); - -- return 0; -- --bad_desc: -- dev_info(&dev->udev->dev, "bad CDC descriptors\n"); -- return -ENODEV; -+bail_out: -+ return rv; - } --EXPORT_SYMBOL_GPL(usbnet_generic_cdc_bind); -+EXPORT_SYMBOL_GPL(usbnet_ether_cdc_bind); - - void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf) - { -@@ -417,7 +434,7 @@ - BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) - < sizeof(struct cdc_state))); - -- status = usbnet_generic_cdc_bind(dev, intf); -+ status = usbnet_ether_cdc_bind(dev, intf); - if (status < 0) - return status; - ---- linux-4.9.37/drivers/phy/goke/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/phy/goke/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,26 @@ -+config PHY_GOKE_USBP2 -+ tristate "GOKE USBP2 PHY Driver" -+ select GENERIC_PHY -+ default n -+ help -+ Support for PHY on goke Socs. This Phy supports -+ USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one -+ USB host port to accept one USB device. Support init the phy -+ and adjust phy Eye Diagram. -+ -+menuconfig USB_MODE_OPTION -+ bool "goke USB related configuration" -+ -+if USB_MODE_OPTION -+ -+config USB_DRD0_IN_HOST -+ bool "USB DRD0 Mode Select HOST" -+ help -+ Select whether the USB drd0 is working in host mode. -+ -+config USB_DRD0_IN_DEVICE -+ bool "USB DRD0 Mode Select DEVICE" -+ help -+ Select whether the USB drd0 is working in device mode. -+ -+endif # USB_MODE_OPTION ---- linux-4.9.37/drivers/phy/goke/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/phy/goke/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1 @@ -+obj-$(CONFIG_PHY_GOKE_USBP2) += phy-goke-usbp2.o ---- linux-4.9.37/drivers/phy/goke/phy-goke-usb.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/phy/goke/phy-goke-usb.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef USB2_INCLUDE_PHY_H -+#define USB2_INCLUDE_PHY_H -+ -+extern void bsp_usb_phy_on(struct phy *phy); -+extern void bsp_usb_phy_off(struct phy *phy); -+extern void bsp_usb3_phy_on(struct phy *phy); -+extern void bsp_usb3_phy_off(struct phy *phy); -+ -+ -+struct bsp_priv { -+ void __iomem *sys_ctrl; -+ void __iomem *peri_ctrl; -+ void __iomem *combphy_base; -+ void __iomem *misc_ctrl; -+ unsigned int phyid; -+ void __iomem *ctrl_base; -+ void __iomem *switch_base; -+}; -+ -+typedef enum mode { -+ PCIE_X2 = 0, -+ PCIE_X1, -+ USB3 -+} combphy_mode; -+ -+#define U_LEVEL1 10 -+#define U_LEVEL2 20 -+#define U_LEVEL3 30 -+#define U_LEVEL4 50 -+#define U_LEVEL5 100 -+#define U_LEVEL6 200 -+#define U_LEVEL7 300 -+#define U_LEVEL8 500 -+ -+#define M_LEVEL1 2 -+#define M_LEVEL2 5 -+#define M_LEVEL3 10 -+#define M_LEVEL4 20 -+#define M_LEVEL5 50 -+#define M_LEVEL6 100 -+#define M_LEVEL7 200 -+ -+#define __1K__ 0x400 -+#define __2K__ 0x800 -+#define __4K__ 0x1000 -+#define __8K__ 0x2000 -+#define __64K__ 0x10000 -+ -+#define CRG_REGBASE_NODE_IDX 0 -+#define MISC_REGBASE_NODE_IDX 1 -+#define CTRL_REGBASE_NODE_IDX 2 -+#define PHY_REGBASE_NODE_IDX 3 -+ -+#endif /* USB2_INCLUDE_PHY_H */ ---- linux-4.9.37/drivers/phy/goke/phy-goke-usbp2.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/phy/goke/phy-goke-usbp2.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,758 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "phy-goke-usb.h" -+ -+#define USBP2_PHY_TRIM_OFFSET 0x0008 -+#define USBP2_PHY_TRIM_MASK 0x1f00 -+#define USBP2_PHY_TRIM_VAL(a) (((a) << 8) & USBP2_PHY_TRIM_MASK) -+ -+#define USBP2_PHY_SVB_OFFSET 0x0000 -+#define USBP2_PHY_SVB_MASK 0x0f000000 -+#define USBP2_PHY_SVB_VAL(a) (((a) << 24) & USBP2_PHY_SVB_MASK) -+ -+struct bsp_usbp2_priv { -+ void __iomem *crg_base; -+ void __iomem *phy_base; -+ void __iomem *pin_base; -+ struct phy *phy; -+ struct device *dev; -+ struct clk **clks; -+ int num_clocks; -+ u32 phy_pll_offset; -+ u32 phy_pll_mask; -+ u32 phy_pll_val; -+ u32 crg_offset; -+ u32 crg_defal_mask; -+ u32 crg_defal_val; -+ u32 vbus_offset; -+ u32 vbus_val; -+ int vbus_flag; -+ u32 pwren_offset; -+ u32 pwren_val; -+ int pwren_flag; -+ u32 ana_cfg_0_eye_val; -+ u32 ana_cfg_0_offset; -+ int ana_cfg_0_flag; -+ u32 ana_cfg_2_eye_val; -+ u32 ana_cfg_2_offset; -+ int ana_cfg_2_flag; -+ u32 ana_cfg_4_eye_val; -+ u32 ana_cfg_4_offset; -+ int ana_cfg_4_flag; -+ struct reset_control *usb_phy_tpor_rst; -+ struct reset_control *usb_phy_por_rst; -+ u32 trim_otp_addr; -+ u32 trim_otp_mask; -+ u32 trim_otp_bit_offset; -+ u32 trim_otp_min; -+ u32 trim_otp_max; -+ int trim_flag; -+ u32 svb_otp_addr; -+ u32 svb_otp_predev5_min; -+ u32 svb_otp_predev5_max; -+ u32 svb_phy_predev5_val; -+ int svb_predev5_flag; -+ u32 svb_otp_predev4_min; -+ u32 svb_otp_predev4_max; -+ u32 svb_phy_predev4_val; -+ int svb_predev4_flag; -+ u32 svb_otp_predev3_min; -+ u32 svb_otp_predev3_max; -+ u32 svb_phy_predev3_val; -+ int svb_predev3_flag; -+ u32 svb_otp_predev2_min; -+ u32 svb_otp_predev2_max; -+ u32 svb_phy_predev2_val; -+ int svb_predev2_flag; -+ int svb_flag; -+}; -+ -+void bsp_usbp2_def_all_exist(struct bsp_usbp2_priv *priv) -+{ -+ if (priv == NULL) -+ return; -+ -+ /* All parameters exist by default */ -+ priv->vbus_flag = 1; -+ -+ priv->pwren_flag = 1; -+ -+ priv->ana_cfg_0_flag = 1; -+ -+ priv->ana_cfg_2_flag = 1; -+ -+ priv->ana_cfg_4_flag = 1; -+ -+ priv->trim_flag = 1; -+ -+ priv->svb_predev5_flag = 1; -+ -+ priv->svb_predev4_flag = 1; -+ -+ priv->svb_predev3_flag = 1; -+ -+ priv->svb_predev2_flag = 1; -+ -+ priv->svb_flag = 1; -+} -+ -+void bsp_usbp2_get_eye_para(struct device *dev, struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return; -+ -+ /* -+ * Get phy eye parameters,if you want to change them,please open -+ * dtsi file and modify parameters at phy node. -+ */ -+ ret = of_property_read_u32(dev->of_node, "ana_cfg_0_eye_val", -+ &(priv->ana_cfg_0_eye_val)); -+ if (ret) -+ priv->ana_cfg_0_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "ana_cfg_0_offset", -+ &(priv->ana_cfg_0_offset)); -+ if (ret) -+ priv->ana_cfg_0_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "ana_cfg_2_eye_val", -+ &(priv->ana_cfg_2_eye_val)); -+ if (ret) -+ priv->ana_cfg_2_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "ana_cfg_2_offset", -+ &(priv->ana_cfg_2_offset)); -+ if (ret) -+ priv->ana_cfg_2_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "ana_cfg_4_eye_val", -+ &(priv->ana_cfg_4_eye_val)); -+ if (ret) -+ priv->ana_cfg_4_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "ana_cfg_4_offset", -+ &(priv->ana_cfg_4_offset)); -+ if (ret) -+ priv->ana_cfg_4_flag = 0; -+} -+ -+void bsp_usbp2_phy_eye_config(struct bsp_usbp2_priv *priv) -+{ -+ if (priv == NULL) -+ return; -+ -+ if (priv->ana_cfg_0_flag) -+ writel(priv->ana_cfg_0_eye_val, priv->phy_base + priv->ana_cfg_0_offset); -+ -+ if (priv->ana_cfg_2_flag) -+ writel(priv->ana_cfg_2_eye_val, priv->phy_base + priv->ana_cfg_2_offset); -+ -+ if (priv->ana_cfg_4_flag) -+ writel(priv->ana_cfg_4_eye_val, priv->phy_base + priv->ana_cfg_4_offset); -+} -+ -+void bsp_usbp2_get_trim_para(struct device *dev, struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return; -+ -+ /* get phy trim parameters */ -+ ret = of_property_read_u32(dev->of_node, "trim_otp_addr", -+ &(priv->trim_otp_addr)); -+ if (ret) -+ priv->trim_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "trim_otp_mask", -+ &(priv->trim_otp_mask)); -+ if (ret) -+ priv->trim_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "trim_otp_bit_offset", -+ &(priv->trim_otp_bit_offset)); -+ if (ret) -+ priv->trim_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "trim_otp_min", &(priv->trim_otp_min)); -+ if (ret) -+ priv->trim_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "trim_otp_max", &(priv->trim_otp_max)); -+ if (ret) -+ priv->trim_flag = 0; -+} -+ -+void bsp_usbp2_phy_trim_config(struct bsp_usbp2_priv *priv) -+{ -+ unsigned int trim_otp_val; -+ unsigned int reg; -+ void __iomem *phy_trim = NULL; -+ -+ if (priv == NULL) -+ return; -+ -+ if (priv->trim_flag) { -+ phy_trim = ioremap_nocache(priv->trim_otp_addr, __1K__); -+ if (phy_trim == NULL) -+ return; -+ -+ reg = readl(phy_trim); -+ trim_otp_val = (reg & priv->trim_otp_mask); -+ if ((trim_otp_val >= priv->trim_otp_min) && -+ (trim_otp_val <= priv->trim_otp_max)) { -+ /* set trim value to phy */ -+ reg = readl(priv->phy_base + USBP2_PHY_TRIM_OFFSET); -+ reg &= ~USBP2_PHY_TRIM_MASK; -+ reg |= USBP2_PHY_TRIM_VAL(trim_otp_val >> priv->trim_otp_bit_offset); -+ writel(reg, priv->phy_base + USBP2_PHY_TRIM_OFFSET); -+ } -+ iounmap(phy_trim); -+ } -+} -+ -+void bsp_usbp2_get_svb_para_1(struct device *dev, struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return; -+ -+ /* get phy svb parmteters */ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_addr", &(priv->svb_otp_addr)); -+ if (ret) -+ priv->svb_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_min", -+ &(priv->svb_otp_predev5_min)); -+ if (ret) -+ priv->svb_predev5_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_max", -+ &(priv->svb_otp_predev5_max)); -+ if (ret) -+ priv->svb_predev5_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev5_val", -+ &(priv->svb_phy_predev5_val)); -+ if (ret) -+ priv->svb_predev5_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_min", -+ &(priv->svb_otp_predev4_min)); -+ if (ret) -+ priv->svb_predev4_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_max", -+ &(priv->svb_otp_predev4_max)); -+ if (ret) -+ priv->svb_predev4_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev4_val", -+ &(priv->svb_phy_predev4_val)); -+ if (ret) -+ priv->svb_predev4_flag = 0; -+} -+ -+void bsp_usbp2_get_svb_para_2(struct device *dev, struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_min", -+ &(priv->svb_otp_predev3_min)); -+ if (ret) -+ priv->svb_predev3_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_max", -+ &(priv->svb_otp_predev3_max)); -+ if (ret) -+ priv->svb_predev3_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev3_val", -+ &(priv->svb_phy_predev3_val)); -+ if (ret) -+ priv->svb_predev3_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_min", -+ &(priv->svb_otp_predev2_min)); -+ if (ret) -+ priv->svb_predev2_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_max", -+ &(priv->svb_otp_predev2_max)); -+ if (ret) -+ priv->svb_predev2_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "svb_phy_predev2_val", -+ &(priv->svb_phy_predev2_val)); -+ if (ret) -+ priv->svb_predev2_flag = 0; -+} -+ -+void bsp_usbp2_phy_svb_config(struct bsp_usbp2_priv *priv) -+{ -+ unsigned int reg; -+ unsigned int ret; -+ void __iomem *phy_svb = NULL; -+ -+ if (priv == NULL) -+ return; -+ -+ if (priv->svb_flag) { -+ phy_svb = ioremap_nocache(priv->svb_otp_addr, __1K__); -+ if (phy_svb == NULL) -+ return; -+ -+ ret = readl(phy_svb); -+ reg = readl(priv->phy_base + USBP2_PHY_SVB_OFFSET); -+ reg &= ~USBP2_PHY_SVB_MASK; -+ if ((ret >= priv->svb_otp_predev5_min) && -+ (ret < priv->svb_otp_predev5_max) && (priv->svb_predev5_flag)) -+ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev5_val); -+ else if ((ret >= priv->svb_otp_predev4_min) && -+ (ret < priv->svb_otp_predev4_max) && (priv->svb_predev4_flag)) -+ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev4_val); -+ else if ((ret >= priv->svb_otp_predev3_min) && -+ (ret <= priv->svb_otp_predev3_max) && (priv->svb_predev3_flag)) -+ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev3_val); -+ else if ((ret > priv->svb_otp_predev2_min) && -+ (ret <= priv->svb_otp_predev2_max) && (priv->svb_predev2_flag)) -+ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev2_val); -+ else -+ reg |= USBP2_PHY_SVB_VAL(priv->svb_phy_predev4_val); -+ -+ writel(reg, priv->phy_base + USBP2_PHY_SVB_OFFSET); -+ iounmap(phy_svb); -+ } -+} -+ -+static void bsp_usb_vbus_and_pwren_config(struct device *dev, struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return; -+ -+ /* Some chips do not have VBUS encapsulation and need to be configured */ -+ ret = of_property_read_u32(dev->of_node, "vbus_offset", &(priv->vbus_offset)); -+ if (ret) -+ priv->vbus_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "vbus_val", &(priv->vbus_val)); -+ if (ret) -+ priv->vbus_flag = 0; -+ -+ /* Some chips do not have PWREN encapsulation and need to be configured */ -+ ret = of_property_read_u32(dev->of_node, "pwren_offset", &(priv->pwren_offset)); -+ if (ret) -+ priv->pwren_flag = 0; -+ -+ ret = of_property_read_u32(dev->of_node, "pwren_val", &(priv->pwren_val)); -+ if (ret) -+ priv->pwren_flag = 0; -+ -+ if (priv->vbus_flag) -+ writel(priv->vbus_val, priv->pin_base + priv->vbus_offset); -+ -+ udelay(U_LEVEL2); -+ -+ if (priv->pwren_flag) -+ writel(priv->pwren_val, priv->pin_base + priv->pwren_offset); -+ -+ udelay(U_LEVEL2); -+} -+ -+static int bsp_usbp2_get_pll_clk(struct device *dev, -+ struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return -EINVAL; -+ -+ /* Get phy pll clk config parameters from the phy node of the dtsi file */ -+ ret = of_property_read_u32(dev->of_node, "phy_pll_offset", -+ &(priv->phy_pll_offset)); -+ if (ret) { -+ dev_err(dev, "get phy_pll_offset failed: %d\n", ret); -+ return ret; -+ } -+ -+ ret = of_property_read_u32(dev->of_node, "phy_pll_mask", &(priv->phy_pll_mask)); -+ if (ret) { -+ dev_err(dev, "get phy_pll_mask failed: %d\n", ret); -+ return ret; -+ } -+ -+ ret = of_property_read_u32(dev->of_node, "phy_pll_val", &(priv->phy_pll_val)); -+ if (ret) { -+ dev_err(dev, "get phy_pll_val failed: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int bsp_usbp2_set_crg_val(struct device *dev, -+ struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ unsigned int reg; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return -EINVAL; -+ -+ /* Get CRG default value from the phy node of the dtsi file */ -+ ret = of_property_read_u32(dev->of_node, "crg_offset", &(priv->crg_offset)); -+ if (ret) { -+ dev_err(dev, "get crg_offset failed: %d\n", ret); -+ return ret; -+ } -+ -+ ret = of_property_read_u32(dev->of_node, "crg_defal_mask", -+ &(priv->crg_defal_mask)); -+ if (ret) { -+ dev_err(dev, "get crg_defal_mask failed: %d\n", ret); -+ return ret; -+ } -+ -+ ret = of_property_read_u32(dev->of_node, "crg_defal_val", -+ &(priv->crg_defal_val)); -+ if (ret) { -+ dev_err(dev, "get crg_defal_val failed: %d\n", ret); -+ return ret; -+ } -+ -+ /* write phy crg default value */ -+ reg = readl(priv->crg_base + priv->crg_offset); -+ reg &= ~priv->crg_defal_mask; -+ reg |= priv->crg_defal_val; -+ writel(reg, priv->crg_base + priv->crg_offset); -+ -+ return 0; -+} -+ -+static int bsp_usbp2_phy_get_para(struct device *dev, -+ struct bsp_usbp2_priv *priv) -+{ -+ unsigned int ret; -+ -+ if ((dev == NULL) || (priv == NULL)) -+ return -EINVAL; -+ -+ bsp_usbp2_def_all_exist(priv); -+ -+ ret = bsp_usbp2_get_pll_clk(dev, priv); -+ if (ret) { -+ dev_err(dev, "get pll clk failed: %d\n", ret); -+ return ret; -+ } -+ -+ bsp_usbp2_get_trim_para(dev, priv); -+ bsp_usbp2_get_eye_para(dev, priv); -+ bsp_usbp2_get_svb_para_1(dev, priv); -+ bsp_usbp2_get_svb_para_2(dev, priv); -+ -+ return 0; -+} -+ -+static int bsp_usbp2_phy_get_clks(struct bsp_usbp2_priv *priv, int count) -+{ -+ struct device *dev = priv->dev; -+ struct device_node *np = dev->of_node; -+ int i; -+ -+ priv->num_clocks = count; -+ -+ if (!count) -+ return 0; -+ -+ priv->clks = -+ devm_kcalloc(dev, priv->num_clocks, sizeof(struct clk *), GFP_KERNEL); -+ if (priv->clks == NULL) -+ return -ENOMEM; -+ -+ for (i = 0; i < priv->num_clocks; i++) { -+ struct clk *clk; -+ -+ clk = of_clk_get(np, i); -+ if (IS_ERR(clk)) { -+ while (--i >= 0) -+ clk_put(priv->clks[i]); -+ -+ devm_kfree(dev, priv->clks); -+ priv->clks = NULL; -+ return PTR_ERR(clk); -+ } -+ -+ priv->clks[i] = clk; -+ } -+ return 0; -+} -+ -+static int bsp_usbp2_clk_rst_config(struct platform_device *pdev, -+ struct bsp_usbp2_priv *priv) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = pdev->dev.of_node; -+ unsigned int ret; -+ -+ ret = bsp_usbp2_phy_get_clks(priv, of_clk_get_parent_count(np)); -+ if (ret) { -+ dev_err(dev, "get phy clk failed\n"); -+ return ret; -+ } -+ -+ priv->usb_phy_tpor_rst = devm_reset_control_get(dev, "phy_tpor_reset"); -+ if (IS_ERR_OR_NULL(priv->usb_phy_tpor_rst)) { -+ dev_err(dev, "get phy_tpor_reset failed: %d\n", ret); -+ return PTR_ERR(priv->usb_phy_tpor_rst); -+ } -+ -+ priv->usb_phy_por_rst = devm_reset_control_get(dev, "phy_por_reset"); -+ if (IS_ERR_OR_NULL(priv->usb_phy_por_rst)) { -+ dev_err(dev, "get phy_por_reset failed: %d\n", ret); -+ return PTR_ERR(priv->usb_phy_por_rst);; -+ } -+ -+ return 0; -+} -+ -+static int bsp_usbp2_iomap(struct device_node *np, -+ struct bsp_usbp2_priv *priv) -+{ -+ if ((np == NULL) || (priv == NULL)) -+ return -EINVAL; -+ -+ priv->phy_base = of_iomap(np, 0); -+ if (IS_ERR(priv->phy_base)) -+ return -ENOMEM; -+ -+ priv->crg_base = of_iomap(np, 1); -+ if (IS_ERR(priv->crg_base)) { -+ iounmap(priv->phy_base); -+ return -ENOMEM; -+ } -+ -+ priv->pin_base = of_iomap(np, 2); -+ if (IS_ERR(priv->pin_base)) { -+ iounmap(priv->phy_base); -+ iounmap(priv->crg_base); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static int bsp_usbp2_phy_init(struct phy *phy) -+{ -+ struct bsp_usbp2_priv *priv = phy_get_drvdata(phy); -+ int i, ret; -+ unsigned int reg; -+ -+ for (i = 0; i < priv->num_clocks; i++) { -+ ret = clk_prepare_enable(priv->clks[i]); -+ if (ret < 0) { -+ while (--i >= 0) { -+ clk_disable_unprepare(priv->clks[i]); -+ clk_put(priv->clks[i]); -+ } -+ } -+ } -+ -+ udelay(U_LEVEL5); -+ -+ /* undo por reset */ -+ ret = reset_control_deassert(priv->usb_phy_por_rst); -+ if (ret) -+ return ret; -+ -+ /* pll out clk */ -+ reg = readl(priv->phy_base + priv->phy_pll_offset); -+ reg &= ~priv->phy_pll_mask; -+ reg |= priv->phy_pll_val; -+ writel(reg, priv->phy_base + priv->phy_pll_offset); -+ -+ mdelay(M_LEVEL1); -+ -+ /* undo tpor reset */ -+ ret = reset_control_deassert(priv->usb_phy_tpor_rst); -+ if (ret) -+ return ret; -+ -+ udelay(U_LEVEL6); -+ -+ bsp_usbp2_phy_eye_config(priv); -+ -+ bsp_usbp2_phy_trim_config(priv); -+ -+ bsp_usbp2_phy_svb_config(priv); -+ return 0; -+} -+ -+static int bsp_usbp2_phy_exit(struct phy *phy) -+{ -+ struct bsp_usbp2_priv *priv = phy_get_drvdata(phy); -+ int i, ret; -+ -+ for (i = 0; i < priv->num_clocks; i++) -+ clk_disable_unprepare(priv->clks[i]); -+ -+ ret = reset_control_assert(priv->usb_phy_por_rst); -+ if (ret) -+ return ret; -+ -+ ret = reset_control_assert(priv->usb_phy_tpor_rst); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static const struct phy_ops bsp_usbp2_phy_ops = { -+ .init = bsp_usbp2_phy_init, -+ .exit = bsp_usbp2_phy_exit, -+ .owner = THIS_MODULE, -+}; -+ -+static int bsp_usbp2_phy_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct phy *phy = NULL; -+ struct bsp_usbp2_priv *priv = NULL; -+ struct device_node *np = pdev->dev.of_node; -+ struct phy_provider *phy_provider = NULL; -+ unsigned int ret; -+ -+ phy = devm_phy_create(dev, dev->of_node, &bsp_usbp2_phy_ops); -+ if (IS_ERR(phy)) -+ return PTR_ERR(phy); -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (priv == NULL) -+ return -ENOMEM; -+ -+ ret = bsp_usbp2_iomap(np, priv); -+ if (ret) { -+ devm_kfree(dev, priv); -+ priv = NULL; -+ -+ return -ENOMEM; -+ } -+ -+ platform_set_drvdata(pdev, priv); -+ priv->dev = dev; -+ -+ ret = bsp_usbp2_clk_rst_config(pdev, priv); -+ if (ret) -+ goto xvp_unmap; -+ -+ ret = bsp_usbp2_phy_get_para(dev, priv); -+ if (ret) -+ goto xvp_unmap; -+ -+ bsp_usb_vbus_and_pwren_config(dev, priv); -+ -+ ret = bsp_usbp2_set_crg_val(dev, priv); -+ if (ret) -+ goto xvp_unmap; -+ -+ platform_set_drvdata(pdev, priv); -+ phy_set_drvdata(phy, priv); -+ -+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ if (IS_ERR(phy_provider)) { -+ ret = PTR_ERR(phy_provider); -+ goto xvp_unmap; -+ } -+ -+ return 0; -+xvp_unmap: -+ iounmap(priv->phy_base); -+ iounmap(priv->crg_base); -+ iounmap(priv->pin_base); -+ -+ devm_kfree(dev, priv); -+ priv = NULL; -+ -+ return ret; -+} -+ -+static int bsp_usbp2_phy_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct bsp_usbp2_priv *priv = platform_get_drvdata(pdev); -+ int i; -+ -+ for (i = 0; i < priv->num_clocks; i++) -+ clk_put(priv->clks[i]); -+ -+ iounmap(priv->phy_base); -+ iounmap(priv->crg_base); -+ iounmap(priv->pin_base); -+ -+ devm_kfree(dev, priv); -+ priv = NULL; -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM_SLEEP -+static int bsp_usbp2_phy_suspend(struct device *dev) -+{ -+ struct phy *phy = dev_get_drvdata(dev); -+ -+ if (bsp_usbp2_phy_exit(phy)) -+ return -1; -+ -+ return 0; -+} -+ -+static int bsp_usbp2_phy_resume(struct device *dev) -+{ -+ struct phy *phy = dev_get_drvdata(dev); -+ -+ if (bsp_usbp2_phy_init(phy)) -+ return -1; -+ -+ return 0; -+} -+#endif /* CONFIG_PM_SLEEP */ -+ -+static SIMPLE_DEV_PM_OPS(bsp_usb_pm_ops, bsp_usbp2_phy_suspend, -+ bsp_usbp2_phy_resume); -+ -+static const struct of_device_id bsp_usbp2_phy_of_match[] = { -+ { .compatible = "goke,usbp2-phy" }, -+ {}, -+}; -+ -+static struct platform_driver bsp_usbp2_phy_driver = { -+ .probe = bsp_usbp2_phy_probe, -+ .remove = bsp_usbp2_phy_remove, -+ .driver = { -+ .name = "goke-usbp2-phy", -+ .pm = &bsp_usb_pm_ops, -+ .of_match_table = bsp_usbp2_phy_of_match, -+ } -+}; -+module_platform_driver(bsp_usbp2_phy_driver); -+MODULE_DESCRIPTION("GOKE USB PHY driver"); -+MODULE_ALIAS("platform:usbp2-phy"); -+MODULE_LICENSE("GPL v2"); ---- linux-4.9.37/drivers/phy/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/phy/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -481,6 +481,7 @@ - If unsure, say N. - - source "drivers/phy/tegra/Kconfig" -+source "drivers/phy/goke/Kconfig" - - config PHY_NS2_PCIE - tristate "Broadcom Northstar2 PCIe PHY driver" ---- linux-4.9.37/drivers/phy/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/phy/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -59,4 +59,5 @@ - obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o - obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o - obj-$(CONFIG_ARCH_TEGRA) += tegra/ -+obj-$(CONFIG_ARCH_GOKE) += goke/ - obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o ---- linux-4.9.37/drivers/power/reset/goke-reboot.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/power/reset/goke-reboot.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+static void __iomem *base; -+static u32 reboot_offset; -+ -+static int bsp_restart_handler(struct notifier_block *this, -+ unsigned long mode, void *cmd) -+{ -+ writel_relaxed(0xdeadbeef, base + reboot_offset); -+ -+ while (1) -+ cpu_do_idle(); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block bsp_restart_nb = { -+ .notifier_call = bsp_restart_handler, -+ .priority = 128, -+}; -+ -+static int bsp_reboot_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ int err; -+ -+ base = of_iomap(np, 0); -+ if (!base) { -+ WARN(1, "failed to map base address"); -+ return -ENODEV; -+ } -+ -+ if (of_property_read_u32(np, "reboot-offset", &reboot_offset) < 0) { -+ pr_err("failed to find reboot-offset property\n"); -+ iounmap(base); -+ return -EINVAL; -+ } -+ -+ err = register_restart_handler(&bsp_restart_nb); -+ if (err) { -+ dev_err(&pdev->dev, "cannot register restart handler (err=%d)\n", -+ err); -+ iounmap(base); -+ } -+ -+ return err; -+} -+ -+static const struct of_device_id bsp_reboot_of_match[] = { -+ { .compatible = "goke,sysctrl" }, -+ {} -+}; -+ -+static struct platform_driver bsp_reboot_driver = { -+ .probe = bsp_reboot_probe, -+ .driver = { -+ .name = "goke-reboot", -+ .of_match_table = bsp_reboot_of_match, -+ }, -+}; -+module_platform_driver(bsp_reboot_driver); ---- linux-4.9.37/drivers/power/reset/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/power/reset/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -67,6 +67,12 @@ - Say Y here if you have a Broadcom STB board and you wish - to have restart support. - -+config POWER_RESET_GOKE -+ bool "Goke power-off driver" -+ depends on ARCH_GOKE -+ help -+ Reboot support for Goke boards. -+ - config POWER_RESET_GPIO - bool "GPIO power-off driver" - depends on OF_GPIO ---- linux-4.9.37/drivers/power/reset/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/power/reset/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -5,6 +5,7 @@ - obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o - obj-$(CONFIG_POWER_RESET_BRCMKONA) += brcm-kona-reset.o - obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o -+obj-$(CONFIG_POWER_RESET_GOKE) += goke-reboot.o - obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o - obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o - obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o ---- linux-4.9.37/drivers/pwm/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/pwm/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -175,6 +175,14 @@ - To compile this driver as a module, choose M here: the module - will be called pwm-fsl-ftm. - -+config PWM_GOKE -+ tristate "Goke PWM support" -+ help -+ Generic PWM framework driver for Goke SoCs. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called pwm-goke. -+ - config PWM_IMG - tristate "Imagination Technologies PWM driver" - depends on HAS_IOMEM ---- linux-4.9.37/drivers/pwm/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/pwm/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -15,6 +15,7 @@ - obj-$(CONFIG_PWM_CROS_EC) += pwm-cros-ec.o - obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o - obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o -+obj-$(CONFIG_PWM_GOKE) += pwm-goke.o - obj-$(CONFIG_PWM_IMG) += pwm-img.o - obj-$(CONFIG_PWM_IMX) += pwm-imx.o - obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o ---- linux-4.9.37/drivers/pwm/pwm-goke.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/pwm/pwm-goke.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,260 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PWM_CFG0_ADDR(x) (((x)*0x20) + 0x0) -+#define PWM_CFG1_ADDR(x) (((x)*0x20) + 0x4) -+#define PWM_CFG2_ADDR(x) (((x)*0x20) + 0x8) -+#define PWM_CTRL_ADDR(x) (((x)*0x20) + 0xC) -+ -+#define PWM_ENABLE_SHIFT 0 -+#define PWM_ENABLE_MASK BIT(0) -+ -+#define PWM_POLARITY_SHIFT 1 -+#define PWM_POLARITY_MASK BIT(1) -+ -+#define PWM_KEEP_SHIFT 2 -+#define PWM_KEEP_MASK BIT(2) -+ -+#define PWM_PERIOD_MASK GENMASK(31, 0) -+#define PWM_DUTY_MASK GENMASK(31, 0) -+ -+struct goke_pwm_chip { -+ struct pwm_chip chip; -+ struct clk *clk; -+ void __iomem *base; -+ struct reset_control *rstc; -+}; -+ -+struct goke_pwm_soc { -+ u32 num_pwms; -+}; -+ -+static const struct goke_pwm_soc pwm_soc[1] = { -+ { .num_pwms = 2 }, -+}; -+ -+static inline struct goke_pwm_chip *to_goke_pwm_chip(struct pwm_chip *chip) -+{ -+ return container_of(chip, struct goke_pwm_chip, chip); -+} -+ -+static void goke_pwm_set_bits(void __iomem *base, u32 offset, -+ u32 mask, u32 data) -+{ -+ void __iomem *address = base + offset; -+ u32 value; -+ -+ value = readl(address); -+ value &= ~mask; -+ value |= (data & mask); -+ writel(value, address); -+} -+ -+static void goke_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); -+ -+ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), -+ PWM_ENABLE_MASK, 0x1); -+} -+ -+static void goke_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -+{ -+ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); -+ -+ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), -+ PWM_ENABLE_MASK, 0x0); -+} -+ -+static void goke_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, -+ int duty_cycle_ns, int period_ns) -+{ -+ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); -+ u32 duty; -+ u64 period, freq; -+ -+ freq = div_u64(clk_get_rate(bsp_pwm_chip->clk), 1000000); -+ -+ period = div_u64(freq * period_ns, 1000); -+ duty = div_u64(period * duty_cycle_ns, period_ns); -+ -+ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CFG0_ADDR(pwm->hwpwm), -+ PWM_PERIOD_MASK, period); -+ -+ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CFG1_ADDR(pwm->hwpwm), -+ PWM_DUTY_MASK, duty); -+} -+ -+static void goke_pwm_set_polarity(struct pwm_chip *chip, -+ struct pwm_device *pwm, -+ enum pwm_polarity polarity) -+{ -+ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); -+ -+ if (polarity == PWM_POLARITY_INVERSED) -+ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), -+ PWM_POLARITY_MASK, (0x1 << PWM_POLARITY_SHIFT)); -+ else -+ goke_pwm_set_bits(bsp_pwm_chip->base, PWM_CTRL_ADDR(pwm->hwpwm), -+ PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT)); -+} -+ -+static void goke_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, -+ struct pwm_state *state) { -+ struct goke_pwm_chip *bsp_pwm_chip = to_goke_pwm_chip(chip); -+ void __iomem *base; -+ u32 freq; -+ u64 value; -+ -+ freq = div_u64(clk_get_rate(bsp_pwm_chip->clk), 1000000); -+ base = bsp_pwm_chip->base; -+ -+ value = readl(base + PWM_CFG0_ADDR(pwm->hwpwm)); -+ state->period = div_u64(value * 1000, freq); -+ -+ value = readl(base + PWM_CFG1_ADDR(pwm->hwpwm)); -+ state->duty_cycle = div_u64(value * 1000, freq); -+ -+ value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm)); -+ state->enabled = (PWM_ENABLE_MASK & value); -+} -+ -+static int goke_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, -+ struct pwm_state *state) -+{ -+ if (state->polarity != pwm->state.polarity) { -+ goke_pwm_set_polarity(chip, pwm, state->polarity); -+ } -+ -+ if (state->period != pwm->state.period || -+ state->duty_cycle != pwm->state.duty_cycle) { -+ goke_pwm_config(chip, pwm, state->duty_cycle, state->period); -+ } -+ -+ if (state->enabled != pwm->state.enabled) { -+ if (state->enabled) { -+ goke_pwm_enable(chip, pwm); -+ } -+ else { -+ goke_pwm_disable(chip, pwm); -+ } -+ } -+ -+ return 0; -+} -+ -+static struct pwm_ops goke_pwm_ops = { -+ .get_state = goke_pwm_get_state, -+ .apply = goke_pwm_apply, -+ -+ .owner = THIS_MODULE, -+}; -+ -+static int goke_pwm_probe(struct platform_device *pdev) -+{ -+ const struct goke_pwm_soc *soc = -+ of_device_get_match_data(&pdev->dev); -+ struct goke_pwm_chip *pwm_chip; -+ struct resource *res; -+ int ret; -+ int i; -+ -+ pwm_chip = devm_kzalloc(&pdev->dev, sizeof(*pwm_chip), GFP_KERNEL); -+ if (pwm_chip == NULL) { -+ return -ENOMEM; -+ } -+ -+ pwm_chip->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(pwm_chip->clk)) { -+ dev_err(&pdev->dev, "getting clock failed with %ld\n", -+ PTR_ERR(pwm_chip->clk)); -+ return PTR_ERR(pwm_chip->clk); -+ } -+ -+ pwm_chip->chip.ops = &goke_pwm_ops; -+ pwm_chip->chip.dev = &pdev->dev; -+ pwm_chip->chip.base = -1; -+ pwm_chip->chip.npwm = soc->num_pwms; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ pwm_chip->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(pwm_chip->base)) { -+ return PTR_ERR(pwm_chip->base); -+ } -+ -+ ret = clk_prepare_enable(pwm_chip->clk); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ pwm_chip->rstc = devm_reset_control_get(&pdev->dev, NULL); -+ if (IS_ERR(pwm_chip->rstc)) { -+ clk_disable_unprepare(pwm_chip->clk); -+ return PTR_ERR(pwm_chip->rstc); -+ } -+ -+ reset_control_assert(pwm_chip->rstc); -+ msleep(30); -+ reset_control_deassert(pwm_chip->rstc); -+ -+ ret = pwmchip_add(&pwm_chip->chip); -+ if (ret < 0) { -+ clk_disable_unprepare(pwm_chip->clk); -+ return ret; -+ } -+ -+ for (i = 0; i < pwm_chip->chip.npwm; i++) { -+ goke_pwm_set_bits(pwm_chip->base, PWM_CTRL_ADDR(i), -+ PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT)); -+ } -+ -+ platform_set_drvdata(pdev, pwm_chip); -+ -+ return 0; -+} -+ -+static int goke_pwm_remove(struct platform_device *pdev) -+{ -+ struct goke_pwm_chip *pwm_chip; -+ -+ pwm_chip = platform_get_drvdata(pdev); -+ -+ reset_control_assert(pwm_chip->rstc); -+ msleep(30); -+ reset_control_deassert(pwm_chip->rstc); -+ -+ clk_disable_unprepare(pwm_chip->clk); -+ -+ return pwmchip_remove(&pwm_chip->chip); -+} -+ -+static const struct of_device_id goke_pwm_of_match[] = { -+ { .compatible = "goke,goke-pwm" }, -+ { .compatible = "goke,pwm", .data = &pwm_soc[0] }, {} -+}; -+MODULE_DEVICE_TABLE(of, goke_pwm_of_match); -+ -+static struct platform_driver goke_pwm_driver = { -+ .driver = { -+ .name = "goke-pwm", -+ .of_match_table = goke_pwm_of_match, -+ }, -+ .probe = goke_pwm_probe, -+ .remove = goke_pwm_remove, -+}; -+module_platform_driver(goke_pwm_driver); -+ -+MODULE_AUTHOR("Goke"); -+MODULE_DESCRIPTION("Goke SoCs PWM driver"); -+MODULE_LICENSE("GPL"); ---- linux-4.9.37/drivers/rtc/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/rtc/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -3,7 +3,7 @@ - # - - config RTC_LIB -- bool -+ bool "Real Time Clock LIB" - - config RTC_MC146818_LIB - bool -@@ -824,6 +824,14 @@ - # requires defining CMOS_READ/CMOS_WRITE, and a - # global rtc_lock ... it's not yet just another platform_device. - -+config RTC_DRV_GOKE -+ tristate "Goke RTC support" -+ help -+ Generic RTC framework driver for Goke SoCs. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called rtc. -+ - config RTC_DRV_CMOS - tristate "PC-style 'CMOS'" - depends on X86 || ARM || M32R || PPC || MIPS || SPARC64 || MN10300 ---- linux-4.9.37/drivers/rtc/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/rtc/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -68,6 +68,7 @@ - obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o - obj-$(CONFIG_RTC_DRV_GEMINI) += rtc-gemini.o - obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o -+obj-$(CONFIG_RTC_DRV_GOKE) += rtc-goke.o - obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o - obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o - obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o ---- linux-4.9.37/drivers/rtc/rtc-goke.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/rtc/rtc-goke.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,586 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+union u_spi_rw { -+ struct { -+ unsigned int spi_wdata : 8; /* [7:0] */ -+ unsigned int spi_rdata : 8; /* [15:8] */ -+ unsigned int spi_addr : 7; /* [22:16] */ -+ unsigned int spi_rw : 1; /* [23] */ -+ unsigned int spi_start : 1; /* [24] */ -+ unsigned int reserved : 6; /* [30:25] */ -+ unsigned int spi_busy : 1; /* [31] */ -+ } bits; -+ unsigned int u32; -+}; -+ -+#define SPI_CLK_DIV (0x000) -+#define SPI_RW (0x004) -+ -+#define SPI_WRITE (0) -+#define SPI_READ (1) -+ -+/* RTC REG */ -+#define RTC_10MS_COUN 0x00 -+#define RTC_S_COUNT 0x01 -+#define RTC_M_COUNT 0x02 -+#define RTC_H_COUNT 0x03 -+#define RTC_D_COUNT_L 0x04 -+#define RTC_D_COUNT_H 0x05 -+ -+#define RTC_MR_10MS 0x06 -+#define RTC_MR_S 0x07 -+#define RTC_MR_M 0x08 -+#define RTC_MR_H 0x09 -+#define RTC_MR_D_L 0x0A -+#define RTC_MR_D_H 0x0B -+ -+#define RTC_LR_10MS 0x0C -+#define RTC_LR_S 0x0D -+#define RTC_LR_M 0x0E -+#define RTC_LR_H 0x0F -+#define RTC_LR_D_L 0x10 -+#define RTC_LR_D_H 0x11 -+ -+#define RTC_LORD 0x12 -+ -+#define RTC_IMSC 0x13 -+#define RTC_INT_CLR 0x14 -+#define RTC_INT 0x15 -+#define RTC_INT_RAW 0x16 -+ -+#define RTC_CLK 0x17 -+#define RTC_POR_N 0x18 -+#define RTC_SAR_CTRL 0x1A -+#define RTC_CLK_CFG 0x1B -+ -+#define RTC_FREQ_H 0x51 -+#define RTC_FREQ_L 0x52 -+ -+#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) || \ -+ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) -+ -+#define RTC_REG_LOCK1 0x64 -+#define RTC_REG_LOCK2 0x65 -+#define RTC_REG_LOCK3 0x66 -+#define RTC_REG_LOCK4 0x67 -+#endif -+ -+ -+#define FREQ_H_DEFAULT 0x8 -+#define FREQ_L_DEFAULT 0x1B -+ -+#define LV_CTL_DEFAULT 0x20 -+#define CLK_DIV_DEFAULT 0x4 -+#define INT_RST_DEFAULT 0x0 -+#define INT_MSK_DEFAULT 0x4 -+ -+#define AIE_INT_MASK BIT(0) -+#define LV_INT_MASK BIT(1) -+#define REG_LOAD_STAT BIT(0) -+#define REG_LOCK_STAT BIT(1) -+#define REG_LOCK_BYPASS BIT(2) -+ -+#define RTC_RW_RETRY_CNT 5 -+#define SPI_RW_RETRY_CNT 500 -+#define RTC_SLEEP_TIME_MS 20 -+ -+#define DATE_TO_SEC(d, h, m, s) (s + m*60 + h*60*60 + d*24*60*60) -+#define SEC_TO_DAY(s) (s/(60*60*24)) -+ -+struct goke_rtc { -+ struct rtc_device *rtc_dev; -+ void __iomem *regs; -+ int rtc_irq; -+}; -+ -+static int goke_spi_write(void *spi_reg, unsigned char reg, -+ unsigned char val) -+{ -+ union u_spi_rw w_data, r_data; -+ int cnt = SPI_RW_RETRY_CNT; -+ -+ r_data.u32 = 0; -+ w_data.u32 = 0; -+ -+ w_data.bits.spi_wdata = val; -+ w_data.bits.spi_addr = reg; -+ w_data.bits.spi_rw = SPI_WRITE; -+ w_data.bits.spi_start = 0x1; -+ -+ writel(w_data.u32, (spi_reg+SPI_RW)); -+ -+ do -+ r_data.u32 = readl(spi_reg+SPI_RW); -+ while (r_data.bits.spi_busy && (--cnt)); -+ -+ if (r_data.bits.spi_busy) -+ return -EIO; -+ -+ return 0; -+} -+ -+ -+static int goke_spi_rtc_write(void *spi_reg, unsigned char reg, -+ unsigned char val) -+{ -+ return goke_spi_write(spi_reg, reg, val); -+} -+ -+static int goke_spi_read(void *spi_reg, unsigned char reg, -+ unsigned char *val) -+{ -+ union u_spi_rw w_data, r_data; -+ int cnt = SPI_RW_RETRY_CNT; -+ -+ r_data.u32 = 0; -+ w_data.u32 = 0; -+ w_data.bits.spi_addr = reg; -+ w_data.bits.spi_rw = SPI_READ; -+ w_data.bits.spi_start = 0x1; -+ -+ writel(w_data.u32, (spi_reg+SPI_RW)); -+ -+ do -+ r_data.u32 = readl(spi_reg+SPI_RW); -+ while (r_data.bits.spi_busy && (--cnt)); -+ -+ if (r_data.bits.spi_busy) -+ return -EIO; -+ -+ *val = r_data.bits.spi_rdata; -+ -+ return 0; -+} -+ -+static int goke_spi_rtc_read(void *spi_reg, unsigned char reg, -+ unsigned char *val) -+{ -+ return goke_spi_read(spi_reg, reg, val); -+} -+ -+static int goke_rtc_read_time(struct device *dev, struct rtc_time *time) -+{ -+ struct goke_rtc *rtc = dev_get_drvdata(dev); -+ unsigned char dayl = 0, dayh = 0; -+ unsigned char second = 0, minute = 0, hour = 0; -+ unsigned long seconds = 0; -+ unsigned int day = 0; -+ unsigned char raw_value = 0; -+ int cnt = RTC_RW_RETRY_CNT; -+ unsigned int ret = 0; -+ -+ ret = (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_INT_RAW, &raw_value); -+ if (ret) { -+ dev_err(dev, "IO err.\n"); -+ return ret; -+ } -+ -+ if (raw_value & LV_INT_MASK) { -+ //dev_err(dev, "low voltage detected, date/time is not reliable.\n"); -+ (unsigned int)goke_spi_write(rtc->regs, RTC_INT_CLR, 1); -+ //return -EINVAL; -+ } -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); -+ if (raw_value & REG_LOCK_BYPASS) -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LORD, -+ (~(REG_LOCK_BYPASS)) & raw_value); -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); -+ /* lock the time */ -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LORD, -+ (REG_LOCK_STAT) | raw_value); -+ /* wait rtc load flag */ -+ do { -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); -+ msleep(RTC_SLEEP_TIME_MS); -+ } while ((ret || (raw_value & REG_LOCK_STAT)) && (--cnt)); -+ -+ if (!ret && (raw_value & REG_LOCK_STAT)) -+ return -EBUSY; -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_S_COUNT, &second); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_M_COUNT, &minute); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_H_COUNT, &hour); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_D_COUNT_L, &dayl); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_D_COUNT_H, &dayh); -+ -+ if (ret) { -+ dev_err(dev, "IO err.\n"); -+ return ret; -+ } -+ -+ day = (dayl | (dayh << 8)); -+ seconds = DATE_TO_SEC(day, hour, minute, second); -+ -+ rtc_time_to_tm(seconds, time); -+ -+ return rtc_valid_tm(time); -+} -+ -+static int goke_rtc_set_time(struct device *dev, struct rtc_time *time) -+{ -+ struct goke_rtc *rtc = dev_get_drvdata(dev); -+ unsigned int ret = 0; -+ unsigned int days; -+ unsigned long seconds = 0; -+ unsigned int cnt = RTC_RW_RETRY_CNT; -+ unsigned char raw_value = 0; -+ -+ ret = rtc_tm_to_time(time, &seconds); -+ if (ret) -+ return ret; -+ days = SEC_TO_DAY(seconds); -+ -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_10MS, 0); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_S, time->tm_sec); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_M, time->tm_min); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_H, time->tm_hour); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_D_L, (days & 0xFF)); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LR_D_H, (days >> 8)); -+ -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_LORD, -+ (raw_value | REG_LOAD_STAT)); -+ /* wait rtc load flag */ -+ do { -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_LORD, &raw_value); -+ msleep(RTC_SLEEP_TIME_MS); -+ } while ((ret || (raw_value & REG_LOAD_STAT)) && (--cnt)); -+ -+ if (!ret && (raw_value & REG_LOAD_STAT)) -+ return -EBUSY; -+ -+ if (ret) -+ dev_err(dev, "IO err.\n"); -+ -+ return ret; -+} -+ -+static int goke_rtc_read_alarm(struct device *dev, -+ struct rtc_wkalrm *alrm) -+{ -+ struct goke_rtc *rtc = dev_get_drvdata(dev); -+ unsigned char dayl = 0, dayh = 0; -+ unsigned char second = 0, minute = 0, hour = 0; -+ unsigned long seconds = 0; -+ unsigned int day = 0; -+ unsigned char int_state = 0; -+ unsigned int ret = 0; -+ -+ memset(alrm, 0, sizeof(struct rtc_wkalrm)); -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_S, &second); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_M, &minute); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_H, &hour); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_D_L, &dayl); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_MR_D_H, &dayh); -+ -+ day = (unsigned int)(dayl | (dayh << 8)); -+ seconds = DATE_TO_SEC(day, hour, minute, second); -+ -+ rtc_time_to_tm(seconds, &alrm->time); -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_IMSC, &int_state); -+ if (ret) { -+ dev_err(dev, "IO err.\n"); -+ return ret; -+ } -+ -+ alrm->enabled = !!(int_state & AIE_INT_MASK); -+ alrm->pending = alrm->enabled; -+ -+ return 0; -+} -+ -+static int goke_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -+{ -+ struct goke_rtc *rtc = dev_get_drvdata(dev); -+ unsigned int days; -+ unsigned long seconds = 0; -+ unsigned char val = 0; -+ unsigned int ret = 0; -+ -+ rtc_tm_to_time(&alrm->time, &seconds); -+ -+ days = SEC_TO_DAY(seconds); -+ -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_10MS, 0); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_S, alrm->time.tm_sec); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_M, alrm->time.tm_min); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_H, alrm->time.tm_hour); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_D_L, (days & 0xFF)); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_MR_D_H, (days >> 8)); -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_IMSC, &val); -+ if (alrm->enabled) -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, -+ val | AIE_INT_MASK); -+ else -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, -+ val & ~AIE_INT_MASK); -+ -+ if (ret) { -+ dev_err(dev, "IO err.\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int goke_rtc_alarm_irq_enable(struct device *dev, -+ unsigned int enabled) -+{ -+ struct goke_rtc *rtc = dev_get_drvdata(dev); -+ unsigned char val = 0; -+ unsigned int ret = 0; -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_IMSC, &val); -+ if (enabled) -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, -+ val | AIE_INT_MASK); -+ else -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_IMSC, -+ val & ~AIE_INT_MASK); -+ -+ if (ret) { -+ dev_err(dev, "IO err.\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+ -+/* -+ * interrupt function -+ * do nothing. left for future -+ */ -+static irqreturn_t goke_rtc_alm_interrupt(int irq, void *data) -+{ -+ struct goke_rtc *rtc = (struct goke_rtc *)data; -+ unsigned char val = 0; -+ unsigned int ret = 0; -+ -+ ret |= (unsigned int)goke_spi_read(rtc->regs, RTC_INT, &val); -+ ret |= (unsigned int)goke_spi_write(rtc->regs, RTC_INT_CLR, AIE_INT_MASK); -+ -+ if (ret) { -+ dev_err(&rtc->rtc_dev->dev, "IO err.\n"); -+ return ret; -+ } -+ -+ if (val & AIE_INT_MASK) -+ rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); -+ -+ return IRQ_HANDLED; -+} -+ -+#define FREQ_MAX_VAL 3277000 -+#define FREQ_MIN_VAL 3276000 -+ -+static int goke_rtc_ioctl(struct device *dev, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct goke_rtc *rtc = dev_get_drvdata(dev); -+ unsigned int ret = 0; -+ -+ switch (cmd) { -+ case RTC_PLL_SET: { -+ char freq_l, freq_h; -+ struct rtc_pll_info pll_info; -+ -+ if (copy_from_user(&pll_info, (struct rtc_pll_info *)(uintptr_t)arg, -+ sizeof(struct rtc_pll_info))) -+ return -EFAULT; -+ -+ /* freq = 32700 + (freq /3052)*100 */ -+ if (pll_info.pll_value > FREQ_MAX_VAL -+ || pll_info.pll_value < FREQ_MIN_VAL) -+ return -EINVAL; -+ -+ pll_info.pll_value = (pll_info.pll_value - 3270000) -+ * 3052 / 10000; -+ -+ freq_l = (char)((unsigned int)pll_info.pll_value & 0xff); -+ freq_h = (char)(((unsigned int)pll_info.pll_value >> 8) & 0xf); -+ -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_FREQ_H, freq_h); -+ ret |= (unsigned int)goke_spi_rtc_write(rtc->regs, RTC_FREQ_L, freq_l); -+ -+ if (ret) { -+ dev_err(dev, "IO err.\n"); -+ return ret; -+ } -+ -+ return 0; -+ } -+ case RTC_PLL_GET: { -+ char freq_l, freq_h; -+ struct rtc_pll_info pll_info; -+ -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_FREQ_H, &freq_h); -+ ret |= (unsigned int)goke_spi_rtc_read(rtc->regs, RTC_FREQ_L, &freq_l); -+ -+ if (ret) { -+ dev_err(dev, "IO err.\n"); -+ return ret; -+ } -+ -+ pll_info.pll_value = (((unsigned char)freq_h & 0xf) << 8) + freq_l; -+ pll_info.pll_value = 3270000 -+ + (pll_info.pll_value * 10000) / 3052; -+ -+ pll_info.pll_max = FREQ_MAX_VAL; -+ pll_info.pll_min = FREQ_MIN_VAL; -+ -+ if (copy_to_user((void __user *)(uintptr_t)arg, -+ &pll_info, sizeof(struct rtc_pll_info))) -+ return -EFAULT; -+ -+ return 0; -+ } -+ default: -+ return -ENOIOCTLCMD; -+ } -+} -+ -+static const struct rtc_class_ops goke_rtc_ops = { -+ .read_time = goke_rtc_read_time, -+ .set_time = goke_rtc_set_time, -+ .read_alarm = goke_rtc_read_alarm, -+ .set_alarm = goke_rtc_set_alarm, -+ .alarm_irq_enable = goke_rtc_alarm_irq_enable, -+ .ioctl = goke_rtc_ioctl, -+}; -+ -+static int goke_rtc_init(struct goke_rtc *rtc) -+{ -+ void *spi_reg = rtc->regs; -+ unsigned int ret = 0; -+ unsigned char val = 0; -+ /* -+ * clk div value = (apb_clk/spi_clk)/2-1, -+ * apb clk = 100MHz, spi_clk = 10MHz,so value= 0x4 -+ */ -+ writel(CLK_DIV_DEFAULT, (spi_reg+SPI_CLK_DIV)); -+ -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_IMSC, INT_MSK_DEFAULT); -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_SAR_CTRL, LV_CTL_DEFAULT); -+ -+#if defined(CONFIG_ARCH_GK7205V200) || defined(CONFIG_ARCH_GK7205V300) || \ -+ defined(CONFIG_ARCH_GK7202V300) || defined(CONFIG_ARCH_GK7605V100) -+ /* default driver capability */ -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK4, 0x5A); -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK3, 0x5A); -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK2, 0xAB); -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_REG_LOCK1, 0xCD); -+#endif -+ -+ /*driver capability */ -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_CLK_CFG, 0x01); -+ -+ /* default FREQ COEF */ -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_FREQ_H, FREQ_H_DEFAULT); -+ ret |= (unsigned int)goke_spi_rtc_write(spi_reg, RTC_FREQ_L, FREQ_L_DEFAULT); -+ -+ ret |= (unsigned int)goke_spi_rtc_read(spi_reg, RTC_INT_RAW, &val); -+ if (ret) { -+ dev_err(&rtc->rtc_dev->dev, "IO err.\n"); -+ return ret; -+ } -+ -+ if (val & LV_INT_MASK) { -+ /* dev_err(&rtc->rtc_dev->dev, -+ "low voltage detected, date/time is not reliable.\n"); */ -+ goke_spi_write(rtc->regs, RTC_INT_CLR, 1); -+ } -+ -+ return ret; -+} -+ -+static int goke_rtc_probe(struct platform_device *pdev) -+{ -+ struct resource *mem = NULL; -+ struct goke_rtc *rtc; -+ int ret; -+ -+ rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); -+ if (!rtc) -+ return -ENOMEM; -+ -+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ rtc->regs = devm_ioremap_resource(&pdev->dev, mem); -+ if (IS_ERR((const void *)rtc->regs)) { -+ dev_err(&pdev->dev, "could not map I/O memory\n"); -+ return PTR_ERR((const void *)rtc->regs); -+ } -+ -+ rtc->rtc_irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(&pdev->dev, rtc->rtc_irq, -+ goke_rtc_alm_interrupt, 0, pdev->name, rtc); -+ if (ret) { -+ dev_err(&pdev->dev, "could not request irq %d\n", rtc->rtc_irq); -+ return ret; -+ } -+ -+ platform_set_drvdata(pdev, rtc); -+ rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, -+ &goke_rtc_ops, THIS_MODULE); -+ if (IS_ERR(rtc->rtc_dev)) { -+ dev_err(&pdev->dev, "could not register rtc device\n"); -+ return PTR_ERR(rtc->rtc_dev); -+ } -+ -+ if (goke_rtc_init(rtc)) { -+ dev_err(&pdev->dev, "goke_rtc_init failed.\n"); -+ return -EIO; -+ } -+ -+ dev_info(&pdev->dev, "RTC driver for goke enabled\n"); -+ -+ return 0; -+} -+ -+static int goke_rtc_remove(struct platform_device *pdev) -+{ -+ return 0; -+} -+ -+static const struct of_device_id goke_rtc_match[] = { -+ { .compatible = "goke,rtc" }, -+ {}, -+}; -+ -+static struct platform_driver goke_rtc_driver = { -+ .probe = goke_rtc_probe, -+ .remove = goke_rtc_remove, -+ .driver = { -+ .name = "goke_rtc", -+ .of_match_table = goke_rtc_match, -+ }, -+}; -+ -+module_platform_driver(goke_rtc_driver); -+ -+ -+MODULE_AUTHOR("Goke"); -+MODULE_DESCRIPTION("Goke RTC driver"); -+MODULE_LICENSE("GPL v2"); -+ ---- linux-4.9.37/drivers/scsi/scsi_lib.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/scsi/scsi_lib.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1420,7 +1420,7 @@ - if (scsi_host_in_recovery(shost)) - return 0; - -- busy = atomic_inc_return(&shost->host_busy) - 1; -+ busy = atomic_read(&shost->host_busy); - if (atomic_read(&shost->host_blocked) > 0) { - if (busy) - goto starved; -@@ -1429,7 +1429,7 @@ - * unblock after host_blocked iterates to zero - */ - if (atomic_dec_return(&shost->host_blocked) > 0) -- goto out_dec; -+ goto out; - - SCSI_LOG_MLQUEUE(3, - shost_printk(KERN_INFO, shost, -@@ -1449,6 +1449,7 @@ - spin_unlock_irq(shost->host_lock); - } - -+ atomic_inc(&shost->host_busy); - return 1; - - starved: -@@ -1456,8 +1457,7 @@ - if (list_empty(&sdev->starved_entry)) - list_add_tail(&sdev->starved_entry, &shost->starved_list); - spin_unlock_irq(shost->host_lock); --out_dec: -- atomic_dec(&shost->host_busy); -+out: - return 0; - } - ---- linux-4.9.37/drivers/spi/spi.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/spi/spi.c 2021-06-07 13:01:34.000000000 +0300 -@@ -323,11 +323,125 @@ - return 0; - } - -+#ifdef CONFIG_PM_SLEEP -+static int spi_legacy_suspend(struct device *dev, pm_message_t message) -+{ -+ int value = 0; -+ struct spi_driver *drv = to_spi_driver(dev->driver); -+ -+ /* suspend will stop irqs and dma; no more i/o */ -+ if (drv) { -+ if (drv->suspend) -+ value = drv->suspend(to_spi_device(dev), message); -+ else -+ dev_dbg(dev, "... can't suspend\n"); -+ } -+ return value; -+} -+ -+static int spi_legacy_resume(struct device *dev) -+{ -+ int value = 0; -+ struct spi_driver *drv = to_spi_driver(dev->driver); -+ -+ /* resume may restart the i/o queue */ -+ if (drv) { -+ if (drv->resume) -+ value = drv->resume(to_spi_device(dev)); -+ else -+ dev_dbg(dev, "... can't resume\n"); -+ } -+ return value; -+} -+ -+static int spi_pm_suspend(struct device *dev) -+{ -+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; -+ -+ if (pm) -+ return pm_generic_suspend(dev); -+ else -+ return spi_legacy_suspend(dev, PMSG_SUSPEND); -+} -+ -+static int spi_pm_resume(struct device *dev) -+{ -+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; -+ -+ if (pm) -+ return pm_generic_resume(dev); -+ else -+ return spi_legacy_resume(dev); -+} -+ -+static int spi_pm_freeze(struct device *dev) -+{ -+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; -+ -+ if (pm) -+ return pm_generic_freeze(dev); -+ else -+ return spi_legacy_suspend(dev, PMSG_FREEZE); -+} -+ -+static int spi_pm_thaw(struct device *dev) -+{ -+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; -+ -+ if (pm) -+ return pm_generic_thaw(dev); -+ else -+ return spi_legacy_resume(dev); -+} -+ -+static int spi_pm_poweroff(struct device *dev) -+{ -+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; -+ -+ if (pm) -+ return pm_generic_poweroff(dev); -+ else -+ return spi_legacy_suspend(dev, PMSG_HIBERNATE); -+} -+ -+static int spi_pm_restore(struct device *dev) -+{ -+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; -+ -+ if (pm) -+ return pm_generic_restore(dev); -+ else -+ return spi_legacy_resume(dev); -+} -+#else -+#define spi_pm_suspend NULL -+#define spi_pm_resume NULL -+#define spi_pm_freeze NULL -+#define spi_pm_thaw NULL -+#define spi_pm_poweroff NULL -+#define spi_pm_restore NULL -+#endif -+ -+static const struct dev_pm_ops spi_pm = { -+ .suspend = spi_pm_suspend, -+ .resume = spi_pm_resume, -+ .freeze = spi_pm_freeze, -+ .thaw = spi_pm_thaw, -+ .poweroff = spi_pm_poweroff, -+ .restore = spi_pm_restore, -+ SET_RUNTIME_PM_OPS( -+ pm_generic_runtime_suspend, -+ pm_generic_runtime_resume, -+ NULL -+ ) -+}; -+ - struct bus_type spi_bus_type = { - .name = "spi", - .dev_groups = spi_dev_groups, - .match = spi_match_device, - .uevent = spi_uevent, -+ .pm = &spi_pm, - }; - EXPORT_SYMBOL_GPL(spi_bus_type); - ---- linux-4.9.37/drivers/spi/spi-pl022.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/spi/spi-pl022.c 2021-06-07 13:01:34.000000000 +0300 -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - - /* - * This macro is used to define some register default values. -@@ -136,6 +137,18 @@ - /* This one is only in the PL023 variant */ - #define SSP_CR1_MASK_FBCLKDEL_ST (0x7UL << 13) - -+#ifdef CONFIG_ARCH_GOKE -+/* -+ * The Goke version of this block adds some bits -+ * in SSP_CR1 -+ */ -+#define SSP_CR1_MASK_BIGEND_GOKE (0x1UL << 4) -+#define SSP_CR1_MASK_ALTASENS_GOKE (0x1UL << 6) -+ -+#define SSP_TX_FIFO_CR(r) (r + 0x28) -+#define SSP_RX_FIFO_CR(r) (r + 0x2C) -+#endif -+ - /* - * SSP Status Register - SSP_SR - */ -@@ -296,6 +309,10 @@ - - #define SPI_POLLING_TIMEOUT 1000 - -+#ifdef CONFIG_ARCH_GOKE -+#define PL022_IDS_INDEX_GOKE 4 -+#endif -+ - /* - * The type of reading going on on this chip - */ -@@ -337,6 +354,15 @@ - bool internal_cs_ctrl; - }; - -+#ifdef CONFIG_ARCH_GOKE -+struct cs_data { -+ struct resource res; -+ void __iomem *virt_addr; -+ unsigned int cs_sb; -+ unsigned int cs_mask_bit; -+}; -+#endif -+ - /** - * struct pl022 - This is the private SSP driver data structure - * @adev: AMBA device model hookup -@@ -346,6 +372,13 @@ - * @clk: outgoing clock "SPICLK" for the SPI bus - * @master: SPI framework hookup - * @master_info: controller-specific data from machine setup -+ * @kworker: thread struct for message pump -+ * @kworker_task: pointer to task for message pump kworker thread -+ * @pump_messages: work struct for scheduling work to the message pump -+ * @queue_lock: spinlock to syncronise access to message queue -+ * @queue: message queue -+ * @busy: message pump is busy -+ * @running: message pump is running - * @pump_transfers: Tasklet used in Interrupt Transfer mode - * @cur_msg: Pointer to current spi_message being processed - * @cur_transfer: Pointer to current spi_transfer -@@ -403,6 +436,9 @@ - #endif - int cur_cs; - int *chipselects; -+#ifdef CONFIG_ARCH_GOKE -+ struct cs_data *cs_data; -+#endif - }; - - /** -@@ -459,13 +495,41 @@ - static void internal_cs_control(struct pl022 *pl022, u32 command) - { - u32 tmp; -- -+#ifdef CONFIG_ARCH_GOKE -+ struct amba_device *adev = pl022->adev; -+ struct amba_driver *adrv = container_of(adev->dev.driver, -+ struct amba_driver, drv); -+ -+ if (pl022->vendor->extended_cr && (adev->periphid == -+ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) { -+ if (pl022->cs_data) { -+ tmp = readl(pl022->cs_data->virt_addr); -+ tmp &= ~(pl022->cs_data->cs_mask_bit); -+ tmp |= ((u32)pl022->cur_cs) << pl022->cs_data->cs_sb; -+ writel(tmp, pl022->cs_data->virt_addr); -+ } -+ -+ if (command == SSP_CHIP_SELECT) -+ /* Enable SSP */ -+ writew((readw(SSP_CR1(pl022->virtbase)) | -+ SSP_CR1_MASK_SSE), -+ SSP_CR1(pl022->virtbase)); -+ else -+ /* disable SSP */ -+ writew((readw(SSP_CR1(pl022->virtbase)) & -+ (~SSP_CR1_MASK_SSE)), -+ SSP_CR1(pl022->virtbase)); -+ } else { -+#endif - tmp = readw(SSP_CSR(pl022->virtbase)); - if (command == SSP_CHIP_SELECT) -- tmp &= ~BIT(pl022->cur_cs); -+ tmp &= ~BIT((u32)pl022->cur_cs); - else -- tmp |= BIT(pl022->cur_cs); -+ tmp |= BIT((u32)pl022->cur_cs); - writew(tmp, SSP_CSR(pl022->virtbase)); -+#ifdef CONFIG_ARCH_GOKE -+ } -+#endif - } - - static void pl022_cs_control(struct pl022 *pl022, u32 command) -@@ -566,8 +630,16 @@ - static void restore_state(struct pl022 *pl022) - { - struct chip_data *chip = pl022->cur_chip; -+#ifdef CONFIG_ARCH_GOKE -+ struct amba_device *adev = pl022->adev; -+ struct amba_driver *adrv = container_of(adev->dev.driver, -+ struct amba_driver, drv); - -+ if (pl022->vendor->extended_cr && (adev->periphid != -+ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) -+#else - if (pl022->vendor->extended_cr) -+#endif - writel(chip->cr0, SSP_CR0(pl022->virtbase)); - else - writew(chip->cr0, SSP_CR0(pl022->virtbase)); -@@ -640,6 +712,15 @@ - GEN_MASK_BITS(SSP_FEEDBACK_CLK_DELAY_NONE, SSP_CR1_MASK_FBCLKDEL_ST, 13) \ - ) - -+#ifdef CONFIG_ARCH_GOKE -+/* Goke versions extend this register to use all 16 bits */ -+#define DEFAULT_SSP_REG_CR1_GOKE ( \ -+ DEFAULT_SSP_REG_CR1 | \ -+ GEN_MASK_BITS(SSP_RX_MSB, SSP_CR1_MASK_BIGEND_GOKE, 4) | \ -+ GEN_MASK_BITS(0x0, SSP_CR1_MASK_ALTASENS_GOKE, 6) \ -+) -+#endif -+ - #define DEFAULT_SSP_REG_CPSR ( \ - GEN_MASK_BITS(SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \ - ) -@@ -659,8 +740,22 @@ - writel(DEFAULT_SSP_REG_CR0_ST_PL023, SSP_CR0(pl022->virtbase)); - writew(DEFAULT_SSP_REG_CR1_ST_PL023, SSP_CR1(pl022->virtbase)); - } else if (pl022->vendor->extended_cr) { -+#ifdef CONFIG_ARCH_GOKE -+ struct amba_device *adev = pl022->adev; -+ struct amba_driver *adrv = container_of(adev->dev.driver, -+ struct amba_driver, drv); -+ -+ if (adev->periphid == adrv->id_table[PL022_IDS_INDEX_GOKE].id) { -+ writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); -+ writew(DEFAULT_SSP_REG_CR1_GOKE, -+ SSP_CR1(pl022->virtbase)); -+ } else { -+#endif - writel(DEFAULT_SSP_REG_CR0_ST, SSP_CR0(pl022->virtbase)); - writew(DEFAULT_SSP_REG_CR1_ST, SSP_CR1(pl022->virtbase)); -+#ifdef CONFIG_ARCH_GOKE -+ } -+#endif - } else { - writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase)); - writew(DEFAULT_SSP_REG_CR1, SSP_CR1(pl022->virtbase)); -@@ -1803,7 +1898,7 @@ - .com_mode = POLLING_TRANSFER, - .iface = SSP_INTERFACE_MOTOROLA_SPI, - .hierarchy = SSP_SLAVE, -- .slave_tx_disable = DO_NOT_DRIVE_TX, -+ .slave_tx_disable = DRIVE_TX, - .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, - .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, - .ctrl_len = SSP_BITS_8, -@@ -1835,6 +1930,13 @@ - unsigned int bits = spi->bits_per_word; - u32 tmp; - struct device_node *np = spi->dev.of_node; -+#ifdef CONFIG_ARCH_GOKE -+ struct amba_device *adev = pl022->adev; -+ struct amba_driver *adrv = container_of(adev->dev.driver, -+ struct amba_driver, drv); -+ writel(0, SSP_TX_FIFO_CR(pl022->virtbase)); -+ writel(0, SSP_RX_FIFO_CR(pl022->virtbase)); -+#endif - - if (!spi->max_speed_hz) - return -EINVAL; -@@ -1856,8 +1958,10 @@ - if (chip_info == NULL) { - if (np) { - chip_info_dt = pl022_default_chip_info; -- -- chip_info_dt.hierarchy = SSP_MASTER; -+ if(pl022->master->slave) -+ chip_info_dt.hierarchy = SSP_SLAVE; -+ else -+ chip_info_dt.hierarchy = SSP_MASTER; - of_property_read_u32(np, "pl022,interface", - &chip_info_dt.iface); - of_property_read_u32(np, "pl022,com-mode", -@@ -1977,7 +2081,12 @@ - chip->cpsr = clk_freq.cpsdvsr; - - /* Special setup for the ST micro extended control registers */ -+#ifdef CONFIG_ARCH_GOKE -+ if (pl022->vendor->extended_cr && (adev->periphid != -+ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) { -+#else - if (pl022->vendor->extended_cr) { -+#endif - u32 etx; - - if (pl022->vendor->pl023) { -@@ -2011,6 +2120,22 @@ - SSP_CR1_MASK_RXIFLSEL_ST, 7); - SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig, - SSP_CR1_MASK_TXIFLSEL_ST, 10); -+#ifdef CONFIG_ARCH_GOKE -+ } else if (pl022->vendor->extended_cr && (adev->periphid == -+ adrv->id_table[PL022_IDS_INDEX_GOKE].id)) { -+ SSP_WRITE_BITS(chip->cr0, bits - 1, -+ SSP_CR0_MASK_DSS, 0); -+ SSP_WRITE_BITS(chip->cr0, chip_info->iface, -+ SSP_CR0_MASK_FRF, 4); -+ -+ if (spi->mode & SPI_LSB_FIRST) -+ tmp = !!SPI_LSB_FIRST; -+ else -+ tmp = !SPI_LSB_FIRST; -+ -+ SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_BIGEND_GOKE, 4); -+ SSP_WRITE_BITS(chip->cr1, 0x0, SSP_CR1_MASK_ALTASENS_GOKE, 6); -+#endif - } else { - SSP_WRITE_BITS(chip->cr0, bits - 1, - SSP_CR0_MASK_DSS, 0); -@@ -2099,11 +2224,14 @@ - static int pl022_probe(struct amba_device *adev, const struct amba_id *id) - { - struct device *dev = &adev->dev; -+ struct amba_driver *adrv = container_of(adev->dev.driver, -+ struct amba_driver, drv); - struct pl022_ssp_controller *platform_info = - dev_get_platdata(&adev->dev); - struct spi_master *master; - struct pl022 *pl022 = NULL; /*Data for this driver */ - struct device_node *np = adev->dev.of_node; -+ unsigned int slave_mode; - int status = 0, i, num_cs; - - dev_info(&adev->dev, -@@ -2156,12 +2284,62 @@ - master->rt = platform_info->rt; - master->dev.of_node = dev->of_node; - -+ if (of_property_read_u32(np, "pl022,slave_mode", -+ &slave_mode) == 0) { -+ if (slave_mode == 1){ -+ master->slave = true; -+ } else if (slave_mode == 0) { -+ master->slave = false; -+ } else { -+ dev_err(&adev->dev, "spi Master/Slave mode err!!!\n"); -+ goto err_no_gpio; -+ } -+ -+ } -+ - if (platform_info->num_chipselect && platform_info->chipselects) { - for (i = 0; i < num_cs; i++) - pl022->chipselects[i] = platform_info->chipselects[i]; - } else if (pl022->vendor->internal_cs_ctrl) { - for (i = 0; i < num_cs; i++) - pl022->chipselects[i] = i; -+ -+#ifdef CONFIG_ARCH_GOKE -+ if ((adev->periphid == adrv->id_table[PL022_IDS_INDEX_GOKE].id) -+ && pl022->vendor->extended_cr -+ && (num_cs > 1)) { -+ pl022->cs_data = devm_kzalloc(dev, -+ sizeof(struct cs_data), -+ GFP_KERNEL); -+ if (!pl022->cs_data) { -+ status = -ENOMEM; -+ goto err_no_mem; -+ } -+ -+ if (of_address_to_resource(np, 1, -+ &pl022->cs_data->res)) { -+ status = -EPROBE_DEFER; -+ goto err_no_gpio; -+ } -+ -+ if (of_property_read_u32(np, "spi_cs_sb", -+ &pl022->cs_data->cs_sb)) { -+ status = -EPROBE_DEFER; -+ goto err_no_gpio; -+ } -+ -+ if (of_property_read_u32(np, "spi_cs_mask_bit", -+ &pl022->cs_data->cs_mask_bit)) { -+ status = -EPROBE_DEFER; -+ goto err_no_gpio; -+ } -+ -+ pl022->cs_data->virt_addr = devm_ioremap(dev, -+ pl022->cs_data->res.start, -+ resource_size(&adev->res)); -+ } else -+ pl022->cs_data = NULL; -+#endif - } else if (IS_ENABLED(CONFIG_OF)) { - for (i = 0; i < num_cs; i++) { - int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); -@@ -2288,6 +2466,11 @@ - err_no_ioremap: - amba_release_regions(adev); - err_no_ioregion: -+#ifdef CONFIG_ARCH_GOKE -+ if (pl022->cs_data) -+ release_mem_region(pl022->cs_data->res.start, -+ resource_size(&pl022->cs_data->res)); -+#endif - err_no_gpio: - err_no_mem: - spi_master_put(master); -@@ -2314,6 +2497,11 @@ - - clk_disable_unprepare(pl022->clk); - amba_release_regions(adev); -+#ifdef CONFIG_ARCH_GOKE -+ if (pl022->cs_data) -+ release_mem_region(pl022->cs_data->res.start, -+ resource_size(&pl022->cs_data->res)); -+#endif - tasklet_disable(&pl022->pump_transfers); - return 0; - } -@@ -2390,13 +2578,13 @@ - }; - - static struct vendor_data vendor_arm = { -- .fifodepth = 8, -+ .fifodepth = 256, - .max_bpw = 16, - .unidir = false, -- .extended_cr = false, -+ .extended_cr = true, - .pl023 = false, - .loopback = true, -- .internal_cs_ctrl = false, -+ .internal_cs_ctrl = true, - }; - - static struct vendor_data vendor_st = { -@@ -2433,7 +2621,7 @@ - { - /* - * ARM PL022 variant, this has a 16bit wide -- * and 8 locations deep TX/RX FIFO -+ * and 256 locations deep TX/RX FIFO - */ - .id = 0x00041022, - .mask = 0x000fffff, ---- linux-4.9.37/drivers/tty/serial/amba-pl011.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/tty/serial/amba-pl011.c 2021-06-07 13:01:34.000000000 +0300 -@@ -109,12 +109,20 @@ - - static unsigned int get_fifosize_arm(struct amba_device *dev) - { -+#ifdef CONFIG_ARCH_GOKE -+ return 64; -+#else - return amba_rev(dev) < 3 ? 16 : 32; -+#endif - } - - static struct vendor_data vendor_arm = { - .reg_offset = pl011_std_offsets, -+#ifdef CONFIG_ARCH_GOKE -+ .ifls = UART011_IFLS_RX1_8|UART011_IFLS_TX1_8, -+#else - .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, -+#endif - .fr_busy = UART01x_FR_BUSY, - .fr_dsr = UART01x_FR_DSR, - .fr_cts = UART01x_FR_CTS, -@@ -405,7 +413,11 @@ - pl011_reg_to_offset(uap, REG_DR), - .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, - .direction = DMA_MEM_TO_DEV, -+#ifdef CONFIG_ARCH_GOKE -+ .dst_maxburst = 7, -+#else - .dst_maxburst = uap->fifosize >> 1, -+#endif - .device_fc = false, - }; - struct dma_chan *chan; -@@ -461,7 +473,11 @@ - pl011_reg_to_offset(uap, REG_DR), - .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, - .direction = DMA_DEV_TO_MEM, -+#ifdef CONFIG_ARCH_GOKE -+ .src_maxburst = 7, -+#else - .src_maxburst = uap->fifosize >> 2, -+#endif - .device_fc = false, - }; - struct dma_slave_caps caps; ---- linux-4.9.37/drivers/tty/vt/selection.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/tty/vt/selection.c 2021-06-07 13:01:34.000000000 +0300 -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -40,6 +41,7 @@ - static int sel_end; - static int sel_buffer_lth; - static char *sel_buffer; -+static DEFINE_MUTEX(sel_lock); - - /* clear_selection, highlight and highlight_pointer can be called - from interrupt (via scrollback/front) */ -@@ -163,7 +165,7 @@ - char *bp, *obp; - int i, ps, pe, multiplier; - u16 c; -- int mode; -+ int mode, ret = 0; - - poke_blanked_console(); - -@@ -203,6 +205,7 @@ - pe = tmp; - } - -+ mutex_lock(&sel_lock); - if (sel_cons != vc_cons[fg_console].d) { - clear_selection(); - sel_cons = vc_cons[fg_console].d; -@@ -248,9 +251,10 @@ - break; - case TIOCL_SELPOINTER: - highlight_pointer(pe); -- return 0; -+ goto unlock; - default: -- return -EINVAL; -+ ret = -EINVAL; -+ goto unlock; - } - - /* remove the pointer */ -@@ -272,7 +276,7 @@ - else if (new_sel_start == sel_start) - { - if (new_sel_end == sel_end) /* no action required */ -- return 0; -+ goto unlock; - else if (new_sel_end > sel_end) /* extend to right */ - highlight(sel_end + 2, new_sel_end); - else /* contract from right */ -@@ -299,7 +303,8 @@ - if (!bp) { - printk(KERN_WARNING "selection: kmalloc() failed\n"); - clear_selection(); -- return -ENOMEM; -+ ret = -ENOMEM; -+ goto unlock; - } - kfree(sel_buffer); - sel_buffer = bp; -@@ -324,7 +329,9 @@ - } - } - sel_buffer_lth = bp - sel_buffer; -- return 0; -+unlock: -+ mutex_unlock(&sel_lock); -+ return ret; - } - - /* Insert the contents of the selection buffer into the -@@ -352,10 +359,13 @@ - tty_buffer_lock_exclusive(&vc->port); - - add_wait_queue(&vc->paste_wait, &wait); -+ mutex_lock(&sel_lock); - while (sel_buffer && sel_buffer_lth > pasted) { - set_current_state(TASK_INTERRUPTIBLE); - if (tty_throttled(tty)) { -+ mutex_unlock(&sel_lock); - schedule(); -+ mutex_lock(&sel_lock); - continue; - } - __set_current_state(TASK_RUNNING); -@@ -364,6 +374,7 @@ - count); - pasted += count; - } -+ mutex_unlock(&sel_lock); - remove_wait_queue(&vc->paste_wait, &wait); - __set_current_state(TASK_RUNNING); - ---- linux-4.9.37/drivers/usb/core/devices.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/core/devices.c 2021-06-07 13:01:34.000000000 +0300 -@@ -182,14 +182,8 @@ - - dir = usb_endpoint_dir_in(desc) ? 'I' : 'O'; - -- if (speed == USB_SPEED_HIGH) { -- switch (usb_endpoint_maxp(desc) & (0x03 << 11)) { -- case 1 << 11: -- bandwidth = 2; break; -- case 2 << 11: -- bandwidth = 3; break; -- } -- } -+ if (speed == USB_SPEED_HIGH) -+ bandwidth = usb_endpoint_maxp_mult(desc); - - /* this isn't checking for illegal values */ - switch (usb_endpoint_type(desc)) { ---- linux-4.9.37/drivers/usb/core/hub.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/core/hub.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1345,6 +1345,10 @@ - ret = -ENODEV; - goto fail; - } else if (hub->descriptor->bNbrPorts == 0) { -+ if (!hdev->parent) { -+ dev_info(hub_dev, "hub can't support USB3.0\n"); -+ return -ENODEV; -+ } - message = "hub doesn't have any ports!"; - ret = -ENODEV; - goto fail; ---- linux-4.9.37/drivers/usb/core/urb.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/core/urb.c 2021-06-07 13:01:34.000000000 +0300 -@@ -407,11 +407,8 @@ - } - - /* "high bandwidth" mode, 1-3 packets/uframe? */ -- if (dev->speed == USB_SPEED_HIGH) { -- int mult = 1 + ((max >> 11) & 0x03); -- max &= 0x07ff; -- max *= mult; -- } -+ if (dev->speed == USB_SPEED_HIGH) -+ max *= usb_endpoint_maxp_mult(&ep->desc); - - if (urb->number_of_packets <= 0) - return -EINVAL; ---- linux-4.9.37/drivers/usb/dwc3/core.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/core.c 2021-06-07 13:01:34.000000000 +0300 -@@ -44,11 +44,27 @@ - #include "core.h" - #include "gadget.h" - #include "io.h" -+#include "dwc3-goke.h" - - #include "debug.h" - - #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ - -+ -+/* -+ * Default to the number of outstanding pipelined transfer -+ * requests is 0x3[11:8], modify the field change to 0x7. -+ */ -+static void dwc3_outstanding_pipe_choose(struct dwc3 *dwc) -+{ -+ u32 reg; -+ -+ reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1); -+ reg &= ~DWC3_PIPE_TRANS_LIMIT_MASK; -+ reg |= DWC3_PIPE_TRANS_LIMIT; -+ dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg); -+} -+ - /** - * dwc3_get_dr_mode - Validates and sets dr_mode - * @dwc: pointer to our context structure -@@ -305,13 +321,7 @@ - struct dwc3_event_buffer *evt; - - evt = dwc->ev_buf; -- dwc3_trace(trace_dwc3_core, -- "Event buf %p dma %08llx length %d\n", -- evt->buf, (unsigned long long) evt->dma, -- evt->length); -- - evt->lpos = 0; -- - dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), - lower_32_bits(evt->dma)); - dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), -@@ -428,9 +438,6 @@ - - dwc->num_in_eps = DWC3_NUM_IN_EPS(parms); - dwc->num_out_eps = DWC3_NUM_EPS(parms) - dwc->num_in_eps; -- -- dwc3_trace(trace_dwc3_core, "found %d IN and %d OUT endpoints", -- dwc->num_in_eps, dwc->num_out_eps); - } - - static void dwc3_cache_hwparams(struct dwc3 *dwc) -@@ -683,13 +690,13 @@ - reg |= DWC3_GCTL_GBLHIBERNATIONEN; - break; - default: -- dwc3_trace(trace_dwc3_core, "No power optimization available\n"); -+ /* nothing */ -+ break; - } - - /* check if current dwc3 is on simulation board */ - if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { -- dwc3_trace(trace_dwc3_core, -- "running on FPGA platform\n"); -+ dev_info(dwc->dev, "Running with FPGA optmizations\n"); - dwc->is_fpga = true; - } - -@@ -982,7 +989,8 @@ - */ - hird_threshold = 12; - -- dwc->maximum_speed = usb_get_maximum_speed(dev); -+ dwc->maximum_speed = usb_get_max_speed(dev); -+ - dwc->dr_mode = usb_get_dr_mode(dev); - dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); - -@@ -996,6 +1004,8 @@ - &hird_threshold); - dwc->usb3_lpm_capable = device_property_read_bool(dev, - "snps,usb3_lpm_capable"); -+ dwc->usb2_lpm_disable = device_property_read_bool(dev, -+ "snps,usb2-lpm-disable"); - - dwc->disable_scramble_quirk = device_property_read_bool(dev, - "snps,disable_scramble_quirk"); -@@ -1026,6 +1036,16 @@ - dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev, - "snps,dis-del-phy-power-chg-quirk"); - -+ dwc->dis_initiate_u1 = device_property_read_bool(dev, -+ "snps,dis_initiate_u1"); -+ dwc->dis_initiate_u2 = device_property_read_bool(dev, -+ "snps,dis_initiate_u2"); -+ -+ dwc->eps_new_init = device_property_read_bool(dev, -+ "snps,eps_new_init"); -+ device_property_read_u32(dev, "eps_directions", -+ &dwc->eps_directions); -+ - dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, - "snps,tx_de_emphasis_quirk"); - device_property_read_u8(dev, "snps,tx_de_emphasis", -@@ -1044,6 +1064,10 @@ - platform_set_drvdata(pdev, dwc); - dwc3_cache_hwparams(dwc); - -+ device_property_read_u32_array(dev, "eps_map", -+ dwc->dwceps_map_to_usbeps, -+ DWC3_NUM_EPS(&dwc->hwparams)); -+ - ret = dwc3_core_get_phy(dwc); - if (ret) - goto err0; -@@ -1087,6 +1111,8 @@ - goto err4; - } - -+ dwc3_outstanding_pipe_choose(dwc); -+ - /* Check the maximum_speed parameter */ - switch (dwc->maximum_speed) { - case USB_SPEED_LOW: -@@ -1177,6 +1203,10 @@ - dwc3_free_event_buffers(dwc); - dwc3_free_scratch_buffers(dwc); - -+ bsp_dwc3_exited(); -+ -+ dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST); -+ - return 0; - } - ---- linux-4.9.37/drivers/usb/dwc3/core.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/core.h 2021-06-07 13:01:34.000000000 +0300 -@@ -35,6 +35,8 @@ - #include - - #define DWC3_MSG_MAX 500 -+#define DWC3_PIPE_TRANS_LIMIT_MASK (0xf << 8) -+#define DWC3_PIPE_TRANS_LIMIT (0x7 << 8) - - /* Global constants */ - #define DWC3_ZLP_BUF_SIZE 1024 /* size of a superspeed bulk */ -@@ -386,6 +388,9 @@ - - #define DWC3_DSTS_RXFIFOEMPTY (1 << 17) - -+#define DWC3_EVENT_PRAM_MAX_SOFFN 0x3fff -+#define DWC3_EVENT_PRAM_SOFFN_MASK 0x3fff -+ - #define DWC3_DSTS_SOFFN_MASK (0x3fff << 3) - #define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3) - -@@ -488,7 +493,7 @@ - #define DWC3_EP_DIRECTION_TX true - #define DWC3_EP_DIRECTION_RX false - --#define DWC3_TRB_NUM 256 -+#define DWC3_TRB_NUM 4096 - - /** - * struct dwc3_ep - device side endpoint representation -@@ -535,7 +540,8 @@ - #define DWC3_EP_WEDGE (1 << 2) - #define DWC3_EP_BUSY (1 << 4) - #define DWC3_EP_PENDING_REQUEST (1 << 5) --#define DWC3_EP_MISSED_ISOC (1 << 6) -+#define DWC3_EP_MISSED_ISOC (1 << 6) -+#define DWC3_EP_UPDATE (1 << 7) - - /* This last one is specific to EP0 */ - #define DWC3_EP0_DIR_IN (1 << 31) -@@ -549,14 +555,15 @@ - * By using u8 types we ensure that our % operator when incrementing - * enqueue and dequeue get optimized away by the compiler. - */ -- u8 trb_enqueue; -- u8 trb_dequeue; -+ u32 trb_enqueue; -+ u32 trb_dequeue; - - u8 number; - u8 type; - u8 resource_index; - u32 allocated_requests; - u32 queued_requests; -+ u32 frame_number; - u32 interval; - - char name[20]; -@@ -806,6 +813,7 @@ - * @start_config_issued: true when StartConfig command has been issued - * @three_stage_setup: set if we perform a three phase setup - * @usb3_lpm_capable: set if hadrware supports Link Power Management -+ * @usb2_lpm_disable: set to disable usb2 lpm - * @disable_scramble_quirk: set if we enable the disable scramble quirk - * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk - * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk -@@ -854,6 +862,7 @@ - struct dwc3_event_buffer *ev_buf; - struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM]; - -+ u32 dwceps_map_to_usbeps[DWC3_ENDPOINTS_NUM]; - struct usb_gadget gadget; - struct usb_gadget_driver *gadget_driver; - -@@ -929,6 +938,12 @@ - - u8 num_out_eps; - u8 num_in_eps; -+/* -+ * NOTICE: eps_directions bitmap[0~31] 0: out ep, 1: in ep -+ * and used with total ep numbers(num_out_eps + num_in_eps) -+ */ -+#define DWC3_EPS_DEFAULT_DIRECTIONS 0xaaaaaaaa -+ u32 eps_directions; - - void *mem; - -@@ -941,6 +956,13 @@ - u8 lpm_nyet_threshold; - u8 hird_threshold; - -+ struct proc_dir_entry* parent_entry; -+ struct proc_dir_entry* csts_entry; -+ u8 udc_connect_status; -+ #define UDC_DISCONNECTED 0 -+ #define UDC_CONNECT_HOST 1 -+ #define UDC_CONNECT_CHARGER 2 -+ - const char *hsphy_interface; - - unsigned connected:1; -@@ -956,6 +978,7 @@ - unsigned setup_packet_pending:1; - unsigned three_stage_setup:1; - unsigned usb3_lpm_capable:1; -+ unsigned usb2_lpm_disable:1; - - unsigned disable_scramble_quirk:1; - unsigned u2exit_lfps_quirk:1; -@@ -972,6 +995,11 @@ - unsigned dis_u2_freeclk_exists_quirk:1; - unsigned dis_del_phy_power_chg_quirk:1; - -+ unsigned dis_initiate_u1:1; -+ unsigned dis_initiate_u2:1; -+ -+ unsigned eps_new_init:1; -+ - unsigned tx_de_emphasis_quirk:1; - unsigned tx_de_emphasis:2; - }; -@@ -1175,6 +1203,9 @@ - { return 0; } - #endif - -+int dwc3_proc_init(struct dwc3 *dwc); -+int dwc3_proc_shutdown(struct dwc3 *dwc); -+ - /* power management interface */ - #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) - int dwc3_gadget_suspend(struct dwc3 *dwc); ---- linux-4.9.37/drivers/usb/dwc3/debugfs.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/debugfs.c 2021-06-07 13:01:34.000000000 +0300 -@@ -689,30 +689,6 @@ - return 0; - } - --static inline const char *dwc3_trb_type_string(struct dwc3_trb *trb) --{ -- switch (DWC3_TRBCTL_TYPE(trb->ctrl)) { -- case DWC3_TRBCTL_NORMAL: -- return "normal"; -- case DWC3_TRBCTL_CONTROL_SETUP: -- return "control-setup"; -- case DWC3_TRBCTL_CONTROL_STATUS2: -- return "control-status2"; -- case DWC3_TRBCTL_CONTROL_STATUS3: -- return "control-status3"; -- case DWC3_TRBCTL_CONTROL_DATA: -- return "control-data"; -- case DWC3_TRBCTL_ISOCHRONOUS_FIRST: -- return "isoc-first"; -- case DWC3_TRBCTL_ISOCHRONOUS: -- return "isoc"; -- case DWC3_TRBCTL_LINK_TRB: -- return "link"; -- default: -- return "UNKNOWN"; -- } --} -- - static int dwc3_ep_trb_ring_show(struct seq_file *s, void *unused) - { - struct dwc3_ep *dep = s->private; -@@ -733,10 +709,11 @@ - - for (i = 0; i < DWC3_TRB_NUM; i++) { - struct dwc3_trb *trb = &dep->trb_pool[i]; -+ unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl); - - seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d\n", - trb->bph, trb->bpl, trb->size, -- dwc3_trb_type_string(trb), -+ dwc3_trb_type_string(type), - !!(trb->ctrl & DWC3_TRB_CTRL_IOC), - !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI), - !!(trb->ctrl & DWC3_TRB_CTRL_CSP), ---- linux-4.9.37/drivers/usb/dwc3/debug.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/debug.h 2021-06-07 13:01:34.000000000 +0300 -@@ -125,55 +125,344 @@ - } - - /** -+ * dwc3_trb_type_string - returns TRB type as a string -+ * @type: the type of the TRB -+ */ -+static inline const char *dwc3_trb_type_string(unsigned int type) -+{ -+ switch (type) { -+ case DWC3_TRBCTL_NORMAL: -+ return "normal"; -+ case DWC3_TRBCTL_CONTROL_SETUP: -+ return "setup"; -+ case DWC3_TRBCTL_CONTROL_STATUS2: -+ return "status2"; -+ case DWC3_TRBCTL_CONTROL_STATUS3: -+ return "status3"; -+ case DWC3_TRBCTL_CONTROL_DATA: -+ return "data"; -+ case DWC3_TRBCTL_ISOCHRONOUS_FIRST: -+ return "isoc-first"; -+ case DWC3_TRBCTL_ISOCHRONOUS: -+ return "isoc"; -+ case DWC3_TRBCTL_LINK_TRB: -+ return "link"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) -+{ -+ switch (state) { -+ case EP0_UNCONNECTED: -+ return "Unconnected"; -+ case EP0_SETUP_PHASE: -+ return "Setup Phase"; -+ case EP0_DATA_PHASE: -+ return "Data Phase"; -+ case EP0_STATUS_PHASE: -+ return "Status Phase"; -+ default: -+ return "UNKNOWN"; -+ } -+} -+ -+/** - * dwc3_gadget_event_string - returns event name - * @event: the event code - */ --static inline const char * --dwc3_gadget_event_string(const struct dwc3_event_devt *event) -+static inline const char *dwc3_gadget_event_string(char *str, size_t size, -+ const struct dwc3_event_devt *event) - { -- static char str[256]; - enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; - - switch (event->type) { - case DWC3_DEVICE_EVENT_DISCONNECT: -- sprintf(str, "Disconnect: [%s]", -+ snprintf(str, size, "Disconnect: [%s]", - dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_RESET: -- sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state)); -+ snprintf(str, size, "Reset [%s]", -+ dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_CONNECT_DONE: -- sprintf(str, "Connection Done [%s]", -+ snprintf(str, size, "Connection Done [%s]", - dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: -- sprintf(str, "Link Change [%s]", -+ snprintf(str, size, "Link Change [%s]", - dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_WAKEUP: -- sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state)); -+ snprintf(str, size, "WakeUp [%s]", -+ dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_EOPF: -- sprintf(str, "End-Of-Frame [%s]", -+ snprintf(str, size, "End-Of-Frame [%s]", - dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_SOF: -- sprintf(str, "Start-Of-Frame [%s]", -+ snprintf(str, size, "Start-Of-Frame [%s]", - dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_ERRATIC_ERROR: -- sprintf(str, "Erratic Error [%s]", -+ snprintf(str, size, "Erratic Error [%s]", - dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_CMD_CMPL: -- sprintf(str, "Command Complete [%s]", -+ snprintf(str, size, "Command Complete [%s]", - dwc3_gadget_link_string(state)); - break; - case DWC3_DEVICE_EVENT_OVERFLOW: -- sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state)); -+ snprintf(str, size, "Overflow [%s]", -+ dwc3_gadget_link_string(state)); - break; - default: -- sprintf(str, "UNKNOWN"); -+ snprintf(str, size, "UNKNOWN"); -+ } -+ -+ return str; -+} -+ -+static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str, -+ size_t size) -+{ -+ switch (t & USB_RECIP_MASK) { -+ case USB_RECIP_DEVICE: -+ snprintf(str, size, "Get Device Status(Length = %d)", l); -+ break; -+ case USB_RECIP_INTERFACE: -+ snprintf(str, size, "Get Interface Status(Intf = %d, Length = %d)", -+ i, l); -+ break; -+ case USB_RECIP_ENDPOINT: -+ snprintf(str, size, "Get Endpoint Status(ep%d%s)", -+ i & ~USB_DIR_IN, -+ i & USB_DIR_IN ? "in" : "out"); -+ break; -+ } -+} -+ -+static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, -+ __u16 i, char *str, size_t size) -+{ -+ switch (t & USB_RECIP_MASK) { -+ case USB_RECIP_DEVICE: -+ snprintf(str, size, "%s Device Feature(%s%s)", -+ b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", -+ ({char *s; -+ switch (v) { -+ case USB_DEVICE_SELF_POWERED: -+ s = "Self Powered"; -+ break; -+ case USB_DEVICE_REMOTE_WAKEUP: -+ s = "Remote Wakeup"; -+ break; -+ case USB_DEVICE_TEST_MODE: -+ s = "Test Mode"; -+ break; -+ default: -+ s = "UNKNOWN"; -+ } s; }), -+ v == USB_DEVICE_TEST_MODE ? -+ ({ char *s; -+ switch (i) { -+ case TEST_J: -+ s = ": TEST_J"; -+ break; -+ case TEST_K: -+ s = ": TEST_K"; -+ break; -+ case TEST_SE0_NAK: -+ s = ": TEST_SE0_NAK"; -+ break; -+ case TEST_PACKET: -+ s = ": TEST_PACKET"; -+ break; -+ case TEST_FORCE_EN: -+ s = ": TEST_FORCE_EN"; -+ break; -+ default: -+ s = ": UNKNOWN"; -+ } s; }) : ""); -+ break; -+ case USB_RECIP_INTERFACE: -+ snprintf(str, size, "%s Interface Feature(%s)", -+ b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", -+ v == USB_INTRF_FUNC_SUSPEND ? -+ "Function Suspend" : "UNKNOWN"); -+ break; -+ case USB_RECIP_ENDPOINT: -+ snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)", -+ b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", -+ v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN", -+ i & ~USB_DIR_IN, -+ i & USB_DIR_IN ? "in" : "out"); -+ break; -+ } -+} -+ -+static inline void dwc3_decode_set_address(__u16 v, char *str, size_t size) -+{ -+ snprintf(str, size, "Set Address(Addr = %02x)", v); -+} -+ -+static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v, -+ __u16 i, __u16 l, char *str, size_t size) -+{ -+ snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)", -+ b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set", -+ ({ char *s; -+ switch (v >> 8) { -+ case USB_DT_DEVICE: -+ s = "Device"; -+ break; -+ case USB_DT_CONFIG: -+ s = "Configuration"; -+ break; -+ case USB_DT_STRING: -+ s = "String"; -+ break; -+ case USB_DT_INTERFACE: -+ s = "Interface"; -+ break; -+ case USB_DT_ENDPOINT: -+ s = "Endpoint"; -+ break; -+ case USB_DT_DEVICE_QUALIFIER: -+ s = "Device Qualifier"; -+ break; -+ case USB_DT_OTHER_SPEED_CONFIG: -+ s = "Other Speed Config"; -+ break; -+ case USB_DT_INTERFACE_POWER: -+ s = "Interface Power"; -+ break; -+ case USB_DT_OTG: -+ s = "OTG"; -+ break; -+ case USB_DT_DEBUG: -+ s = "Debug"; -+ break; -+ case USB_DT_INTERFACE_ASSOCIATION: -+ s = "Interface Association"; -+ break; -+ case USB_DT_BOS: -+ s = "BOS"; -+ break; -+ case USB_DT_DEVICE_CAPABILITY: -+ s = "Device Capability"; -+ break; -+ case USB_DT_PIPE_USAGE: -+ s = "Pipe Usage"; -+ break; -+ case USB_DT_SS_ENDPOINT_COMP: -+ s = "SS Endpoint Companion"; -+ break; -+ case USB_DT_SSP_ISOC_ENDPOINT_COMP: -+ s = "SSP Isochronous Endpoint Companion"; -+ break; -+ default: -+ s = "UNKNOWN"; -+ break; -+ } s; }), v & 0xff, l); -+} -+ -+ -+static inline void dwc3_decode_get_configuration(__u16 l, char *str, -+ size_t size) -+{ -+ snprintf(str, size, "Get Configuration(Length = %d)", l); -+} -+ -+static inline void dwc3_decode_set_configuration(__u8 v, char *str, size_t size) -+{ -+ snprintf(str, size, "Set Configuration(Config = %d)", v); -+} -+ -+static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str, -+ size_t size) -+{ -+ snprintf(str, size, "Get Interface(Intf = %d, Length = %d)", i, l); -+} -+ -+static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str, size_t size) -+{ -+ snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v); -+} -+ -+static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str, -+ size_t size) -+{ -+ snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)", i, l); -+} -+ -+static inline void dwc3_decode_set_sel(__u16 l, char *str, size_t size) -+{ -+ snprintf(str, size, "Set SEL(Length = %d)", l); -+} -+ -+static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str, size_t size) -+{ -+ snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", v); -+} -+ -+/** -+ * dwc3_decode_ctrl - returns a string represetion of ctrl request -+ */ -+static inline const char *dwc3_decode_ctrl(char *str, size_t size, -+ __u8 bRequestType, __u8 bRequest, __u16 wValue, __u16 wIndex, -+ __u16 wLength) -+{ -+ switch (bRequest) { -+ case USB_REQ_GET_STATUS: -+ dwc3_decode_get_status(bRequestType, wIndex, wLength, str, -+ size); -+ break; -+ case USB_REQ_CLEAR_FEATURE: -+ case USB_REQ_SET_FEATURE: -+ dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue, -+ wIndex, str, size); -+ break; -+ case USB_REQ_SET_ADDRESS: -+ dwc3_decode_set_address(wValue, str, size); -+ break; -+ case USB_REQ_GET_DESCRIPTOR: -+ case USB_REQ_SET_DESCRIPTOR: -+ dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue, -+ wIndex, wLength, str, size); -+ break; -+ case USB_REQ_GET_CONFIGURATION: -+ dwc3_decode_get_configuration(wLength, str, size); -+ break; -+ case USB_REQ_SET_CONFIGURATION: -+ dwc3_decode_set_configuration(wValue, str, size); -+ break; -+ case USB_REQ_GET_INTERFACE: -+ dwc3_decode_get_intf(wIndex, wLength, str, size); -+ break; -+ case USB_REQ_SET_INTERFACE: -+ dwc3_decode_set_intf(wValue, wIndex, str, size); -+ break; -+ case USB_REQ_SYNCH_FRAME: -+ dwc3_decode_synch_frame(wIndex, wLength, str, size); -+ break; -+ case USB_REQ_SET_SEL: -+ dwc3_decode_set_sel(wLength, str, size); -+ break; -+ case USB_REQ_SET_ISOCH_DELAY: -+ dwc3_decode_set_isoch_delay(wValue, str, size); -+ break; -+ default: -+ snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x", -+ bRequestType, bRequest, -+ cpu_to_le16(wValue) & 0xff, -+ cpu_to_le16(wValue) >> 8, -+ cpu_to_le16(wIndex) & 0xff, -+ cpu_to_le16(wIndex) >> 8, -+ cpu_to_le16(wLength) & 0xff, -+ cpu_to_le16(wLength) >> 8); - } - - return str; -@@ -183,30 +472,52 @@ - * dwc3_ep_event_string - returns event name - * @event: then event code - */ --static inline const char * --dwc3_ep_event_string(const struct dwc3_event_depevt *event) -+static inline const char *dwc3_ep_event_string(char *str, size_t size, -+ const struct dwc3_event_depevt *event, u32 ep0state) - { - u8 epnum = event->endpoint_number; -- static char str[256]; -+ size_t len; - int status; - int ret; - -- ret = sprintf(str, "ep%d%s: ", epnum >> 1, -+ ret = snprintf(str, size, "ep%d%s: ", epnum >> 1, - (epnum & 1) ? "in" : "out"); - if (ret < 0) - return "UNKNOWN"; - -+ status = event->status; -+ - switch (event->endpoint_event) { - case DWC3_DEPEVT_XFERCOMPLETE: -- strcat(str, "Transfer Complete"); -+ len = strlen(str); -+ snprintf(str + len, size - len, "Transfer Complete (%c%c%c)", -+ status & DEPEVT_STATUS_SHORT ? 'S' : 's', -+ status & DEPEVT_STATUS_IOC ? 'I' : 'i', -+ status & DEPEVT_STATUS_LST ? 'L' : 'l'); -+ -+ len = strlen(str); -+ -+ if (epnum <= 1) -+ snprintf(str + len, size - len, " [%s]", -+ dwc3_ep0_state_string(ep0state)); - break; - case DWC3_DEPEVT_XFERINPROGRESS: -- strcat(str, "Transfer In-Progress"); -+ len = strlen(str); -+ -+ snprintf(str + len, size - len, "Transfer In Progress [%d] (%c%c%c)", -+ event->parameters, -+ status & DEPEVT_STATUS_SHORT ? 'S' : 's', -+ status & DEPEVT_STATUS_IOC ? 'I' : 'i', -+ status & DEPEVT_STATUS_LST ? 'M' : 'm'); - break; - case DWC3_DEPEVT_XFERNOTREADY: -- strcat(str, "Transfer Not Ready"); -- status = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; -- strcat(str, status ? " (Active)" : " (Not Active)"); -+ len = strlen(str); -+ -+ snprintf(str + len, size - len, "Transfer Not Ready [%d]%s", -+ event->parameters, -+ status & DEPEVT_STATUS_TRANSFER_ACTIVE ? -+ " (Active)" : " (Not Active)"); -+ - break; - case DWC3_DEPEVT_RXTXFIFOEVT: - strcat(str, "FIFO"); -@@ -216,7 +527,7 @@ - - switch (status) { - case DEPEVT_STREAMEVT_FOUND: -- sprintf(str + ret, " Stream %d Found", -+ snprintf(str + ret, size - ret, " Stream %d Found", - event->parameters); - break; - case DEPEVT_STREAMEVT_NOTFOUND: -@@ -230,7 +541,7 @@ - strcat(str, "Endpoint Command Complete"); - break; - default: -- sprintf(str, "UNKNOWN"); -+ snprintf(str, size, "UNKNOWN"); - } - - return str; -@@ -270,14 +581,15 @@ - } - } - --static inline const char *dwc3_decode_event(u32 event) -+static inline const char *dwc3_decode_event(char *str, size_t size, u32 event, -+ u32 ep0state) - { - const union dwc3_event evt = (union dwc3_event) event; - - if (evt.type.is_devspec) -- return dwc3_gadget_event_string(&evt.devt); -+ return dwc3_gadget_event_string(str, size, &evt.devt); - else -- return dwc3_ep_event_string(&evt.depevt); -+ return dwc3_ep_event_string(str, size, &evt.depevt, ep0state); - } - - static inline const char *dwc3_ep_cmd_status_string(int status) -@@ -310,7 +622,6 @@ - } - } - --void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...); - - #ifdef CONFIG_DEBUG_FS - extern void dwc3_debugfs_init(struct dwc3 *); ---- linux-4.9.37/drivers/usb/dwc3/dwc3-goke.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/dwc3-goke.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,359 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dwc3-goke.h" -+ -+#define USB3_CTRL 0x190 -+#define REG_SYS_STAT 0x8c -+#define PCIE_USB3_MODE_MASK (0x3 << 12) -+#define USB3_PCLK_OCC_SEL (0x1 << 30) -+ -+#define PERI_USB3_GTXTHRCFG 0x2310000 -+ -+#define REG_GUSB3PIPECTL0 0xc2c0 -+#define GTXTHRCFG 0xc108 -+ -+#define PCS_SSP_SOFT_RESET (0x1 << 31) -+#define SUSPEND_USB3_SS_PHY (0x1 << 17) -+ -+#define GUSB2PHYCFG_OFFSET 0xc200 -+#define GCTL_OFFSET 0xc110 -+#define GUCTL_OFFSET 0xc12C -+#define GFLADJ_OFFSET 0xc630 -+ -+#define U2_FREECLK_EXISTS (0x1 << 30) -+#define SOFITPSYNC (0x1 << 10) -+#define REFCLKPER_MASK 0xffc00000 -+#define REFCLKPER_VAL 0x29 -+#define set_refclkper(a) (((a) << 22) & REFCLKPER_MASK) -+ -+#define PLS1 (0x1 << 31) -+#define DECR_MASK 0x7f000000 -+#define DECR_VAL 0xa -+#define set_decr(a) (((a) << 24) & DECR_MASK) -+ -+#define LPM_SEL (0x1 << 23) -+#define FLADJ_MASK 0x003fff00 -+#define FLADJ_VAL 0x7f0 -+#define set_fladj(a) (((a) << 8) & FLADJ_MASK) -+ -+#define DOUBLE_PCIE_MODE 0x0 -+#define P0_PCIE_ADD_P1_USB3 (0x1 << 12) -+#define DOUBLE_USB3 (0x2 << 12) -+ -+#define PCIE_X1_MODE (0x0 << 12) -+#define USB3_MODE (0x1 << 12) -+ -+static struct bsp_priv *usb_priv = NULL; -+ -+ -+ -+int usb_get_max_speed(struct device *dev) -+{ -+ unsigned int ret; -+ struct device_node *np = dev->of_node; -+ -+ if (np == NULL) -+ return -EINVAL; -+ -+ usb_priv = kzalloc(sizeof(*usb_priv), GFP_KERNEL); -+ if (usb_priv == NULL) -+ return -ENOMEM; -+ -+ usb_priv->peri_crg = of_iomap(np, DEV_NODE_FLAG1); -+ if (IS_ERR(usb_priv->peri_crg)) { -+ kfree(usb_priv); -+ usb_priv = NULL; -+ return -ENOMEM; -+ } -+ -+ usb_priv->sys_ctrl = of_iomap(np, DEV_NODE_FLAG2); -+ if (IS_ERR(usb_priv->sys_ctrl)) { -+ iounmap(usb_priv->peri_crg); -+ -+ kfree(usb_priv); -+ usb_priv = NULL; -+ return -ENOMEM; -+ } -+ -+ ret = usb_get_maximum_speed(dev); -+ -+ iounmap(usb_priv->sys_ctrl); -+ iounmap(usb_priv->peri_crg); -+ -+ return ret; -+} -+EXPORT_SYMBOL(usb_get_max_speed); -+ -+void bsp_dwc3_exited(void) -+{ -+ kfree(usb_priv); -+ usb_priv = NULL; -+} -+EXPORT_SYMBOL(bsp_dwc3_exited); -+ -+static int set_ctrl_crg_val(struct device_node *np, struct dwc3_host *host) -+{ -+ unsigned int ret; -+ unsigned int reg; -+ -+ if ((np == NULL) || (host == NULL)) -+ return -EINVAL; -+ -+ /* get usb ctrl crg para */ -+ ret = of_property_read_u32(np, "crg_offset", &host->crg_offset); -+ if (ret) -+ return ret; -+ -+ ret = of_property_read_u32(np, "crg_ctrl_def_mask", &host->crg_ctrl_def_mask); -+ if (ret) -+ return ret; -+ -+ ret = of_property_read_u32(np, "crg_ctrl_def_val", &host->crg_ctrl_def_val); -+ if (ret) -+ return ret; -+ -+ /* write usb ctrl crg default value */ -+ reg = readl(host->crg_base + host->crg_offset); -+ reg &= ~host->crg_ctrl_def_mask; -+ reg |= host->crg_ctrl_def_val; -+ writel(reg, host->crg_base + host->crg_offset); -+ -+ return 0; -+} -+ -+static int dwc3_bsp_clk_init(struct dwc3_host *host, int count) -+{ -+ struct device *dev = host->dev; -+ struct device_node *np = dev->of_node; -+ int i, ret; -+ -+ if (!count) -+ return -EINVAL; -+ -+ if (np == NULL) -+ return -EINVAL; -+ -+ host->num_clocks = count; -+ -+ host->clks = devm_kcalloc(dev, host->num_clocks, sizeof(struct clk *), GFP_KERNEL); -+ if (host->clks == NULL) -+ return -ENOMEM; -+ -+ for (i = 0; i < host->num_clocks; i++) { -+ struct clk *clk; -+ -+ clk = of_clk_get(np, i); -+ if (IS_ERR(clk)) { -+ while (--i >= 0) -+ clk_put(host->clks[i]); -+ -+ ret = PTR_ERR(clk); -+ goto clk_free; -+ } -+ -+ ret = clk_prepare_enable(clk); -+ if (ret < 0) { -+ while (--i >= 0) { -+ clk_disable_unprepare(host->clks[i]); -+ clk_put(host->clks[i]); -+ } -+ clk_put(clk); -+ -+ goto clk_free; -+ } -+ -+ host->clks[i] = clk; -+ } -+ -+ return 0; -+clk_free: -+ devm_kfree(dev, host->clks); -+ host->clks = NULL; -+ -+ return ret; -+} -+ -+static void control_free_clk_config(struct dwc3_host *host) -+{ -+ unsigned int reg; -+ -+ if (host == NULL) -+ return; -+ -+ reg = readl(host->ctrl_base + GUSB2PHYCFG_OFFSET); -+ reg &= ~U2_FREECLK_EXISTS; -+ writel(reg, host->ctrl_base + GUSB2PHYCFG_OFFSET); -+ -+ reg = readl(host->ctrl_base + GCTL_OFFSET); -+ reg &= ~SOFITPSYNC; -+ writel(reg, host->ctrl_base + GCTL_OFFSET); -+ -+ reg = readl(host->ctrl_base + GUCTL_OFFSET); -+ reg &= ~REFCLKPER_MASK; -+ reg |= set_refclkper(REFCLKPER_VAL); -+ writel(reg, host->ctrl_base + GUCTL_OFFSET); -+ -+ reg = readl(host->ctrl_base + GFLADJ_OFFSET); -+ reg &= ~PLS1; -+ writel(reg, host->ctrl_base + GFLADJ_OFFSET); -+ -+ reg = readl(host->ctrl_base + GFLADJ_OFFSET); -+ reg &= ~DECR_MASK; -+ reg |= set_decr(DECR_VAL); -+ writel(reg, host->ctrl_base + GFLADJ_OFFSET); -+ -+ reg = readl(host->ctrl_base + GFLADJ_OFFSET); -+ reg |= LPM_SEL; -+ writel(reg, host->ctrl_base + GFLADJ_OFFSET); -+ -+ reg = readl(host->ctrl_base + GFLADJ_OFFSET); -+ reg &= ~FLADJ_MASK; -+ reg |= set_fladj(FLADJ_VAL); -+ writel(reg, host->ctrl_base + GFLADJ_OFFSET); -+} -+ -+static int dwc3_bsp_iomap(struct device_node *np, struct dwc3_host *host) -+{ -+ if ((np == NULL) || (host == NULL)) -+ return -EINVAL; -+ -+ host->ctrl_base = of_iomap(np, DEV_NODE_FLAG0); -+ if (IS_ERR(host->ctrl_base)) -+ return -ENOMEM; -+ -+ host->crg_base = of_iomap(np, DEV_NODE_FLAG1); -+ if (IS_ERR(host->crg_base)) { -+ iounmap(host->ctrl_base); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static int dwc3_bsp_probe(struct platform_device *pdev) -+{ -+ struct dwc3_host *host = NULL; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ int ret, i; -+ -+ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); -+ if (host == NULL) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, host); -+ host->dev = dev; -+ -+ ret = dwc3_bsp_iomap(np, host); -+ if (ret) { -+ devm_kfree(dev, host); -+ host = NULL; -+ -+ return -ENOMEM; -+ } -+ -+ host->port_rst = devm_reset_control_get(dev, "vcc_reset"); -+ if (IS_ERR_OR_NULL(host->port_rst)) { -+ ret = PTR_ERR(host->port_rst); -+ goto dwc3_unmap; -+ } -+ -+ ret = set_ctrl_crg_val(np, host); -+ if (ret) -+ goto dwc3_unmap; -+ -+ reset_control_assert(host->port_rst); -+ -+ ret = dwc3_bsp_clk_init(host, of_clk_get_parent_count(np)); -+ if (ret) -+ goto dwc3_unmap; -+ -+ reset_control_deassert(host->port_rst); -+ -+ control_free_clk_config(host); -+ -+ udelay(U_LEVEL2); -+ -+ ret = of_platform_populate(np, NULL, NULL, dev); -+ if (ret) { -+ for (i = 0; i < host->num_clocks; i++) { -+ clk_disable_unprepare(host->clks[i]); -+ clk_put(host->clks[i]); -+ } -+ goto dwc3_unmap; -+ } -+ -+ return 0; -+dwc3_unmap: -+ iounmap(host->ctrl_base); -+ iounmap(host->crg_base); -+ -+ devm_kfree(dev, host); -+ host = NULL; -+ -+ return ret; -+} -+ -+static int dwc3_bsp_remove(struct platform_device *pdev) -+{ -+ struct dwc3_host *host = platform_get_drvdata(pdev); -+ struct device *dev = &pdev->dev; -+ int i; -+ -+ for (i = 0; i < host->num_clocks; i++) { -+ clk_disable_unprepare(host->clks[i]); -+ clk_put(host->clks[i]); -+ } -+ -+ reset_control_assert(host->port_rst); -+ -+ of_platform_depopulate(dev); -+ -+ iounmap(host->ctrl_base); -+ iounmap(host->crg_base); -+ -+ devm_kfree(dev, host); -+ host = NULL; -+ -+ return 0; -+} -+ -+static const struct of_device_id bsp_dwc3_match[] = { -+ { .compatible = "goke,dwusb2" }, -+ { .compatible = "goke,dwusb3" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bsp_dwc3_match); -+ -+static struct platform_driver dwc3_bsp_driver = { -+ .probe = dwc3_bsp_probe, -+ .remove = dwc3_bsp_remove, -+ .driver = { -+ .name = "goke-dwc3", -+ .of_match_table = bsp_dwc3_match, -+ }, -+}; -+module_platform_driver(dwc3_bsp_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("DesignWare USB3 of Goke"); -+MODULE_AUTHOR("Goke Technologies Co., Ltd..>"); ---- linux-4.9.37/drivers/usb/dwc3/dwc3-goke.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/dwc3-goke.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,36 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef USB_INCLUDE_DWC3_GOKE_H -+#define USB_INCLUDE_DWC3_GOKE_H -+ -+struct bsp_priv { -+ void __iomem *peri_crg; -+ void __iomem *sys_ctrl; -+ void __iomem *misc_ctrl; -+ unsigned int speed_id; -+}; -+ -+struct dwc3_host { -+ struct device *dev; -+ struct clk **clks; -+ int num_clocks; -+ void __iomem *ctrl_base; -+ void __iomem *crg_base; -+ struct reset_control *port_rst; -+ u32 crg_offset; -+ u32 crg_ctrl_def_mask; -+ u32 crg_ctrl_def_val; -+}; -+ -+extern int usb_get_max_speed(struct device *dev); -+extern void bsp_dwc3_exited(void); -+ -+#define DEV_NODE_FLAG0 0 -+#define DEV_NODE_FLAG1 1 -+#define DEV_NODE_FLAG2 2 -+ -+#define U_LEVEL2 200 -+ -+#endif ---- linux-4.9.37/drivers/usb/dwc3/ep0.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/ep0.c 2021-06-07 13:01:34.000000000 +0300 -@@ -39,22 +39,6 @@ - static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, - struct dwc3_ep *dep, struct dwc3_request *req); - --static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) --{ -- switch (state) { -- case EP0_UNCONNECTED: -- return "Unconnected"; -- case EP0_SETUP_PHASE: -- return "Setup Phase"; -- case EP0_DATA_PHASE: -- return "Data Phase"; -- case EP0_STATUS_PHASE: -- return "Status Phase"; -- default: -- return "UNKNOWN"; -- } --} -- - static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum, - dma_addr_t buf_dma, u32 len, u32 type, bool chain) - { -@@ -92,21 +76,16 @@ - int ret; - - dep = dwc->eps[epnum]; -- if (dep->flags & DWC3_EP_BUSY) { -- dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name); -+ if (dep->flags & DWC3_EP_BUSY) - return 0; -- } - - memset(¶ms, 0, sizeof(params)); - params.param0 = upper_32_bits(dwc->ep0_trb_addr); - params.param1 = lower_32_bits(dwc->ep0_trb_addr); - - ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); -- if (ret < 0) { -- dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed", -- dep->name); -+ if (ret < 0) - return ret; -- } - - dep->flags |= DWC3_EP_BUSY; - dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep); -@@ -166,9 +145,6 @@ - - if (dwc->ep0state == EP0_STATUS_PHASE) - __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]); -- else -- dwc3_trace(trace_dwc3_ep0, -- "too early for delayed status"); - - return 0; - } -@@ -232,9 +208,8 @@ - - spin_lock_irqsave(&dwc->lock, flags); - if (!dep->endpoint.desc) { -- dwc3_trace(trace_dwc3_ep0, -- "trying to queue request %p to disabled %s", -- request, dep->name); -+ dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", -+ dep->name); - ret = -ESHUTDOWN; - goto out; - } -@@ -245,11 +220,6 @@ - goto out; - } - -- dwc3_trace(trace_dwc3_ep0, -- "queueing request %p to %s length %d state '%s'", -- request, dep->name, request->length, -- dwc3_ep0_state_string(dwc->ep0state)); -- - ret = __dwc3_gadget_ep0_queue(dep, req); - - out: -@@ -317,6 +287,24 @@ - WARN_ON(ret < 0); - } - -+static u32 dwc3_usbep_to_dwc3ep(struct dwc3 *dwc, u32 num) -+{ -+ u32 res = 0; -+ int i = 0; -+ -+ if (!dwc) -+ return 0; -+ -+ for (i = 0; i < dwc->num_in_eps + dwc->num_out_eps; i++) { -+ if (dwc->dwceps_map_to_usbeps[i] == num) { -+ res = i; -+ break; -+ } -+ } -+ -+ return res; -+} -+ - static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) - { - struct dwc3_ep *dep; -@@ -327,6 +315,9 @@ - if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) - epnum |= 1; - -+ if (dwc->eps_new_init) -+ epnum = dwc3_usbep_to_dwc3ep(dwc, epnum); -+ - dep = dwc->eps[epnum]; - if (dep->flags & DWC3_EP_ENABLED) - return dep; -@@ -399,126 +390,203 @@ - return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); - } - --static int dwc3_ep0_handle_feature(struct dwc3 *dwc, -+static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state, -+ int set) -+{ -+ u32 reg; -+ -+ if (state != USB_STATE_CONFIGURED) -+ return -EINVAL; -+ if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && -+ (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) -+ return -EINVAL; -+ -+ if (dwc->dis_initiate_u1) -+ return -EINVAL; -+ -+ reg = dwc3_readl(dwc->regs, DWC3_DCTL); -+ if (set) -+ reg |= DWC3_DCTL_INITU1ENA; -+ else -+ reg &= ~DWC3_DCTL_INITU1ENA; -+ dwc3_writel(dwc->regs, DWC3_DCTL, reg); -+ -+ return 0; -+} -+ -+static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state, -+ int set) -+{ -+ u32 reg; -+ -+ -+ if (state != USB_STATE_CONFIGURED) -+ return -EINVAL; -+ if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && -+ (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) -+ return -EINVAL; -+ -+ if (dwc->dis_initiate_u2) -+ return -EINVAL; -+ -+ reg = dwc3_readl(dwc->regs, DWC3_DCTL); -+ if (set) -+ reg |= DWC3_DCTL_INITU2ENA; -+ else -+ reg &= ~DWC3_DCTL_INITU2ENA; -+ dwc3_writel(dwc->regs, DWC3_DCTL, reg); -+ -+ return 0; -+} -+ -+static int dwc3_ep0_handle_test(struct dwc3 *dwc, enum usb_device_state state, -+ u32 wIndex, int set) -+{ -+ if ((wIndex & 0xff) != 0) -+ return -EINVAL; -+ if (!set) -+ return -EINVAL; -+ -+ switch (wIndex >> 8) { -+ case TEST_J: -+ case TEST_K: -+ case TEST_SE0_NAK: -+ case TEST_PACKET: -+ case TEST_FORCE_EN: -+ dwc->test_mode_nr = wIndex >> 8; -+ dwc->test_mode = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int dwc3_ep0_handle_device(struct dwc3 *dwc, - struct usb_ctrlrequest *ctrl, int set) - { -- struct dwc3_ep *dep; -- u32 recip; -+ enum usb_device_state state; - u32 wValue; - u32 wIndex; -- u32 reg; -- int ret; -- enum usb_device_state state; -+ int ret = 0; - - wValue = le16_to_cpu(ctrl->wValue); - wIndex = le16_to_cpu(ctrl->wIndex); -- recip = ctrl->bRequestType & USB_RECIP_MASK; - state = dwc->gadget.state; - -- switch (recip) { -- case USB_RECIP_DEVICE: -+ switch (wValue) { -+ case USB_DEVICE_REMOTE_WAKEUP: -+ break; -+ /* -+ * 9.4.1 says only only for SS, in AddressState only for -+ * default control pipe -+ */ -+ case USB_DEVICE_U1_ENABLE: -+ ret = dwc3_ep0_handle_u1(dwc, state, set); -+ break; -+ case USB_DEVICE_U2_ENABLE: -+ ret = dwc3_ep0_handle_u2(dwc, state, set); -+ break; -+ case USB_DEVICE_LTM_ENABLE: -+ ret = -EINVAL; -+ break; -+ case USB_DEVICE_TEST_MODE: -+ ret = dwc3_ep0_handle_test(dwc, state, wIndex, set); -+ break; -+ default: -+ ret = -EINVAL; -+ } - -- switch (wValue) { -- case USB_DEVICE_REMOTE_WAKEUP: -- break; -- /* -- * 9.4.1 says only only for SS, in AddressState only for -- * default control pipe -- */ -- case USB_DEVICE_U1_ENABLE: -- if (state != USB_STATE_CONFIGURED) -- return -EINVAL; -- if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && -- (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) -- return -EINVAL; -+ return ret; -+} - -- reg = dwc3_readl(dwc->regs, DWC3_DCTL); -- if (set) -- reg |= DWC3_DCTL_INITU1ENA; -- else -- reg &= ~DWC3_DCTL_INITU1ENA; -- dwc3_writel(dwc->regs, DWC3_DCTL, reg); -- break; -+static int dwc3_ep0_handle_intf(struct dwc3 *dwc, -+ struct usb_ctrlrequest *ctrl, int set) -+{ -+ enum usb_device_state state; -+ u32 wValue; -+ u32 wIndex; -+ int ret = 0; - -- case USB_DEVICE_U2_ENABLE: -- if (state != USB_STATE_CONFIGURED) -- return -EINVAL; -- if ((dwc->speed != DWC3_DSTS_SUPERSPEED) && -- (dwc->speed != DWC3_DSTS_SUPERSPEED_PLUS)) -- return -EINVAL; -+ wValue = le16_to_cpu(ctrl->wValue); -+ wIndex = le16_to_cpu(ctrl->wIndex); -+ state = dwc->gadget.state; - -- reg = dwc3_readl(dwc->regs, DWC3_DCTL); -- if (set) -- reg |= DWC3_DCTL_INITU2ENA; -- else -- reg &= ~DWC3_DCTL_INITU2ENA; -- dwc3_writel(dwc->regs, DWC3_DCTL, reg); -- break; -+ switch (wValue) { -+ case USB_INTRF_FUNC_SUSPEND: -+ if (wIndex & USB_INTRF_FUNC_SUSPEND_LP) -+ /* XXX enable Low power suspend */ -+ ; -+ if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) -+ /* XXX enable remote wakeup */ -+ ; -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static int dwc3_ep0_handle_endpoint(struct dwc3 *dwc, -+ struct usb_ctrlrequest *ctrl, int set) -+{ -+ struct dwc3_ep *dep; -+ enum usb_device_state state; -+ u32 wValue; -+ u32 wIndex; -+ int ret; - -- case USB_DEVICE_LTM_ENABLE: -+ wValue = le16_to_cpu(ctrl->wValue); -+ wIndex = le16_to_cpu(ctrl->wIndex); -+ state = dwc->gadget.state; -+ -+ switch (wValue) { -+ case USB_ENDPOINT_HALT: -+ dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); -+ if (!dep) - return -EINVAL; - -- case USB_DEVICE_TEST_MODE: -- if ((wIndex & 0xff) != 0) -- return -EINVAL; -- if (!set) -- return -EINVAL; -- -- switch (wIndex >> 8) { -- case TEST_J: -- case TEST_K: -- case TEST_SE0_NAK: -- case TEST_PACKET: -- case TEST_FORCE_EN: -- dwc->test_mode_nr = wIndex >> 8; -- dwc->test_mode = true; -- break; -- default: -- return -EINVAL; -- } -+ if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) - break; -- default: -+ -+ ret = __dwc3_gadget_ep_set_halt(dep, set, true); -+ if (ret) - return -EINVAL; -- } - break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int dwc3_ep0_handle_feature(struct dwc3 *dwc, -+ struct usb_ctrlrequest *ctrl, int set) -+{ -+ u32 recip; -+ int ret; -+ enum usb_device_state state; -+ -+ recip = ctrl->bRequestType & USB_RECIP_MASK; -+ state = dwc->gadget.state; - -+ switch (recip) { -+ case USB_RECIP_DEVICE: -+ ret = dwc3_ep0_handle_device(dwc, ctrl, set); -+ break; - case USB_RECIP_INTERFACE: -- switch (wValue) { -- case USB_INTRF_FUNC_SUSPEND: -- if (wIndex & USB_INTRF_FUNC_SUSPEND_LP) -- /* XXX enable Low power suspend */ -- ; -- if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) -- /* XXX enable remote wakeup */ -- ; -- break; -- default: -- return -EINVAL; -- } -+ ret = dwc3_ep0_handle_intf(dwc, ctrl, set); - break; -- - case USB_RECIP_ENDPOINT: -- switch (wValue) { -- case USB_ENDPOINT_HALT: -- dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); -- if (!dep) -- return -EINVAL; -- if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) -- break; -- ret = __dwc3_gadget_ep_set_halt(dep, set, true); -- if (ret) -- return -EINVAL; -- break; -- default: -- return -EINVAL; -- } -+ ret = dwc3_ep0_handle_endpoint(dwc, ctrl, set); - break; -- - default: -- return -EINVAL; -+ ret = -EINVAL; - } - -- return 0; -+ return ret; - } - - static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) -@@ -529,13 +597,12 @@ - - addr = le16_to_cpu(ctrl->wValue); - if (addr > 127) { -- dwc3_trace(trace_dwc3_ep0, "invalid device address %d", addr); -+ dev_err(dwc->dev, "invalid device address %d\n", addr); - return -EINVAL; - } - - if (state == USB_STATE_CONFIGURED) { -- dwc3_trace(trace_dwc3_ep0, -- "trying to set address when configured"); -+ dev_err(dwc->dev, "can't SetAddress() from Configured State\n"); - return -EINVAL; - } - -@@ -595,7 +662,15 @@ - * nothing is pending from application. - */ - reg = dwc3_readl(dwc->regs, DWC3_DCTL); -- reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); -+ if (dwc->dis_initiate_u1) -+ reg &= (~DWC3_DCTL_ACCEPTU1ENA); -+ else -+ reg |= DWC3_DCTL_ACCEPTU1ENA; -+ -+ if (dwc->dis_initiate_u2) -+ reg &= (~DWC3_DCTL_ACCEPTU2ENA); -+ else -+ reg |= DWC3_DCTL_ACCEPTU2ENA; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); - } - break; -@@ -720,35 +795,27 @@ - - switch (ctrl->bRequest) { - case USB_REQ_GET_STATUS: -- dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS"); - ret = dwc3_ep0_handle_status(dwc, ctrl); - break; - case USB_REQ_CLEAR_FEATURE: -- dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE"); - ret = dwc3_ep0_handle_feature(dwc, ctrl, 0); - break; - case USB_REQ_SET_FEATURE: -- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE"); - ret = dwc3_ep0_handle_feature(dwc, ctrl, 1); - break; - case USB_REQ_SET_ADDRESS: -- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS"); - ret = dwc3_ep0_set_address(dwc, ctrl); - break; - case USB_REQ_SET_CONFIGURATION: -- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION"); - ret = dwc3_ep0_set_config(dwc, ctrl); - break; - case USB_REQ_SET_SEL: -- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL"); - ret = dwc3_ep0_set_sel(dwc, ctrl); - break; - case USB_REQ_SET_ISOCH_DELAY: -- dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY"); - ret = dwc3_ep0_set_isoch_delay(dwc, ctrl); - break; - default: -- dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver"); - ret = dwc3_ep0_delegate_req(dwc, ctrl); - break; - } -@@ -824,9 +891,6 @@ - status = DWC3_TRB_SIZE_TRBSTS(trb->size); - if (status == DWC3_TRBSTS_SETUP_PENDING) { - dwc->setup_packet_pending = true; -- -- dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); -- - if (r) - dwc3_gadget_giveback(ep0, r, -ECONNRESET); - -@@ -916,7 +980,7 @@ - - ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr); - if (ret < 0) { -- dwc3_trace(trace_dwc3_ep0, "Invalid Test #%d", -+ dev_err(dwc->dev, "invalid test #%d\n", - dwc->test_mode_nr); - dwc3_ep0_stall_and_restart(dwc); - return; -@@ -924,10 +988,8 @@ - } - - status = DWC3_TRB_SIZE_TRBSTS(trb->size); -- if (status == DWC3_TRBSTS_SETUP_PENDING) { -+ if (status == DWC3_TRBSTS_SETUP_PENDING) - dwc->setup_packet_pending = true; -- dwc3_trace(trace_dwc3_ep0, "Setup Pending received"); -- } - - dwc->ep0state = EP0_SETUP_PHASE; - dwc3_ep0_out_start(dwc); -@@ -944,17 +1006,14 @@ - - switch (dwc->ep0state) { - case EP0_SETUP_PHASE: -- dwc3_trace(trace_dwc3_ep0, "Setup Phase"); - dwc3_ep0_inspect_setup(dwc, event); - break; - - case EP0_DATA_PHASE: -- dwc3_trace(trace_dwc3_ep0, "Data Phase"); - dwc3_ep0_complete_data(dwc, event); - break; - - case EP0_STATUS_PHASE: -- dwc3_trace(trace_dwc3_ep0, "Status Phase"); - dwc3_ep0_complete_status(dwc, event); - break; - default: -@@ -981,10 +1040,8 @@ - - ret = usb_gadget_map_request(&dwc->gadget, &req->request, - dep->number); -- if (ret) { -- dwc3_trace(trace_dwc3_ep0, "failed to map request"); -+ if (ret) - return; -- } - - maxpacket = dep->endpoint.maxpacket; - -@@ -1010,10 +1067,8 @@ - } else { - ret = usb_gadget_map_request(&dwc->gadget, &req->request, - dep->number); -- if (ret) { -- dwc3_trace(trace_dwc3_ep0, "failed to map request"); -+ if (ret) - return; -- } - - dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma, - req->request.length, DWC3_TRBCTL_CONTROL_DATA, -@@ -1073,8 +1128,6 @@ - { - switch (event->status) { - case DEPEVT_STATUS_CONTROL_DATA: -- dwc3_trace(trace_dwc3_ep0, "Control Data"); -- - /* - * We already have a DATA transfer in the controller's cache, - * if we receive a XferNotReady(DATA) we will ignore it, unless -@@ -1087,8 +1140,7 @@ - if (dwc->ep0_expect_in != event->endpoint_number) { - struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; - -- dwc3_trace(trace_dwc3_ep0, -- "Wrong direction for Data phase"); -+ dev_err(dwc->dev, "unexpected direction for Data Phase\n"); - dwc3_ep0_end_control_data(dwc, dep); - dwc3_ep0_stall_and_restart(dwc); - return; -@@ -1100,13 +1152,10 @@ - if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) - return; - -- dwc3_trace(trace_dwc3_ep0, "Control Status"); -- - dwc->ep0state = EP0_STATUS_PHASE; - - if (dwc->delayed_status) { - WARN_ON_ONCE(event->endpoint_number != 1); -- dwc3_trace(trace_dwc3_ep0, "Delayed Status"); - return; - } - -@@ -1117,10 +1166,6 @@ - void dwc3_ep0_interrupt(struct dwc3 *dwc, - const struct dwc3_event_depevt *event) - { -- dwc3_trace(trace_dwc3_ep0, "%s: state '%s'", -- dwc3_ep_event_string(event), -- dwc3_ep0_state_string(dwc->ep0state)); -- - switch (event->endpoint_event) { - case DWC3_DEPEVT_XFERCOMPLETE: - dwc3_ep0_xfer_complete(dwc, event); ---- linux-4.9.37/drivers/usb/dwc3/gadget.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/gadget.c 2021-06-07 13:01:34.000000000 +0300 -@@ -35,6 +35,15 @@ - #include "gadget.h" - #include "io.h" - -+static void dwc3_gadget_sync_connected_status(struct dwc3 *dwc); -+static int __dwc3_gadget_get_frame(struct dwc3 *dwc); -+static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep, -+ const struct dwc3_event_depevt *event); -+static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep); -+ -+#define DWC3_ALIGN_FRAME(d) (((d)->frame_number + (d)->interval) \ -+ & ~((d)->interval - 1)) -+ - /** - * dwc3_gadget_set_test_mode - Enables USB2 Test Modes - * @dwc: pointer to our context structure -@@ -139,9 +148,6 @@ - udelay(5); - } - -- dwc3_trace(trace_dwc3_gadget, -- "link state change request timed out"); -- - return -ETIMEDOUT; - } - -@@ -153,7 +159,7 @@ - * if it is point to the link TRB, wrap around to the beginning. The - * link TRB is always at the last TRB entry. - */ --static void dwc3_ep_inc_trb(u8 *index) -+static void dwc3_ep_inc_trb(u32 *index) - { - (*index)++; - if (*index == (DWC3_TRB_NUM - 1)) -@@ -247,7 +253,7 @@ - struct dwc3_gadget_ep_cmd_params *params) - { - struct dwc3 *dwc = dep->dwc; -- u32 timeout = 500; -+ u32 timeout = 5000; - u32 reg; - - int cmd_status = 0; -@@ -563,8 +569,6 @@ - u32 reg; - int ret; - -- dwc3_trace(trace_dwc3_gadget, "Enabling %s", dep->name); -- - if (!(dep->flags & DWC3_EP_ENABLED)) { - ret = dwc3_gadget_start_config(dwc, dep); - if (ret) -@@ -590,7 +594,7 @@ - dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); - - if (usb_endpoint_xfer_control(desc)) -- return 0; -+ goto out; - - /* Initialize the TRB ring */ - dep->trb_dequeue = 0; -@@ -608,15 +612,19 @@ - trb_link->ctrl |= DWC3_TRB_CTRL_HWO; - } - -+ -+out: -+ trace_dwc3_gadget_ep_enable(dep); -+ - return 0; - } - --static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force); -+static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force); - static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) - { - struct dwc3_request *req; - -- dwc3_stop_active_transfer(dwc, dep->number, true); -+ dwc3_stop_active_transfer(dep, true); - - /* - giveback all requests to gadget driver */ - while (!list_empty(&dep->started_list)) { -@@ -645,7 +653,7 @@ - struct dwc3 *dwc = dep->dwc; - u32 reg; - -- dwc3_trace(trace_dwc3_gadget, "Disabling %s", dep->name); -+ trace_dwc3_gadget_ep_disable(dep); - - dwc3_remove_requests(dwc, dep); - -@@ -787,10 +795,7 @@ - struct dwc3 *dwc = dep->dwc; - struct usb_gadget *gadget = &dwc->gadget; - enum usb_device_speed speed = gadget->speed; -- -- dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s", -- dep->name, req, (unsigned long long) dma, -- length, chain ? " chain" : ""); -+ unsigned int chain_skip = 0; - - trb = &dep->trb_pool[dep->trb_enqueue]; - -@@ -816,12 +821,55 @@ - case USB_ENDPOINT_XFER_ISOC: - if (!node) { - trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; -- -+ /* -+ * USB Specification 2.0 Section 5.9.2 states that: "If -+ * there is only a single transaction in the microframe, -+ * only a DATA0 data packet PID is used. If there are -+ * two transactions per microframe, DATA1 is used for -+ * the first transaction data packet and DATA0 is used -+ * for the second transaction data packet. If there are -+ * three transactions per microframe, DATA2 is used for -+ * the first transaction data packet, DATA1 is used for -+ * the second, and DATA0 is used for the third." -+ * -+ * IOW, we should satisfy the following cases: -+ * -+ * 1) length <= maxpacket -+ * - DATA0 -+ * -+ * 2) maxpacket < length <= (2 * maxpacket) -+ * - DATA1, DATA0 -+ * -+ * 3) (2 * maxpacket) < length <= (3 * maxpacket) -+ * - DATA2, DATA1, DATA0 -+ */ - if (speed == USB_SPEED_HIGH) { - struct usb_ep *ep = &dep->endpoint; -- trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1); -+ //unsigned int mult = ep->mult - 1; -+ unsigned int mult = 2; //backport commit ec5bb87e4e2a1d3a35563a7bcfac9febf67aba9d -+ unsigned int maxp = usb_endpoint_maxp(ep->desc); -+ -+ if (length <= (2 * maxp)) -+ mult--; -+ -+ if (length <= maxp) -+ mult--; -+ -+ trb->size |= DWC3_TRB_SIZE_PCM1(mult); -+ -+ /* -+ * If there are three transactions per mframe, -+ * and each transcation length = 1024B, no any -+ * chain trb needed, so skip it. -+ */ -+ if (length == (3 * maxp)) -+ chain_skip = 1; - } -+ -+ if (speed == USB_SPEED_SUPER) -+ chain_skip = 1; - } else { -+ chain_skip = 1; - trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; - } - -@@ -848,7 +896,7 @@ - (dwc3_calc_trbs_left(dep) == 0)) - trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI; - -- if (chain) -+ if ((!chain_skip) && chain) - trb->ctrl |= DWC3_TRB_CTRL_CHN; - - if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable) -@@ -868,9 +916,9 @@ - * index is 0, we will wrap backwards, skip the link TRB, and return - * the one just before that. - */ --static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) -+static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u32 index) - { -- u8 tmp = index; -+ u32 tmp = index; - - if (!tmp) - tmp = DWC3_TRB_NUM - 1; -@@ -881,7 +929,7 @@ - static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) - { - struct dwc3_trb *tmp; -- u8 trbs_left; -+ u32 trbs_left; - - /* - * If enqueue & dequeue are equal than it is either full or empty. -@@ -910,11 +958,13 @@ - static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, - struct dwc3_request *req) - { -+ struct dwc3 *dwc = dep->dwc; -+ struct usb_gadget *gadget = &dwc->gadget; -+ enum usb_device_speed speed = gadget->speed; - struct scatterlist *sg = req->sg; - struct scatterlist *s; -- unsigned int length; -+ unsigned int length, i; - dma_addr_t dma; -- int i; - - for_each_sg(sg, s, req->num_pending_sgs, i) { - unsigned chain = true; -@@ -925,8 +975,11 @@ - if (sg_is_last(s)) - chain = false; - -- dwc3_prepare_one_trb(dep, req, dma, length, -- chain, i); -+ if ((speed == USB_SPEED_HIGH) && -+ usb_endpoint_xfer_isoc(dep->endpoint.desc)) -+ dwc3_prepare_one_trb(dep, req, dma, length, chain, 0); -+ else -+ dwc3_prepare_one_trb(dep, req, dma, length, chain, i); - - if (!dwc3_calc_trbs_left(dep)) - break; -@@ -994,11 +1047,22 @@ - - memset(¶ms, 0, sizeof(params)); - -- if (starting) { -+ if (starting && !(dep->flags&DWC3_EP_UPDATE)) { - params.param0 = upper_32_bits(req->trb_dma); - params.param1 = lower_32_bits(req->trb_dma); -- cmd = DWC3_DEPCMD_STARTTRANSFER | -- DWC3_DEPCMD_PARAM(cmd_param); -+ -+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -+ while (__dwc3_gadget_target_frame_elapsed(dep)) -+ dep->frame_number = DWC3_ALIGN_FRAME(dep); -+ -+ dep->frame_number = DWC3_ALIGN_FRAME(dep); -+ cmd_param = dep->frame_number; -+ } -+ -+ cmd = DWC3_DEPCMD_STARTTRANSFER | DWC3_DEPCMD_PARAM(cmd_param); -+ -+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) -+ dep->flags |= DWC3_EP_UPDATE; - } else { - cmd = DWC3_DEPCMD_UPDATETRANSFER | - DWC3_DEPCMD_PARAM(dep->resource_index); -@@ -1027,34 +1091,36 @@ - return 0; - } - --static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, -- struct dwc3_ep *dep, u32 cur_uf) --{ -- u32 uf; -+static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep) { -+ u16 cframe = __dwc3_gadget_get_frame(dep->dwc); -+ u16 eframe = dep->frame_number & DWC3_EVENT_PRAM_SOFFN_MASK; -+ -+ if (eframe == cframe) -+ return true; -+ -+ return (((eframe - cframe) & DWC3_EVENT_PRAM_SOFFN_MASK) -+ > DWC3_EVENT_PRAM_MAX_SOFFN / 2); -+} - -+static void __dwc3_gadget_start_isoc(struct dwc3_ep *dep) -+{ - if (list_empty(&dep->pending_list)) { -- dwc3_trace(trace_dwc3_gadget, -- "ISOC ep %s run out for requests", -- dep->name); - dep->flags |= DWC3_EP_PENDING_REQUEST; - return; - } - -- /* 4 micro frames in the future */ -- uf = cur_uf + dep->interval * 4; -+ while (__dwc3_gadget_target_frame_elapsed(dep)) -+ dep->frame_number = DWC3_ALIGN_FRAME(dep); - -- __dwc3_gadget_kick_transfer(dep, uf); -+ dep->frame_number = DWC3_ALIGN_FRAME(dep); -+ __dwc3_gadget_kick_transfer(dep, dep->frame_number); - } - --static void dwc3_gadget_start_isoc(struct dwc3 *dwc, -- struct dwc3_ep *dep, const struct dwc3_event_depevt *event) -+static void dwc3_gadget_start_isoc(struct dwc3_ep *dep, -+ const struct dwc3_event_depevt *event) - { -- u32 cur_uf, mask; -- -- mask = ~(dep->interval - 1); -- cur_uf = event->parameters & mask; -- -- __dwc3_gadget_start_isoc(dwc, dep, cur_uf); -+ dwc3_gadget_endpoint_frame_from_event(dep, event); -+ __dwc3_gadget_start_isoc(dep); - } - - static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) -@@ -1063,16 +1129,15 @@ - int ret; - - if (!dep->endpoint.desc) { -- dwc3_trace(trace_dwc3_gadget, -- "trying to queue request %p to disabled %s", -- &req->request, dep->endpoint.name); -+ dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n", -+ dep->name); - return -ESHUTDOWN; - } - - if (WARN(req->dep != dep, "request %pK belongs to '%s'\n", - &req->request, req->dep->name)) { -- dwc3_trace(trace_dwc3_gadget, "request %pK belongs to '%s'", -- &req->request, req->dep->name); -+ dev_err(dwc->dev, "%s: request %p belongs to '%s'\n", -+ dep->name, &req->request, req->dep->name); - return -EINVAL; - } - -@@ -1106,7 +1171,7 @@ - if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { - if ((dep->flags & DWC3_EP_PENDING_REQUEST) && - list_empty(&dep->started_list)) { -- dwc3_stop_active_transfer(dwc, dep->number, true); -+ dwc3_stop_active_transfer(dep, true); - dep->flags = DWC3_EP_ENABLED; - } - return 0; -@@ -1116,10 +1181,6 @@ - return 0; - - ret = __dwc3_gadget_kick_transfer(dep, 0); -- if (ret && ret != -EBUSY) -- dwc3_trace(trace_dwc3_gadget, -- "%s: failed to kick transfers", -- dep->name); - if (ret == -EBUSY) - ret = 0; - -@@ -1138,7 +1199,6 @@ - struct usb_request *request; - struct usb_ep *ep = &dep->endpoint; - -- dwc3_trace(trace_dwc3_gadget, "queueing ZLP"); - request = dwc3_gadget_ep_alloc_request(ep, GFP_ATOMIC); - if (!request) - return -ENOMEM; -@@ -1197,6 +1257,10 @@ - - spin_lock_irqsave(&dwc->lock, flags); - -+ -+ if (list_empty(&dep->pending_list) && list_empty(&dep->started_list) ) -+ goto out0 ; -+ - list_for_each_entry(r, &dep->pending_list, list) { - if (r == req) - break; -@@ -1209,7 +1273,7 @@ - } - if (r == req) { - /* wait until it is processed */ -- dwc3_stop_active_transfer(dwc, dep->number, true); -+ dwc3_stop_active_transfer(dep, true); - goto out1; - } - dev_err(dwc->dev, "request %pK was not queued to %s\n", -@@ -1247,9 +1311,6 @@ - unsigned transfer_in_flight; - unsigned started; - -- if (dep->flags & DWC3_EP_STALL) -- return 0; -- - if (dep->number > 1) - trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue); - else -@@ -1260,9 +1321,6 @@ - - if (!protocol && ((dep->direction && transfer_in_flight) || - (!dep->direction && started))) { -- dwc3_trace(trace_dwc3_gadget, -- "%s: pending request, cannot halt", -- dep->name); - return -EAGAIN; - } - -@@ -1274,8 +1332,6 @@ - else - dep->flags |= DWC3_EP_STALL; - } else { -- if (!(dep->flags & DWC3_EP_STALL)) -- return 0; - - ret = dwc3_send_clear_stall_ep_cmd(dep); - if (ret) -@@ -1355,15 +1411,21 @@ - - /* -------------------------------------------------------------------------- */ - --static int dwc3_gadget_get_frame(struct usb_gadget *g) -+static int __dwc3_gadget_get_frame(struct dwc3 *dwc) - { -- struct dwc3 *dwc = gadget_to_dwc(g); - u32 reg; - - reg = dwc3_readl(dwc->regs, DWC3_DSTS); - return DWC3_DSTS_SOFFN(reg); - } - -+static int dwc3_gadget_get_frame(struct usb_gadget *g) -+{ -+ struct dwc3 *dwc = gadget_to_dwc(g); -+ -+ return __dwc3_gadget_get_frame(dwc); -+} -+ - static int __dwc3_gadget_wakeup(struct dwc3 *dwc) - { - int retries; -@@ -1384,10 +1446,8 @@ - - speed = reg & DWC3_DSTS_CONNECTSPD; - if ((speed == DWC3_DSTS_SUPERSPEED) || -- (speed == DWC3_DSTS_SUPERSPEED_PLUS)) { -- dwc3_trace(trace_dwc3_gadget, "no wakeup on SuperSpeed"); -+ (speed == DWC3_DSTS_SUPERSPEED_PLUS)) - return 0; -- } - - link_state = DWC3_DSTS_USBLNKST(reg); - -@@ -1396,9 +1456,6 @@ - case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */ - break; - default: -- dwc3_trace(trace_dwc3_gadget, -- "can't wakeup from '%s'", -- dwc3_gadget_link_string(link_state)); - return -EINVAL; - } - -@@ -1503,11 +1560,6 @@ - if (!timeout) - return -ETIMEDOUT; - -- dwc3_trace(trace_dwc3_gadget, "gadget %s data soft-%s", -- dwc->gadget_driver -- ? dwc->gadget_driver->function : "no-function", -- is_on ? "connect" : "disconnect"); -- - return 0; - } - -@@ -1677,6 +1729,7 @@ - - /* begin to receive SETUP packets */ - dwc->ep0state = EP0_SETUP_PHASE; -+ dwc->link_state = DWC3_LINK_STATE_SS_DIS; - dwc3_ep0_out_start(dwc); - - dwc3_gadget_enable_irq(dwc); -@@ -1767,6 +1820,81 @@ - .udc_stop = dwc3_gadget_stop, - }; - -+static int dwc3_gadget_init_hw_all_endpoints(struct dwc3 *dwc) -+{ -+ struct dwc3_ep *dep; -+ struct dwc3_hwparams *parms = &dwc->hwparams; -+ u32 direction = dwc->eps_directions; -+ u8 num_eps = DWC3_NUM_EPS(parms); -+ u8 num_in_eps = 0; -+ u8 num_out_eps = 0; -+ u8 epnum = 0; -+ u8 i; -+ -+ if (!direction) -+ direction = DWC3_EPS_DEFAULT_DIRECTIONS; -+ -+ for (i = 0; i < num_eps; i++) { -+ if (direction & 0x1) -+ epnum = (num_in_eps++ << 1) + 1; -+ else -+ epnum = (num_out_eps++ << 1); -+ -+ dep = kzalloc(sizeof(*dep), GFP_KERNEL); -+ if (!dep) -+ return -ENOMEM; -+ -+ dep->dwc = dwc; -+ dep->number = epnum; -+ dep->direction = !!(direction & 0x1); -+ dep->regs = dwc->regs + DWC3_DEP_BASE(i); -+ dwc->eps[i] = dep; -+ -+ snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, -+ (epnum & 1) ? "in" : "out"); -+ -+ dep->endpoint.name = dep->name; -+ spin_lock_init(&dep->lock); -+ -+ if (epnum == 0 || epnum == 1) { -+ usb_ep_set_maxpacket_limit(&dep->endpoint, 512); -+ dep->endpoint.maxburst = 1; -+ dep->endpoint.ops = &dwc3_gadget_ep0_ops; -+ if (!epnum) -+ dwc->gadget.ep0 = &dep->endpoint; -+ } else { -+ int ret; -+ -+ usb_ep_set_maxpacket_limit(&dep->endpoint, 1024); -+ dep->endpoint.max_streams = 15; -+ dep->endpoint.ops = &dwc3_gadget_ep_ops; -+ list_add_tail(&dep->endpoint.ep_list, -+ &dwc->gadget.ep_list); -+ -+ ret = dwc3_alloc_trb_pool(dep); -+ if (ret) -+ return ret; -+ } -+ -+ if (epnum == 0 || epnum == 1) { -+ dep->endpoint.caps.type_control = true; -+ } else { -+ dep->endpoint.caps.type_iso = true; -+ dep->endpoint.caps.type_bulk = true; -+ dep->endpoint.caps.type_int = true; -+ } -+ -+ dep->endpoint.caps.dir_in = !!(direction & 0x1); -+ dep->endpoint.caps.dir_out = !(direction & 0x1); -+ direction = (direction >> 1); -+ -+ INIT_LIST_HEAD(&dep->pending_list); -+ INIT_LIST_HEAD(&dep->started_list); -+ } -+ -+ return 0; -+} -+ - /* -------------------------------------------------------------------------- */ - - static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, -@@ -1794,8 +1922,6 @@ - dep->endpoint.name = dep->name; - spin_lock_init(&dep->lock); - -- dwc3_trace(trace_dwc3_gadget, "initializing %s", dep->name); -- - if (epnum == 0 || epnum == 1) { - usb_ep_set_maxpacket_limit(&dep->endpoint, 512); - dep->endpoint.maxburst = 1; -@@ -1840,17 +1966,24 @@ - - INIT_LIST_HEAD(&dwc->gadget.ep_list); - -+ if (dwc->eps_new_init) { -+ ret = dwc3_gadget_init_hw_all_endpoints(dwc); -+ if (ret < 0) { -+ dev_err(dwc->dev, "failed to initialize OUT endpoints\n"); -+ return ret; -+ } -+ return 0; -+ } -+ - ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0); - if (ret < 0) { -- dwc3_trace(trace_dwc3_gadget, -- "failed to allocate OUT endpoints"); -+ dev_err(dwc->dev, "failed to initialize OUT endpoints\n"); - return ret; - } - - ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1); - if (ret < 0) { -- dwc3_trace(trace_dwc3_gadget, -- "failed to allocate IN endpoints"); -+ dev_err(dwc->dev, "failed to initialize IN endpoints\n"); - return ret; - } - -@@ -1886,14 +2019,12 @@ - - /* -------------------------------------------------------------------------- */ - --static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep, -- struct dwc3_request *req, struct dwc3_trb *trb, -- const struct dwc3_event_depevt *event, int status, -- int chain) -+static int __dwc3_cleanup_done_trbs(struct dwc3_ep *dep, struct dwc3_request *req, -+ struct dwc3_trb *trb, const struct dwc3_event_depevt *event, -+ int status, int chain) - { - unsigned int count; - unsigned int s_pkt = 0; -- unsigned int trb_status; - - dwc3_ep_inc_deq(dep); - -@@ -1922,37 +2053,6 @@ - req->request.actual += count; - - if (dep->direction) { -- if (count) { -- trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); -- if (trb_status == DWC3_TRBSTS_MISSED_ISOC) { -- dwc3_trace(trace_dwc3_gadget, -- "%s: incomplete IN transfer", -- dep->name); -- /* -- * If missed isoc occurred and there is -- * no request queued then issue END -- * TRANSFER, so that core generates -- * next xfernotready and we will issue -- * a fresh START TRANSFER. -- * If there are still queued request -- * then wait, do not issue either END -- * or UPDATE TRANSFER, just attach next -- * request in pending_list during -- * giveback.If any future queued request -- * is successfully transferred then we -- * will issue UPDATE TRANSFER for all -- * request in the pending_list. -- */ -- dep->flags |= DWC3_EP_MISSED_ISOC; -- } else { -- dev_err(dwc->dev, "incomplete IN transfer %s\n", -- dep->name); -- status = -ECONNRESET; -- } -- } else { -- dep->flags &= ~DWC3_EP_MISSED_ISOC; -- } -- } else { - if (count && (event->status & DEPEVT_STATUS_SHORT)) - s_pkt = 1; - } -@@ -1967,7 +2067,7 @@ - return 0; - } - --static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, -+static int dwc3_cleanup_done_reqs(struct dwc3_ep *dep, - const struct dwc3_event_depevt *event, int status) - { - struct dwc3_request *req, *n; -@@ -1994,14 +2094,14 @@ - req->sg = sg_next(s); - req->num_pending_sgs--; - -- ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, -+ ret = __dwc3_cleanup_done_trbs(dep, req, trb, - event, status, chain); - if (ret) - break; - } - } else { - trb = &dep->trb_pool[dep->trb_dequeue]; -- ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, -+ ret = __dwc3_cleanup_done_trbs(dep, req, trb, - event, status, chain); - } - -@@ -2045,9 +2145,9 @@ - * flag, so that END TRANSFER is issued when an - * entry is added into request list. - */ -- dep->flags = DWC3_EP_PENDING_REQUEST; -+ dep->flags |= DWC3_EP_PENDING_REQUEST; - } else { -- dwc3_stop_active_transfer(dwc, dep->number, true); -+ dwc3_stop_active_transfer(dep, true); - dep->flags = DWC3_EP_ENABLED; - } - return 1; -@@ -2059,19 +2159,28 @@ - return 1; - } - --static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, -- struct dwc3_ep *dep, const struct dwc3_event_depevt *event) -+static void dwc3_gadget_endpoint_frame_from_event(struct dwc3_ep *dep, -+ const struct dwc3_event_depevt *event) -+{ -+ dep->frame_number = event->parameters; -+} -+ -+static void dwc3_endpoint_transfer_complete(struct dwc3_ep *dep, -+ const struct dwc3_event_depevt *event) - { -+ struct dwc3 *dwc = dep->dwc; - unsigned status = 0; - int clean_busy; - u32 is_xfer_complete; - -+ dwc3_gadget_endpoint_frame_from_event(dep, event); -+ - is_xfer_complete = (event->endpoint_event == DWC3_DEPEVT_XFERCOMPLETE); - - if (event->status & DEPEVT_STATUS_BUSERR) - status = -ECONNRESET; - -- clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status); -+ clean_busy = dwc3_cleanup_done_reqs(dep, event, status); - if (clean_busy && (!dep->endpoint.desc || is_xfer_complete || - usb_endpoint_xfer_isoc(dep->endpoint.desc))) - dep->flags &= ~DWC3_EP_BUSY; -@@ -2109,12 +2218,16 @@ - if (!dep->endpoint.desc) - return; - -- if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -+ if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) || (dep->flags&DWC3_EP_ENABLED)) { - int ret; -- -- ret = __dwc3_gadget_kick_transfer(dep, 0); -- if (!ret || ret == -EBUSY) -- return; -+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && -+ (!(dep->flags & (DWC3_EP_BUSY | DWC3_EP_UPDATE)))) { -+ __dwc3_gadget_start_isoc(dep); -+ } else { -+ ret = __dwc3_gadget_kick_transfer(dep, 0); -+ if (!ret || ret == -EBUSY) -+ return; -+ } - } - } - -@@ -2139,37 +2252,24 @@ - dep->resource_index = 0; - - if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -- dwc3_trace(trace_dwc3_gadget, -- "%s is an Isochronous endpoint", -- dep->name); -+ dev_err(dwc->dev, "XferComplete for Isochronous endpoint\n"); - return; - } - -- dwc3_endpoint_transfer_complete(dwc, dep, event); -+ dwc3_endpoint_transfer_complete(dep, event); - break; - case DWC3_DEPEVT_XFERINPROGRESS: -- dwc3_endpoint_transfer_complete(dwc, dep, event); -+ dwc3_endpoint_transfer_complete(dep, event); - break; - case DWC3_DEPEVT_XFERNOTREADY: - if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -- dwc3_gadget_start_isoc(dwc, dep, event); -+ dwc3_gadget_start_isoc(dep, event); - } else { -- int active; - int ret; - -- active = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; -- -- dwc3_trace(trace_dwc3_gadget, "%s: reason %s", -- dep->name, active ? "Transfer Active" -- : "Transfer Not Active"); -- - ret = __dwc3_gadget_kick_transfer(dep, 0); - if (!ret || ret == -EBUSY) - return; -- -- dwc3_trace(trace_dwc3_gadget, -- "%s: failed to kick transfers", -- dep->name); - } - - break; -@@ -2179,26 +2279,9 @@ - dep->name); - return; - } -- -- switch (event->status) { -- case DEPEVT_STREAMEVT_FOUND: -- dwc3_trace(trace_dwc3_gadget, -- "Stream %d found and started", -- event->parameters); -- -- break; -- case DEPEVT_STREAMEVT_NOTFOUND: -- /* FALLTHROUGH */ -- default: -- dwc3_trace(trace_dwc3_gadget, -- "unable to find suitable stream"); -- } - break; - case DWC3_DEPEVT_RXTXFIFOEVT: -- dwc3_trace(trace_dwc3_gadget, "%s FIFO Overrun", dep->name); -- break; - case DWC3_DEPEVT_EPCMDCMPLT: -- dwc3_trace(trace_dwc3_gadget, "Endpoint Command Complete"); - break; - } - } -@@ -2242,15 +2325,13 @@ - } - } - --static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum, bool force) -+static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force) - { -- struct dwc3_ep *dep; -+ struct dwc3 *dwc = dep->dwc; - struct dwc3_gadget_ep_cmd_params params; - u32 cmd; - int ret; - -- dep = dwc->eps[epnum]; -- - if (!dep->resource_index) - return; - -@@ -2596,8 +2677,6 @@ - (pwropt != DWC3_GHWPARAMS1_EN_PWROPT_HIB)) { - if ((dwc->link_state == DWC3_LINK_STATE_U3) && - (next == DWC3_LINK_STATE_RESUME)) { -- dwc3_trace(trace_dwc3_gadget, -- "ignoring transition U3 -> Resume"); - return; - } - } -@@ -2731,11 +2810,7 @@ - break; - case DWC3_DEVICE_EVENT_EOPF: - /* It changed to be suspend event for version 2.30a and above */ -- if (dwc->revision < DWC3_REVISION_230A) { -- dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame"); -- } else { -- dwc3_trace(trace_dwc3_gadget, "U3/L1-L2 Suspend Event"); -- -+ if (dwc->revision >= DWC3_REVISION_230A) { - /* - * Ignore suspend event until the gadget enters into - * USB_STATE_CONFIGURED state. -@@ -2746,26 +2821,21 @@ - } - break; - case DWC3_DEVICE_EVENT_SOF: -- dwc3_trace(trace_dwc3_gadget, "Start of Periodic Frame"); -- break; - case DWC3_DEVICE_EVENT_ERRATIC_ERROR: -- dwc3_trace(trace_dwc3_gadget, "Erratic Error"); -- break; - case DWC3_DEVICE_EVENT_CMD_CMPL: -- dwc3_trace(trace_dwc3_gadget, "Command Complete"); -- break; - case DWC3_DEVICE_EVENT_OVERFLOW: -- dwc3_trace(trace_dwc3_gadget, "Overflow"); - break; -+ - default: - dev_WARN(dwc->dev, "UNKNOWN IRQ %d\n", event->type); - } -+ dwc3_gadget_sync_connected_status(dwc); - } - - static void dwc3_process_event_entry(struct dwc3 *dwc, - const union dwc3_event *event) - { -- trace_dwc3_event(event->raw); -+ trace_dwc3_event(event->raw, dwc); - - /* Endpoint IRQ, handle it and return early */ - if (event->type.is_devspec == 0) { -@@ -2984,8 +3054,7 @@ - * composite.c that we are USB 2.0 + LPM ECN. - */ - if (dwc->revision < DWC3_REVISION_220A) -- dwc3_trace(trace_dwc3_gadget, -- "Changing max_speed on rev %08x", -+ dev_info(dwc->dev, "changing max_speed on rev %08x\n", - dwc->revision); - - dwc->gadget.max_speed = dwc->maximum_speed; -@@ -3005,6 +3074,8 @@ - if (ret) - goto err5; - -+ dwc3_proc_init(dwc); -+ - ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); - if (ret) { - dev_err(dwc->dev, "failed to register udc\n"); -@@ -3042,6 +3113,8 @@ - { - usb_del_gadget_udc(&dwc->gadget); - -+ dwc3_proc_shutdown(dwc); -+ - dwc3_gadget_free_endpoints(dwc); - - dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE, -@@ -3106,3 +3179,70 @@ - enable_irq(dwc->irq_gadget); - } - } -+ -+/* -+ * dwc3_gadget_sync_connected_status() function just for -+ * user space get udc connected status. and this function -+ * just report three status: Disconnected, Connected host, -+ * Connected charger. -+ * -+ * After some tests, report connected udc connected status by -+ * DSTS register, [21:18]USB Link Status and [2:0] Connect Speed. -+ * -+ * How to identify whitch status is the UDC connected? -+ * 1. Host connected: -+ * Host would reset udc, so dwc3 core get reset event interrupt, -+ * dwc3_gadget_reset_interrupt() set dwc->connected = true, -+ * so check connected host by dwc->connected == true -+ * -+ * 2. Disconnected: -+ * When vbus detect 5V lose, dwc3 core generated a disconnect event intr. -+ * dwc3_gadget_disconnect_interrupt() set dwc->connected = false. -+ * so check disconnected by dwc->connected == false -+ * -+ * 3. Charger connected: (Fixedme) -+ * As dwc3 core size, DP keep pullup register when connected to charger. -+ * no any port reset action created, so dwc3 would entry FullSpeed mode. -+ * so chect connected charger by FullSpeed && dwc->connectd == false -+ * -+ */ -+static void dwc3_gadget_sync_connected_status(struct dwc3 *dwc) -+{ -+ u32 reg; -+ u8 speed; -+ u8 state; -+ static int prev = UDC_DISCONNECTED; -+ -+ reg = dwc3_readl(dwc->regs, DWC3_DSTS); -+ speed = reg & DWC3_DSTS_CONNECTSPD; -+ state = DWC3_DSTS_USBLNKST(reg); -+ -+ /* -+ * step1 check is connected host? -+ */ -+ if (dwc->connected == true) { -+ if (prev != UDC_CONNECT_HOST) -+ dwc->udc_connect_status = UDC_CONNECT_HOST; -+ goto out; -+ } -+ -+ /* -+ * step2 disconectd status && fullspeed mode, -+ * as connected charger. -+ */ -+ if ((speed == DWC3_DSTS_FULLSPEED) && (state != DWC3_LINK_STATE_SS_DIS)) { -+ if (prev != UDC_CONNECT_CHARGER) -+ dwc->udc_connect_status = UDC_CONNECT_CHARGER; -+ goto out; -+ } -+ -+ /* -+ * step3 not host and charger connected, so just -+ * disconnectd. -+ */ -+ if (prev != UDC_DISCONNECTED) -+ dwc->udc_connect_status = UDC_DISCONNECTED; -+ -+out: -+ prev = dwc->udc_connect_status; -+} ---- linux-4.9.37/drivers/usb/dwc3/host.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/host.c 2021-06-07 13:01:34.000000000 +0300 -@@ -21,7 +21,7 @@ - - int dwc3_host_init(struct dwc3 *dwc) - { -- struct property_entry props[3]; -+ struct property_entry props[4]; - struct platform_device *xhci; - int ret, irq; - struct resource *res; -@@ -93,6 +93,9 @@ - if (dwc->usb3_lpm_capable) - props[prop_idx++].name = "usb3-lpm-capable"; - -+ if (dwc->usb2_lpm_disable) -+ props[prop_idx++].name = "usb2-lpm-disable"; -+ - /** - * WORKAROUND: dwc3 revisions <=3.00a have a limitation - * where Port Disable command doesn't work. ---- linux-4.9.37/drivers/usb/dwc3/io.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/io.h 2021-06-07 13:01:34.000000000 +0300 -@@ -40,8 +40,7 @@ - * documentation, so we revert it back to the proper addresses, the - * same way they are described on SNPS documentation - */ -- dwc3_trace(trace_dwc3_readl, "addr %p value %08x", -- base - DWC3_GLOBALS_REGS_START + offset, value); -+ trace_dwc3_readl(base - DWC3_GLOBALS_REGS_START, offset, value); - - return value; - } -@@ -60,8 +59,7 @@ - * documentation, so we revert it back to the proper addresses, the - * same way they are described on SNPS documentation - */ -- dwc3_trace(trace_dwc3_writel, "addr %p value %08x", -- base - DWC3_GLOBALS_REGS_START + offset, value); -+ trace_dwc3_writel(base - DWC3_GLOBALS_REGS_START, offset, value); - } - - #endif /* __DRIVERS_USB_DWC3_IO_H */ ---- linux-4.9.37/drivers/usb/dwc3/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -1,9 +1,12 @@ - # define_trace.h needs to know how to find our header - CFLAGS_trace.o := -I$(src) - --obj-$(CONFIG_USB_DWC3) += dwc3.o -+obj-$(CONFIG_USB_DWC3) += dwc3.o dwc3-goke.o - --dwc3-y := core.o debug.o trace.o -+dwc3-y := core.o proc.o -+ifneq ($(CONFIG_TRACING),) -+dwc3-y += trace.o -+endif - - ifneq ($(filter y,$(CONFIG_USB_DWC3_HOST) $(CONFIG_USB_DWC3_DUAL_ROLE)),) - dwc3-y += host.o ---- linux-4.9.37/drivers/usb/dwc3/proc.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/proc.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,120 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "core.h" -+ -+#define DWC3_PROC_ROOT "dwc3" -+#define DWC3_PROC_CONNECTED_STATUS "csts" -+ -+static struct proc_dir_entry *proc_dwc3_dir = NULL; -+static int proc_dwc3_dir_cnt = 0; -+ -+static void dwc3_stats_seq_printout(struct seq_file *s) -+{ -+ struct dwc3 *dwc = s->private; -+ -+ switch (dwc->udc_connect_status) { -+ case UDC_CONNECT_HOST: -+ seq_puts(s, "cnt2host\n"); -+ break; -+ case UDC_CONNECT_CHARGER: -+ seq_puts(s, "cnt2charger\n"); -+ break; -+ default: -+ seq_puts(s, "disconnected\n"); -+ break; -+ } -+} -+ -+/* define parameters where showed in proc file */ -+static int dwc3_stats_seq_show(struct seq_file *s, void *v) -+{ -+ if (s == NULL) -+ return -EINVAL; -+ -+ dwc3_stats_seq_printout(s); -+ return 0; -+} -+ -+/* proc file open */ -+static int dwc3_stats_proc_open(struct inode *inode, struct file *file) -+{ -+ if ((inode == NULL) || (file == NULL)) -+ return -EINVAL; -+ -+ return single_open(file, dwc3_stats_seq_show, PDE_DATA(inode)); -+}; -+ -+/* proc file operation */ -+static const struct file_operations dwc3_stats_proc_ops = { -+ .owner = THIS_MODULE, -+ .open = dwc3_stats_proc_open, -+ .read = seq_read, -+ .release = single_release, -+}; -+ -+int dwc3_proc_init(struct dwc3 *dwc) -+{ -+ struct proc_dir_entry *proc_entry = NULL; -+ -+ if (dwc == NULL) -+ return -EINVAL; -+ -+ if (proc_dwc3_dir == NULL) { -+ proc_entry = proc_mkdir(DWC3_PROC_ROOT, NULL); -+ if (proc_entry == NULL) { -+ pr_err("%s: failed to create proc file %s\n", -+ __func__, DWC3_PROC_ROOT); -+ return 1; -+ } -+ proc_dwc3_dir = proc_entry; -+ } -+ proc_dwc3_dir_cnt++; -+ -+ proc_entry = proc_mkdir(to_platform_device(dwc->dev)->name, proc_dwc3_dir); -+ if (proc_entry == NULL) { -+ pr_err("%s: failed to create proc file %s\n", -+ __func__, to_platform_device(dwc->dev)->name); -+ return -1; -+ } -+ dwc->parent_entry = proc_entry; -+ -+ proc_entry = proc_create_data(DWC3_PROC_CONNECTED_STATUS, -+ 0, dwc->parent_entry, &dwc3_stats_proc_ops, dwc); -+ if (proc_entry == NULL) { -+ pr_err("%s: failed to create proc file %s\n", -+ __func__, DWC3_PROC_CONNECTED_STATUS); -+ return -1; -+ } -+ dwc->csts_entry = proc_entry; -+ -+ /* -+ * add here if more proc information need. -+ */ -+ return 0; -+} -+ -+int dwc3_proc_shutdown(struct dwc3 *dwc) -+{ -+ if (proc_dwc3_dir != NULL) { -+ remove_proc_entry(DWC3_PROC_CONNECTED_STATUS, dwc->parent_entry); -+ remove_proc_entry(to_platform_device(dwc->dev)->name, proc_dwc3_dir); -+ } -+ -+ if (proc_dwc3_dir_cnt) -+ proc_dwc3_dir_cnt--; -+ -+ if (proc_dwc3_dir_cnt == 0) { -+ remove_proc_entry(DWC3_PROC_ROOT, NULL); -+ proc_dwc3_dir = NULL; -+ } -+ -+ return 0; -+} ---- linux-4.9.37/drivers/usb/dwc3/trace.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/dwc3/trace.h 2021-06-07 13:01:34.000000000 +0300 -@@ -27,57 +27,53 @@ - #include "core.h" - #include "debug.h" - --DECLARE_EVENT_CLASS(dwc3_log_msg, -- TP_PROTO(struct va_format *vaf), -- TP_ARGS(vaf), -- TP_STRUCT__entry(__dynamic_array(char, msg, DWC3_MSG_MAX)), -+DECLARE_EVENT_CLASS(dwc3_log_io, -+ TP_PROTO(void *base, u32 offset, u32 value), -+ TP_ARGS(base, offset, value), -+ TP_STRUCT__entry( -+ __field(void *, base) -+ __field(u32, offset) -+ __field(u32, value) -+ ), - TP_fast_assign( -- vsnprintf(__get_str(msg), DWC3_MSG_MAX, vaf->fmt, *vaf->va); -+ __entry->base = base; -+ __entry->offset = offset; -+ __entry->value = value; - ), -- TP_printk("%s", __get_str(msg)) --); -- --DEFINE_EVENT(dwc3_log_msg, dwc3_readl, -- TP_PROTO(struct va_format *vaf), -- TP_ARGS(vaf) --); -- --DEFINE_EVENT(dwc3_log_msg, dwc3_writel, -- TP_PROTO(struct va_format *vaf), -- TP_ARGS(vaf) --); -- --DEFINE_EVENT(dwc3_log_msg, dwc3_gadget, -- TP_PROTO(struct va_format *vaf), -- TP_ARGS(vaf) -+ TP_printk("addr %p value %08x", __entry->base + __entry->offset, -+ __entry->value) - ); - --DEFINE_EVENT(dwc3_log_msg, dwc3_core, -- TP_PROTO(struct va_format *vaf), -- TP_ARGS(vaf) -+DEFINE_EVENT(dwc3_log_io, dwc3_readl, -+ TP_PROTO(void *base, u32 offset, u32 value), -+ TP_ARGS(base, offset, value) - ); - --DEFINE_EVENT(dwc3_log_msg, dwc3_ep0, -- TP_PROTO(struct va_format *vaf), -- TP_ARGS(vaf) -+DEFINE_EVENT(dwc3_log_io, dwc3_writel, -+ TP_PROTO(void *base, u32 offset, u32 value), -+ TP_ARGS(base, offset, value) - ); - - DECLARE_EVENT_CLASS(dwc3_log_event, -- TP_PROTO(u32 event), -- TP_ARGS(event), -+ TP_PROTO(u32 event, struct dwc3 *dwc), -+ TP_ARGS(event, dwc), - TP_STRUCT__entry( - __field(u32, event) -+ __field(u32, ep0state) -+ __dynamic_array(char, str, DWC3_MSG_MAX) - ), - TP_fast_assign( - __entry->event = event; -+ __entry->ep0state = dwc->ep0state; - ), - TP_printk("event (%08x): %s", __entry->event, -- dwc3_decode_event(__entry->event)) -+ dwc3_decode_event(__get_str(str), DWC3_MSG_MAX, -+ __entry->event, __entry->ep0state)) - ); - - DEFINE_EVENT(dwc3_log_event, dwc3_event, -- TP_PROTO(u32 event), -- TP_ARGS(event) -+ TP_PROTO(u32 event, struct dwc3 *dwc), -+ TP_ARGS(event, dwc) - ); - - DECLARE_EVENT_CLASS(dwc3_log_ctrl, -@@ -89,6 +85,7 @@ - __field(__u16, wValue) - __field(__u16, wIndex) - __field(__u16, wLength) -+ __dynamic_array(char, str, DWC3_MSG_MAX) - ), - TP_fast_assign( - __entry->bRequestType = ctrl->bRequestType; -@@ -97,10 +94,10 @@ - __entry->wIndex = le16_to_cpu(ctrl->wIndex); - __entry->wLength = le16_to_cpu(ctrl->wLength); - ), -- TP_printk("bRequestType %02x bRequest %02x wValue %04x wIndex %04x wLength %d", -- __entry->bRequestType, __entry->bRequest, -- __entry->wValue, __entry->wIndex, -- __entry->wLength -+ TP_printk("%s", dwc3_decode_ctrl(__get_str(str), DWC3_MSG_MAX, -+ __entry->bRequestType, -+ __entry->bRequest, __entry->wValue, -+ __entry->wIndex, __entry->wLength) - ) - ); - -@@ -113,7 +110,7 @@ - TP_PROTO(struct dwc3_request *req), - TP_ARGS(req), - TP_STRUCT__entry( -- __dynamic_array(char, name, DWC3_MSG_MAX) -+ __string(name, req->dep->name) - __field(struct dwc3_request *, req) - __field(unsigned, actual) - __field(unsigned, length) -@@ -123,7 +120,7 @@ - __field(int, no_interrupt) - ), - TP_fast_assign( -- snprintf(__get_str(name), DWC3_MSG_MAX, "%s", req->dep->name); -+ __assign_str(name, req->dep->name); - __entry->req = req; - __entry->actual = req->request.actual; - __entry->length = req->request.length; -@@ -179,7 +176,7 @@ - __entry->param = param; - __entry->status = status; - ), -- TP_printk("cmd '%s' [%d] param %08x --> status: %s", -+ TP_printk("cmd '%s' [%x] param %08x --> status: %s", - dwc3_gadget_generic_cmd_string(__entry->cmd), - __entry->cmd, __entry->param, - dwc3_gadget_generic_cmd_status_string(__entry->status) -@@ -196,7 +193,7 @@ - struct dwc3_gadget_ep_cmd_params *params, int cmd_status), - TP_ARGS(dep, cmd, params, cmd_status), - TP_STRUCT__entry( -- __dynamic_array(char, name, DWC3_MSG_MAX) -+ __string(name, dep->name) - __field(unsigned int, cmd) - __field(u32, param0) - __field(u32, param1) -@@ -204,14 +201,14 @@ - __field(int, cmd_status) - ), - TP_fast_assign( -- snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); -+ __assign_str(name, dep->name); - __entry->cmd = cmd; - __entry->param0 = params->param0; - __entry->param1 = params->param1; - __entry->param2 = params->param2; - __entry->cmd_status = cmd_status; - ), -- TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x --> status: %s", -+ TP_printk("%s: cmd '%s' [%x] params %08x %08x %08x --> status: %s", - __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), - __entry->cmd, __entry->param0, - __entry->param1, __entry->param2, -@@ -229,7 +226,7 @@ - TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb), - TP_ARGS(dep, trb), - TP_STRUCT__entry( -- __dynamic_array(char, name, DWC3_MSG_MAX) -+ __string(name, dep->name) - __field(struct dwc3_trb *, trb) - __field(u32, allocated) - __field(u32, queued) -@@ -237,9 +234,10 @@ - __field(u32, bph) - __field(u32, size) - __field(u32, ctrl) -+ __field(u32, type) - ), - TP_fast_assign( -- snprintf(__get_str(name), DWC3_MSG_MAX, "%s", dep->name); -+ __assign_str(name, dep->name); - __entry->trb = trb; - __entry->allocated = dep->allocated_requests; - __entry->queued = dep->queued_requests; -@@ -247,47 +245,40 @@ - __entry->bph = trb->bph; - __entry->size = trb->size; - __entry->ctrl = trb->ctrl; -+ __entry->type = usb_endpoint_type(dep->endpoint.desc); - ), -- TP_printk("%s: %d/%d trb %p buf %08x%08x size %d ctrl %08x (%c%c%c%c:%c%c:%s)", -+ TP_printk("%s: %d/%d trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", - __get_str(name), __entry->queued, __entry->allocated, - __entry->trb, __entry->bph, __entry->bpl, -- __entry->size, __entry->ctrl, -+ ({char *s; -+ int pcm = ((__entry->size >> 24) & 3) + 1; -+ switch (__entry->type) { -+ case USB_ENDPOINT_XFER_INT: -+ case USB_ENDPOINT_XFER_ISOC: -+ switch (pcm) { -+ case 1: -+ s = "1x "; -+ break; -+ case 2: -+ s = "2x "; -+ break; -+ case 3: -+ default: -+ s = "3x "; -+ break; -+ } -+ break; -+ default: -+ s = ""; -+ } s; }), -+ DWC3_TRB_SIZE_LENGTH(__entry->size), __entry->ctrl, - __entry->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h', - __entry->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l', - __entry->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c', - __entry->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's', - __entry->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's', - __entry->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c', -- ({char *s; -- switch (__entry->ctrl & 0x3f0) { -- case DWC3_TRBCTL_NORMAL: -- s = "normal"; -- break; -- case DWC3_TRBCTL_CONTROL_SETUP: -- s = "setup"; -- break; -- case DWC3_TRBCTL_CONTROL_STATUS2: -- s = "status2"; -- break; -- case DWC3_TRBCTL_CONTROL_STATUS3: -- s = "status3"; -- break; -- case DWC3_TRBCTL_CONTROL_DATA: -- s = "data"; -- break; -- case DWC3_TRBCTL_ISOCHRONOUS_FIRST: -- s = "isoc-first"; -- break; -- case DWC3_TRBCTL_ISOCHRONOUS: -- s = "isoc"; -- break; -- case DWC3_TRBCTL_LINK_TRB: -- s = "link"; -- break; -- default: -- s = "UNKNOWN"; -- break; -- } s; }) -+ dwc3_trb_type_string(DWC3_TRBCTL_TYPE(__entry->ctrl)) - ) - ); - -@@ -301,6 +292,56 @@ - TP_ARGS(dep, trb) - ); - -+DECLARE_EVENT_CLASS(dwc3_log_ep, -+ TP_PROTO(struct dwc3_ep *dep), -+ TP_ARGS(dep), -+ TP_STRUCT__entry( -+ __string(name, dep->name) -+ __field(unsigned, maxpacket) -+ __field(unsigned, maxpacket_limit) -+ __field(unsigned, max_streams) -+ __field(unsigned, maxburst) -+ __field(unsigned, flags) -+ __field(unsigned, direction) -+ __field(u8, trb_enqueue) -+ __field(u8, trb_dequeue) -+ ), -+ TP_fast_assign( -+ __assign_str(name, dep->name); -+ __entry->maxpacket = dep->endpoint.maxpacket; -+ __entry->maxpacket_limit = dep->endpoint.maxpacket_limit; -+ __entry->max_streams = dep->endpoint.max_streams; -+ __entry->maxburst = dep->endpoint.maxburst; -+ __entry->flags = dep->flags; -+ __entry->direction = dep->direction; -+ __entry->trb_enqueue = dep->trb_enqueue; -+ __entry->trb_dequeue = dep->trb_dequeue; -+ ), -+ TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c%c:%c", -+ __get_str(name), __entry->maxpacket, -+ __entry->maxpacket_limit, __entry->max_streams, -+ __entry->maxburst, __entry->trb_enqueue, -+ __entry->trb_dequeue, -+ __entry->flags & DWC3_EP_ENABLED ? 'E' : 'e', -+ __entry->flags & DWC3_EP_STALL ? 'S' : 's', -+ __entry->flags & DWC3_EP_WEDGE ? 'W' : 'w', -+ __entry->flags & DWC3_EP_BUSY ? 'B' : 'b', -+ __entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p', -+ __entry->flags & DWC3_EP_MISSED_ISOC ? 'M' : 'm', -+ __entry->direction ? '<' : '>' -+ ) -+); -+ -+DEFINE_EVENT(dwc3_log_ep, dwc3_gadget_ep_enable, -+ TP_PROTO(struct dwc3_ep *dep), -+ TP_ARGS(dep) -+); -+ -+DEFINE_EVENT(dwc3_log_ep, dwc3_gadget_ep_disable, -+ TP_PROTO(struct dwc3_ep *dep), -+ TP_ARGS(dep) -+); -+ - #endif /* __DWC3_TRACE_H */ - - /* this part has to be here */ ---- linux-4.9.37/drivers/usb/gadget/composite.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/composite.c 2021-06-07 13:01:34.000000000 +0300 -@@ -205,7 +205,7 @@ - - if (g->speed == USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) || - usb_endpoint_xfer_int(_ep->desc))) -- _ep->mult = ((usb_endpoint_maxp(_ep->desc) & 0x1800) >> 11) + 1; -+ _ep->mult = usb_endpoint_maxp_mult(_ep->desc); - - if (!want_comp_desc) - return 0; -@@ -315,6 +315,9 @@ - list_del(&f->list); - if (f->unbind) - f->unbind(c, f); -+ -+ if (f->bind_deactivated) -+ usb_function_activate(f); - } - EXPORT_SYMBOL_GPL(usb_remove_function); - -@@ -956,12 +959,8 @@ - - f = list_first_entry(&config->functions, - struct usb_function, list); -- list_del(&f->list); -- if (f->unbind) { -- DBG(cdev, "unbind function '%s'/%p\n", f->name, f); -- f->unbind(config, f); -- /* may free memory for "f" */ -- } -+ -+ usb_remove_function(config, f); - } - list_del(&config->list); - if (config->unbind) { ---- linux-4.9.37/drivers/usb/gadget/configfs.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/configfs.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1209,6 +1209,9 @@ - - list_for_each_entry_safe(f, tmp, &c->functions, list) { - -+ if (f->disable) -+ f->disable(f); -+ - list_move_tail(&f->list, &cfg->func_list); - if (f->unbind) { - dev_dbg(&gi->cdev.gadget->dev, -@@ -1216,6 +1219,9 @@ - f->name, f); - f->unbind(c, f); - } -+ -+ if (f->bind_deactivated) -+ usb_function_activate(f); - } - c->next_interface_id = 0; - memset(c->interface, 0, sizeof(c->interface)); ---- linux-4.9.37/drivers/usb/gadget/epautoconf.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/epautoconf.c 2021-06-07 13:01:34.000000000 +0300 -@@ -82,9 +82,16 @@ - } - - /* Second, look at endpoints until an unclaimed one looks usable */ -- list_for_each_entry (ep, &gadget->ep_list, ep_list) { -- if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) -- goto found_ep; -+ if (type == USB_ENDPOINT_XFER_INT) { -+ list_for_each_entry_reverse(ep, &gadget->ep_list, ep_list) { -+ if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) -+ goto found_ep; -+ } -+ } else { -+ list_for_each_entry(ep, &gadget->ep_list, ep_list) { -+ if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp)) -+ goto found_ep; -+ } - } - - /* Fail */ ---- linux-4.9.37/drivers/usb/gadget/function/f_hid.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/f_hid.c 2021-06-07 13:01:34.000000000 +0300 -@@ -284,6 +284,7 @@ - size_t count, loff_t *offp) - { - struct f_hidg *hidg = file->private_data; -+ struct usb_request *req; - unsigned long flags; - ssize_t status = -ENOMEM; - -@@ -293,7 +294,7 @@ - spin_lock_irqsave(&hidg->write_spinlock, flags); - - #define WRITE_COND (!hidg->write_pending) -- -+try_again: - /* write queue */ - while (!WRITE_COND) { - spin_unlock_irqrestore(&hidg->write_spinlock, flags); -@@ -308,6 +309,7 @@ - } - - hidg->write_pending = 1; -+ req = hidg->req; - count = min_t(unsigned, count, hidg->report_length); - - spin_unlock_irqrestore(&hidg->write_spinlock, flags); -@@ -320,24 +322,38 @@ - goto release_write_pending; - } - -- hidg->req->status = 0; -- hidg->req->zero = 0; -- hidg->req->length = count; -- hidg->req->complete = f_hidg_req_complete; -- hidg->req->context = hidg; -+ spin_lock_irqsave(&hidg->write_spinlock, flags); -+ -+ /* we our function has been disabled by host */ -+ if (!hidg->req) { -+ free_ep_req(hidg->in_ep, hidg->req); -+ /* -+ * TODO -+ * Should we fail with error here? -+ */ -+ goto try_again; -+ } -+ -+ req->status = 0; -+ req->zero = 0; -+ req->length = count; -+ req->complete = f_hidg_req_complete; -+ req->context = hidg; - - status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC); - if (status < 0) { - ERROR(hidg->func.config->cdev, - "usb_ep_queue error on int endpoint %zd\n", status); -- goto release_write_pending; -+ goto release_write_pending_unlocked; - } else { - status = count; - } -+ spin_unlock_irqrestore(&hidg->write_spinlock, flags); - - return status; - release_write_pending: - spin_lock_irqsave(&hidg->write_spinlock, flags); -+release_write_pending_unlocked: - hidg->write_pending = 0; - spin_unlock_irqrestore(&hidg->write_spinlock, flags); - -@@ -541,12 +557,23 @@ - kfree(list); - } - spin_unlock_irqrestore(&hidg->read_spinlock, flags); -+ -+ spin_lock_irqsave(&hidg->write_spinlock, flags); -+ if (!hidg->write_pending) { -+ free_ep_req(hidg->in_ep, hidg->req); -+ hidg->write_pending = 1; -+ } -+ -+ hidg->req = NULL; -+ spin_unlock_irqrestore(&hidg->write_spinlock, flags); - } - - static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) - { - struct usb_composite_dev *cdev = f->config->cdev; - struct f_hidg *hidg = func_to_hidg(f); -+ struct usb_request *req_in = NULL; -+ unsigned long flags; - int i, status = 0; - - VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt); -@@ -567,6 +594,12 @@ - goto fail; - } - hidg->in_ep->driver_data = hidg; -+ -+ req_in = hidg_alloc_ep_req(hidg->in_ep, hidg->report_length); -+ if (!req_in) { -+ status = -ENOMEM; -+ goto disable_ep_in; -+ } - } - - -@@ -578,12 +611,12 @@ - hidg->out_ep); - if (status) { - ERROR(cdev, "config_ep_by_speed FAILED!\n"); -- goto fail; -+ goto free_req_in; - } - status = usb_ep_enable(hidg->out_ep); - if (status < 0) { -- ERROR(cdev, "Enable IN endpoint FAILED!\n"); -- goto fail; -+ ERROR(cdev, "Enable OUT endpoint FAILED!\n"); -+ goto free_req_in; - } - hidg->out_ep->driver_data = hidg; - -@@ -599,17 +632,37 @@ - req->context = hidg; - status = usb_ep_queue(hidg->out_ep, req, - GFP_ATOMIC); -- if (status) -+ if (status) { - ERROR(cdev, "%s queue req --> %d\n", - hidg->out_ep->name, status); -+ free_ep_req(hidg->out_ep, req); -+ } - } else { -- usb_ep_disable(hidg->out_ep); - status = -ENOMEM; -- goto fail; -+ goto disable_out_ep; - } - } - } - -+ if (hidg->in_ep != NULL) { -+ spin_lock_irqsave(&hidg->write_spinlock, flags); -+ hidg->req = req_in; -+ hidg->write_pending = 0; -+ spin_unlock_irqrestore(&hidg->write_spinlock, flags); -+ -+ wake_up(&hidg->write_queue); -+ } -+ return 0; -+disable_out_ep: -+ usb_ep_disable(hidg->out_ep); -+free_req_in: -+ if (req_in) -+ free_ep_req(hidg->in_ep, req_in); -+ -+disable_ep_in: -+ if (hidg->in_ep) -+ usb_ep_disable(hidg->in_ep); -+ - fail: - return status; - } -@@ -658,12 +711,6 @@ - goto fail; - hidg->out_ep = ep; - -- /* preallocate request and buffer */ -- status = -ENOMEM; -- hidg->req = alloc_ep_req(hidg->in_ep, hidg->report_length); -- if (!hidg->req) -- goto fail; -- - /* set descriptor dynamic values */ - hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; - hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; -@@ -690,6 +737,8 @@ - goto fail; - - spin_lock_init(&hidg->write_spinlock); -+ hidg->write_pending = 1; -+ hidg->req = NULL; - spin_lock_init(&hidg->read_spinlock); - init_waitqueue_head(&hidg->write_queue); - init_waitqueue_head(&hidg->read_queue); -@@ -954,10 +1003,6 @@ - device_destroy(hidg_class, MKDEV(major, hidg->minor)); - cdev_del(&hidg->cdev); - -- /* disable/free request and end point */ -- usb_ep_disable(hidg->in_ep); -- free_ep_req(hidg->in_ep, hidg->req); -- - usb_free_all_descriptors(f); - } - ---- linux-4.9.37/drivers/usb/gadget/function/f_mass_storage.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/f_mass_storage.c 2021-06-07 13:01:34.000000000 +0300 -@@ -301,6 +301,7 @@ - unsigned int bad_lun_okay:1; - unsigned int running:1; - unsigned int sysfs:1; -+ unsigned int actived:1; - - int thread_wakeup_needed; - struct completion thread_notifier; -@@ -1371,7 +1372,7 @@ - - up_read(&common->filesem); - down_write(&common->filesem); -- fsg_lun_close(curlun); -+ common->actived = 0; - up_write(&common->filesem); - down_read(&common->filesem); - -@@ -1815,7 +1816,7 @@ - - /* If the medium isn't mounted and the command needs to access - * it, return an error. */ -- if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { -+ if (curlun && !common->actived && needs_medium) { - curlun->sense_data = SS_MEDIUM_NOT_PRESENT; - return -EINVAL; - } -@@ -2280,6 +2281,7 @@ - } - - common->running = 0; -+ common->actived = 0; - if (!new_fsg || rc) - return rc; - -@@ -2323,7 +2325,7 @@ - bh->inreq->complete = bulk_in_complete; - bh->outreq->complete = bulk_out_complete; - } -- -+ common->actived = 1; - common->running = 1; - for (i = 0; i < ARRAY_SIZE(common->luns); ++i) - if (common->luns[i]) ---- linux-4.9.37/drivers/usb/gadget/function/f_uac1.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/f_uac1.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1,24 +1,34 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* -- * f_audio.c -- USB Audio class function driver -- * -- * Copyright (C) 2008 Bryan Wu -- * Copyright (C) 2008 Analog Devices, Inc -+ * f_uac1.c -- USB Audio Class 1.0 Function (using u_audio API) - * -- * Enter bugs at http://blackfin.uclinux.org/ -+ * Copyright (C) 2016 Ruslan Bilovol - * -- * Licensed under the GPL-2 or later. -+ * This driver doesn't expect any real Audio codec to be present -+ * on the device - the audio streams are simply sinked to and -+ * sourced from a virtual ALSA sound card created. -+ * -+ * This file is based on f_uac1.c which is -+ * Copyright (C) 2008 Bryan Wu -+ * Copyright (C) 2008 Analog Devices, Inc - */ - --#include --#include -+#include - #include --#include --#include - -+#include "u_audio.h" - #include "u_uac1.h" - --static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); --static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); -+struct f_uac1 { -+ struct g_audio g_audio; -+ u8 ac_intf, as_in_intf, as_out_intf; -+ u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */ -+}; -+ -+static inline struct f_uac1 *func_to_uac1(struct usb_function *f) -+{ -+ return container_of(f, struct f_uac1, g_audio.func); -+} - - /* - * DESCRIPTORS ... most are static, but strings and full -@@ -26,12 +36,27 @@ - */ - - /* -- * We have two interfaces- AudioControl and AudioStreaming -- * TODO: only supcard playback currently -+ * We have three interfaces - one AudioControl and two AudioStreaming -+ * -+ * The driver implements a simple UAC_1 topology. -+ * USB-OUT -> IT_1 -> OT_2 -> ALSA_Capture -+ * ALSA_Playback -> IT_3 -> OT_4 -> USB-IN - */ --#define F_AUDIO_AC_INTERFACE 0 --#define F_AUDIO_AS_INTERFACE 1 --#define F_AUDIO_NUM_INTERFACES 1 -+#define F_AUDIO_AC_INTERFACE 0 -+#define F_AUDIO_AS_OUT_INTERFACE 1 -+#define F_AUDIO_AS_IN_INTERFACE 2 -+/* Number of streaming interfaces */ -+#define F_AUDIO_NUM_INTERFACES 2 -+ -+static struct usb_interface_assoc_descriptor uac_iad = { -+ .bLength = sizeof(uac_iad), -+ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, -+ .bFirstInterface = 0, -+ .bInterfaceCount = 3, -+ .bFunctionClass = USB_CLASS_AUDIO, -+ .bFunctionSubClass = 0, -+ .bFunctionProtocol = UAC_VERSION_1, -+}; - - /* B.3.1 Standard AC Interface Descriptor */ - static struct usb_interface_descriptor ac_interface_desc = { -@@ -46,89 +71,91 @@ - * The number of AudioStreaming and MIDIStreaming interfaces - * in the Audio Interface Collection - */ --DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); -+DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); - - #define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) --/* 1 input terminal, 1 output terminal and 1 feature unit */ --#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ -- + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) -+/* 2 input terminals and 2 output terminals */ -+#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \ -+ + 2*UAC_DT_INPUT_TERMINAL_SIZE + 2*UAC_DT_OUTPUT_TERMINAL_SIZE) - /* B.3.2 Class-Specific AC Interface Descriptor */ --static struct uac1_ac_header_descriptor_1 ac_header_desc = { -+static struct uac1_ac_header_descriptor_2 ac_header_desc = { - .bLength = UAC_DT_AC_HEADER_LENGTH, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_HEADER, -- .bcdADC = __constant_cpu_to_le16(0x0100), -- .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), -+ .bcdADC = cpu_to_le16(0x0100), -+ .wTotalLength = cpu_to_le16(UAC_DT_TOTAL_LENGTH), - .bInCollection = F_AUDIO_NUM_INTERFACES, - .baInterfaceNr = { -- /* Interface number of the first AudioStream interface */ -+ /* Interface number of the AudioStream interfaces */ - [0] = 1, -+ [1] = 2, - } - }; - --#define INPUT_TERMINAL_ID 1 --static struct uac_input_terminal_descriptor input_terminal_desc = { -+#define USB_OUT_IT_ID 1 -+static struct uac_input_terminal_descriptor usb_out_it_desc = { - .bLength = UAC_DT_INPUT_TERMINAL_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_INPUT_TERMINAL, -- .bTerminalID = INPUT_TERMINAL_ID, -- .wTerminalType = UAC_TERMINAL_STREAMING, -+ .bTerminalID = USB_OUT_IT_ID, -+ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), - .bAssocTerminal = 0, -- .wChannelConfig = 0x3, -+ .wChannelConfig = cpu_to_le16(0x3), - }; - --DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); -- --#define FEATURE_UNIT_ID 2 --static struct uac_feature_unit_descriptor_0 feature_unit_desc = { -- .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), -+#define IO_OUT_OT_ID 2 -+static struct uac1_output_terminal_descriptor io_out_ot_desc = { -+ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, -- .bDescriptorSubtype = UAC_FEATURE_UNIT, -- .bUnitID = FEATURE_UNIT_ID, -- .bSourceID = INPUT_TERMINAL_ID, -- .bControlSize = 2, -- .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), --}; -- --static struct usb_audio_control mute_control = { -- .list = LIST_HEAD_INIT(mute_control.list), -- .name = "Mute Control", -- .type = UAC_FU_MUTE, -- /* Todo: add real Mute control code */ -- .set = generic_set_cmd, -- .get = generic_get_cmd, --}; -- --static struct usb_audio_control volume_control = { -- .list = LIST_HEAD_INIT(volume_control.list), -- .name = "Volume Control", -- .type = UAC_FU_VOLUME, -- /* Todo: add real Volume control code */ -- .set = generic_set_cmd, -- .get = generic_get_cmd, --}; -- --static struct usb_audio_control_selector feature_unit = { -- .list = LIST_HEAD_INIT(feature_unit.list), -- .id = FEATURE_UNIT_ID, -- .name = "Mute & Volume Control", -- .type = UAC_FEATURE_UNIT, -- .desc = (struct usb_descriptor_header *)&feature_unit_desc, -+ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, -+ .bTerminalID = IO_OUT_OT_ID, -+ .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER), -+ .bAssocTerminal = 0, -+ .bSourceID = USB_OUT_IT_ID, - }; - --#define OUTPUT_TERMINAL_ID 3 --static struct uac1_output_terminal_descriptor output_terminal_desc = { -- .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, -+#define IO_IN_IT_ID 3 -+static struct uac_input_terminal_descriptor io_in_it_desc = { -+ .bLength = UAC_DT_INPUT_TERMINAL_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, -- .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, -- .bTerminalID = OUTPUT_TERMINAL_ID, -- .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER, -- .bAssocTerminal = FEATURE_UNIT_ID, -- .bSourceID = FEATURE_UNIT_ID, -+ .bDescriptorSubtype = UAC_INPUT_TERMINAL, -+ .bTerminalID = IO_IN_IT_ID, -+ .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE), -+ .bAssocTerminal = 0, -+ .wChannelConfig = cpu_to_le16(0x3), -+}; -+ -+#define USB_IN_OT_ID 4 -+static struct uac1_output_terminal_descriptor usb_in_ot_desc = { -+ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, -+ .bTerminalID = USB_IN_OT_ID, -+ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), -+ .bAssocTerminal = 0, -+ .bSourceID = IO_IN_IT_ID, - }; - - /* B.4.1 Standard AS Interface Descriptor */ --static struct usb_interface_descriptor as_interface_alt_0_desc = { -+static struct usb_interface_descriptor as_out_interface_alt_0_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bAlternateSetting = 0, -+ .bNumEndpoints = 0, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -+}; -+ -+static struct usb_interface_descriptor as_out_interface_alt_1_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bAlternateSetting = 1, -+ .bNumEndpoints = 1, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -+}; -+ -+static struct usb_interface_descriptor as_in_interface_alt_0_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bAlternateSetting = 0, -@@ -137,7 +164,7 @@ - .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, - }; - --static struct usb_interface_descriptor as_interface_alt_1_desc = { -+static struct usb_interface_descriptor as_in_interface_alt_1_desc = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bAlternateSetting = 1, -@@ -147,18 +174,27 @@ - }; - - /* B.4.2 Class-Specific AS Interface Descriptor */ --static struct uac1_as_header_descriptor as_header_desc = { -+static struct uac1_as_header_descriptor as_out_header_desc = { -+ .bLength = UAC_DT_AS_HEADER_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_AS_GENERAL, -+ .bTerminalLink = USB_OUT_IT_ID, -+ .bDelay = 1, -+ .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), -+}; -+ -+static struct uac1_as_header_descriptor as_in_header_desc = { - .bLength = UAC_DT_AS_HEADER_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_AS_GENERAL, -- .bTerminalLink = INPUT_TERMINAL_ID, -+ .bTerminalLink = USB_IN_OT_ID, - .bDelay = 1, -- .wFormatTag = UAC_FORMAT_TYPE_I_PCM, -+ .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), - }; - - DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); - --static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { -+static struct uac_format_type_i_discrete_descriptor_1 as_out_type_i_desc = { - .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_FORMAT_TYPE, -@@ -184,48 +220,138 @@ - .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, - .bDescriptorType = USB_DT_CS_ENDPOINT, - .bDescriptorSubtype = UAC_EP_GENERAL, -- .bmAttributes = 1, -+ .bmAttributes = 1, - .bLockDelayUnits = 1, -- .wLockDelay = __constant_cpu_to_le16(1), -+ .wLockDelay = cpu_to_le16(1), -+}; -+ -+static struct uac_format_type_i_discrete_descriptor_1 as_in_type_i_desc = { -+ .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_FORMAT_TYPE, -+ .bFormatType = UAC_FORMAT_TYPE_I, -+ .bSubframeSize = 2, -+ .bBitResolution = 16, -+ .bSamFreqType = 1, -+}; -+ -+/* Standard ISO OUT Endpoint Descriptor */ -+static struct usb_endpoint_descriptor as_in_ep_desc = { -+ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_IN, -+ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -+ | USB_ENDPOINT_XFER_ISOC, -+ .wMaxPacketSize = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), -+ .bInterval = 4, -+}; -+ -+/* Class-specific AS ISO OUT Endpoint Descriptor */ -+static struct uac_iso_endpoint_descriptor as_iso_in_desc = { -+ .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, -+ .bDescriptorType = USB_DT_CS_ENDPOINT, -+ .bDescriptorSubtype = UAC_EP_GENERAL, -+ .bmAttributes = 1, -+ .bLockDelayUnits = 0, -+ .wLockDelay = 0, -+}; -+ -+static struct usb_ss_ep_comp_descriptor as_ss_ep_comp = { -+ .bLength = sizeof(as_ss_ep_comp), -+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -+ .bMaxBurst = 0, -+ .bmAttributes = 0, -+ .wBytesPerInterval = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), - }; - - static struct usb_descriptor_header *f_audio_desc[] = { -+ (struct usb_descriptor_header *)&uac_iad, -+ (struct usb_descriptor_header *)&ac_interface_desc, -+ (struct usb_descriptor_header *)&ac_header_desc, -+ -+ (struct usb_descriptor_header *)&usb_out_it_desc, -+ (struct usb_descriptor_header *)&io_out_ot_desc, -+ (struct usb_descriptor_header *)&io_in_it_desc, -+ (struct usb_descriptor_header *)&usb_in_ot_desc, -+ -+ (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, -+ (struct usb_descriptor_header *)&as_out_interface_alt_1_desc, -+ (struct usb_descriptor_header *)&as_out_header_desc, -+ -+ (struct usb_descriptor_header *)&as_out_type_i_desc, -+ -+ (struct usb_descriptor_header *)&as_out_ep_desc, -+ (struct usb_descriptor_header *)&as_iso_out_desc, -+ -+ (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, -+ (struct usb_descriptor_header *)&as_in_interface_alt_1_desc, -+ (struct usb_descriptor_header *)&as_in_header_desc, -+ -+ (struct usb_descriptor_header *)&as_in_type_i_desc, -+ -+ (struct usb_descriptor_header *)&as_in_ep_desc, -+ (struct usb_descriptor_header *)&as_iso_in_desc, -+ NULL, -+}; -+ -+static struct usb_descriptor_header *f_audio_ss_desc[] = { -+ (struct usb_descriptor_header *)&uac_iad, - (struct usb_descriptor_header *)&ac_interface_desc, - (struct usb_descriptor_header *)&ac_header_desc, - -- (struct usb_descriptor_header *)&input_terminal_desc, -- (struct usb_descriptor_header *)&output_terminal_desc, -- (struct usb_descriptor_header *)&feature_unit_desc, -- -- (struct usb_descriptor_header *)&as_interface_alt_0_desc, -- (struct usb_descriptor_header *)&as_interface_alt_1_desc, -- (struct usb_descriptor_header *)&as_header_desc, -+ (struct usb_descriptor_header *)&usb_out_it_desc, -+ (struct usb_descriptor_header *)&io_out_ot_desc, -+ (struct usb_descriptor_header *)&io_in_it_desc, -+ (struct usb_descriptor_header *)&usb_in_ot_desc, -+ -+ (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, -+ (struct usb_descriptor_header *)&as_out_interface_alt_1_desc, -+ (struct usb_descriptor_header *)&as_out_header_desc, - -- (struct usb_descriptor_header *)&as_type_i_desc, -+ (struct usb_descriptor_header *)&as_out_type_i_desc, - - (struct usb_descriptor_header *)&as_out_ep_desc, -+ (struct usb_descriptor_header *)&as_ss_ep_comp, - (struct usb_descriptor_header *)&as_iso_out_desc, -+ -+ (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, -+ (struct usb_descriptor_header *)&as_in_interface_alt_1_desc, -+ (struct usb_descriptor_header *)&as_in_header_desc, -+ -+ (struct usb_descriptor_header *)&as_in_type_i_desc, -+ -+ (struct usb_descriptor_header *)&as_in_ep_desc, -+ (struct usb_descriptor_header *)&as_ss_ep_comp, -+ (struct usb_descriptor_header *)&as_iso_in_desc, - NULL, - }; - - enum { - STR_AC_IF, -- STR_INPUT_TERMINAL, -- STR_INPUT_TERMINAL_CH_NAMES, -- STR_FEAT_DESC_0, -- STR_OUTPUT_TERMINAL, -- STR_AS_IF_ALT0, -- STR_AS_IF_ALT1, -+ STR_USB_OUT_IT, -+ STR_USB_OUT_IT_CH_NAMES, -+ STR_IO_OUT_OT, -+ STR_IO_IN_IT, -+ STR_IO_IN_IT_CH_NAMES, -+ STR_USB_IN_OT, -+ STR_AS_OUT_IF_ALT0, -+ STR_AS_OUT_IF_ALT1, -+ STR_AS_IN_IF_ALT0, -+ STR_AS_IN_IF_ALT1, - }; - - static struct usb_string strings_uac1[] = { - [STR_AC_IF].s = "AC Interface", -- [STR_INPUT_TERMINAL].s = "Input terminal", -- [STR_INPUT_TERMINAL_CH_NAMES].s = "Channels", -- [STR_FEAT_DESC_0].s = "Volume control & mute", -- [STR_OUTPUT_TERMINAL].s = "Output terminal", -- [STR_AS_IF_ALT0].s = "AS Interface", -- [STR_AS_IF_ALT1].s = "AS Interface", -+ [STR_USB_OUT_IT].s = "Playback Input terminal", -+ [STR_USB_OUT_IT_CH_NAMES].s = "Playback Channels", -+ [STR_IO_OUT_OT].s = "Playback Output terminal", -+ [STR_IO_IN_IT].s = "Capture Input terminal", -+ [STR_IO_IN_IT_CH_NAMES].s = "Capture Channels", -+ [STR_USB_IN_OT].s = "Capture Output terminal", -+ [STR_AS_OUT_IF_ALT0].s = "Playback Inactive", -+ [STR_AS_OUT_IF_ALT1].s = "Playback Active", -+ [STR_AS_IN_IF_ALT0].s = "Capture Inactive", -+ [STR_AS_IN_IF_ALT1].s = "Capture Active", - { }, - }; - -@@ -243,216 +369,6 @@ - * This function is an ALSA sound card following USB Audio Class Spec 1.0. - */ - --/*-------------------------------------------------------------------------*/ --struct f_audio_buf { -- u8 *buf; -- int actual; -- struct list_head list; --}; -- --static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) --{ -- struct f_audio_buf *copy_buf; -- -- copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); -- if (!copy_buf) -- return ERR_PTR(-ENOMEM); -- -- copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); -- if (!copy_buf->buf) { -- kfree(copy_buf); -- return ERR_PTR(-ENOMEM); -- } -- -- return copy_buf; --} -- --static void f_audio_buffer_free(struct f_audio_buf *audio_buf) --{ -- kfree(audio_buf->buf); -- kfree(audio_buf); --} --/*-------------------------------------------------------------------------*/ -- --struct f_audio { -- struct gaudio card; -- -- /* endpoints handle full and/or high speeds */ -- struct usb_ep *out_ep; -- -- spinlock_t lock; -- struct f_audio_buf *copy_buf; -- struct work_struct playback_work; -- struct list_head play_queue; -- -- /* Control Set command */ -- struct list_head cs; -- u8 set_cmd; -- struct usb_audio_control *set_con; --}; -- --static inline struct f_audio *func_to_audio(struct usb_function *f) --{ -- return container_of(f, struct f_audio, card.func); --} -- --/*-------------------------------------------------------------------------*/ -- --static void f_audio_playback_work(struct work_struct *data) --{ -- struct f_audio *audio = container_of(data, struct f_audio, -- playback_work); -- struct f_audio_buf *play_buf; -- -- spin_lock_irq(&audio->lock); -- if (list_empty(&audio->play_queue)) { -- spin_unlock_irq(&audio->lock); -- return; -- } -- play_buf = list_first_entry(&audio->play_queue, -- struct f_audio_buf, list); -- list_del(&play_buf->list); -- spin_unlock_irq(&audio->lock); -- -- u_audio_playback(&audio->card, play_buf->buf, play_buf->actual); -- f_audio_buffer_free(play_buf); --} -- --static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) --{ -- struct f_audio *audio = req->context; -- struct usb_composite_dev *cdev = audio->card.func.config->cdev; -- struct f_audio_buf *copy_buf = audio->copy_buf; -- struct f_uac1_opts *opts; -- int audio_buf_size; -- int err; -- -- opts = container_of(audio->card.func.fi, struct f_uac1_opts, -- func_inst); -- audio_buf_size = opts->audio_buf_size; -- -- if (!copy_buf) -- return -EINVAL; -- -- /* Copy buffer is full, add it to the play_queue */ -- if (audio_buf_size - copy_buf->actual < req->actual) { -- list_add_tail(©_buf->list, &audio->play_queue); -- schedule_work(&audio->playback_work); -- copy_buf = f_audio_buffer_alloc(audio_buf_size); -- if (IS_ERR(copy_buf)) -- return -ENOMEM; -- } -- -- memcpy(copy_buf->buf + copy_buf->actual, req->buf, req->actual); -- copy_buf->actual += req->actual; -- audio->copy_buf = copy_buf; -- -- err = usb_ep_queue(ep, req, GFP_ATOMIC); -- if (err) -- ERROR(cdev, "%s queue req: %d\n", ep->name, err); -- -- return 0; -- --} -- --static void f_audio_complete(struct usb_ep *ep, struct usb_request *req) --{ -- struct f_audio *audio = req->context; -- int status = req->status; -- u32 data = 0; -- struct usb_ep *out_ep = audio->out_ep; -- -- switch (status) { -- -- case 0: /* normal completion? */ -- if (ep == out_ep) -- f_audio_out_ep_complete(ep, req); -- else if (audio->set_con) { -- memcpy(&data, req->buf, req->length); -- audio->set_con->set(audio->set_con, audio->set_cmd, -- le16_to_cpu(data)); -- audio->set_con = NULL; -- } -- break; -- default: -- break; -- } --} -- --static int audio_set_intf_req(struct usb_function *f, -- const struct usb_ctrlrequest *ctrl) --{ -- struct f_audio *audio = func_to_audio(f); -- struct usb_composite_dev *cdev = f->config->cdev; -- struct usb_request *req = cdev->req; -- u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); -- u16 len = le16_to_cpu(ctrl->wLength); -- u16 w_value = le16_to_cpu(ctrl->wValue); -- u8 con_sel = (w_value >> 8) & 0xFF; -- u8 cmd = (ctrl->bRequest & 0x0F); -- struct usb_audio_control_selector *cs; -- struct usb_audio_control *con; -- -- DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", -- ctrl->bRequest, w_value, len, id); -- -- list_for_each_entry(cs, &audio->cs, list) { -- if (cs->id == id) { -- list_for_each_entry(con, &cs->control, list) { -- if (con->type == con_sel) { -- audio->set_con = con; -- break; -- } -- } -- break; -- } -- } -- -- audio->set_cmd = cmd; -- req->context = audio; -- req->complete = f_audio_complete; -- -- return len; --} -- --static int audio_get_intf_req(struct usb_function *f, -- const struct usb_ctrlrequest *ctrl) --{ -- struct f_audio *audio = func_to_audio(f); -- struct usb_composite_dev *cdev = f->config->cdev; -- struct usb_request *req = cdev->req; -- int value = -EOPNOTSUPP; -- u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); -- u16 len = le16_to_cpu(ctrl->wLength); -- u16 w_value = le16_to_cpu(ctrl->wValue); -- u8 con_sel = (w_value >> 8) & 0xFF; -- u8 cmd = (ctrl->bRequest & 0x0F); -- struct usb_audio_control_selector *cs; -- struct usb_audio_control *con; -- -- DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", -- ctrl->bRequest, w_value, len, id); -- -- list_for_each_entry(cs, &audio->cs, list) { -- if (cs->id == id) { -- list_for_each_entry(con, &cs->control, list) { -- if (con->type == con_sel && con->get) { -- value = con->get(con, cmd); -- break; -- } -- } -- break; -- } -- } -- -- req->context = audio; -- req->complete = f_audio_complete; -- len = min_t(size_t, sizeof(value), len); -- memcpy(req->buf, &value, len); -- -- return len; --} -- - static int audio_set_endpoint_req(struct usb_function *f, - const struct usb_ctrlrequest *ctrl) - { -@@ -531,14 +447,6 @@ - * activation uses set_alt(). - */ - switch (ctrl->bRequestType) { -- case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: -- value = audio_set_intf_req(f, ctrl); -- break; -- -- case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: -- value = audio_get_intf_req(f, ctrl); -- break; -- - case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: - value = audio_set_endpoint_req(f, ctrl); - break; -@@ -571,143 +479,162 @@ - - static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) - { -- struct f_audio *audio = func_to_audio(f); - struct usb_composite_dev *cdev = f->config->cdev; -- struct usb_ep *out_ep = audio->out_ep; -- struct usb_request *req; -- struct f_uac1_opts *opts; -- int req_buf_size, req_count, audio_buf_size; -- int i = 0, err = 0; -- -- DBG(cdev, "intf %d, alt %d\n", intf, alt); -+ struct usb_gadget *gadget = cdev->gadget; -+ struct device *dev = &gadget->dev; -+ struct f_uac1 *uac1 = func_to_uac1(f); -+ int ret = 0; -+ -+ /* No i/f has more than 2 alt settings */ -+ if (alt > 1) { -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ return -EINVAL; -+ } - -- opts = container_of(f->fi, struct f_uac1_opts, func_inst); -- req_buf_size = opts->req_buf_size; -- req_count = opts->req_count; -- audio_buf_size = opts->audio_buf_size; -- -- if (intf == 1) { -- if (alt == 1) { -- err = config_ep_by_speed(cdev->gadget, f, out_ep); -- if (err) -- return err; -- -- usb_ep_enable(out_ep); -- audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); -- if (IS_ERR(audio->copy_buf)) -- return -ENOMEM; -- -- /* -- * allocate a bunch of read buffers -- * and queue them all at once. -- */ -- for (i = 0; i < req_count && err == 0; i++) { -- req = usb_ep_alloc_request(out_ep, GFP_ATOMIC); -- if (req) { -- req->buf = kzalloc(req_buf_size, -- GFP_ATOMIC); -- if (req->buf) { -- req->length = req_buf_size; -- req->context = audio; -- req->complete = -- f_audio_complete; -- err = usb_ep_queue(out_ep, -- req, GFP_ATOMIC); -- if (err) -- ERROR(cdev, -- "%s queue req: %d\n", -- out_ep->name, err); -- } else -- err = -ENOMEM; -- } else -- err = -ENOMEM; -- } -- -- } else { -- struct f_audio_buf *copy_buf = audio->copy_buf; -- if (copy_buf) { -- list_add_tail(©_buf->list, -- &audio->play_queue); -- schedule_work(&audio->playback_work); -- } -+ if (intf == uac1->ac_intf) { -+ /* Control I/f has only 1 AltSetting - 0 */ -+ if (alt) { -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ return -EINVAL; - } -+ return 0; -+ } -+ -+ if (intf == uac1->as_out_intf) { -+ uac1->as_out_alt = alt; -+ -+ if (alt) -+ ret = u_audio_start_capture(&uac1->g_audio); -+ else -+ u_audio_stop_capture(&uac1->g_audio); -+ } else if (intf == uac1->as_in_intf) { -+ uac1->as_in_alt = alt; -+ -+ if (alt) -+ ret = u_audio_start_playback(&uac1->g_audio); -+ else -+ u_audio_stop_playback(&uac1->g_audio); -+ } else { -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ return -EINVAL; - } - -- return err; -+ return ret; - } - --static void f_audio_disable(struct usb_function *f) -+static int f_audio_get_alt(struct usb_function *f, unsigned intf) - { -- return; -+ struct usb_composite_dev *cdev = f->config->cdev; -+ struct usb_gadget *gadget = cdev->gadget; -+ struct device *dev = &gadget->dev; -+ struct f_uac1 *uac1 = func_to_uac1(f); -+ -+ if (intf == uac1->ac_intf) -+ return uac1->ac_alt; -+ else if (intf == uac1->as_out_intf) -+ return uac1->as_out_alt; -+ else if (intf == uac1->as_in_intf) -+ return uac1->as_in_alt; -+ else -+ dev_err(dev, "%s:%d Invalid Interface %d!\n", -+ __func__, __LINE__, intf); -+ -+ return -EINVAL; - } - --/*-------------------------------------------------------------------------*/ - --static void f_audio_build_desc(struct f_audio *audio) -+static void f_audio_disable(struct usb_function *f) - { -- struct gaudio *card = &audio->card; -- u8 *sam_freq; -- int rate; -- -- /* Set channel numbers */ -- input_terminal_desc.bNrChannels = u_audio_get_playback_channels(card); -- as_type_i_desc.bNrChannels = u_audio_get_playback_channels(card); -+ struct f_uac1 *uac1 = func_to_uac1(f); - -- /* Set sample rates */ -- rate = u_audio_get_playback_rate(card); -- sam_freq = as_type_i_desc.tSamFreq[0]; -- memcpy(sam_freq, &rate, 3); -+ uac1->as_out_alt = 0; -+ uac1->as_in_alt = 0; - -- /* Todo: Set Sample bits and other parameters */ -- -- return; -+ u_audio_stop_capture(&uac1->g_audio); - } - -+/*-------------------------------------------------------------------------*/ -+ - /* audio function driver setup/binding */ --static int --f_audio_bind(struct usb_configuration *c, struct usb_function *f) -+static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) - { -- struct usb_composite_dev *cdev = c->cdev; -- struct f_audio *audio = func_to_audio(f); -- struct usb_string *us; -- int status; -- struct usb_ep *ep = NULL; -- struct f_uac1_opts *audio_opts; -+ struct usb_composite_dev *cdev = c->cdev; -+ struct usb_gadget *gadget = cdev->gadget; -+ struct f_uac1 *uac1 = func_to_uac1(f); -+ struct g_audio *audio = func_to_g_audio(f); -+ struct f_uac1_opts *audio_opts; -+ struct usb_ep *ep = NULL; -+ struct usb_string *us; -+ u8 *sam_freq; -+ int rate; -+ int status; - - audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); -- audio->card.gadget = c->cdev->gadget; -- /* set up ASLA audio devices */ -- if (!audio_opts->bound) { -- status = gaudio_setup(&audio->card); -- if (status < 0) -- return status; -- audio_opts->bound = true; -- } -+ - us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); - if (IS_ERR(us)) - return PTR_ERR(us); -+ uac_iad.iFunction = us[STR_AC_IF].id; - ac_interface_desc.iInterface = us[STR_AC_IF].id; -- input_terminal_desc.iTerminal = us[STR_INPUT_TERMINAL].id; -- input_terminal_desc.iChannelNames = us[STR_INPUT_TERMINAL_CH_NAMES].id; -- feature_unit_desc.iFeature = us[STR_FEAT_DESC_0].id; -- output_terminal_desc.iTerminal = us[STR_OUTPUT_TERMINAL].id; -- as_interface_alt_0_desc.iInterface = us[STR_AS_IF_ALT0].id; -- as_interface_alt_1_desc.iInterface = us[STR_AS_IF_ALT1].id; -+ usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id; -+ usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id; -+ io_out_ot_desc.iTerminal = us[STR_IO_OUT_OT].id; -+ as_out_interface_alt_0_desc.iInterface = us[STR_AS_OUT_IF_ALT0].id; -+ as_out_interface_alt_1_desc.iInterface = us[STR_AS_OUT_IF_ALT1].id; -+ io_in_it_desc.iTerminal = us[STR_IO_IN_IT].id; -+ io_in_it_desc.iChannelNames = us[STR_IO_IN_IT_CH_NAMES].id; -+ usb_in_ot_desc.iTerminal = us[STR_USB_IN_OT].id; -+ as_in_interface_alt_0_desc.iInterface = us[STR_AS_IN_IF_ALT0].id; -+ as_in_interface_alt_1_desc.iInterface = us[STR_AS_IN_IF_ALT1].id; - -+ /* Set channel numbers */ -+ usb_out_it_desc.bNrChannels = num_channels(audio_opts->c_chmask); -+ usb_out_it_desc.wChannelConfig = cpu_to_le16(audio_opts->c_chmask); -+ as_out_type_i_desc.bNrChannels = num_channels(audio_opts->c_chmask); -+ as_out_type_i_desc.bSubframeSize = audio_opts->c_ssize; -+ as_out_type_i_desc.bBitResolution = audio_opts->c_ssize * 8; -+ io_in_it_desc.bNrChannels = num_channels(audio_opts->p_chmask); -+ io_in_it_desc.wChannelConfig = cpu_to_le16(audio_opts->p_chmask); -+ as_in_type_i_desc.bNrChannels = num_channels(audio_opts->p_chmask); -+ as_in_type_i_desc.bSubframeSize = audio_opts->p_ssize; -+ as_in_type_i_desc.bBitResolution = audio_opts->p_ssize * 8; - -- f_audio_build_desc(audio); -+ /* Set sample rates */ -+ rate = audio_opts->c_srate; -+ sam_freq = as_out_type_i_desc.tSamFreq[0]; -+ memcpy(sam_freq, &rate, 3); -+ rate = audio_opts->p_srate; -+ sam_freq = as_in_type_i_desc.tSamFreq[0]; -+ memcpy(sam_freq, &rate, 3); - - /* allocate instance-specific interface IDs, and patch descriptors */ - status = usb_interface_id(c, f); - if (status < 0) - goto fail; -+ uac_iad.bFirstInterface = status; - ac_interface_desc.bInterfaceNumber = status; -+ uac1->ac_intf = status; -+ uac1->ac_alt = 0; -+ -+ status = usb_interface_id(c, f); -+ if (status < 0) -+ goto fail; -+ as_out_interface_alt_0_desc.bInterfaceNumber = status; -+ as_out_interface_alt_1_desc.bInterfaceNumber = status; -+ ac_header_desc.baInterfaceNr[0] = status; -+ uac1->as_out_intf = status; -+ uac1->as_out_alt = 0; - - status = usb_interface_id(c, f); - if (status < 0) - goto fail; -- as_interface_alt_0_desc.bInterfaceNumber = status; -- as_interface_alt_1_desc.bInterfaceNumber = status; -+ as_in_interface_alt_0_desc.bInterfaceNumber = status; -+ as_in_interface_alt_1_desc.bInterfaceNumber = status; -+ ac_header_desc.baInterfaceNr[1] = status; -+ uac1->as_in_intf = status; -+ uac1->as_in_alt = 0; -+ -+ audio->gadget = gadget; - - status = -ENODEV; - -@@ -718,51 +645,41 @@ - audio->out_ep = ep; - audio->out_ep->desc = &as_out_ep_desc; - -- status = -ENOMEM; -+ ep = usb_ep_autoconfig(cdev->gadget, &as_in_ep_desc); -+ if (!ep) -+ goto fail; -+ audio->in_ep = ep; -+ audio->in_ep->desc = &as_in_ep_desc; - - /* copy descriptors, and track endpoint copies */ -- status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, -- NULL); -+ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, -+ f_audio_ss_desc, NULL); - if (status) - goto fail; -- return 0; -- --fail: -- gaudio_cleanup(&audio->card); -- return status; --} - --/*-------------------------------------------------------------------------*/ -+ audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize); -+ audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); -+ audio->params.c_chmask = audio_opts->c_chmask; -+ audio->params.c_srate = audio_opts->c_srate; -+ audio->params.c_ssize = audio_opts->c_ssize; -+ audio->params.p_chmask = audio_opts->p_chmask; -+ audio->params.p_srate = audio_opts->p_srate; -+ audio->params.p_ssize = audio_opts->p_ssize; -+ audio->params.req_number = audio_opts->req_number; - --static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) --{ -- con->data[cmd] = value; -+ status = g_audio_setup(audio, "UAC1_PCM", "UAC1_Gadget"); -+ if (status) -+ goto err_card_register; - - return 0; --} - --static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) --{ -- return con->data[cmd]; -+err_card_register: -+ usb_free_all_descriptors(f); -+fail: -+ return status; - } - --/* Todo: add more control selecotor dynamically */ --static int control_selector_init(struct f_audio *audio) --{ -- INIT_LIST_HEAD(&audio->cs); -- list_add(&feature_unit.list, &audio->cs); -- -- INIT_LIST_HEAD(&feature_unit.control); -- list_add(&mute_control.list, &feature_unit.control); -- list_add(&volume_control.list, &feature_unit.control); -- -- volume_control.data[UAC__CUR] = 0xffc0; -- volume_control.data[UAC__MIN] = 0xe3a0; -- volume_control.data[UAC__MAX] = 0xfff0; -- volume_control.data[UAC__RES] = 0x0030; -- -- return 0; --} -+/*-------------------------------------------------------------------------*/ - - static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item) - { -@@ -781,9 +698,10 @@ - .release = f_uac1_attr_release, - }; - --#define UAC1_INT_ATTRIBUTE(name) \ --static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ -- char *page) \ -+#define UAC1_ATTRIBUTE(name) \ -+static ssize_t f_uac1_opts_##name##_show( \ -+ struct config_item *item, \ -+ char *page) \ - { \ - struct f_uac1_opts *opts = to_f_uac1_opts(item); \ - int result; \ -@@ -795,7 +713,8 @@ - return result; \ - } \ - \ --static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ -+static ssize_t f_uac1_opts_##name##_store( \ -+ struct config_item *item, \ - const char *page, size_t len) \ - { \ - struct f_uac1_opts *opts = to_f_uac1_opts(item); \ -@@ -822,64 +741,22 @@ - \ - CONFIGFS_ATTR(f_uac1_opts_, name) - --UAC1_INT_ATTRIBUTE(req_buf_size); --UAC1_INT_ATTRIBUTE(req_count); --UAC1_INT_ATTRIBUTE(audio_buf_size); -- --#define UAC1_STR_ATTRIBUTE(name) \ --static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ -- char *page) \ --{ \ -- struct f_uac1_opts *opts = to_f_uac1_opts(item); \ -- int result; \ -- \ -- mutex_lock(&opts->lock); \ -- result = sprintf(page, "%s\n", opts->name); \ -- mutex_unlock(&opts->lock); \ -- \ -- return result; \ --} \ -- \ --static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ -- const char *page, size_t len) \ --{ \ -- struct f_uac1_opts *opts = to_f_uac1_opts(item); \ -- int ret = -EBUSY; \ -- char *tmp; \ -- \ -- mutex_lock(&opts->lock); \ -- if (opts->refcnt) \ -- goto end; \ -- \ -- tmp = kstrndup(page, len, GFP_KERNEL); \ -- if (tmp) { \ -- ret = -ENOMEM; \ -- goto end; \ -- } \ -- if (opts->name##_alloc) \ -- kfree(opts->name); \ -- opts->name##_alloc = true; \ -- opts->name = tmp; \ -- ret = len; \ -- \ --end: \ -- mutex_unlock(&opts->lock); \ -- return ret; \ --} \ -- \ --CONFIGFS_ATTR(f_uac1_opts_, name) -- --UAC1_STR_ATTRIBUTE(fn_play); --UAC1_STR_ATTRIBUTE(fn_cap); --UAC1_STR_ATTRIBUTE(fn_cntl); -+UAC1_ATTRIBUTE(c_chmask); -+UAC1_ATTRIBUTE(c_srate); -+UAC1_ATTRIBUTE(c_ssize); -+UAC1_ATTRIBUTE(p_chmask); -+UAC1_ATTRIBUTE(p_srate); -+UAC1_ATTRIBUTE(p_ssize); -+UAC1_ATTRIBUTE(req_number); - - static struct configfs_attribute *f_uac1_attrs[] = { -- &f_uac1_opts_attr_req_buf_size, -- &f_uac1_opts_attr_req_count, -- &f_uac1_opts_attr_audio_buf_size, -- &f_uac1_opts_attr_fn_play, -- &f_uac1_opts_attr_fn_cap, -- &f_uac1_opts_attr_fn_cntl, -+ &f_uac1_opts_attr_c_chmask, -+ &f_uac1_opts_attr_c_srate, -+ &f_uac1_opts_attr_c_ssize, -+ &f_uac1_opts_attr_p_chmask, -+ &f_uac1_opts_attr_p_srate, -+ &f_uac1_opts_attr_p_ssize, -+ &f_uac1_opts_attr_req_number, - NULL, - }; - -@@ -894,12 +771,6 @@ - struct f_uac1_opts *opts; - - opts = container_of(f, struct f_uac1_opts, func_inst); -- if (opts->fn_play_alloc) -- kfree(opts->fn_play); -- if (opts->fn_cap_alloc) -- kfree(opts->fn_cap); -- if (opts->fn_cntl_alloc) -- kfree(opts->fn_cntl); - kfree(opts); - } - -@@ -917,21 +788,22 @@ - config_group_init_type_name(&opts->func_inst.group, "", - &f_uac1_func_type); - -- opts->req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE; -- opts->req_count = UAC1_REQ_COUNT; -- opts->audio_buf_size = UAC1_AUDIO_BUF_SIZE; -- opts->fn_play = FILE_PCM_PLAYBACK; -- opts->fn_cap = FILE_PCM_CAPTURE; -- opts->fn_cntl = FILE_CONTROL; -+ opts->c_chmask = UAC1_DEF_CCHMASK; -+ opts->c_srate = UAC1_DEF_CSRATE; -+ opts->c_ssize = UAC1_DEF_CSSIZE; -+ opts->p_chmask = UAC1_DEF_PCHMASK; -+ opts->p_srate = UAC1_DEF_PSRATE; -+ opts->p_ssize = UAC1_DEF_PSSIZE; -+ opts->req_number = UAC1_DEF_REQ_NUM; - return &opts->func_inst; - } - - static void f_audio_free(struct usb_function *f) - { -- struct f_audio *audio = func_to_audio(f); -+ struct g_audio *audio; - struct f_uac1_opts *opts; - -- gaudio_cleanup(&audio->card); -+ audio = func_to_g_audio(f); - opts = container_of(f->fi, struct f_uac1_opts, func_inst); - kfree(audio); - mutex_lock(&opts->lock); -@@ -941,42 +813,41 @@ - - static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) - { -+ struct g_audio *audio = func_to_g_audio(f); -+ -+ g_audio_cleanup(audio); - usb_free_all_descriptors(f); -+ -+ audio->gadget = NULL; - } - - static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) - { -- struct f_audio *audio; -+ struct f_uac1 *uac1; - struct f_uac1_opts *opts; - - /* allocate and initialize one new instance */ -- audio = kzalloc(sizeof(*audio), GFP_KERNEL); -- if (!audio) -+ uac1 = kzalloc(sizeof(*uac1), GFP_KERNEL); -+ if (!uac1) - return ERR_PTR(-ENOMEM); - -- audio->card.func.name = "g_audio"; -- - opts = container_of(fi, struct f_uac1_opts, func_inst); - mutex_lock(&opts->lock); - ++opts->refcnt; - mutex_unlock(&opts->lock); -- INIT_LIST_HEAD(&audio->play_queue); -- spin_lock_init(&audio->lock); -- -- audio->card.func.bind = f_audio_bind; -- audio->card.func.unbind = f_audio_unbind; -- audio->card.func.set_alt = f_audio_set_alt; -- audio->card.func.setup = f_audio_setup; -- audio->card.func.disable = f_audio_disable; -- audio->card.func.free_func = f_audio_free; -- -- control_selector_init(audio); - -- INIT_WORK(&audio->playback_work, f_audio_playback_work); -+ uac1->g_audio.func.name = "uac1_func"; -+ uac1->g_audio.func.bind = f_audio_bind; -+ uac1->g_audio.func.unbind = f_audio_unbind; -+ uac1->g_audio.func.set_alt = f_audio_set_alt; -+ uac1->g_audio.func.get_alt = f_audio_get_alt; -+ uac1->g_audio.func.setup = f_audio_setup; -+ uac1->g_audio.func.disable = f_audio_disable; -+ uac1->g_audio.func.free_func = f_audio_free; - -- return &audio->card.func; -+ return &uac1->g_audio.func; - } - - DECLARE_USB_FUNCTION_INIT(uac1, f_audio_alloc_inst, f_audio_alloc); - MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Bryan Wu"); -+MODULE_AUTHOR("Ruslan Bilovol"); ---- linux-4.9.37/drivers/usb/gadget/function/f_uac1_legacy.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/f_uac1_legacy.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,1020 @@ -+/* -+ * f_audio.c -- USB Audio class function driver -+ * -+ * Copyright (C) 2008 Bryan Wu -+ * Copyright (C) 2008 Analog Devices, Inc -+ * -+ * Enter bugs at http://blackfin.uclinux.org/ -+ * -+ * Licensed under the GPL-2 or later. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "u_uac1_legacy.h" -+ -+static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); -+static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); -+ -+/* -+ * DESCRIPTORS ... most are static, but strings and full -+ * configuration descriptors are built on demand. -+ */ -+ -+/* -+ * We have two interfaces- AudioControl and AudioStreaming -+ * TODO: only supcard playback currently -+ */ -+#define F_AUDIO_AC_INTERFACE 0 -+#define F_AUDIO_AS_INTERFACE 1 -+#define F_AUDIO_NUM_INTERFACES 1 -+ -+/* B.3.1 Standard AC Interface Descriptor */ -+static struct usb_interface_descriptor ac_interface_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bNumEndpoints = 0, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, -+}; -+ -+/* -+ * The number of AudioStreaming and MIDIStreaming interfaces -+ * in the Audio Interface Collection -+ */ -+DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); -+ -+#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) -+/* 1 input terminal, 1 output terminal and 1 feature unit */ -+#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \ -+ + UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0)) -+/* B.3.2 Class-Specific AC Interface Descriptor */ -+static struct uac1_ac_header_descriptor_1 ac_header_desc = { -+ .bLength = UAC_DT_AC_HEADER_LENGTH, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_HEADER, -+ .bcdADC = __constant_cpu_to_le16(0x0100), -+ .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), -+ .bInCollection = F_AUDIO_NUM_INTERFACES, -+ .baInterfaceNr = { -+ /* Interface number of the first AudioStream interface */ -+ [0] = 1, -+ } -+}; -+ -+#define INPUT_TERMINAL_ID 1 -+static struct uac_input_terminal_descriptor input_terminal_desc = { -+ .bLength = UAC_DT_INPUT_TERMINAL_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_INPUT_TERMINAL, -+ .bTerminalID = INPUT_TERMINAL_ID, -+ .wTerminalType = UAC_TERMINAL_STREAMING, -+ .bAssocTerminal = 0, -+ .wChannelConfig = 0x3, -+}; -+ -+DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); -+ -+#define FEATURE_UNIT_ID 2 -+static struct uac_feature_unit_descriptor_0 feature_unit_desc = { -+ .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_FEATURE_UNIT, -+ .bUnitID = FEATURE_UNIT_ID, -+ .bSourceID = INPUT_TERMINAL_ID, -+ .bControlSize = 2, -+ .bmaControls[0] = (UAC_FU_MUTE | UAC_FU_VOLUME), -+}; -+ -+static struct usb_audio_control mute_control = { -+ .list = LIST_HEAD_INIT(mute_control.list), -+ .name = "Mute Control", -+ .type = UAC_FU_MUTE, -+ /* Todo: add real Mute control code */ -+ .set = generic_set_cmd, -+ .get = generic_get_cmd, -+}; -+ -+static struct usb_audio_control volume_control = { -+ .list = LIST_HEAD_INIT(volume_control.list), -+ .name = "Volume Control", -+ .type = UAC_FU_VOLUME, -+ /* Todo: add real Volume control code */ -+ .set = generic_set_cmd, -+ .get = generic_get_cmd, -+}; -+ -+static struct usb_audio_control_selector feature_unit = { -+ .list = LIST_HEAD_INIT(feature_unit.list), -+ .id = FEATURE_UNIT_ID, -+ .name = "Mute & Volume Control", -+ .type = UAC_FEATURE_UNIT, -+ .desc = (struct usb_descriptor_header *)&feature_unit_desc, -+}; -+ -+#define OUTPUT_TERMINAL_ID 3 -+static struct uac1_output_terminal_descriptor output_terminal_desc = { -+ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, -+ .bTerminalID = OUTPUT_TERMINAL_ID, -+ .wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER, -+ .bAssocTerminal = FEATURE_UNIT_ID, -+ .bSourceID = FEATURE_UNIT_ID, -+}; -+ -+/* B.4.1 Standard AS Interface Descriptor */ -+static struct usb_interface_descriptor as_interface_alt_0_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bAlternateSetting = 0, -+ .bNumEndpoints = 0, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -+}; -+ -+static struct usb_interface_descriptor as_interface_alt_1_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bAlternateSetting = 1, -+ .bNumEndpoints = 1, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -+}; -+ -+/* B.4.2 Class-Specific AS Interface Descriptor */ -+static struct uac1_as_header_descriptor as_header_desc = { -+ .bLength = UAC_DT_AS_HEADER_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_AS_GENERAL, -+ .bTerminalLink = INPUT_TERMINAL_ID, -+ .bDelay = 1, -+ .wFormatTag = UAC_FORMAT_TYPE_I_PCM, -+}; -+ -+DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); -+ -+static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { -+ .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_FORMAT_TYPE, -+ .bFormatType = UAC_FORMAT_TYPE_I, -+ .bSubframeSize = 2, -+ .bBitResolution = 16, -+ .bSamFreqType = 1, -+}; -+ -+/* Standard ISO OUT Endpoint Descriptor */ -+static struct usb_endpoint_descriptor as_out_ep_desc = { -+ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_OUT, -+ .bmAttributes = USB_ENDPOINT_SYNC_ADAPTIVE -+ | USB_ENDPOINT_XFER_ISOC, -+ .wMaxPacketSize = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), -+ .bInterval = 4, -+}; -+ -+/* Class-specific AS ISO OUT Endpoint Descriptor */ -+static struct uac_iso_endpoint_descriptor as_iso_out_desc = { -+ .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, -+ .bDescriptorType = USB_DT_CS_ENDPOINT, -+ .bDescriptorSubtype = UAC_EP_GENERAL, -+ .bmAttributes = 1, -+ .bLockDelayUnits = 1, -+ .wLockDelay = __constant_cpu_to_le16(1), -+}; -+ -+static struct usb_descriptor_header *f_audio_desc[] = { -+ (struct usb_descriptor_header *)&ac_interface_desc, -+ (struct usb_descriptor_header *)&ac_header_desc, -+ -+ (struct usb_descriptor_header *)&input_terminal_desc, -+ (struct usb_descriptor_header *)&output_terminal_desc, -+ (struct usb_descriptor_header *)&feature_unit_desc, -+ -+ (struct usb_descriptor_header *)&as_interface_alt_0_desc, -+ (struct usb_descriptor_header *)&as_interface_alt_1_desc, -+ (struct usb_descriptor_header *)&as_header_desc, -+ -+ (struct usb_descriptor_header *)&as_type_i_desc, -+ -+ (struct usb_descriptor_header *)&as_out_ep_desc, -+ (struct usb_descriptor_header *)&as_iso_out_desc, -+ NULL, -+}; -+ -+enum { -+ STR_AC_IF, -+ STR_INPUT_TERMINAL, -+ STR_INPUT_TERMINAL_CH_NAMES, -+ STR_FEAT_DESC_0, -+ STR_OUTPUT_TERMINAL, -+ STR_AS_IF_ALT0, -+ STR_AS_IF_ALT1, -+}; -+ -+static struct usb_string strings_uac1[] = { -+ [STR_AC_IF].s = "AC Interface", -+ [STR_INPUT_TERMINAL].s = "Input terminal", -+ [STR_INPUT_TERMINAL_CH_NAMES].s = "Channels", -+ [STR_FEAT_DESC_0].s = "Volume control & mute", -+ [STR_OUTPUT_TERMINAL].s = "Output terminal", -+ [STR_AS_IF_ALT0].s = "AS Interface", -+ [STR_AS_IF_ALT1].s = "AS Interface", -+ { }, -+}; -+ -+static struct usb_gadget_strings str_uac1 = { -+ .language = 0x0409, /* en-us */ -+ .strings = strings_uac1, -+}; -+ -+static struct usb_gadget_strings *uac1_strings[] = { -+ &str_uac1, -+ NULL, -+}; -+ -+/* -+ * This function is an ALSA sound card following USB Audio Class Spec 1.0. -+ */ -+ -+/*-------------------------------------------------------------------------*/ -+struct f_audio_buf { -+ u8 *buf; -+ int actual; -+ struct list_head list; -+}; -+ -+static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) -+{ -+ struct f_audio_buf *copy_buf; -+ -+ copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); -+ if (!copy_buf) -+ return ERR_PTR(-ENOMEM); -+ -+ copy_buf->buf = kzalloc(buf_size, GFP_ATOMIC); -+ if (!copy_buf->buf) { -+ kfree(copy_buf); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ return copy_buf; -+} -+ -+static void f_audio_buffer_free(struct f_audio_buf *audio_buf) -+{ -+ kfree(audio_buf->buf); -+ kfree(audio_buf); -+} -+/*-------------------------------------------------------------------------*/ -+ -+struct f_audio { -+ struct gaudio card; -+ -+ u8 ac_intf, ac_alt; -+ u8 as_intf, as_alt; -+ -+ /* endpoints handle full and/or high speeds */ -+ struct usb_ep *out_ep; -+ -+ spinlock_t lock; -+ struct f_audio_buf *copy_buf; -+ struct work_struct playback_work; -+ struct list_head play_queue; -+ -+ /* Control Set command */ -+ struct list_head cs; -+ u8 set_cmd; -+ struct usb_audio_control *set_con; -+}; -+ -+static inline struct f_audio *func_to_audio(struct usb_function *f) -+{ -+ return container_of(f, struct f_audio, card.func); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static void f_audio_playback_work(struct work_struct *data) -+{ -+ struct f_audio *audio = container_of(data, struct f_audio, -+ playback_work); -+ struct f_audio_buf *play_buf; -+ -+ spin_lock_irq(&audio->lock); -+ if (list_empty(&audio->play_queue)) { -+ spin_unlock_irq(&audio->lock); -+ return; -+ } -+ play_buf = list_first_entry(&audio->play_queue, -+ struct f_audio_buf, list); -+ list_del(&play_buf->list); -+ spin_unlock_irq(&audio->lock); -+ -+ u_audio_playback(&audio->card, play_buf->buf, play_buf->actual); -+ f_audio_buffer_free(play_buf); -+} -+ -+static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) -+{ -+ struct f_audio *audio = req->context; -+ struct usb_composite_dev *cdev = audio->card.func.config->cdev; -+ struct f_audio_buf *copy_buf = audio->copy_buf; -+ struct f_uac1_legacy_opts *opts; -+ int audio_buf_size; -+ int err; -+ -+ opts = container_of(audio->card.func.fi, struct f_uac1_legacy_opts, -+ func_inst); -+ audio_buf_size = opts->audio_buf_size; -+ -+ if (!copy_buf) -+ return -EINVAL; -+ -+ /* Copy buffer is full, add it to the play_queue */ -+ if (audio_buf_size - copy_buf->actual < req->actual) { -+ list_add_tail(©_buf->list, &audio->play_queue); -+ schedule_work(&audio->playback_work); -+ copy_buf = f_audio_buffer_alloc(audio_buf_size); -+ if (IS_ERR(copy_buf)) -+ return -ENOMEM; -+ } -+ -+ memcpy(copy_buf->buf + copy_buf->actual, req->buf, req->actual); -+ copy_buf->actual += req->actual; -+ audio->copy_buf = copy_buf; -+ -+ err = usb_ep_queue(ep, req, GFP_ATOMIC); -+ if (err) -+ ERROR(cdev, "%s queue req: %d\n", ep->name, err); -+ -+ return 0; -+ -+} -+ -+static void f_audio_complete(struct usb_ep *ep, struct usb_request *req) -+{ -+ struct f_audio *audio = req->context; -+ int status = req->status; -+ u32 data = 0; -+ struct usb_ep *out_ep = audio->out_ep; -+ -+ switch (status) { -+ -+ case 0: /* normal completion? */ -+ if (ep == out_ep) -+ f_audio_out_ep_complete(ep, req); -+ else if (audio->set_con) { -+ memcpy(&data, req->buf, req->length); -+ audio->set_con->set(audio->set_con, audio->set_cmd, -+ le16_to_cpu(data)); -+ audio->set_con = NULL; -+ } -+ break; -+ default: -+ break; -+ } -+} -+ -+static int audio_set_intf_req(struct usb_function *f, -+ const struct usb_ctrlrequest *ctrl) -+{ -+ struct f_audio *audio = func_to_audio(f); -+ struct usb_composite_dev *cdev = f->config->cdev; -+ struct usb_request *req = cdev->req; -+ u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); -+ u16 len = le16_to_cpu(ctrl->wLength); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ u8 con_sel = (w_value >> 8) & 0xFF; -+ u8 cmd = (ctrl->bRequest & 0x0F); -+ struct usb_audio_control_selector *cs; -+ struct usb_audio_control *con; -+ -+ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", -+ ctrl->bRequest, w_value, len, id); -+ -+ list_for_each_entry(cs, &audio->cs, list) { -+ if (cs->id == id) { -+ list_for_each_entry(con, &cs->control, list) { -+ if (con->type == con_sel) { -+ audio->set_con = con; -+ break; -+ } -+ } -+ break; -+ } -+ } -+ -+ audio->set_cmd = cmd; -+ req->context = audio; -+ req->complete = f_audio_complete; -+ -+ return len; -+} -+ -+static int audio_get_intf_req(struct usb_function *f, -+ const struct usb_ctrlrequest *ctrl) -+{ -+ struct f_audio *audio = func_to_audio(f); -+ struct usb_composite_dev *cdev = f->config->cdev; -+ struct usb_request *req = cdev->req; -+ int value = -EOPNOTSUPP; -+ u8 id = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); -+ u16 len = le16_to_cpu(ctrl->wLength); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ u8 con_sel = (w_value >> 8) & 0xFF; -+ u8 cmd = (ctrl->bRequest & 0x0F); -+ struct usb_audio_control_selector *cs; -+ struct usb_audio_control *con; -+ -+ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, entity %d\n", -+ ctrl->bRequest, w_value, len, id); -+ -+ list_for_each_entry(cs, &audio->cs, list) { -+ if (cs->id == id) { -+ list_for_each_entry(con, &cs->control, list) { -+ if (con->type == con_sel && con->get) { -+ value = con->get(con, cmd); -+ break; -+ } -+ } -+ break; -+ } -+ } -+ -+ req->context = audio; -+ req->complete = f_audio_complete; -+ len = min_t(size_t, sizeof(value), len); -+ memcpy(req->buf, &value, len); -+ -+ return len; -+} -+ -+static int audio_set_endpoint_req(struct usb_function *f, -+ const struct usb_ctrlrequest *ctrl) -+{ -+ struct usb_composite_dev *cdev = f->config->cdev; -+ int value = -EOPNOTSUPP; -+ u16 ep = le16_to_cpu(ctrl->wIndex); -+ u16 len = le16_to_cpu(ctrl->wLength); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ -+ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", -+ ctrl->bRequest, w_value, len, ep); -+ -+ switch (ctrl->bRequest) { -+ case UAC_SET_CUR: -+ value = len; -+ break; -+ -+ case UAC_SET_MIN: -+ break; -+ -+ case UAC_SET_MAX: -+ break; -+ -+ case UAC_SET_RES: -+ break; -+ -+ case UAC_SET_MEM: -+ break; -+ -+ default: -+ break; -+ } -+ -+ return value; -+} -+ -+static int audio_get_endpoint_req(struct usb_function *f, -+ const struct usb_ctrlrequest *ctrl) -+{ -+ struct usb_composite_dev *cdev = f->config->cdev; -+ int value = -EOPNOTSUPP; -+ u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); -+ u16 len = le16_to_cpu(ctrl->wLength); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ -+ DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", -+ ctrl->bRequest, w_value, len, ep); -+ -+ switch (ctrl->bRequest) { -+ case UAC_GET_CUR: -+ case UAC_GET_MIN: -+ case UAC_GET_MAX: -+ case UAC_GET_RES: -+ value = len; -+ break; -+ case UAC_GET_MEM: -+ break; -+ default: -+ break; -+ } -+ -+ return value; -+} -+ -+static int -+f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) -+{ -+ struct usb_composite_dev *cdev = f->config->cdev; -+ struct usb_request *req = cdev->req; -+ int value = -EOPNOTSUPP; -+ u16 w_index = le16_to_cpu(ctrl->wIndex); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ u16 w_length = le16_to_cpu(ctrl->wLength); -+ -+ /* composite driver infrastructure handles everything; interface -+ * activation uses set_alt(). -+ */ -+ switch (ctrl->bRequestType) { -+ case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: -+ value = audio_set_intf_req(f, ctrl); -+ break; -+ -+ case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: -+ value = audio_get_intf_req(f, ctrl); -+ break; -+ -+ case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: -+ value = audio_set_endpoint_req(f, ctrl); -+ break; -+ -+ case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: -+ value = audio_get_endpoint_req(f, ctrl); -+ break; -+ -+ default: -+ ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", -+ ctrl->bRequestType, ctrl->bRequest, -+ w_value, w_index, w_length); -+ } -+ -+ /* respond with data transfer or status phase? */ -+ if (value >= 0) { -+ DBG(cdev, "audio req%02x.%02x v%04x i%04x l%d\n", -+ ctrl->bRequestType, ctrl->bRequest, -+ w_value, w_index, w_length); -+ req->zero = 0; -+ req->length = value; -+ value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); -+ if (value < 0) -+ ERROR(cdev, "audio response on err %d\n", value); -+ } -+ -+ /* device either stalls (value < 0) or reports success */ -+ return value; -+} -+ -+static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) -+{ -+ struct f_audio *audio = func_to_audio(f); -+ struct usb_composite_dev *cdev = f->config->cdev; -+ struct usb_ep *out_ep = audio->out_ep; -+ struct usb_request *req; -+ struct f_uac1_legacy_opts *opts; -+ int req_buf_size, req_count, audio_buf_size; -+ int i = 0, err = 0; -+ -+ DBG(cdev, "intf %d, alt %d\n", intf, alt); -+ -+ opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst); -+ req_buf_size = opts->req_buf_size; -+ req_count = opts->req_count; -+ audio_buf_size = opts->audio_buf_size; -+ -+ /* No i/f has more than 2 alt settings */ -+ if (alt > 1) { -+ ERROR(cdev, "%s:%d Error!\n", __func__, __LINE__); -+ return -EINVAL; -+ } -+ -+ if (intf == audio->ac_intf) { -+ /* Control I/f has only 1 AltSetting - 0 */ -+ if (alt) { -+ ERROR(cdev, "%s:%d Error!\n", __func__, __LINE__); -+ return -EINVAL; -+ } -+ return 0; -+ } else if (intf == audio->as_intf) { -+ if (alt == 1) { -+ err = config_ep_by_speed(cdev->gadget, f, out_ep); -+ if (err) -+ return err; -+ -+ usb_ep_enable(out_ep); -+ audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); -+ if (IS_ERR(audio->copy_buf)) -+ return -ENOMEM; -+ -+ /* -+ * allocate a bunch of read buffers -+ * and queue them all at once. -+ */ -+ for (i = 0; i < req_count && err == 0; i++) { -+ req = usb_ep_alloc_request(out_ep, GFP_ATOMIC); -+ if (req) { -+ req->buf = kzalloc(req_buf_size, -+ GFP_ATOMIC); -+ if (req->buf) { -+ req->length = req_buf_size; -+ req->context = audio; -+ req->complete = -+ f_audio_complete; -+ err = usb_ep_queue(out_ep, -+ req, GFP_ATOMIC); -+ if (err) -+ ERROR(cdev, -+ "%s queue req: %d\n", -+ out_ep->name, err); -+ } else -+ err = -ENOMEM; -+ } else -+ err = -ENOMEM; -+ } -+ -+ } else { -+ struct f_audio_buf *copy_buf = audio->copy_buf; -+ if (copy_buf) { -+ list_add_tail(©_buf->list, -+ &audio->play_queue); -+ schedule_work(&audio->playback_work); -+ } -+ } -+ audio->as_alt = alt; -+ } -+ -+ return err; -+} -+ -+static int f_audio_get_alt(struct usb_function *f, unsigned intf) -+{ -+ struct f_audio *audio = func_to_audio(f); -+ struct usb_composite_dev *cdev = f->config->cdev; -+ -+ if (intf == audio->ac_intf) -+ return audio->ac_alt; -+ else if (intf == audio->as_intf) -+ return audio->as_alt; -+ else -+ ERROR(cdev, "%s:%d Invalid Interface %d!\n", -+ __func__, __LINE__, intf); -+ -+ return -EINVAL; -+} -+ -+static void f_audio_disable(struct usb_function *f) -+{ -+ return; -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static void f_audio_build_desc(struct f_audio *audio) -+{ -+ struct gaudio *card = &audio->card; -+ u8 *sam_freq; -+ int rate; -+ -+ /* Set channel numbers */ -+ input_terminal_desc.bNrChannels = u_audio_get_playback_channels(card); -+ as_type_i_desc.bNrChannels = u_audio_get_playback_channels(card); -+ -+ /* Set sample rates */ -+ rate = u_audio_get_playback_rate(card); -+ sam_freq = as_type_i_desc.tSamFreq[0]; -+ memcpy(sam_freq, &rate, 3); -+ -+ /* Todo: Set Sample bits and other parameters */ -+ -+ return; -+} -+ -+/* audio function driver setup/binding */ -+static int -+f_audio_bind(struct usb_configuration *c, struct usb_function *f) -+{ -+ struct usb_composite_dev *cdev = c->cdev; -+ struct f_audio *audio = func_to_audio(f); -+ struct usb_string *us; -+ int status; -+ struct usb_ep *ep = NULL; -+ struct f_uac1_legacy_opts *audio_opts; -+ -+ audio_opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst); -+ audio->card.gadget = c->cdev->gadget; -+ /* set up ASLA audio devices */ -+ if (!audio_opts->bound) { -+ status = gaudio_setup(&audio->card); -+ if (status < 0) -+ return status; -+ audio_opts->bound = true; -+ } -+ us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); -+ if (IS_ERR(us)) -+ return PTR_ERR(us); -+ ac_interface_desc.iInterface = us[STR_AC_IF].id; -+ input_terminal_desc.iTerminal = us[STR_INPUT_TERMINAL].id; -+ input_terminal_desc.iChannelNames = us[STR_INPUT_TERMINAL_CH_NAMES].id; -+ feature_unit_desc.iFeature = us[STR_FEAT_DESC_0].id; -+ output_terminal_desc.iTerminal = us[STR_OUTPUT_TERMINAL].id; -+ as_interface_alt_0_desc.iInterface = us[STR_AS_IF_ALT0].id; -+ as_interface_alt_1_desc.iInterface = us[STR_AS_IF_ALT1].id; -+ -+ -+ f_audio_build_desc(audio); -+ -+ /* allocate instance-specific interface IDs, and patch descriptors */ -+ status = usb_interface_id(c, f); -+ if (status < 0) -+ goto fail; -+ ac_interface_desc.bInterfaceNumber = status; -+ audio->ac_intf = status; -+ audio->ac_alt = 0; -+ -+ status = usb_interface_id(c, f); -+ if (status < 0) -+ goto fail; -+ as_interface_alt_0_desc.bInterfaceNumber = status; -+ as_interface_alt_1_desc.bInterfaceNumber = status; -+ audio->as_intf = status; -+ audio->as_alt = 0; -+ -+ status = -ENODEV; -+ -+ /* allocate instance-specific endpoints */ -+ ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); -+ if (!ep) -+ goto fail; -+ audio->out_ep = ep; -+ audio->out_ep->desc = &as_out_ep_desc; -+ -+ status = -ENOMEM; -+ -+ /* copy descriptors, and track endpoint copies */ -+ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, -+ NULL); -+ if (status) -+ goto fail; -+ return 0; -+ -+fail: -+ gaudio_cleanup(&audio->card); -+ return status; -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) -+{ -+ con->data[cmd] = value; -+ -+ return 0; -+} -+ -+static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) -+{ -+ return con->data[cmd]; -+} -+ -+/* Todo: add more control selecotor dynamically */ -+static int control_selector_init(struct f_audio *audio) -+{ -+ INIT_LIST_HEAD(&audio->cs); -+ list_add(&feature_unit.list, &audio->cs); -+ -+ INIT_LIST_HEAD(&feature_unit.control); -+ list_add(&mute_control.list, &feature_unit.control); -+ list_add(&volume_control.list, &feature_unit.control); -+ -+ volume_control.data[UAC__CUR] = 0xffc0; -+ volume_control.data[UAC__MIN] = 0xe3a0; -+ volume_control.data[UAC__MAX] = 0xfff0; -+ volume_control.data[UAC__RES] = 0x0030; -+ -+ return 0; -+} -+ -+static inline -+struct f_uac1_legacy_opts *to_f_uac1_opts(struct config_item *item) -+{ -+ return container_of(to_config_group(item), struct f_uac1_legacy_opts, -+ func_inst.group); -+} -+ -+static void f_uac1_attr_release(struct config_item *item) -+{ -+ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); -+ -+ usb_put_function_instance(&opts->func_inst); -+} -+ -+static struct configfs_item_operations f_uac1_item_ops = { -+ .release = f_uac1_attr_release, -+}; -+ -+#define UAC1_INT_ATTRIBUTE(name) \ -+static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ -+ char *page) \ -+{ \ -+ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ -+ int result; \ -+ \ -+ mutex_lock(&opts->lock); \ -+ result = sprintf(page, "%u\n", opts->name); \ -+ mutex_unlock(&opts->lock); \ -+ \ -+ return result; \ -+} \ -+ \ -+static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ -+ const char *page, size_t len) \ -+{ \ -+ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ -+ int ret; \ -+ u32 num; \ -+ \ -+ mutex_lock(&opts->lock); \ -+ if (opts->refcnt) { \ -+ ret = -EBUSY; \ -+ goto end; \ -+ } \ -+ \ -+ ret = kstrtou32(page, 0, &num); \ -+ if (ret) \ -+ goto end; \ -+ \ -+ opts->name = num; \ -+ ret = len; \ -+ \ -+end: \ -+ mutex_unlock(&opts->lock); \ -+ return ret; \ -+} \ -+ \ -+CONFIGFS_ATTR(f_uac1_opts_, name) -+ -+UAC1_INT_ATTRIBUTE(req_buf_size); -+UAC1_INT_ATTRIBUTE(req_count); -+UAC1_INT_ATTRIBUTE(audio_buf_size); -+ -+#define UAC1_STR_ATTRIBUTE(name) \ -+static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ -+ char *page) \ -+{ \ -+ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ -+ int result; \ -+ \ -+ mutex_lock(&opts->lock); \ -+ result = sprintf(page, "%s\n", opts->name); \ -+ mutex_unlock(&opts->lock); \ -+ \ -+ return result; \ -+} \ -+ \ -+static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ -+ const char *page, size_t len) \ -+{ \ -+ struct f_uac1_legacy_opts *opts = to_f_uac1_opts(item); \ -+ int ret = -EBUSY; \ -+ char *tmp; \ -+ \ -+ mutex_lock(&opts->lock); \ -+ if (opts->refcnt) \ -+ goto end; \ -+ \ -+ tmp = kstrndup(page, len, GFP_KERNEL); \ -+ if (tmp) { \ -+ ret = -ENOMEM; \ -+ goto end; \ -+ } \ -+ if (opts->name##_alloc) \ -+ kfree(opts->name); \ -+ opts->name##_alloc = true; \ -+ opts->name = tmp; \ -+ ret = len; \ -+ \ -+end: \ -+ mutex_unlock(&opts->lock); \ -+ return ret; \ -+} \ -+ \ -+CONFIGFS_ATTR(f_uac1_opts_, name) -+ -+UAC1_STR_ATTRIBUTE(fn_play); -+UAC1_STR_ATTRIBUTE(fn_cap); -+UAC1_STR_ATTRIBUTE(fn_cntl); -+ -+static struct configfs_attribute *f_uac1_attrs[] = { -+ &f_uac1_opts_attr_req_buf_size, -+ &f_uac1_opts_attr_req_count, -+ &f_uac1_opts_attr_audio_buf_size, -+ &f_uac1_opts_attr_fn_play, -+ &f_uac1_opts_attr_fn_cap, -+ &f_uac1_opts_attr_fn_cntl, -+ NULL, -+}; -+ -+static const struct config_item_type f_uac1_func_type = { -+ .ct_item_ops = &f_uac1_item_ops, -+ .ct_attrs = f_uac1_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static void f_audio_free_inst(struct usb_function_instance *f) -+{ -+ struct f_uac1_legacy_opts *opts; -+ -+ opts = container_of(f, struct f_uac1_legacy_opts, func_inst); -+ if (opts->fn_play_alloc) -+ kfree(opts->fn_play); -+ if (opts->fn_cap_alloc) -+ kfree(opts->fn_cap); -+ if (opts->fn_cntl_alloc) -+ kfree(opts->fn_cntl); -+ kfree(opts); -+} -+ -+static struct usb_function_instance *f_audio_alloc_inst(void) -+{ -+ struct f_uac1_legacy_opts *opts; -+ -+ opts = kzalloc(sizeof(*opts), GFP_KERNEL); -+ if (!opts) -+ return ERR_PTR(-ENOMEM); -+ -+ mutex_init(&opts->lock); -+ opts->func_inst.free_func_inst = f_audio_free_inst; -+ -+ config_group_init_type_name(&opts->func_inst.group, "", -+ &f_uac1_func_type); -+ -+ opts->req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE; -+ opts->req_count = UAC1_REQ_COUNT; -+ opts->audio_buf_size = UAC1_AUDIO_BUF_SIZE; -+ opts->fn_play = FILE_PCM_PLAYBACK; -+ opts->fn_cap = FILE_PCM_CAPTURE; -+ opts->fn_cntl = FILE_CONTROL; -+ return &opts->func_inst; -+} -+ -+static void f_audio_free(struct usb_function *f) -+{ -+ struct f_audio *audio = func_to_audio(f); -+ struct f_uac1_legacy_opts *opts; -+ -+ gaudio_cleanup(&audio->card); -+ opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst); -+ kfree(audio); -+ mutex_lock(&opts->lock); -+ --opts->refcnt; -+ mutex_unlock(&opts->lock); -+} -+ -+static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) -+{ -+ usb_free_all_descriptors(f); -+} -+ -+static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) -+{ -+ struct f_audio *audio; -+ struct f_uac1_legacy_opts *opts; -+ -+ /* allocate and initialize one new instance */ -+ audio = kzalloc(sizeof(*audio), GFP_KERNEL); -+ if (!audio) -+ return ERR_PTR(-ENOMEM); -+ -+ audio->card.func.name = "g_audio"; -+ -+ opts = container_of(fi, struct f_uac1_legacy_opts, func_inst); -+ mutex_lock(&opts->lock); -+ ++opts->refcnt; -+ mutex_unlock(&opts->lock); -+ INIT_LIST_HEAD(&audio->play_queue); -+ spin_lock_init(&audio->lock); -+ -+ audio->card.func.bind = f_audio_bind; -+ audio->card.func.unbind = f_audio_unbind; -+ audio->card.func.set_alt = f_audio_set_alt; -+ audio->card.func.get_alt = f_audio_get_alt; -+ audio->card.func.setup = f_audio_setup; -+ audio->card.func.disable = f_audio_disable; -+ audio->card.func.free_func = f_audio_free; -+ -+ control_selector_init(audio); -+ -+ INIT_WORK(&audio->playback_work, f_audio_playback_work); -+ -+ return &audio->card.func; -+} -+ -+DECLARE_USB_FUNCTION_INIT(uac1_legacy, f_audio_alloc_inst, f_audio_alloc); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Bryan Wu"); ---- linux-4.9.37/drivers/usb/gadget/function/f_uac2.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/f_uac2.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1,30 +1,19 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * f_uac2.c -- USB Audio Class 2.0 Function - * - * Copyright (C) 2011 - * Yadwinder Singh (yadi.brar01@gmail.com) - * Jaswinder Singh (jaswinder.singh@linaro.org) -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. - */ - - #include - #include --#include - #include - --#include --#include --#include -- -+#include "u_audio.h" - #include "u_uac2.h" - --/* Keep everyone on toes */ --#define USB_XFERS 2 -- - /* - * The driver implements a simple UAC_2 topology. - * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture -@@ -33,12 +22,8 @@ - * controlled by two clock sources : - * CLK_5 := c_srate, and CLK_6 := p_srate - */ --#define USB_OUT_IT_ID 1 --#define IO_IN_IT_ID 2 --#define IO_OUT_OT_ID 3 --#define USB_IN_OT_ID 4 --#define USB_OUT_CLK_ID 5 --#define USB_IN_CLK_ID 6 -+#define USB_OUT_CLK_ID (out_clk_src_desc.bClockID) -+#define USB_IN_CLK_ID (in_clk_src_desc.bClockID) - - #define CONTROL_ABSENT 0 - #define CONTROL_RDONLY 1 -@@ -54,504 +39,26 @@ - #define UNFLW_CTRL 8 - #define OVFLW_CTRL 10 - --static const char *uac2_name = "snd_uac2"; -- --struct uac2_req { -- struct uac2_rtd_params *pp; /* parent param */ -- struct usb_request *req; --}; -- --struct uac2_rtd_params { -- struct snd_uac2_chip *uac2; /* parent chip */ -- bool ep_enabled; /* if the ep is enabled */ -- /* Size of the ring buffer */ -- size_t dma_bytes; -- unsigned char *dma_area; -- -- struct snd_pcm_substream *ss; -+#define EPIN_EN(_opts) ((_opts)->p_chmask != 0) -+#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) - -- /* Ring buffer */ -- ssize_t hw_ptr; -- -- void *rbuf; -- -- size_t period_size; -- -- unsigned max_psize; -- struct uac2_req ureq[USB_XFERS]; -- -- spinlock_t lock; -+struct f_uac2 { -+ struct g_audio g_audio; -+ u8 ac_intf, as_in_intf, as_out_intf; -+ u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */ - }; - --struct snd_uac2_chip { -- struct platform_device pdev; -- struct platform_driver pdrv; -- -- struct uac2_rtd_params p_prm; -- struct uac2_rtd_params c_prm; -- -- struct snd_card *card; -- struct snd_pcm *pcm; -- -- /* timekeeping for the playback endpoint */ -- unsigned int p_interval; -- unsigned int p_residue; -- -- /* pre-calculated values for playback iso completion */ -- unsigned int p_pktsize; -- unsigned int p_pktsize_residue; -- unsigned int p_framesize; --}; -- --#define BUFF_SIZE_MAX (PAGE_SIZE * 16) --#define PRD_SIZE_MAX PAGE_SIZE --#define MIN_PERIODS 4 -- --static struct snd_pcm_hardware uac2_pcm_hardware = { -- .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER -- | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID -- | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, -- .rates = SNDRV_PCM_RATE_CONTINUOUS, -- .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX, -- .buffer_bytes_max = BUFF_SIZE_MAX, -- .period_bytes_max = PRD_SIZE_MAX, -- .periods_min = MIN_PERIODS, --}; -- --struct audio_dev { -- u8 ac_intf, ac_alt; -- u8 as_out_intf, as_out_alt; -- u8 as_in_intf, as_in_alt; -- -- struct usb_ep *in_ep, *out_ep; -- struct usb_function func; -- -- /* The ALSA Sound Card it represents on the USB-Client side */ -- struct snd_uac2_chip uac2; --}; -- --static inline --struct audio_dev *func_to_agdev(struct usb_function *f) --{ -- return container_of(f, struct audio_dev, func); --} -- --static inline --struct audio_dev *uac2_to_agdev(struct snd_uac2_chip *u) -+static inline struct f_uac2 *func_to_uac2(struct usb_function *f) - { -- return container_of(u, struct audio_dev, uac2); -+ return container_of(f, struct f_uac2, g_audio.func); - } - - static inline --struct snd_uac2_chip *pdev_to_uac2(struct platform_device *p) --{ -- return container_of(p, struct snd_uac2_chip, pdev); --} -- --static inline --struct f_uac2_opts *agdev_to_uac2_opts(struct audio_dev *agdev) -+struct f_uac2_opts *g_audio_to_uac2_opts(struct g_audio *agdev) - { - return container_of(agdev->func.fi, struct f_uac2_opts, func_inst); - } - --static inline --uint num_channels(uint chanmask) --{ -- uint num = 0; -- -- while (chanmask) { -- num += (chanmask & 1); -- chanmask >>= 1; -- } -- -- return num; --} -- --static void --agdev_iso_complete(struct usb_ep *ep, struct usb_request *req) --{ -- unsigned pending; -- unsigned long flags; -- unsigned int hw_ptr; -- bool update_alsa = false; -- int status = req->status; -- struct uac2_req *ur = req->context; -- struct snd_pcm_substream *substream; -- struct uac2_rtd_params *prm = ur->pp; -- struct snd_uac2_chip *uac2 = prm->uac2; -- -- /* i/f shutting down */ -- if (!prm->ep_enabled || req->status == -ESHUTDOWN) -- return; -- -- /* -- * We can't really do much about bad xfers. -- * Afterall, the ISOCH xfers could fail legitimately. -- */ -- if (status) -- pr_debug("%s: iso_complete status(%d) %d/%d\n", -- __func__, status, req->actual, req->length); -- -- substream = prm->ss; -- -- /* Do nothing if ALSA isn't active */ -- if (!substream) -- goto exit; -- -- spin_lock_irqsave(&prm->lock, flags); -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -- /* -- * For each IN packet, take the quotient of the current data -- * rate and the endpoint's interval as the base packet size. -- * If there is a residue from this division, add it to the -- * residue accumulator. -- */ -- req->length = uac2->p_pktsize; -- uac2->p_residue += uac2->p_pktsize_residue; -- -- /* -- * Whenever there are more bytes in the accumulator than we -- * need to add one more sample frame, increase this packet's -- * size and decrease the accumulator. -- */ -- if (uac2->p_residue / uac2->p_interval >= uac2->p_framesize) { -- req->length += uac2->p_framesize; -- uac2->p_residue -= uac2->p_framesize * -- uac2->p_interval; -- } -- -- req->actual = req->length; -- } -- -- pending = prm->hw_ptr % prm->period_size; -- pending += req->actual; -- if (pending >= prm->period_size) -- update_alsa = true; -- -- hw_ptr = prm->hw_ptr; -- prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes; -- -- spin_unlock_irqrestore(&prm->lock, flags); -- -- /* Pack USB load in ALSA ring buffer */ -- pending = prm->dma_bytes - hw_ptr; -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -- if (unlikely(pending < req->actual)) { -- memcpy(req->buf, prm->dma_area + hw_ptr, pending); -- memcpy(req->buf + pending, prm->dma_area, -- req->actual - pending); -- } else { -- memcpy(req->buf, prm->dma_area + hw_ptr, req->actual); -- } -- } else { -- if (unlikely(pending < req->actual)) { -- memcpy(prm->dma_area + hw_ptr, req->buf, pending); -- memcpy(prm->dma_area, req->buf + pending, -- req->actual - pending); -- } else { -- memcpy(prm->dma_area + hw_ptr, req->buf, req->actual); -- } -- } -- --exit: -- if (usb_ep_queue(ep, req, GFP_ATOMIC)) -- dev_err(&uac2->pdev.dev, "%d Error!\n", __LINE__); -- -- if (update_alsa) -- snd_pcm_period_elapsed(substream); -- -- return; --} -- --static int --uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd) --{ -- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); -- struct uac2_rtd_params *prm; -- unsigned long flags; -- int err = 0; -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -- prm = &uac2->p_prm; -- else -- prm = &uac2->c_prm; -- -- spin_lock_irqsave(&prm->lock, flags); -- -- /* Reset */ -- prm->hw_ptr = 0; -- -- switch (cmd) { -- case SNDRV_PCM_TRIGGER_START: -- case SNDRV_PCM_TRIGGER_RESUME: -- prm->ss = substream; -- break; -- case SNDRV_PCM_TRIGGER_STOP: -- case SNDRV_PCM_TRIGGER_SUSPEND: -- prm->ss = NULL; -- break; -- default: -- err = -EINVAL; -- } -- -- spin_unlock_irqrestore(&prm->lock, flags); -- -- /* Clear buffer after Play stops */ -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss) -- memset(prm->rbuf, 0, prm->max_psize * USB_XFERS); -- -- return err; --} -- --static snd_pcm_uframes_t uac2_pcm_pointer(struct snd_pcm_substream *substream) --{ -- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); -- struct uac2_rtd_params *prm; -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -- prm = &uac2->p_prm; -- else -- prm = &uac2->c_prm; -- -- return bytes_to_frames(substream->runtime, prm->hw_ptr); --} -- --static int uac2_pcm_hw_params(struct snd_pcm_substream *substream, -- struct snd_pcm_hw_params *hw_params) --{ -- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); -- struct uac2_rtd_params *prm; -- int err; -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -- prm = &uac2->p_prm; -- else -- prm = &uac2->c_prm; -- -- err = snd_pcm_lib_malloc_pages(substream, -- params_buffer_bytes(hw_params)); -- if (err >= 0) { -- prm->dma_bytes = substream->runtime->dma_bytes; -- prm->dma_area = substream->runtime->dma_area; -- prm->period_size = params_period_bytes(hw_params); -- } -- -- return err; --} -- --static int uac2_pcm_hw_free(struct snd_pcm_substream *substream) --{ -- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); -- struct uac2_rtd_params *prm; -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -- prm = &uac2->p_prm; -- else -- prm = &uac2->c_prm; -- -- prm->dma_area = NULL; -- prm->dma_bytes = 0; -- prm->period_size = 0; -- -- return snd_pcm_lib_free_pages(substream); --} -- --static int uac2_pcm_open(struct snd_pcm_substream *substream) --{ -- struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); -- struct snd_pcm_runtime *runtime = substream->runtime; -- struct audio_dev *audio_dev; -- struct f_uac2_opts *opts; -- int p_ssize, c_ssize; -- int p_srate, c_srate; -- int p_chmask, c_chmask; -- -- audio_dev = uac2_to_agdev(uac2); -- opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); -- p_ssize = opts->p_ssize; -- c_ssize = opts->c_ssize; -- p_srate = opts->p_srate; -- c_srate = opts->c_srate; -- p_chmask = opts->p_chmask; -- c_chmask = opts->c_chmask; -- uac2->p_residue = 0; -- -- runtime->hw = uac2_pcm_hardware; -- -- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -- spin_lock_init(&uac2->p_prm.lock); -- runtime->hw.rate_min = p_srate; -- switch (p_ssize) { -- case 3: -- runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; -- break; -- case 4: -- runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; -- break; -- default: -- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; -- break; -- } -- runtime->hw.channels_min = num_channels(p_chmask); -- runtime->hw.period_bytes_min = 2 * uac2->p_prm.max_psize -- / runtime->hw.periods_min; -- } else { -- spin_lock_init(&uac2->c_prm.lock); -- runtime->hw.rate_min = c_srate; -- switch (c_ssize) { -- case 3: -- runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; -- break; -- case 4: -- runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; -- break; -- default: -- runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; -- break; -- } -- runtime->hw.channels_min = num_channels(c_chmask); -- runtime->hw.period_bytes_min = 2 * uac2->c_prm.max_psize -- / runtime->hw.periods_min; -- } -- -- runtime->hw.rate_max = runtime->hw.rate_min; -- runtime->hw.channels_max = runtime->hw.channels_min; -- -- snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); -- -- return 0; --} -- --/* ALSA cries without these function pointers */ --static int uac2_pcm_null(struct snd_pcm_substream *substream) --{ -- return 0; --} -- --static struct snd_pcm_ops uac2_pcm_ops = { -- .open = uac2_pcm_open, -- .close = uac2_pcm_null, -- .ioctl = snd_pcm_lib_ioctl, -- .hw_params = uac2_pcm_hw_params, -- .hw_free = uac2_pcm_hw_free, -- .trigger = uac2_pcm_trigger, -- .pointer = uac2_pcm_pointer, -- .prepare = uac2_pcm_null, --}; -- --static int snd_uac2_probe(struct platform_device *pdev) --{ -- struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); -- struct snd_card *card; -- struct snd_pcm *pcm; -- struct audio_dev *audio_dev; -- struct f_uac2_opts *opts; -- int err; -- int p_chmask, c_chmask; -- -- audio_dev = uac2_to_agdev(uac2); -- opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); -- p_chmask = opts->p_chmask; -- c_chmask = opts->c_chmask; -- -- /* Choose any slot, with no id */ -- err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); -- if (err < 0) -- return err; -- -- uac2->card = card; -- -- /* -- * Create first PCM device -- * Create a substream only for non-zero channel streams -- */ -- err = snd_pcm_new(uac2->card, "UAC2 PCM", 0, -- p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm); -- if (err < 0) -- goto snd_fail; -- -- strcpy(pcm->name, "UAC2 PCM"); -- pcm->private_data = uac2; -- -- uac2->pcm = pcm; -- -- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac2_pcm_ops); -- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac2_pcm_ops); -- -- strcpy(card->driver, "UAC2_Gadget"); -- strcpy(card->shortname, "UAC2_Gadget"); -- sprintf(card->longname, "UAC2_Gadget %i", pdev->id); -- -- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, -- snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); -- -- err = snd_card_register(card); -- if (!err) { -- platform_set_drvdata(pdev, card); -- return 0; -- } -- --snd_fail: -- snd_card_free(card); -- -- uac2->pcm = NULL; -- uac2->card = NULL; -- -- return err; --} -- --static int snd_uac2_remove(struct platform_device *pdev) --{ -- struct snd_card *card = platform_get_drvdata(pdev); -- -- if (card) -- return snd_card_free(card); -- -- return 0; --} -- --static void snd_uac2_release(struct device *dev) --{ -- dev_dbg(dev, "releasing '%s'\n", dev_name(dev)); --} -- --static int alsa_uac2_init(struct audio_dev *agdev) --{ -- struct snd_uac2_chip *uac2 = &agdev->uac2; -- int err; -- -- uac2->pdrv.probe = snd_uac2_probe; -- uac2->pdrv.remove = snd_uac2_remove; -- uac2->pdrv.driver.name = uac2_name; -- -- uac2->pdev.id = 0; -- uac2->pdev.name = uac2_name; -- uac2->pdev.dev.release = snd_uac2_release; -- -- /* Register snd_uac2 driver */ -- err = platform_driver_register(&uac2->pdrv); -- if (err) -- return err; -- -- /* Register snd_uac2 device */ -- err = platform_device_register(&uac2->pdev); -- if (err) -- platform_driver_unregister(&uac2->pdrv); -- -- return err; --} -- --static void alsa_uac2_exit(struct audio_dev *agdev) --{ -- struct snd_uac2_chip *uac2 = &agdev->uac2; -- -- platform_driver_unregister(&uac2->pdrv); -- platform_device_unregister(&uac2->pdev); --} -- -- - /* --------- USB Function Interface ------------- */ - - enum { -@@ -627,7 +134,7 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC2_CLOCK_SOURCE, -- .bClockID = USB_IN_CLK_ID, -+ /* .bClockID = DYNAMIC */ - .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, - .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), - .bAssocTerminal = 0, -@@ -639,7 +146,7 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC2_CLOCK_SOURCE, -- .bClockID = USB_OUT_CLK_ID, -+ /* .bClockID = DYNAMIC */ - .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, - .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), - .bAssocTerminal = 0, -@@ -651,12 +158,12 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_INPUT_TERMINAL, -- .bTerminalID = USB_OUT_IT_ID, -+ /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), - .bAssocTerminal = 0, -- .bCSourceID = USB_OUT_CLK_ID, -+ /* .bCSourceID = DYNAMIC */ - .iChannelNames = 0, -- .bmControls = (CONTROL_RDWR << COPY_CTRL), -+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), - }; - - /* Input Terminal for I/O-In */ -@@ -665,12 +172,12 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_INPUT_TERMINAL, -- .bTerminalID = IO_IN_IT_ID, -+ /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_UNDEFINED), - .bAssocTerminal = 0, -- .bCSourceID = USB_IN_CLK_ID, -+ /* .bCSourceID = DYNAMIC */ - .iChannelNames = 0, -- .bmControls = (CONTROL_RDWR << COPY_CTRL), -+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), - }; - - /* Ouput Terminal for USB_IN */ -@@ -679,12 +186,12 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, -- .bTerminalID = USB_IN_OT_ID, -+ /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), - .bAssocTerminal = 0, -- .bSourceID = IO_IN_IT_ID, -- .bCSourceID = USB_IN_CLK_ID, -- .bmControls = (CONTROL_RDWR << COPY_CTRL), -+ /* .bSourceID = DYNAMIC */ -+ /* .bCSourceID = DYNAMIC */ -+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), - }; - - /* Ouput Terminal for I/O-Out */ -@@ -693,12 +200,12 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, -- .bTerminalID = IO_OUT_OT_ID, -+ /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_UNDEFINED), - .bAssocTerminal = 0, -- .bSourceID = USB_OUT_IT_ID, -- .bCSourceID = USB_OUT_CLK_ID, -- .bmControls = (CONTROL_RDWR << COPY_CTRL), -+ /* .bSourceID = DYNAMIC */ -+ /* .bCSourceID = DYNAMIC */ -+ .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), - }; - - static struct uac2_ac_header_descriptor ac_hdr_desc = { -@@ -708,9 +215,10 @@ - .bDescriptorSubtype = UAC_MS_HEADER, - .bcdADC = cpu_to_le16(0x200), - .bCategory = UAC2_FUNCTION_IO_BOX, -- .wTotalLength = sizeof in_clk_src_desc + sizeof out_clk_src_desc -- + sizeof usb_out_it_desc + sizeof io_in_it_desc -- + sizeof usb_in_ot_desc + sizeof io_out_ot_desc, -+ .wTotalLength = cpu_to_le16(sizeof in_clk_src_desc -+ + sizeof out_clk_src_desc + sizeof usb_out_it_desc -+ + sizeof io_in_it_desc + sizeof usb_in_ot_desc -+ + sizeof io_out_ot_desc), - .bmControls = 0, - }; - -@@ -744,7 +252,7 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_AS_GENERAL, -- .bTerminalLink = USB_OUT_IT_ID, -+ /* .bTerminalLink = DYNAMIC */ - .bmControls = 0, - .bFormatType = UAC_FORMAT_TYPE_I, - .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM), -@@ -821,7 +329,7 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - - .bDescriptorSubtype = UAC_AS_GENERAL, -- .bTerminalLink = USB_IN_OT_ID, -+ /* .bTerminalLink = DYNAMIC */ - .bmControls = 0, - .bFormatType = UAC_FORMAT_TYPE_I, - .bmFormats = cpu_to_le32(UAC_FORMAT_TYPE_I_PCM), -@@ -929,40 +437,16 @@ - }; - - struct cntrl_cur_lay3 { -- __u32 dCUR; -+ __le32 dCUR; - }; - - struct cntrl_range_lay3 { -- __u16 wNumSubRanges; -- __u32 dMIN; -- __u32 dMAX; -- __u32 dRES; -+ __le16 wNumSubRanges; -+ __le32 dMIN; -+ __le32 dMAX; -+ __le32 dRES; - } __packed; - --static inline void --free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep) --{ -- struct snd_uac2_chip *uac2 = prm->uac2; -- int i; -- -- if (!prm->ep_enabled) -- return; -- -- prm->ep_enabled = false; -- -- for (i = 0; i < USB_XFERS; i++) { -- if (prm->ureq[i].req) { -- usb_ep_dequeue(ep, prm->ureq[i].req); -- usb_ep_free_request(ep, prm->ureq[i].req); -- prm->ureq[i].req = NULL; -- } -- } -- -- if (usb_ep_disable(ep)) -- dev_err(&uac2->pdev.dev, -- "%s:%d Error!\n", __func__, __LINE__); --} -- - static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, - struct usb_endpoint_descriptor *ep_desc, - unsigned int factor, bool is_playback) -@@ -986,15 +470,133 @@ - le16_to_cpu(ep_desc->wMaxPacketSize))); - } - -+/* Use macro to overcome line length limitation */ -+#define USBDHDR(p) (struct usb_descriptor_header *)(p) -+ -+static void setup_descriptor(struct f_uac2_opts *opts) -+{ -+ /* patch descriptors */ -+ int i = 1; /* ID's start with 1 */ -+ -+ if (EPOUT_EN(opts)) -+ usb_out_it_desc.bTerminalID = i++; -+ if (EPIN_EN(opts)) -+ io_in_it_desc.bTerminalID = i++; -+ if (EPOUT_EN(opts)) -+ io_out_ot_desc.bTerminalID = i++; -+ if (EPIN_EN(opts)) -+ usb_in_ot_desc.bTerminalID = i++; -+ if (EPOUT_EN(opts)) -+ out_clk_src_desc.bClockID = i++; -+ if (EPIN_EN(opts)) -+ in_clk_src_desc.bClockID = i++; -+ -+ usb_out_it_desc.bCSourceID = out_clk_src_desc.bClockID; -+ usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; -+ usb_in_ot_desc.bCSourceID = in_clk_src_desc.bClockID; -+ io_in_it_desc.bCSourceID = in_clk_src_desc.bClockID; -+ io_out_ot_desc.bCSourceID = out_clk_src_desc.bClockID; -+ io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; -+ as_out_hdr_desc.bTerminalLink = usb_out_it_desc.bTerminalID; -+ as_in_hdr_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; -+ -+ iad_desc.bInterfaceCount = 1; -+ ac_hdr_desc.wTotalLength = 0; -+ -+ if (EPIN_EN(opts)) { -+ u16 len = le16_to_cpu(ac_hdr_desc.wTotalLength); -+ -+ len += sizeof(in_clk_src_desc); -+ len += sizeof(usb_in_ot_desc); -+ len += sizeof(io_in_it_desc); -+ ac_hdr_desc.wTotalLength = cpu_to_le16(len); -+ iad_desc.bInterfaceCount++; -+ } -+ if (EPOUT_EN(opts)) { -+ u16 len = le16_to_cpu(ac_hdr_desc.wTotalLength); -+ -+ len += sizeof(out_clk_src_desc); -+ len += sizeof(usb_out_it_desc); -+ len += sizeof(io_out_ot_desc); -+ ac_hdr_desc.wTotalLength = cpu_to_le16(len); -+ iad_desc.bInterfaceCount++; -+ } -+ -+ i = 0; -+ fs_audio_desc[i++] = USBDHDR(&iad_desc); -+ fs_audio_desc[i++] = USBDHDR(&std_ac_if_desc); -+ fs_audio_desc[i++] = USBDHDR(&ac_hdr_desc); -+ if (EPIN_EN(opts)) -+ fs_audio_desc[i++] = USBDHDR(&in_clk_src_desc); -+ if (EPOUT_EN(opts)) { -+ fs_audio_desc[i++] = USBDHDR(&out_clk_src_desc); -+ fs_audio_desc[i++] = USBDHDR(&usb_out_it_desc); -+ } -+ if (EPIN_EN(opts)) { -+ fs_audio_desc[i++] = USBDHDR(&io_in_it_desc); -+ fs_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); -+ } -+ if (EPOUT_EN(opts)) { -+ fs_audio_desc[i++] = USBDHDR(&io_out_ot_desc); -+ fs_audio_desc[i++] = USBDHDR(&std_as_out_if0_desc); -+ fs_audio_desc[i++] = USBDHDR(&std_as_out_if1_desc); -+ fs_audio_desc[i++] = USBDHDR(&as_out_hdr_desc); -+ fs_audio_desc[i++] = USBDHDR(&as_out_fmt1_desc); -+ fs_audio_desc[i++] = USBDHDR(&fs_epout_desc); -+ fs_audio_desc[i++] = USBDHDR(&as_iso_out_desc); -+ } -+ if (EPIN_EN(opts)) { -+ fs_audio_desc[i++] = USBDHDR(&std_as_in_if0_desc); -+ fs_audio_desc[i++] = USBDHDR(&std_as_in_if1_desc); -+ fs_audio_desc[i++] = USBDHDR(&as_in_hdr_desc); -+ fs_audio_desc[i++] = USBDHDR(&as_in_fmt1_desc); -+ fs_audio_desc[i++] = USBDHDR(&fs_epin_desc); -+ fs_audio_desc[i++] = USBDHDR(&as_iso_in_desc); -+ } -+ fs_audio_desc[i] = NULL; -+ -+ i = 0; -+ hs_audio_desc[i++] = USBDHDR(&iad_desc); -+ hs_audio_desc[i++] = USBDHDR(&std_ac_if_desc); -+ hs_audio_desc[i++] = USBDHDR(&ac_hdr_desc); -+ if (EPIN_EN(opts)) -+ hs_audio_desc[i++] = USBDHDR(&in_clk_src_desc); -+ if (EPOUT_EN(opts)) { -+ hs_audio_desc[i++] = USBDHDR(&out_clk_src_desc); -+ hs_audio_desc[i++] = USBDHDR(&usb_out_it_desc); -+ } -+ if (EPIN_EN(opts)) { -+ hs_audio_desc[i++] = USBDHDR(&io_in_it_desc); -+ hs_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); -+ } -+ if (EPOUT_EN(opts)) { -+ hs_audio_desc[i++] = USBDHDR(&io_out_ot_desc); -+ hs_audio_desc[i++] = USBDHDR(&std_as_out_if0_desc); -+ hs_audio_desc[i++] = USBDHDR(&std_as_out_if1_desc); -+ hs_audio_desc[i++] = USBDHDR(&as_out_hdr_desc); -+ hs_audio_desc[i++] = USBDHDR(&as_out_fmt1_desc); -+ hs_audio_desc[i++] = USBDHDR(&hs_epout_desc); -+ hs_audio_desc[i++] = USBDHDR(&as_iso_out_desc); -+ } -+ if (EPIN_EN(opts)) { -+ hs_audio_desc[i++] = USBDHDR(&std_as_in_if0_desc); -+ hs_audio_desc[i++] = USBDHDR(&std_as_in_if1_desc); -+ hs_audio_desc[i++] = USBDHDR(&as_in_hdr_desc); -+ hs_audio_desc[i++] = USBDHDR(&as_in_fmt1_desc); -+ hs_audio_desc[i++] = USBDHDR(&hs_epin_desc); -+ hs_audio_desc[i++] = USBDHDR(&as_iso_in_desc); -+ } -+ hs_audio_desc[i] = NULL; -+} -+ - static int - afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) - { -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -+ struct f_uac2 *uac2 = func_to_uac2(fn); -+ struct g_audio *agdev = func_to_g_audio(fn); - struct usb_composite_dev *cdev = cfg->cdev; - struct usb_gadget *gadget = cdev->gadget; -- struct device *dev = &uac2->pdev.dev; -- struct uac2_rtd_params *prm; -+ struct device *dev = &gadget->dev; - struct f_uac2_opts *uac2_opts; - struct usb_string *us; - int ret; -@@ -1040,100 +642,103 @@ - dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return ret; - } -- std_ac_if_desc.bInterfaceNumber = ret; -- agdev->ac_intf = ret; -- agdev->ac_alt = 0; -+ iad_desc.bFirstInterface = ret; - -- ret = usb_interface_id(cfg, fn); -- if (ret < 0) { -- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -- return ret; -- } -- std_as_out_if0_desc.bInterfaceNumber = ret; -- std_as_out_if1_desc.bInterfaceNumber = ret; -- agdev->as_out_intf = ret; -- agdev->as_out_alt = 0; -- -- ret = usb_interface_id(cfg, fn); -- if (ret < 0) { -- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -- return ret; -- } -- std_as_in_if0_desc.bInterfaceNumber = ret; -- std_as_in_if1_desc.bInterfaceNumber = ret; -- agdev->as_in_intf = ret; -- agdev->as_in_alt = 0; -+ std_ac_if_desc.bInterfaceNumber = ret; -+ uac2->ac_intf = ret; -+ uac2->ac_alt = 0; - -- agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); -- if (!agdev->out_ep) { -- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -- return ret; -+ if (EPOUT_EN(uac2_opts)) { -+ ret = usb_interface_id(cfg, fn); -+ if (ret < 0) { -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ return ret; -+ } -+ std_as_out_if0_desc.bInterfaceNumber = ret; -+ std_as_out_if1_desc.bInterfaceNumber = ret; -+ uac2->as_out_intf = ret; -+ uac2->as_out_alt = 0; - } - -- agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); -- if (!agdev->in_ep) { -- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -- return ret; -+ if (EPIN_EN(uac2_opts)) { -+ ret = usb_interface_id(cfg, fn); -+ if (ret < 0) { -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ return ret; -+ } -+ std_as_in_if0_desc.bInterfaceNumber = ret; -+ std_as_in_if1_desc.bInterfaceNumber = ret; -+ uac2->as_in_intf = ret; -+ uac2->as_in_alt = 0; - } - -- uac2->p_prm.uac2 = uac2; -- uac2->c_prm.uac2 = uac2; -- - /* Calculate wMaxPacketSize according to audio bandwidth */ - set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); - set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); - set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); - set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); - -+ if (EPOUT_EN(uac2_opts)) { -+ agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); -+ if (!agdev->out_ep) { -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ return -ENODEV; -+ } -+ } -+ -+ if (EPIN_EN(uac2_opts)) { -+ agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); -+ if (!agdev->in_ep) { -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ return -ENODEV; -+ } -+ } -+ -+ agdev->in_ep_maxpsize = max_t(u16, -+ le16_to_cpu(fs_epin_desc.wMaxPacketSize), -+ le16_to_cpu(hs_epin_desc.wMaxPacketSize)); -+ agdev->out_ep_maxpsize = max_t(u16, -+ le16_to_cpu(fs_epout_desc.wMaxPacketSize), -+ le16_to_cpu(hs_epout_desc.wMaxPacketSize)); -+ - hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; - hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; - -+ setup_descriptor(uac2_opts); -+ - ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL, - NULL); - if (ret) - return ret; - -- prm = &agdev->uac2.c_prm; -- prm->max_psize = hs_epout_desc.wMaxPacketSize; -- prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); -- if (!prm->rbuf) { -- prm->max_psize = 0; -- goto err_free_descs; -- } -- -- prm = &agdev->uac2.p_prm; -- prm->max_psize = hs_epin_desc.wMaxPacketSize; -- prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL); -- if (!prm->rbuf) { -- prm->max_psize = 0; -- goto err; -- } -+ agdev->gadget = gadget; - -- ret = alsa_uac2_init(agdev); -+ agdev->params.p_chmask = uac2_opts->p_chmask; -+ agdev->params.p_srate = uac2_opts->p_srate; -+ agdev->params.p_ssize = uac2_opts->p_ssize; -+ agdev->params.c_chmask = uac2_opts->c_chmask; -+ agdev->params.c_srate = uac2_opts->c_srate; -+ agdev->params.c_ssize = uac2_opts->c_ssize; -+ agdev->params.req_number = uac2_opts->req_number; -+ ret = g_audio_setup(agdev, "UAC2 PCM", "UAC2_Gadget"); - if (ret) -- goto err; -+ goto err_free_descs; - return 0; - --err: -- kfree(agdev->uac2.p_prm.rbuf); -- kfree(agdev->uac2.c_prm.rbuf); - err_free_descs: - usb_free_all_descriptors(fn); -- return -EINVAL; -+ agdev->gadget = NULL; -+ return ret; - } - - static int - afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) - { - struct usb_composite_dev *cdev = fn->config->cdev; -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -+ struct f_uac2 *uac2 = func_to_uac2(fn); - struct usb_gadget *gadget = cdev->gadget; -- struct device *dev = &uac2->pdev.dev; -- struct usb_request *req; -- struct usb_ep *ep; -- struct uac2_rtd_params *prm; -- int req_len, i; -+ struct device *dev = &gadget->dev; -+ int ret = 0; - - /* No i/f has more than 2 alt settings */ - if (alt > 1) { -@@ -1141,7 +746,7 @@ - return -EINVAL; - } - -- if (intf == agdev->ac_intf) { -+ if (intf == uac2->ac_intf) { - /* Control I/f has only 1 AltSetting - 0 */ - if (alt) { - dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -@@ -1150,96 +755,42 @@ - return 0; - } - -- if (intf == agdev->as_out_intf) { -- ep = agdev->out_ep; -- prm = &uac2->c_prm; -- config_ep_by_speed(gadget, fn, ep); -- agdev->as_out_alt = alt; -- req_len = prm->max_psize; -- } else if (intf == agdev->as_in_intf) { -- struct f_uac2_opts *opts = agdev_to_uac2_opts(agdev); -- unsigned int factor, rate; -- struct usb_endpoint_descriptor *ep_desc; -- -- ep = agdev->in_ep; -- prm = &uac2->p_prm; -- config_ep_by_speed(gadget, fn, ep); -- agdev->as_in_alt = alt; -- -- /* pre-calculate the playback endpoint's interval */ -- if (gadget->speed == USB_SPEED_FULL) { -- ep_desc = &fs_epin_desc; -- factor = 1000; -- } else { -- ep_desc = &hs_epin_desc; -- factor = 8000; -- } -- -- /* pre-compute some values for iso_complete() */ -- uac2->p_framesize = opts->p_ssize * -- num_channels(opts->p_chmask); -- rate = opts->p_srate * uac2->p_framesize; -- uac2->p_interval = factor / (1 << (ep_desc->bInterval - 1)); -- uac2->p_pktsize = min_t(unsigned int, rate / uac2->p_interval, -- prm->max_psize); -+ if (intf == uac2->as_out_intf) { -+ uac2->as_out_alt = alt; - -- if (uac2->p_pktsize < prm->max_psize) -- uac2->p_pktsize_residue = rate % uac2->p_interval; -+ if (alt) -+ ret = u_audio_start_capture(&uac2->g_audio); - else -- uac2->p_pktsize_residue = 0; -+ u_audio_stop_capture(&uac2->g_audio); -+ } else if (intf == uac2->as_in_intf) { -+ uac2->as_in_alt = alt; - -- req_len = uac2->p_pktsize; -- uac2->p_residue = 0; -+ if (alt) -+ ret = u_audio_start_playback(&uac2->g_audio); -+ else -+ u_audio_stop_playback(&uac2->g_audio); - } else { - dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return -EINVAL; - } - -- if (alt == 0) { -- free_ep(prm, ep); -- return 0; -- } -- -- prm->ep_enabled = true; -- usb_ep_enable(ep); -- -- for (i = 0; i < USB_XFERS; i++) { -- if (!prm->ureq[i].req) { -- req = usb_ep_alloc_request(ep, GFP_ATOMIC); -- if (req == NULL) -- return -ENOMEM; -- -- prm->ureq[i].req = req; -- prm->ureq[i].pp = prm; -- -- req->zero = 0; -- req->context = &prm->ureq[i]; -- req->length = req_len; -- req->complete = agdev_iso_complete; -- req->buf = prm->rbuf + i * prm->max_psize; -- } -- -- if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC)) -- dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -- } -- -- return 0; -+ return ret; - } - - static int - afunc_get_alt(struct usb_function *fn, unsigned intf) - { -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -+ struct f_uac2 *uac2 = func_to_uac2(fn); -+ struct g_audio *agdev = func_to_g_audio(fn); - -- if (intf == agdev->ac_intf) -- return agdev->ac_alt; -- else if (intf == agdev->as_out_intf) -- return agdev->as_out_alt; -- else if (intf == agdev->as_in_intf) -- return agdev->as_in_alt; -+ if (intf == uac2->ac_intf) -+ return uac2->ac_alt; -+ else if (intf == uac2->as_out_intf) -+ return uac2->as_out_alt; -+ else if (intf == uac2->as_in_intf) -+ return uac2->as_in_alt; - else -- dev_err(&uac2->pdev.dev, -+ dev_err(&agdev->gadget->dev, - "%s:%d Invalid Interface %d!\n", - __func__, __LINE__, intf); - -@@ -1249,22 +800,19 @@ - static void - afunc_disable(struct usb_function *fn) - { -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -- -- free_ep(&uac2->p_prm, agdev->in_ep); -- agdev->as_in_alt = 0; -+ struct f_uac2 *uac2 = func_to_uac2(fn); - -- free_ep(&uac2->c_prm, agdev->out_ep); -- agdev->as_out_alt = 0; -+ uac2->as_in_alt = 0; -+ uac2->as_out_alt = 0; -+ u_audio_stop_capture(&uac2->g_audio); -+ u_audio_stop_playback(&uac2->g_audio); - } - - static int - in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) - { - struct usb_request *req = fn->config->cdev->req; -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -+ struct g_audio *agdev = func_to_g_audio(fn); - struct f_uac2_opts *opts; - u16 w_length = le16_to_cpu(cr->wLength); - u16 w_index = le16_to_cpu(cr->wIndex); -@@ -1274,7 +822,7 @@ - int value = -EOPNOTSUPP; - int p_srate, c_srate; - -- opts = agdev_to_uac2_opts(agdev); -+ opts = g_audio_to_uac2_opts(agdev); - p_srate = opts->p_srate; - c_srate = opts->c_srate; - -@@ -1283,9 +831,9 @@ - memset(&c, 0, sizeof(struct cntrl_cur_lay3)); - - if (entity_id == USB_IN_CLK_ID) -- c.dCUR = p_srate; -+ c.dCUR = cpu_to_le32(p_srate); - else if (entity_id == USB_OUT_CLK_ID) -- c.dCUR = c_srate; -+ c.dCUR = cpu_to_le32(c_srate); - - value = min_t(unsigned, w_length, sizeof c); - memcpy(req->buf, &c, value); -@@ -1293,7 +841,7 @@ - *(u8 *)req->buf = 1; - value = min_t(unsigned, w_length, 1); - } else { -- dev_err(&uac2->pdev.dev, -+ dev_err(&agdev->gadget->dev, - "%s:%d control_selector=%d TODO!\n", - __func__, __LINE__, control_selector); - } -@@ -1305,8 +853,7 @@ - in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) - { - struct usb_request *req = fn->config->cdev->req; -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -+ struct g_audio *agdev = func_to_g_audio(fn); - struct f_uac2_opts *opts; - u16 w_length = le16_to_cpu(cr->wLength); - u16 w_index = le16_to_cpu(cr->wIndex); -@@ -1317,26 +864,26 @@ - int value = -EOPNOTSUPP; - int p_srate, c_srate; - -- opts = agdev_to_uac2_opts(agdev); -+ opts = g_audio_to_uac2_opts(agdev); - p_srate = opts->p_srate; - c_srate = opts->c_srate; - - if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { - if (entity_id == USB_IN_CLK_ID) -- r.dMIN = p_srate; -+ r.dMIN = cpu_to_le32(p_srate); - else if (entity_id == USB_OUT_CLK_ID) -- r.dMIN = c_srate; -+ r.dMIN = cpu_to_le32(c_srate); - else - return -EOPNOTSUPP; - - r.dMAX = r.dMIN; - r.dRES = 0; -- r.wNumSubRanges = 1; -+ r.wNumSubRanges = cpu_to_le16(1); - - value = min_t(unsigned, w_length, sizeof r); - memcpy(req->buf, &r, value); - } else { -- dev_err(&uac2->pdev.dev, -+ dev_err(&agdev->gadget->dev, - "%s:%d control_selector=%d TODO!\n", - __func__, __LINE__, control_selector); - } -@@ -1371,13 +918,13 @@ - static int - setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr) - { -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -+ struct f_uac2 *uac2 = func_to_uac2(fn); -+ struct g_audio *agdev = func_to_g_audio(fn); - u16 w_index = le16_to_cpu(cr->wIndex); - u8 intf = w_index & 0xff; - -- if (intf != agdev->ac_intf) { -- dev_err(&uac2->pdev.dev, -+ if (intf != uac2->ac_intf) { -+ dev_err(&agdev->gadget->dev, - "%s:%d Error!\n", __func__, __LINE__); - return -EOPNOTSUPP; - } -@@ -1394,8 +941,7 @@ - afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) - { - struct usb_composite_dev *cdev = fn->config->cdev; -- struct audio_dev *agdev = func_to_agdev(fn); -- struct snd_uac2_chip *uac2 = &agdev->uac2; -+ struct g_audio *agdev = func_to_g_audio(fn); - struct usb_request *req = cdev->req; - u16 w_length = le16_to_cpu(cr->wLength); - int value = -EOPNOTSUPP; -@@ -1407,14 +953,15 @@ - if ((cr->bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE) - value = setup_rq_inf(fn, cr); - else -- dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); -+ dev_err(&agdev->gadget->dev, "%s:%d Error!\n", -+ __func__, __LINE__); - - if (value >= 0) { - req->length = value; - req->zero = value < w_length; - value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); - if (value < 0) { -- dev_err(&uac2->pdev.dev, -+ dev_err(&agdev->gadget->dev, - "%s:%d Error!\n", __func__, __LINE__); - req->status = 0; - } -@@ -1487,6 +1034,7 @@ - UAC2_ATTRIBUTE(c_chmask); - UAC2_ATTRIBUTE(c_srate); - UAC2_ATTRIBUTE(c_ssize); -+UAC2_ATTRIBUTE(req_number); - - static struct configfs_attribute *f_uac2_attrs[] = { - &f_uac2_opts_attr_p_chmask, -@@ -1495,6 +1043,7 @@ - &f_uac2_opts_attr_c_chmask, - &f_uac2_opts_attr_c_srate, - &f_uac2_opts_attr_c_ssize, -+ &f_uac2_opts_attr_req_number, - NULL, - }; - -@@ -1532,15 +1081,16 @@ - opts->c_chmask = UAC2_DEF_CCHMASK; - opts->c_srate = UAC2_DEF_CSRATE; - opts->c_ssize = UAC2_DEF_CSSIZE; -+ opts->req_number = UAC2_DEF_REQ_NUM; - return &opts->func_inst; - } - - static void afunc_free(struct usb_function *f) - { -- struct audio_dev *agdev; -+ struct g_audio *agdev; - struct f_uac2_opts *opts; - -- agdev = func_to_agdev(f); -+ agdev = func_to_g_audio(f); - opts = container_of(f->fi, struct f_uac2_opts, func_inst); - kfree(agdev); - mutex_lock(&opts->lock); -@@ -1550,26 +1100,21 @@ - - static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) - { -- struct audio_dev *agdev = func_to_agdev(f); -- struct uac2_rtd_params *prm; -+ struct g_audio *agdev = func_to_g_audio(f); - -- alsa_uac2_exit(agdev); -- -- prm = &agdev->uac2.p_prm; -- kfree(prm->rbuf); -- -- prm = &agdev->uac2.c_prm; -- kfree(prm->rbuf); -+ g_audio_cleanup(agdev); - usb_free_all_descriptors(f); -+ -+ agdev->gadget = NULL; - } - - static struct usb_function *afunc_alloc(struct usb_function_instance *fi) - { -- struct audio_dev *agdev; -+ struct f_uac2 *uac2; - struct f_uac2_opts *opts; - -- agdev = kzalloc(sizeof(*agdev), GFP_KERNEL); -- if (agdev == NULL) -+ uac2 = kzalloc(sizeof(*uac2), GFP_KERNEL); -+ if (uac2 == NULL) - return ERR_PTR(-ENOMEM); - - opts = container_of(fi, struct f_uac2_opts, func_inst); -@@ -1577,16 +1122,16 @@ - ++opts->refcnt; - mutex_unlock(&opts->lock); - -- agdev->func.name = "uac2_func"; -- agdev->func.bind = afunc_bind; -- agdev->func.unbind = afunc_unbind; -- agdev->func.set_alt = afunc_set_alt; -- agdev->func.get_alt = afunc_get_alt; -- agdev->func.disable = afunc_disable; -- agdev->func.setup = afunc_setup; -- agdev->func.free_func = afunc_free; -+ uac2->g_audio.func.name = "uac2_func"; -+ uac2->g_audio.func.bind = afunc_bind; -+ uac2->g_audio.func.unbind = afunc_unbind; -+ uac2->g_audio.func.set_alt = afunc_set_alt; -+ uac2->g_audio.func.get_alt = afunc_get_alt; -+ uac2->g_audio.func.disable = afunc_disable; -+ uac2->g_audio.func.setup = afunc_setup; -+ uac2->g_audio.func.free_func = afunc_free; - -- return &agdev->func; -+ return &uac2->g_audio.func; - } - - DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc); ---- linux-4.9.37/drivers/usb/gadget/function/f_uvc.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/f_uvc.c 2021-06-07 13:01:34.000000000 +0300 -@@ -594,6 +594,14 @@ - opts->streaming_maxpacket = clamp(opts->streaming_maxpacket, 1U, 3072U); - opts->streaming_maxburst = min(opts->streaming_maxburst, 15U); - -+ /* For SS, wMaxPacketSize has to be 1024 if bMaxBurst is not 0 */ -+ if (opts->streaming_maxburst && -+ (opts->streaming_maxpacket % 1024) != 0) { -+ opts->streaming_maxpacket = roundup(opts->streaming_maxpacket, 1024); -+ INFO(cdev, "overriding streaming_maxpacket to %d\n", -+ opts->streaming_maxpacket); -+ } -+ - /* Fill in the FS/HS/SS Video Streaming specific descriptors from the - * module parameters. - * -@@ -621,7 +629,7 @@ - - uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size); - uvc_ss_streaming_ep.bInterval = opts->streaming_interval; -- uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1; -+ uvc_ss_streaming_comp.bmAttributes = 1; - uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst; - uvc_ss_streaming_comp.wBytesPerInterval = - cpu_to_le16(max_packet_size * max_packet_mult * -@@ -720,7 +728,7 @@ - } - - /* Initialise video. */ -- ret = uvcg_video_init(&uvc->video); -+ ret = uvcg_video_init(&uvc->video, uvc); - if (ret < 0) - goto error; - -@@ -765,6 +773,11 @@ - struct uvc_color_matching_descriptor *md; - struct uvc_descriptor_header **ctl_cls; - -+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; -+ /* GUID of the UVC H.264 extension unit */ -+ static char extension_guid[] = {0x41, 0x76, 0x9E, 0xA2, 0x04, 0xDE, 0xE3, 0x47, -+ 0x8B, 0x2B, 0xF4, 0x34, 0x1A, 0xFF, 0x00, 0x3B}; -+ - opts = kzalloc(sizeof(*opts), GFP_KERNEL); - if (!opts) - return ERR_PTR(-ENOMEM); -@@ -799,6 +812,20 @@ - pd->bmControls[1] = 0; - pd->iProcessing = 0; - -+ ed = &opts->uvc_extension; -+ ed->bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 2); -+ ed->bDescriptorType = USB_DT_CS_INTERFACE; -+ ed->bDescriptorSubType = UVC_VC_EXTENSION_UNIT; -+ ed->bUnitID = 10; -+ memcpy(ed->guidExtensionCode, extension_guid, sizeof(extension_guid)); -+ ed->bNrInPins = 1; -+ ed->baSourceID[0] = 2; -+ ed->bNumControls = 15; -+ ed->bControlSize = 2; -+ ed->bmControls[0] = 1; -+ ed->bmControls[1] = 0; -+ ed->iExtension = 0; -+ - od = &opts->uvc_output_terminal; - od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE; - od->bDescriptorType = USB_DT_CS_INTERFACE; -@@ -822,8 +849,9 @@ - ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ - ctl_cls[1] = (struct uvc_descriptor_header *)cd; - ctl_cls[2] = (struct uvc_descriptor_header *)pd; -- ctl_cls[3] = (struct uvc_descriptor_header *)od; -- ctl_cls[4] = NULL; /* NULL-terminate */ -+ ctl_cls[3] = (struct uvc_descriptor_header *)ed; -+ ctl_cls[4] = (struct uvc_descriptor_header *)od; -+ ctl_cls[5] = NULL; /* NULL-terminate */ - opts->fs_control = - (const struct uvc_descriptor_header * const *)ctl_cls; - -@@ -832,13 +860,15 @@ - ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ - ctl_cls[1] = (struct uvc_descriptor_header *)cd; - ctl_cls[2] = (struct uvc_descriptor_header *)pd; -- ctl_cls[3] = (struct uvc_descriptor_header *)od; -- ctl_cls[4] = NULL; /* NULL-terminate */ -+ ctl_cls[3] = (struct uvc_descriptor_header *)ed; -+ ctl_cls[4] = (struct uvc_descriptor_header *)od; -+ ctl_cls[5] = NULL; /* NULL-terminate */ - opts->ss_control = - (const struct uvc_descriptor_header * const *)ctl_cls; - - opts->streaming_interval = 1; -- opts->streaming_maxpacket = 1024; -+ opts->streaming_maxpacket = 3072; -+ opts->streaming_maxburst = 15; - - uvcg_attach_configfs(opts); - return &opts->func_inst; ---- linux-4.9.37/drivers/usb/gadget/function/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -32,8 +32,11 @@ - obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o - usb_f_fs-y := f_fs.o - obj-$(CONFIG_USB_F_FS) += usb_f_fs.o --usb_f_uac1-y := f_uac1.o u_uac1.o -+obj-$(CONFIG_USB_U_AUDIO) += u_audio.o -+usb_f_uac1-y := f_uac1.o - obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o -+usb_f_uac1_legacy-y := f_uac1_legacy.o u_uac1_legacy.o -+obj-$(CONFIG_USB_F_UAC1_LEGACY) += usb_f_uac1_legacy.o - usb_f_uac2-y := f_uac2.o - obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o - usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_configfs.o ---- linux-4.9.37/drivers/usb/gadget/function/u_audio.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_audio.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,628 @@ -+/* -+ * ALSA audio utilities for Gadget stack -+ * -+ * Copyright (C) 2008 Bryan Wu -+ * Copyright (C) 2008 Analog Devices, Inc -+ * -+ * Enter bugs at http://blackfin.uclinux.org/ -+ * -+ * Licensed under the GPL-2 or later. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "u_audio.h" -+ -+#define BUFF_SIZE_MAX (PAGE_SIZE * 16) -+#define PRD_SIZE_MAX PAGE_SIZE -+#define MIN_PERIODS 4 -+ -+struct uac_req { -+ struct uac_rtd_params *pp; /* parent param */ -+ struct usb_request *req; -+}; -+ -+/* Runtime data params for one stream */ -+struct uac_rtd_params { -+ struct snd_uac_chip *uac; /* parent chip */ -+ bool ep_enabled; /* if the ep is enabled */ -+ -+ struct snd_pcm_substream *ss; -+ -+ /* Ring buffer */ -+ ssize_t hw_ptr; -+ -+ void *rbuf; -+ -+ unsigned max_psize; /* MaxPacketSize of endpoint */ -+ struct uac_req *ureq; -+ -+ spinlock_t lock; -+}; -+ -+struct snd_uac_chip { -+ struct g_audio *audio_dev; -+ -+ struct uac_rtd_params p_prm; -+ struct uac_rtd_params c_prm; -+ -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ -+ /* timekeeping for the playback endpoint */ -+ unsigned int p_interval; -+ unsigned int p_residue; -+ -+ /* pre-calculated values for playback iso completion */ -+ unsigned int p_pktsize; -+ unsigned int p_pktsize_residue; -+ unsigned int p_framesize; -+}; -+ -+static const struct snd_pcm_hardware uac_pcm_hardware = { -+ .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER -+ | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID -+ | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS, -+ .periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX, -+ .buffer_bytes_max = BUFF_SIZE_MAX, -+ .period_bytes_max = PRD_SIZE_MAX, -+ .periods_min = MIN_PERIODS, -+}; -+ -+static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) -+{ -+ unsigned pending; -+ unsigned long flags, flags2; -+ unsigned int hw_ptr; -+ int status = req->status; -+ struct uac_req *ur = req->context; -+ struct snd_pcm_substream *substream; -+ struct snd_pcm_runtime *runtime; -+ struct uac_rtd_params *prm = ur->pp; -+ struct snd_uac_chip *uac = prm->uac; -+ -+ /* i/f shutting down */ -+ if (!prm->ep_enabled || req->status == -ESHUTDOWN) -+ return; -+ -+ /* -+ * We can't really do much about bad xfers. -+ * Afterall, the ISOCH xfers could fail legitimately. -+ */ -+ if (status) -+ pr_debug("%s: iso_complete status(%d) %d/%d\n", -+ __func__, status, req->actual, req->length); -+ -+ substream = prm->ss; -+ -+ /* Do nothing if ALSA isn't active */ -+ if (!substream) -+ goto exit; -+ -+ snd_pcm_stream_lock_irqsave(substream, flags2); -+ -+ runtime = substream->runtime; -+ if (!runtime || !snd_pcm_running(substream)) { -+ snd_pcm_stream_unlock_irqrestore(substream, flags2); -+ goto exit; -+ } -+ -+ spin_lock_irqsave(&prm->lock, flags); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ /* -+ * For each IN packet, take the quotient of the current data -+ * rate and the endpoint's interval as the base packet size. -+ * If there is a residue from this division, add it to the -+ * residue accumulator. -+ */ -+ req->length = uac->p_pktsize; -+ uac->p_residue += uac->p_pktsize_residue; -+ -+ /* -+ * Whenever there are more bytes in the accumulator than we -+ * need to add one more sample frame, increase this packet's -+ * size and decrease the accumulator. -+ */ -+ if (uac->p_residue / uac->p_interval >= uac->p_framesize) { -+ req->length += uac->p_framesize; -+ uac->p_residue -= uac->p_framesize * -+ uac->p_interval; -+ } -+ -+ req->actual = req->length; -+ } -+ -+ hw_ptr = prm->hw_ptr; -+ -+ spin_unlock_irqrestore(&prm->lock, flags); -+ -+ /* Pack USB load in ALSA ring buffer */ -+ pending = runtime->dma_bytes - hw_ptr; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ if (unlikely(pending < req->actual)) { -+ memcpy(req->buf, runtime->dma_area + hw_ptr, pending); -+ memcpy(req->buf + pending, runtime->dma_area, -+ req->actual - pending); -+ } else { -+ memcpy(req->buf, runtime->dma_area + hw_ptr, -+ req->actual); -+ } -+ } else { -+ if (unlikely(pending < req->actual)) { -+ memcpy(runtime->dma_area + hw_ptr, req->buf, pending); -+ memcpy(runtime->dma_area, req->buf + pending, -+ req->actual - pending); -+ } else { -+ memcpy(runtime->dma_area + hw_ptr, req->buf, -+ req->actual); -+ } -+ } -+ -+ spin_lock_irqsave(&prm->lock, flags); -+ /* update hw_ptr after data is copied to memory */ -+ prm->hw_ptr = (hw_ptr + req->actual) % runtime->dma_bytes; -+ hw_ptr = prm->hw_ptr; -+ spin_unlock_irqrestore(&prm->lock, flags); -+ snd_pcm_stream_unlock_irqrestore(substream, flags2); -+ -+ if ((hw_ptr % snd_pcm_lib_period_bytes(substream)) < req->actual) -+ snd_pcm_period_elapsed(substream); -+ -+exit: -+ if (usb_ep_queue(ep, req, GFP_ATOMIC)) -+ dev_err(uac->card->dev, "%d Error!\n", __LINE__); -+} -+ -+static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -+{ -+ struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); -+ struct uac_rtd_params *prm; -+ struct g_audio *audio_dev; -+ struct uac_params *params; -+ unsigned long flags; -+ int err = 0; -+ -+ audio_dev = uac->audio_dev; -+ params = &audio_dev->params; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ prm = &uac->p_prm; -+ else -+ prm = &uac->c_prm; -+ -+ spin_lock_irqsave(&prm->lock, flags); -+ -+ /* Reset */ -+ prm->hw_ptr = 0; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ prm->ss = substream; -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ prm->ss = NULL; -+ break; -+ default: -+ err = -EINVAL; -+ } -+ -+ spin_unlock_irqrestore(&prm->lock, flags); -+ -+ /* Clear buffer after Play stops */ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss) -+ memset(prm->rbuf, 0, prm->max_psize * params->req_number); -+ -+ return err; -+} -+ -+static snd_pcm_uframes_t uac_pcm_pointer(struct snd_pcm_substream *substream) -+{ -+ struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); -+ struct uac_rtd_params *prm; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ prm = &uac->p_prm; -+ else -+ prm = &uac->c_prm; -+ -+ return bytes_to_frames(substream->runtime, prm->hw_ptr); -+} -+ -+static int uac_pcm_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *hw_params) -+{ -+ return snd_pcm_lib_malloc_pages(substream, -+ params_buffer_bytes(hw_params)); -+} -+ -+static int uac_pcm_hw_free(struct snd_pcm_substream *substream) -+{ -+ return snd_pcm_lib_free_pages(substream); -+} -+ -+static int uac_pcm_open(struct snd_pcm_substream *substream) -+{ -+ struct snd_uac_chip *uac = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct g_audio *audio_dev; -+ struct uac_params *params; -+ int p_ssize, c_ssize; -+ int p_srate, c_srate; -+ int p_chmask, c_chmask; -+ -+ audio_dev = uac->audio_dev; -+ params = &audio_dev->params; -+ p_ssize = params->p_ssize; -+ c_ssize = params->c_ssize; -+ p_srate = params->p_srate; -+ c_srate = params->c_srate; -+ p_chmask = params->p_chmask; -+ c_chmask = params->c_chmask; -+ uac->p_residue = 0; -+ -+ runtime->hw = uac_pcm_hardware; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ spin_lock_init(&uac->p_prm.lock); -+ runtime->hw.rate_min = p_srate; -+ switch (p_ssize) { -+ case 3: -+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; -+ break; -+ case 4: -+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; -+ break; -+ default: -+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; -+ break; -+ } -+ runtime->hw.channels_min = num_channels(p_chmask); -+ runtime->hw.period_bytes_min = 2 * uac->p_prm.max_psize -+ / runtime->hw.periods_min; -+ } else { -+ spin_lock_init(&uac->c_prm.lock); -+ runtime->hw.rate_min = c_srate; -+ switch (c_ssize) { -+ case 3: -+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE; -+ break; -+ case 4: -+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; -+ break; -+ default: -+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; -+ break; -+ } -+ runtime->hw.channels_min = num_channels(c_chmask); -+ runtime->hw.period_bytes_min = 2 * uac->c_prm.max_psize -+ / runtime->hw.periods_min; -+ } -+ -+ runtime->hw.rate_max = runtime->hw.rate_min; -+ runtime->hw.channels_max = runtime->hw.channels_min; -+ -+ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); -+ -+ return 0; -+} -+ -+/* ALSA cries without these function pointers */ -+static int uac_pcm_null(struct snd_pcm_substream *substream) -+{ -+ return 0; -+} -+ -+static const struct snd_pcm_ops uac_pcm_ops = { -+ .open = uac_pcm_open, -+ .close = uac_pcm_null, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = uac_pcm_hw_params, -+ .hw_free = uac_pcm_hw_free, -+ .trigger = uac_pcm_trigger, -+ .pointer = uac_pcm_pointer, -+ .prepare = uac_pcm_null, -+}; -+ -+static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep) -+{ -+ struct snd_uac_chip *uac = prm->uac; -+ struct g_audio *audio_dev; -+ struct uac_params *params; -+ int i; -+ -+ if (!prm->ep_enabled) -+ return; -+ -+ prm->ep_enabled = false; -+ -+ audio_dev = uac->audio_dev; -+ params = &audio_dev->params; -+ -+ for (i = 0; i < params->req_number; i++) { -+ if (prm->ureq[i].req) { -+ usb_ep_dequeue(ep, prm->ureq[i].req); -+ usb_ep_free_request(ep, prm->ureq[i].req); -+ prm->ureq[i].req = NULL; -+ } -+ } -+ -+ if (usb_ep_disable(ep)) -+ dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); -+} -+ -+ -+int u_audio_start_capture(struct g_audio *audio_dev) -+{ -+ struct snd_uac_chip *uac = audio_dev->uac; -+ struct usb_gadget *gadget = audio_dev->gadget; -+ struct device *dev = &gadget->dev; -+ struct usb_request *req; -+ struct usb_ep *ep; -+ struct uac_rtd_params *prm; -+ struct uac_params *params = &audio_dev->params; -+ int req_len, i; -+ -+ ep = audio_dev->out_ep; -+ prm = &uac->c_prm; -+ config_ep_by_speed(gadget, &audio_dev->func, ep); -+ req_len = prm->max_psize; -+ -+ prm->ep_enabled = true; -+ usb_ep_enable(ep); -+ -+ for (i = 0; i < params->req_number; i++) { -+ if (!prm->ureq[i].req) { -+ req = usb_ep_alloc_request(ep, GFP_ATOMIC); -+ if (req == NULL) -+ return -ENOMEM; -+ -+ prm->ureq[i].req = req; -+ prm->ureq[i].pp = prm; -+ -+ req->zero = 0; -+ req->context = &prm->ureq[i]; -+ req->length = req_len; -+ req->complete = u_audio_iso_complete; -+ req->buf = prm->rbuf + i * prm->max_psize; -+ } -+ -+ if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC)) -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(u_audio_start_capture); -+ -+void u_audio_stop_capture(struct g_audio *audio_dev) -+{ -+ struct snd_uac_chip *uac = audio_dev->uac; -+ -+ free_ep(&uac->c_prm, audio_dev->out_ep); -+} -+EXPORT_SYMBOL_GPL(u_audio_stop_capture); -+ -+int u_audio_start_playback(struct g_audio *audio_dev) -+{ -+ struct snd_uac_chip *uac = audio_dev->uac; -+ struct usb_gadget *gadget = audio_dev->gadget; -+ struct device *dev = &gadget->dev; -+ struct usb_request *req; -+ struct usb_ep *ep; -+ struct uac_rtd_params *prm; -+ struct uac_params *params = &audio_dev->params; -+ unsigned int factor, rate; -+ const struct usb_endpoint_descriptor *ep_desc; -+ int req_len, i; -+ -+ ep = audio_dev->in_ep; -+ prm = &uac->p_prm; -+ config_ep_by_speed(gadget, &audio_dev->func, ep); -+ -+ ep_desc = ep->desc; -+ -+ /* pre-calculate the playback endpoint's interval */ -+ if (gadget->speed == USB_SPEED_FULL) -+ factor = 1000; -+ else -+ factor = 8000; -+ -+ /* pre-compute some values for iso_complete() */ -+ uac->p_framesize = params->p_ssize * -+ num_channels(params->p_chmask); -+ rate = params->p_srate * uac->p_framesize; -+ uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); -+ uac->p_pktsize = min_t(unsigned int, rate / uac->p_interval, -+ prm->max_psize); -+ -+ if (uac->p_pktsize < prm->max_psize) -+ uac->p_pktsize_residue = rate % uac->p_interval; -+ else -+ uac->p_pktsize_residue = 0; -+ -+ req_len = uac->p_pktsize; -+ uac->p_residue = 0; -+ -+ prm->ep_enabled = true; -+ usb_ep_enable(ep); -+ -+ for (i = 0; i < params->req_number; i++) { -+ if (!prm->ureq[i].req) { -+ req = usb_ep_alloc_request(ep, GFP_ATOMIC); -+ if (req == NULL) -+ return -ENOMEM; -+ -+ prm->ureq[i].req = req; -+ prm->ureq[i].pp = prm; -+ -+ req->zero = 0; -+ req->context = &prm->ureq[i]; -+ req->length = req_len; -+ req->complete = u_audio_iso_complete; -+ req->buf = prm->rbuf + i * prm->max_psize; -+ } -+ -+ if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC)) -+ dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(u_audio_start_playback); -+ -+void u_audio_stop_playback(struct g_audio *audio_dev) -+{ -+ struct snd_uac_chip *uac = audio_dev->uac; -+ -+ free_ep(&uac->p_prm, audio_dev->in_ep); -+} -+EXPORT_SYMBOL_GPL(u_audio_stop_playback); -+ -+int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, -+ const char *card_name) -+{ -+ struct snd_uac_chip *uac; -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ struct uac_params *params; -+ int p_chmask, c_chmask; -+ int err; -+ -+ if (!g_audio) -+ return -EINVAL; -+ -+ uac = kzalloc(sizeof(*uac), GFP_KERNEL); -+ if (!uac) -+ return -ENOMEM; -+ g_audio->uac = uac; -+ uac->audio_dev = g_audio; -+ -+ params = &g_audio->params; -+ p_chmask = params->p_chmask; -+ c_chmask = params->c_chmask; -+ -+ if (c_chmask) { -+ struct uac_rtd_params *prm = &uac->c_prm; -+ -+ uac->c_prm.uac = uac; -+ prm->max_psize = g_audio->out_ep_maxpsize; -+ -+ prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req), -+ GFP_KERNEL); -+ if (!prm->ureq) { -+ err = -ENOMEM; -+ goto fail; -+ } -+ -+ prm->rbuf = kcalloc(params->req_number, prm->max_psize, -+ GFP_KERNEL); -+ if (!prm->rbuf) { -+ prm->max_psize = 0; -+ err = -ENOMEM; -+ goto fail; -+ } -+ } -+ -+ if (p_chmask) { -+ struct uac_rtd_params *prm = &uac->p_prm; -+ -+ uac->p_prm.uac = uac; -+ prm->max_psize = g_audio->in_ep_maxpsize; -+ -+ prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req), -+ GFP_KERNEL); -+ if (!prm->ureq) { -+ err = -ENOMEM; -+ goto fail; -+ } -+ -+ prm->rbuf = kcalloc(params->req_number, prm->max_psize, -+ GFP_KERNEL); -+ if (!prm->rbuf) { -+ prm->max_psize = 0; -+ err = -ENOMEM; -+ goto fail; -+ } -+ } -+ -+ /* Choose any slot, with no id */ -+ err = snd_card_new(&g_audio->gadget->dev, -+ -1, NULL, THIS_MODULE, 0, &card); -+ if (err < 0) -+ goto fail; -+ -+ uac->card = card; -+ -+ /* -+ * Create first PCM device -+ * Create a substream only for non-zero channel streams -+ */ -+ err = snd_pcm_new(uac->card, pcm_name, 0, -+ p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm); -+ if (err < 0) -+ goto snd_fail; -+ -+ strlcpy(pcm->name, pcm_name, sizeof(pcm->name)); -+ pcm->private_data = uac; -+ uac->pcm = pcm; -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops); -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops); -+ -+ strlcpy(card->driver, card_name, sizeof(card->driver)); -+ strlcpy(card->shortname, card_name, sizeof(card->shortname)); -+ sprintf(card->longname, "%s %i", card_name, card->dev->id); -+ -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, -+ snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX); -+ -+ err = snd_card_register(card); -+ -+ if (!err) -+ return 0; -+ -+snd_fail: -+ snd_card_free(card); -+fail: -+ kfree(uac->p_prm.ureq); -+ kfree(uac->c_prm.ureq); -+ kfree(uac->p_prm.rbuf); -+ kfree(uac->c_prm.rbuf); -+ kfree(uac); -+ -+ return err; -+} -+EXPORT_SYMBOL_GPL(g_audio_setup); -+ -+void g_audio_cleanup(struct g_audio *g_audio) -+{ -+ struct snd_uac_chip *uac; -+ struct snd_card *card; -+ -+ if (!g_audio || !g_audio->uac) -+ return; -+ -+ uac = g_audio->uac; -+ card = uac->card; -+ if (card) -+ snd_card_free(card); -+ -+ kfree(uac->p_prm.ureq); -+ kfree(uac->c_prm.ureq); -+ kfree(uac->p_prm.rbuf); -+ kfree(uac->c_prm.rbuf); -+ kfree(uac); -+} -+EXPORT_SYMBOL_GPL(g_audio_cleanup); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("USB gadget \"ALSA sound card\" utilities"); -+MODULE_AUTHOR("Ruslan Bilovol"); ---- linux-4.9.37/drivers/usb/gadget/function/u_audio.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_audio.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,88 @@ -+/* -+ * ALSA audio utilities for Gadget stack -+ * -+ * Copyright (C) 2008 Bryan Wu -+ * Copyright (C) 2008 Analog Devices, Inc -+ * -+ * Enter bugs at http://blackfin.uclinux.org/ -+ * -+ * Licensed under the GPL-2 or later. -+ */ -+ -+#ifndef __U_AUDIO_H -+#define __U_AUDIO_H -+ -+#include -+ -+struct uac_params { -+ /* playback */ -+ int p_chmask; /* channel mask */ -+ int p_srate; /* rate in Hz */ -+ int p_ssize; /* sample size */ -+ -+ /* capture */ -+ int c_chmask; /* channel mask */ -+ int c_srate; /* rate in Hz */ -+ int c_ssize; /* sample size */ -+ -+ int req_number; /* number of preallocated requests */ -+}; -+ -+struct g_audio { -+ struct usb_function func; -+ struct usb_gadget *gadget; -+ -+ struct usb_ep *in_ep; -+ struct usb_ep *out_ep; -+ -+ /* Max packet size for all in_ep possible speeds */ -+ unsigned int in_ep_maxpsize; -+ /* Max packet size for all out_ep possible speeds */ -+ unsigned int out_ep_maxpsize; -+ -+ /* The ALSA Sound Card it represents on the USB-Client side */ -+ struct snd_uac_chip *uac; -+ -+ struct uac_params params; -+}; -+ -+static inline struct g_audio *func_to_g_audio(struct usb_function *f) -+{ -+ return container_of(f, struct g_audio, func); -+} -+ -+static inline uint num_channels(uint chanmask) -+{ -+ uint num = 0; -+ -+ while (chanmask) { -+ num += (chanmask & 1); -+ chanmask >>= 1; -+ } -+ -+ return num; -+} -+ -+/* -+ * g_audio_setup - initialize one virtual ALSA sound card -+ * @g_audio: struct with filled params, in_ep_maxpsize, out_ep_maxpsize -+ * @pcm_name: the id string for a PCM instance of this sound card -+ * @card_name: name of this soundcard -+ * -+ * This sets up the single virtual ALSA sound card that may be exported by a -+ * gadget driver using this framework. -+ * -+ * Context: may sleep -+ * -+ * Returns zero on success, or a negative error on failure. -+ */ -+int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, -+ const char *card_name); -+void g_audio_cleanup(struct g_audio *g_audio); -+ -+int u_audio_start_capture(struct g_audio *g_audio); -+void u_audio_stop_capture(struct g_audio *g_audio); -+int u_audio_start_playback(struct g_audio *g_audio); -+void u_audio_stop_playback(struct g_audio *g_audio); -+ -+#endif /* __U_AUDIO_H */ ---- linux-4.9.37/drivers/usb/gadget/function/u_uac1.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_uac1.c 2021-06-07 13:01:34.000000000 +0300 -@@ -157,7 +157,6 @@ - struct gaudio_snd_dev *snd = &card->playback; - struct snd_pcm_substream *substream = snd->substream; - struct snd_pcm_runtime *runtime = substream->runtime; -- mm_segment_t old_fs; - ssize_t result; - snd_pcm_sframes_t frames; - -@@ -174,15 +173,11 @@ - } - - frames = bytes_to_frames(runtime, count); -- old_fs = get_fs(); -- set_fs(KERNEL_DS); -- result = snd_pcm_lib_write(snd->substream, (void __user *)buf, frames); -+ result = snd_pcm_kernel_write(snd->substream, buf, frames); - if (result != frames) { - ERROR(card, "Playback error: %d\n", (int)result); -- set_fs(old_fs); - goto try_again; - } -- set_fs(old_fs); - - return 0; - } ---- linux-4.9.37/drivers/usb/gadget/function/u_uac1.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_uac1.h 2021-06-07 13:01:34.000000000 +0300 -@@ -1,82 +1,38 @@ -+// SPDX-License-Identifier: GPL-2.0 - /* -- * u_uac1.h -- interface to USB gadget "ALSA AUDIO" utilities -+ * u_uac1.h - Utility definitions for UAC1 function - * -- * Copyright (C) 2008 Bryan Wu -- * Copyright (C) 2008 Analog Devices, Inc -- * -- * Enter bugs at http://blackfin.uclinux.org/ -- * -- * Licensed under the GPL-2 or later. -+ * Copyright (C) 2016 Ruslan Bilovol - */ - --#ifndef __U_AUDIO_H --#define __U_AUDIO_H -+#ifndef __U_UAC1_H -+#define __U_UAC1_H - --#include --#include --#include - #include - --#include --#include --#include -- --#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" --#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" --#define FILE_CONTROL "/dev/snd/controlC0" -- - #define UAC1_OUT_EP_MAX_PACKET_SIZE 200 --#define UAC1_REQ_COUNT 256 --#define UAC1_AUDIO_BUF_SIZE 48000 -+#define UAC1_DEF_CCHMASK 0x3 -+#define UAC1_DEF_CSRATE 48000 -+#define UAC1_DEF_CSSIZE 2 -+#define UAC1_DEF_PCHMASK 0x3 -+#define UAC1_DEF_PSRATE 48000 -+#define UAC1_DEF_PSSIZE 2 -+#define UAC1_DEF_REQ_NUM 2 - --/* -- * This represents the USB side of an audio card device, managed by a USB -- * function which provides control and stream interfaces. -- */ -- --struct gaudio_snd_dev { -- struct gaudio *card; -- struct file *filp; -- struct snd_pcm_substream *substream; -- int access; -- int format; -- int channels; -- int rate; --}; -- --struct gaudio { -- struct usb_function func; -- struct usb_gadget *gadget; -- -- /* ALSA sound device interfaces */ -- struct gaudio_snd_dev control; -- struct gaudio_snd_dev playback; -- struct gaudio_snd_dev capture; -- -- /* TODO */ --}; - - struct f_uac1_opts { - struct usb_function_instance func_inst; -- int req_buf_size; -- int req_count; -- int audio_buf_size; -- char *fn_play; -- char *fn_cap; -- char *fn_cntl; -+ int c_chmask; -+ int c_srate; -+ int c_ssize; -+ int p_chmask; -+ int p_srate; -+ int p_ssize; -+ int req_number; - unsigned bound:1; -- unsigned fn_play_alloc:1; -- unsigned fn_cap_alloc:1; -- unsigned fn_cntl_alloc:1; -+ - struct mutex lock; - int refcnt; - }; - --int gaudio_setup(struct gaudio *card); --void gaudio_cleanup(struct gaudio *the_card); -- --size_t u_audio_playback(struct gaudio *card, void *buf, size_t count); --int u_audio_get_playback_channels(struct gaudio *card); --int u_audio_get_playback_rate(struct gaudio *card); -- --#endif /* __U_AUDIO_H */ -+#endif /* __U_UAC1_H */ ---- linux-4.9.37/drivers/usb/gadget/function/u_uac1_legacy.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_uac1_legacy.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,315 @@ -+/* -+ * u_uac1.c -- ALSA audio utilities for Gadget stack -+ * -+ * Copyright (C) 2008 Bryan Wu -+ * Copyright (C) 2008 Analog Devices, Inc -+ * -+ * Enter bugs at http://blackfin.uclinux.org/ -+ * -+ * Licensed under the GPL-2 or later. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "u_uac1_legacy.h" -+ -+/* -+ * This component encapsulates the ALSA devices for USB audio gadget -+ */ -+ -+/*-------------------------------------------------------------------------*/ -+ -+/** -+ * Some ALSA internal helper functions -+ */ -+static int snd_interval_refine_set(struct snd_interval *i, unsigned int val) -+{ -+ struct snd_interval t; -+ t.empty = 0; -+ t.min = t.max = val; -+ t.openmin = t.openmax = 0; -+ t.integer = 1; -+ return snd_interval_refine(i, &t); -+} -+ -+static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, -+ snd_pcm_hw_param_t var, unsigned int val, -+ int dir) -+{ -+ int changed; -+ if (hw_is_mask(var)) { -+ struct snd_mask *m = hw_param_mask(params, var); -+ if (val == 0 && dir < 0) { -+ changed = -EINVAL; -+ snd_mask_none(m); -+ } else { -+ if (dir > 0) -+ val++; -+ else if (dir < 0) -+ val--; -+ changed = snd_mask_refine_set( -+ hw_param_mask(params, var), val); -+ } -+ } else if (hw_is_interval(var)) { -+ struct snd_interval *i = hw_param_interval(params, var); -+ if (val == 0 && dir < 0) { -+ changed = -EINVAL; -+ snd_interval_none(i); -+ } else if (dir == 0) -+ changed = snd_interval_refine_set(i, val); -+ else { -+ struct snd_interval t; -+ t.openmin = 1; -+ t.openmax = 1; -+ t.empty = 0; -+ t.integer = 0; -+ if (dir < 0) { -+ t.min = val - 1; -+ t.max = val; -+ } else { -+ t.min = val; -+ t.max = val+1; -+ } -+ changed = snd_interval_refine(i, &t); -+ } -+ } else -+ return -EINVAL; -+ if (changed) { -+ params->cmask |= 1 << var; -+ params->rmask |= 1 << var; -+ } -+ return changed; -+} -+/*-------------------------------------------------------------------------*/ -+ -+/** -+ * Set default hardware params -+ */ -+static int playback_default_hw_params(struct gaudio_snd_dev *snd) -+{ -+ struct snd_pcm_substream *substream = snd->substream; -+ struct snd_pcm_hw_params *params; -+ snd_pcm_sframes_t result; -+ -+ /* -+ * SNDRV_PCM_ACCESS_RW_INTERLEAVED, -+ * SNDRV_PCM_FORMAT_S16_LE -+ * CHANNELS: 2 -+ * RATE: 48000 -+ */ -+ snd->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED; -+ snd->format = SNDRV_PCM_FORMAT_S16_LE; -+ snd->channels = 2; -+ snd->rate = 48000; -+ -+ params = kzalloc(sizeof(*params), GFP_KERNEL); -+ if (!params) -+ return -ENOMEM; -+ -+ _snd_pcm_hw_params_any(params); -+ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS, -+ snd->access, 0); -+ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT, -+ snd->format, 0); -+ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS, -+ snd->channels, 0); -+ _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE, -+ snd->rate, 0); -+ -+ snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); -+ snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, params); -+ -+ result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); -+ if (result < 0) { -+ ERROR(snd->card, -+ "Preparing sound card failed: %d\n", (int)result); -+ kfree(params); -+ return result; -+ } -+ -+ /* Store the hardware parameters */ -+ snd->access = params_access(params); -+ snd->format = params_format(params); -+ snd->channels = params_channels(params); -+ snd->rate = params_rate(params); -+ -+ kfree(params); -+ -+ INFO(snd->card, -+ "Hardware params: access %x, format %x, channels %d, rate %d\n", -+ snd->access, snd->format, snd->channels, snd->rate); -+ -+ return 0; -+} -+ -+/** -+ * Playback audio buffer data by ALSA PCM device -+ */ -+size_t u_audio_playback(struct gaudio *card, void *buf, size_t count) -+{ -+ struct gaudio_snd_dev *snd = &card->playback; -+ struct snd_pcm_substream *substream = snd->substream; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ mm_segment_t old_fs; -+ ssize_t result; -+ snd_pcm_sframes_t frames; -+ -+try_again: -+ if (runtime->status->state == SNDRV_PCM_STATE_XRUN || -+ runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { -+ result = snd_pcm_kernel_ioctl(substream, -+ SNDRV_PCM_IOCTL_PREPARE, NULL); -+ if (result < 0) { -+ ERROR(card, "Preparing sound card failed: %d\n", -+ (int)result); -+ return result; -+ } -+ } -+ -+ frames = bytes_to_frames(runtime, count); -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ result = snd_pcm_lib_write(snd->substream, (void __user *)buf, frames); -+ if (result != frames) { -+ ERROR(card, "Playback error: %d\n", (int)result); -+ set_fs(old_fs); -+ goto try_again; -+ } -+ set_fs(old_fs); -+ -+ return 0; -+} -+ -+int u_audio_get_playback_channels(struct gaudio *card) -+{ -+ return card->playback.channels; -+} -+ -+int u_audio_get_playback_rate(struct gaudio *card) -+{ -+ return card->playback.rate; -+} -+ -+/** -+ * Open ALSA PCM and control device files -+ * Initial the PCM or control device -+ */ -+static int gaudio_open_snd_dev(struct gaudio *card) -+{ -+ struct snd_pcm_file *pcm_file; -+ struct gaudio_snd_dev *snd; -+ struct f_uac1_legacy_opts *opts; -+ char *fn_play, *fn_cap, *fn_cntl; -+ -+ opts = container_of(card->func.fi, struct f_uac1_legacy_opts, -+ func_inst); -+ fn_play = opts->fn_play; -+ fn_cap = opts->fn_cap; -+ fn_cntl = opts->fn_cntl; -+ -+ /* Open control device */ -+ snd = &card->control; -+ snd->filp = filp_open(fn_cntl, O_RDWR, 0); -+ if (IS_ERR(snd->filp)) { -+ int ret = PTR_ERR(snd->filp); -+ ERROR(card, "unable to open sound control device file: %s\n", -+ fn_cntl); -+ snd->filp = NULL; -+ return ret; -+ } -+ snd->card = card; -+ -+ /* Open PCM playback device and setup substream */ -+ snd = &card->playback; -+ snd->filp = filp_open(fn_play, O_WRONLY, 0); -+ if (IS_ERR(snd->filp)) { -+ int ret = PTR_ERR(snd->filp); -+ -+ ERROR(card, "No such PCM playback device: %s\n", fn_play); -+ snd->filp = NULL; -+ return ret; -+ } -+ pcm_file = snd->filp->private_data; -+ snd->substream = pcm_file->substream; -+ snd->card = card; -+ playback_default_hw_params(snd); -+ -+ /* Open PCM capture device and setup substream */ -+ snd = &card->capture; -+ snd->filp = filp_open(fn_cap, O_RDONLY, 0); -+ if (IS_ERR(snd->filp)) { -+ ERROR(card, "No such PCM capture device: %s\n", fn_cap); -+ snd->substream = NULL; -+ snd->card = NULL; -+ snd->filp = NULL; -+ } else { -+ pcm_file = snd->filp->private_data; -+ snd->substream = pcm_file->substream; -+ snd->card = card; -+ } -+ -+ return 0; -+} -+ -+/** -+ * Close ALSA PCM and control device files -+ */ -+static int gaudio_close_snd_dev(struct gaudio *gau) -+{ -+ struct gaudio_snd_dev *snd; -+ -+ /* Close control device */ -+ snd = &gau->control; -+ if (snd->filp) -+ filp_close(snd->filp, NULL); -+ -+ /* Close PCM playback device and setup substream */ -+ snd = &gau->playback; -+ if (snd->filp) -+ filp_close(snd->filp, NULL); -+ -+ /* Close PCM capture device and setup substream */ -+ snd = &gau->capture; -+ if (snd->filp) -+ filp_close(snd->filp, NULL); -+ -+ return 0; -+} -+ -+/** -+ * gaudio_setup - setup ALSA interface and preparing for USB transfer -+ * -+ * This sets up PCM, mixer or MIDI ALSA devices fore USB gadget using. -+ * -+ * Returns negative errno, or zero on success -+ */ -+int gaudio_setup(struct gaudio *card) -+{ -+ int ret; -+ -+ ret = gaudio_open_snd_dev(card); -+ if (ret) -+ ERROR(card, "we need at least one control device\n"); -+ -+ return ret; -+ -+} -+ -+/** -+ * gaudio_cleanup - remove ALSA device interface -+ * -+ * This is called to free all resources allocated by @gaudio_setup(). -+ */ -+void gaudio_cleanup(struct gaudio *the_card) -+{ -+ if (the_card) -+ gaudio_close_snd_dev(the_card); -+} -+ ---- linux-4.9.37/drivers/usb/gadget/function/u_uac1_legacy.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_uac1_legacy.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,82 @@ -+/* -+ * u_uac1.c -- ALSA audio utilities for Gadget stack -+ * -+ * Copyright (C) 2008 Bryan Wu -+ * Copyright (C) 2008 Analog Devices, Inc -+ * -+ * Enter bugs at http://blackfin.uclinux.org/ -+ * -+ * Licensed under the GPL-2 or later. -+ */ -+ -+#ifndef __U_UAC1_LEGACY_H -+#define __U_UAC1_LEGACY_H -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" -+#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" -+#define FILE_CONTROL "/dev/snd/controlC0" -+ -+#define UAC1_OUT_EP_MAX_PACKET_SIZE 200 -+#define UAC1_REQ_COUNT 256 -+#define UAC1_AUDIO_BUF_SIZE 48000 -+ -+/* -+ * This represents the USB side of an audio card device, managed by a USB -+ * function which provides control and stream interfaces. -+ */ -+ -+struct gaudio_snd_dev { -+ struct gaudio *card; -+ struct file *filp; -+ struct snd_pcm_substream *substream; -+ int access; -+ int format; -+ int channels; -+ int rate; -+}; -+ -+struct gaudio { -+ struct usb_function func; -+ struct usb_gadget *gadget; -+ -+ /* ALSA sound device interfaces */ -+ struct gaudio_snd_dev control; -+ struct gaudio_snd_dev playback; -+ struct gaudio_snd_dev capture; -+ -+ /* TODO */ -+}; -+ -+struct f_uac1_legacy_opts { -+ struct usb_function_instance func_inst; -+ int req_buf_size; -+ int req_count; -+ int audio_buf_size; -+ char *fn_play; -+ char *fn_cap; -+ char *fn_cntl; -+ unsigned bound:1; -+ unsigned fn_play_alloc:1; -+ unsigned fn_cap_alloc:1; -+ unsigned fn_cntl_alloc:1; -+ struct mutex lock; -+ int refcnt; -+}; -+ -+int gaudio_setup(struct gaudio *card); -+void gaudio_cleanup(struct gaudio *the_card); -+ -+size_t u_audio_playback(struct gaudio *card, void *buf, size_t count); -+int u_audio_get_playback_channels(struct gaudio *card); -+int u_audio_get_playback_rate(struct gaudio *card); -+ -+#endif /* __U_UAC1_LEGACY_H */ ---- linux-4.9.37/drivers/usb/gadget/function/u_uac2.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_uac2.h 2021-06-07 13:01:34.000000000 +0300 -@@ -1,3 +1,4 @@ -+// SPDX-License-Identifier: GPL-2.0 - /* - * u_uac2.h - * -@@ -7,10 +8,6 @@ - * http://www.samsung.com - * - * Author: Andrzej Pietrasiewicz -- * -- * 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 U_UAC2_H -@@ -24,6 +21,7 @@ - #define UAC2_DEF_CCHMASK 0x3 - #define UAC2_DEF_CSRATE 64000 - #define UAC2_DEF_CSSIZE 2 -+#define UAC2_DEF_REQ_NUM 2 - - struct f_uac2_opts { - struct usb_function_instance func_inst; -@@ -33,6 +31,7 @@ - int c_chmask; - int c_srate; - int c_ssize; -+ int req_number; - bool bound; - - struct mutex lock; ---- linux-4.9.37/drivers/usb/gadget/function/u_uvc.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/u_uvc.h 2021-06-07 13:01:34.000000000 +0300 -@@ -52,6 +52,7 @@ - struct uvc_processing_unit_descriptor uvc_processing; - struct uvc_output_terminal_descriptor uvc_output_terminal; - struct uvc_color_matching_descriptor uvc_color_matching; -+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_extension; - - /* - * Control descriptors pointers arrays for full-/high-speed and -@@ -60,8 +61,8 @@ - * descriptors. Used by configfs only, must not be touched by legacy - * gadgets. - */ -- struct uvc_descriptor_header *uvc_fs_control_cls[5]; -- struct uvc_descriptor_header *uvc_ss_control_cls[5]; -+ struct uvc_descriptor_header *uvc_fs_control_cls[6]; -+ struct uvc_descriptor_header *uvc_ss_control_cls[6]; - - /* - * Streaming descriptors for full-speed, high-speed and super-speed. ---- linux-4.9.37/drivers/usb/gadget/function/uvc_configfs.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/uvc_configfs.c 2021-06-07 13:01:34.000000000 +0300 -@@ -254,7 +254,49 @@ - return result; - } - --UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls); -+static ssize_t uvcg_default_processing_bm_controls_store( -+ struct config_item *item, const char *page, size_t len) -+{ -+ struct uvcg_default_processing *dp = to_uvcg_default_processing(item); -+ struct f_uvc_opts *opts; -+ struct config_item *opts_item; -+ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; -+ struct uvc_processing_unit_descriptor *pd; -+ int ret, i; -+ const char *pg = page; -+ /* sign, base 2 representation, newline, terminator */ -+ char buf[1 + sizeof(u8) * 8 + 1 + 1]; -+ int idx; -+ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -+ -+ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; -+ opts = to_f_uvc_opts(opts_item); -+ pd = &opts->uvc_processing; -+ -+ idx = 0; -+ while (pg - page < len) { -+ i = 0; -+ while (i < sizeof(buf) && (pg - page < len) && -+ *pg != '\0' && *pg != '\n') -+ buf[i++] = *pg++; -+ while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) -+ ++pg; -+ buf[i] = '\0'; -+ ret = kstrtou8(buf, 0, &pd->bmControls[idx++]); -+ if (ret < 0) -+ goto end; -+ if (idx >= pd->bControlSize) -+ break; -+ } -+ ret = len; -+end: -+ mutex_unlock(&opts->lock); -+ mutex_unlock(su_mutex); -+ return ret; -+} -+ -+UVC_ATTR(uvcg_default_processing_, bm_controls, bmControls); - - static struct configfs_attribute *uvcg_default_processing_attrs[] = { - &uvcg_default_processing_attr_b_unit_id, -@@ -281,6 +323,110 @@ - .ct_owner = THIS_MODULE, - }; - -+/* control/extension/default */ -+static struct uvcg_default_extension { -+ struct config_group group; -+} uvcg_default_extension; -+ -+static inline struct uvcg_default_extension -+*to_uvcg_default_extension(struct config_item *item) -+{ -+ return container_of(to_config_group(item), -+ struct uvcg_default_extension, group); -+} -+ -+#define UVCG_DEFAULT_EXTENSION_ATTR(cname, aname, conv) \ -+static ssize_t uvcg_default_extension_##cname##_show( \ -+ struct config_item *item, char *page) \ -+{ \ -+ struct uvcg_default_extension *dp = to_uvcg_default_extension(item); \ -+ struct f_uvc_opts *opts; \ -+ struct config_item *opts_item; \ -+ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; \ -+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; \ -+ int result; \ -+ \ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ -+ \ -+ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; \ -+ opts = to_f_uvc_opts(opts_item); \ -+ ed = &opts->uvc_extension; \ -+ \ -+ mutex_lock(&opts->lock); \ -+ result = sprintf(page, "%d\n", conv(ed->aname)); \ -+ mutex_unlock(&opts->lock); \ -+ \ -+ mutex_unlock(su_mutex); \ -+ return result; \ -+} \ -+ \ -+UVC_ATTR_RO(uvcg_default_extension_, cname, aname) -+ -+#define identity_conv(x) (x) -+ -+UVCG_DEFAULT_EXTENSION_ATTR(b_unit_id, bUnitID, identity_conv); -+UVCG_DEFAULT_EXTENSION_ATTR(b_num_input_pins, bNrInPins, identity_conv); -+UVCG_DEFAULT_EXTENSION_ATTR(i_extension, iExtension, identity_conv); -+ -+#undef identity_conv -+ -+#undef UVCG_DEFAULT_EXTENSION_ATTR -+ -+static ssize_t uvcg_default_extension_bm_controls_show( -+ struct config_item *item, char *page) -+{ -+ struct uvcg_default_extension *dp = to_uvcg_default_extension(item); -+ struct f_uvc_opts *opts; -+ struct config_item *opts_item; -+ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; -+ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; -+ int result, i; -+ char *pg = page; -+ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -+ -+ opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent; -+ opts = to_f_uvc_opts(opts_item); -+ ed = &opts->uvc_extension; -+ -+ mutex_lock(&opts->lock); -+ for (result = 0, i = 0; i < ed->bControlSize; ++i) { -+ result += sprintf(pg, "%d\n", ed->bmControls[i]); -+ pg = page + result; -+ } -+ mutex_unlock(&opts->lock); -+ -+ mutex_unlock(su_mutex); -+ -+ return result; -+} -+ -+UVC_ATTR_RO(uvcg_default_extension_, bm_controls, bmControls); -+ -+static struct configfs_attribute *uvcg_default_extension_attrs[] = { -+ &uvcg_default_extension_attr_b_unit_id, -+ &uvcg_default_extension_attr_b_num_input_pins, -+ &uvcg_default_extension_attr_bm_controls, -+ &uvcg_default_extension_attr_i_extension, -+ NULL, -+}; -+ -+static struct config_item_type uvcg_default_extension_type = { -+ .ct_attrs = uvcg_default_extension_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+/* struct uvcg_extension {}; */ -+ -+/* control/extension */ -+static struct uvcg_extension_grp { -+ struct config_group group; -+} uvcg_extension_grp; -+ -+static struct config_item_type uvcg_extension_grp_type = { -+ .ct_owner = THIS_MODULE, -+}; -+ - /* control/terminal/camera/default */ - static struct uvcg_default_camera { - struct config_group group; -@@ -368,7 +514,50 @@ - return result; - } - --UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls); -+static ssize_t uvcg_default_camera_bm_controls_store( -+ struct config_item *item, const char *page, size_t len) -+{ -+ struct uvcg_default_camera *dc = to_uvcg_default_camera(item); -+ struct f_uvc_opts *opts; -+ struct config_item *opts_item; -+ struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; -+ struct uvc_camera_terminal_descriptor *cd; -+ int ret, i; -+ const char *pg = page; -+ /* sign, base 2 representation, newline, terminator */ -+ char buf[1 + sizeof(u8) * 8 + 1 + 1]; -+ int idx; -+ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -+ -+ opts_item = dc->group.cg_item.ci_parent->ci_parent->ci_parent-> -+ ci_parent; -+ opts = to_f_uvc_opts(opts_item); -+ cd = &opts->uvc_camera_terminal; -+ -+ idx = 0; -+ while (pg - page < len) { -+ i = 0; -+ while (i < sizeof(buf) && (pg - page < len) && -+ *pg != '\0' && *pg != '\n') -+ buf[i++] = *pg++; -+ while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) -+ ++pg; -+ buf[i] = '\0'; -+ ret = kstrtou8(buf, 0, &cd->bmControls[idx++]); -+ if (ret < 0) -+ goto end; -+ if (idx >= cd->bControlSize) -+ break; -+ } -+ ret = len; -+end: -+ mutex_unlock(&opts->lock); -+ mutex_unlock(su_mutex); -+ return ret; -+} -+ -+UVC_ATTR(uvcg_default_camera_, bm_controls, bmControls); - - static struct configfs_attribute *uvcg_default_camera_attrs[] = { - &uvcg_default_camera_attr_b_terminal_id, -@@ -626,14 +815,21 @@ - struct config_group group; - } uvcg_mjpeg_grp; - -+/* streaming/frame_based */ -+static struct uvcg_frame_based_format_grp { -+ struct config_group group; -+} uvcg_frame_based_format_grp; -+ - static struct config_item *fmt_parent[] = { - &uvcg_uncompressed_grp.group.cg_item, - &uvcg_mjpeg_grp.group.cg_item, -+ &uvcg_frame_based_format_grp.group.cg_item, - }; - - enum uvcg_format_type { - UVCG_UNCOMPRESSED = 0, - UVCG_MJPEG, -+ UVCG_FRAME_FRAME_BASED, - }; - - struct uvcg_format { -@@ -1203,6 +1399,7 @@ - return ERR_PTR(-EINVAL); - } - ++fmt->num_frames; -+ h->frame.b_frame_index = fmt->num_frames; - mutex_unlock(&opts->lock); - - config_item_init_type_name(&h->item, name, &uvcg_frame_type); -@@ -1227,6 +1424,263 @@ - mutex_unlock(&opts->lock); - } - -+struct uvcg_frame_based_frame { -+ struct { -+ u8 b_length; -+ u8 b_descriptor_type; -+ u8 b_descriptor_subtype; -+ u8 b_frame_index; -+ u8 bm_capabilities; -+ u16 w_width; -+ u16 w_height; -+ u32 dw_min_bit_rate; -+ u32 dw_max_bit_rate; -+ u32 dw_default_frame_interval; -+ u8 b_frame_interval_type; -+ u32 dw_bytes_per_line; -+ } __attribute__((packed)) frame; -+ u32 *dw_frame_interval; -+ enum uvcg_format_type fmt_type; -+ struct config_item item; -+}; -+ -+static struct uvcg_frame_based_frame *to_uvcg_frame_based_frame(struct config_item *item) -+{ -+ return container_of(item, struct uvcg_frame_based_frame, item); -+} -+ -+#define UVCG_FRAME_BASED_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \ -+static ssize_t uvcg_frame_based_frame_##cname##_show(struct config_item *item, char *page)\ -+{ \ -+ struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item); \ -+ struct f_uvc_opts *opts; \ -+ struct config_item *opts_item; \ -+ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ -+ int result; \ -+ \ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ -+ \ -+ opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ -+ opts = to_f_uvc_opts(opts_item); \ -+ \ -+ mutex_lock(&opts->lock); \ -+ result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \ -+ mutex_unlock(&opts->lock); \ -+ \ -+ mutex_unlock(su_mutex); \ -+ return result; \ -+} \ -+ \ -+static ssize_t uvcg_frame_based_frame_##cname##_store(struct config_item *item, \ -+ const char *page, size_t len)\ -+{ \ -+ struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item); \ -+ struct f_uvc_opts *opts; \ -+ struct config_item *opts_item; \ -+ struct uvcg_format *fmt; \ -+ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ -+ int ret; \ -+ u##bits num; \ -+ \ -+ ret = kstrtou##bits(page, 0, &num); \ -+ if (ret) \ -+ return ret; \ -+ \ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ -+ \ -+ opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ -+ opts = to_f_uvc_opts(opts_item); \ -+ fmt = to_uvcg_format(f->item.ci_parent); \ -+ \ -+ mutex_lock(&opts->lock); \ -+ if (fmt->linked || opts->refcnt) { \ -+ ret = -EBUSY; \ -+ goto end; \ -+ } \ -+ \ -+ f->frame.cname = to_little_endian(num); \ -+ ret = len; \ -+end: \ -+ mutex_unlock(&opts->lock); \ -+ mutex_unlock(su_mutex); \ -+ return ret; \ -+} \ -+ \ -+UVC_ATTR(uvcg_frame_based_frame_, cname, aname); -+ -+#define noop_conversion(x) (x) -+ -+UVCG_FRAME_BASED_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion, -+ noop_conversion, 8); -+UVCG_FRAME_BASED_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16); -+UVCG_FRAME_BASED_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16); -+UVCG_FRAME_BASED_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32); -+UVCG_FRAME_BASED_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32); -+UVCG_FRAME_BASED_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, -+ le32_to_cpu, cpu_to_le32, 32); -+UVCG_FRAME_BASED_FRAME_ATTR(dw_bytes_per_line, dwBytesPerLine, -+ le32_to_cpu, cpu_to_le32, 32); -+ -+#undef noop_conversion -+ -+#undef UVCG_FRAME_BASED_FRAME_ATTR -+ -+static ssize_t uvcg_frame_based_frame_dw_frame_interval_show(struct config_item *item, -+ char *page) -+{ -+ struct uvcg_frame_based_frame *frm = to_uvcg_frame_based_frame(item); -+ struct f_uvc_opts *opts; -+ struct config_item *opts_item; -+ struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; -+ int result, i; -+ char *pg = page; -+ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -+ -+ opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; -+ opts = to_f_uvc_opts(opts_item); -+ -+ mutex_lock(&opts->lock); -+ for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { -+ result += sprintf(pg, "%d\n", -+ le32_to_cpu(frm->dw_frame_interval[i])); -+ pg = page + result; -+ } -+ mutex_unlock(&opts->lock); -+ -+ mutex_unlock(su_mutex); -+ return result; -+} -+ -+static ssize_t uvcg_frame_based_frame_dw_frame_interval_store(struct config_item *item, -+ const char *page, size_t len) -+{ -+ struct uvcg_frame_based_frame *ch = to_uvcg_frame_based_frame(item); -+ struct f_uvc_opts *opts; -+ struct config_item *opts_item; -+ struct uvcg_format *fmt; -+ struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; -+ int ret = 0, n = 0; -+ u32 *frm_intrv, *tmp; -+ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -+ -+ opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; -+ opts = to_f_uvc_opts(opts_item); -+ fmt = to_uvcg_format(ch->item.ci_parent); -+ -+ mutex_lock(&opts->lock); -+ if (fmt->linked || opts->refcnt) { -+ ret = -EBUSY; -+ goto end; -+ } -+ -+ ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); -+ if (ret) -+ goto end; -+ -+ tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); -+ if (!frm_intrv) { -+ ret = -ENOMEM; -+ goto end; -+ } -+ -+ ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); -+ if (ret) { -+ kfree(frm_intrv); -+ goto end; -+ } -+ -+ kfree(ch->dw_frame_interval); -+ ch->dw_frame_interval = frm_intrv; -+ ch->frame.b_frame_interval_type = n; -+ ret = len; -+ -+end: -+ mutex_unlock(&opts->lock); -+ mutex_unlock(su_mutex); -+ return ret; -+} -+ -+UVC_ATTR(uvcg_frame_based_frame_, dw_frame_interval, dwFrameInterval); -+ -+static struct configfs_attribute *uvcg_frame_based_frame_attrs[] = { -+ &uvcg_frame_based_frame_attr_bm_capabilities, -+ &uvcg_frame_based_frame_attr_w_width, -+ &uvcg_frame_based_frame_attr_w_height, -+ &uvcg_frame_based_frame_attr_dw_min_bit_rate, -+ &uvcg_frame_based_frame_attr_dw_max_bit_rate, -+ &uvcg_frame_based_frame_attr_dw_default_frame_interval, -+ &uvcg_frame_based_frame_attr_dw_frame_interval, -+ &uvcg_frame_based_frame_attr_dw_bytes_per_line, -+ NULL, -+}; -+ -+static struct config_item_type uvcg_frame_based_frame_type = { -+ .ct_attrs = uvcg_frame_based_frame_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *uvcg_frame_based_frame_make(struct config_group *group, -+ const char *name) -+{ -+ struct uvcg_frame_based_frame *h; -+ struct uvcg_format *fmt; -+ struct f_uvc_opts *opts; -+ struct config_item *opts_item; -+ -+ h = kzalloc(sizeof(*h), GFP_KERNEL); -+ if (!h) -+ return ERR_PTR(-ENOMEM); -+ -+ h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; -+ h->frame.b_frame_index = 1; -+ h->frame.w_width = cpu_to_le16(640); -+ h->frame.w_height = cpu_to_le16(360); -+ h->frame.dw_min_bit_rate = cpu_to_le32(18432000); -+ h->frame.dw_max_bit_rate = cpu_to_le32(55296000); -+ h->frame.dw_default_frame_interval = cpu_to_le32(333333); -+ h->frame.dw_bytes_per_line = cpu_to_le32(0); -+ -+ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; -+ opts = to_f_uvc_opts(opts_item); -+ -+ mutex_lock(&opts->lock); -+ fmt = to_uvcg_format(&group->cg_item); -+ if (fmt->type == UVCG_FRAME_FRAME_BASED) { -+ h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED; -+ h->fmt_type = UVCG_FRAME_FRAME_BASED; -+ } else { -+ mutex_unlock(&opts->lock); -+ kfree(h); -+ return ERR_PTR(-EINVAL); -+ } -+ ++fmt->num_frames; -+ h->frame.b_frame_index = fmt->num_frames; -+ mutex_unlock(&opts->lock); -+ -+ config_item_init_type_name(&h->item, name, &uvcg_frame_based_frame_type); -+ -+ return &h->item; -+} -+ -+static void uvcg_frame_based_frame_drop(struct config_group *group, struct config_item *item) -+{ -+ struct uvcg_frame_based_frame *h = to_uvcg_frame_based_frame(item); -+ struct uvcg_format *fmt; -+ struct f_uvc_opts *opts; -+ struct config_item *opts_item; -+ -+ opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; -+ opts = to_f_uvc_opts(opts_item); -+ -+ mutex_lock(&opts->lock); -+ fmt = to_uvcg_format(&group->cg_item); -+ --fmt->num_frames; -+ kfree(h); -+ mutex_unlock(&opts->lock); -+} -+ - /* streaming/uncompressed/ */ - struct uvcg_uncompressed { - struct uvcg_format fmt; -@@ -1438,10 +1892,17 @@ - static struct config_group *uvcg_uncompressed_make(struct config_group *group, - const char *name) - { -+#ifndef CONFIG_GOKE_MC - static char guid[] = { - 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 - }; -+#else -+ static char guid[] = { -+ 'N', 'V', '2', '1', 0x00, 0x00, 0x10, 0x00, -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -+ }; -+#endif - struct uvcg_uncompressed *h; - - h = kzalloc(sizeof(*h), GFP_KERNEL); -@@ -1452,7 +1913,11 @@ - h->desc.bDescriptorType = USB_DT_CS_INTERFACE; - h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; - memcpy(h->desc.guidFormat, guid, sizeof(guid)); -+#ifndef CONFIG_GOKE_MC - h->desc.bBitsPerPixel = 16; -+#else -+ h->desc.bBitsPerPixel = 12; -+#endif - h->desc.bDefaultFrameIndex = 1; - h->desc.bAspectRatioX = 0; - h->desc.bAspectRatioY = 0; -@@ -1678,6 +2143,205 @@ - .ct_owner = THIS_MODULE, - }; - -+/* streaming/frame_based */ -+struct uvcg_frame_based_format { -+ struct uvcg_format fmt; -+ struct uvc_frame_based_format_desc desc; -+}; -+ -+static struct uvcg_frame_based_format *to_uvcg_frame_based_format(struct config_item *item) -+{ -+ return container_of( -+ container_of(to_config_group(item), struct uvcg_format, group), -+ struct uvcg_frame_based_format, fmt); -+} -+ -+static struct configfs_group_operations uvcg_frame_based_format_group_ops = { -+ .make_item = uvcg_frame_based_frame_make, -+ .drop_item = uvcg_frame_based_frame_drop, -+}; -+ -+#define UVCG_FRAME_BASED_FORMAT_ATTR_RO(cname, aname, conv) \ -+static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\ -+{ \ -+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ -+ struct f_uvc_opts *opts; \ -+ struct config_item *opts_item; \ -+ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ -+ int result; \ -+ \ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ -+ \ -+ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ -+ opts = to_f_uvc_opts(opts_item); \ -+ \ -+ mutex_lock(&opts->lock); \ -+ result = sprintf(page, "%d\n", conv(u->desc.aname)); \ -+ mutex_unlock(&opts->lock); \ -+ \ -+ mutex_unlock(su_mutex); \ -+ return result; \ -+} \ -+ \ -+UVC_ATTR_RO(uvcg_frame_based_format_, cname, aname) -+ -+#define UVCG_FRAME_BASED_FORMAT_ATTR(cname, aname, conv) \ -+static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\ -+{ \ -+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ -+ struct f_uvc_opts *opts; \ -+ struct config_item *opts_item; \ -+ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ -+ int result; \ -+ \ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ -+ \ -+ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ -+ opts = to_f_uvc_opts(opts_item); \ -+ \ -+ mutex_lock(&opts->lock); \ -+ result = sprintf(page, "%d\n", conv(u->desc.aname)); \ -+ mutex_unlock(&opts->lock); \ -+ \ -+ mutex_unlock(su_mutex); \ -+ return result; \ -+} \ -+ \ -+static ssize_t \ -+uvcg_frame_based_format_##cname##_store(struct config_item *item, \ -+ const char *page, size_t len) \ -+{ \ -+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); \ -+ struct f_uvc_opts *opts; \ -+ struct config_item *opts_item; \ -+ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ -+ int ret; \ -+ u8 num; \ -+ \ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ -+ \ -+ opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ -+ opts = to_f_uvc_opts(opts_item); \ -+ \ -+ mutex_lock(&opts->lock); \ -+ if (u->fmt.linked || opts->refcnt) { \ -+ ret = -EBUSY; \ -+ goto end; \ -+ } \ -+ \ -+ ret = kstrtou8(page, 0, &num); \ -+ if (ret) \ -+ goto end; \ -+ \ -+ if (num > 255) { \ -+ ret = -EINVAL; \ -+ goto end; \ -+ } \ -+ u->desc.aname = num; \ -+ ret = len; \ -+end: \ -+ mutex_unlock(&opts->lock); \ -+ mutex_unlock(su_mutex); \ -+ return ret; \ -+} \ -+ \ -+UVC_ATTR(uvcg_frame_based_format_, cname, aname) -+ -+#define identity_conv(x) (x) -+ -+UVCG_FRAME_BASED_FORMAT_ATTR(b_default_frame_index, bDefaultFrameIndex, -+ identity_conv); -+UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); -+UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); -+UVCG_FRAME_BASED_FORMAT_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); -+ -+#undef identity_conv -+ -+#undef UVCG_FRAME_BASED_FORMAT_ATTR -+#undef UVCG_FRAME_BASED_FORMAT_ATTR_RO -+ -+static inline ssize_t -+uvcg_frame_based_format_bma_controls_show(struct config_item *item, char *page) -+{ -+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); -+ return uvcg_format_bma_controls_show(&u->fmt, page); -+} -+ -+static inline ssize_t -+uvcg_frame_based_format_bma_controls_store(struct config_item *item, -+ const char *page, size_t len) -+{ -+ struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item); -+ return uvcg_format_bma_controls_store(&u->fmt, page, len); -+} -+ -+UVC_ATTR(uvcg_frame_based_format_, bma_controls, bmaControls); -+ -+static struct configfs_attribute *uvcg_frame_based_format_attrs[] = { -+ &uvcg_frame_based_format_attr_b_default_frame_index, -+ &uvcg_frame_based_format_attr_b_aspect_ratio_x, -+ &uvcg_frame_based_format_attr_b_aspect_ratio_y, -+ &uvcg_frame_based_format_attr_bm_interface_flags, -+ &uvcg_frame_based_format_attr_bma_controls, -+ NULL, -+}; -+ -+static struct config_item_type uvcg_frame_based_format_type = { -+ .ct_group_ops = &uvcg_frame_based_format_group_ops, -+ .ct_attrs = uvcg_frame_based_format_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_group *uvcg_frame_based_format_make(struct config_group *group, -+ const char *name) -+{ -+ static char guid[] = { /*Declear frame frame based as H264*/ -+ 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -+ }; -+ struct uvcg_frame_based_format *h; -+ -+ h = kzalloc(sizeof(*h), GFP_KERNEL); -+ if (!h) -+ return ERR_PTR(-ENOMEM); -+ -+ h->desc.bLength = UVC_DT_FRAME_BASED_FORMAT_SIZE; -+ h->desc.bDescriptorType = USB_DT_CS_INTERFACE; -+ h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED; -+ memcpy(h->desc.guidFormat, guid, sizeof(guid)); -+ h->desc.bBitsPerPixel = 16; -+ h->desc.bDefaultFrameIndex = 1; -+ h->desc.bAspectRatioX = 0; -+ h->desc.bAspectRatioY = 0; -+ h->desc.bmInterfaceFlags = 0; -+ h->desc.bCopyProtect = 0; -+ h->desc.bVariableSize = 1; -+ -+ h->fmt.type = UVCG_FRAME_FRAME_BASED; -+ config_group_init_type_name(&h->fmt.group, name, -+ &uvcg_frame_based_format_type); -+ -+ return &h->fmt.group; -+} -+ -+static void uvcg_frame_based_format_drop(struct config_group *group, -+ struct config_item *item) -+{ -+ struct uvcg_frame_based_format *h = to_uvcg_frame_based_format(item); -+ -+ kfree(h); -+} -+ -+static struct configfs_group_operations uvcg_frame_based_format_grp_ops = { -+ .make_group = uvcg_frame_based_format_make, -+ .drop_item = uvcg_frame_based_format_drop, -+}; -+ -+static struct config_item_type uvcg_frame_based_format_grp_type = { -+ .ct_group_ops = &uvcg_frame_based_format_grp_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ - /* streaming/color_matching/default */ - static struct uvcg_default_color_matching { - struct config_group group; -@@ -1873,6 +2537,11 @@ - container_of(fmt, struct uvcg_mjpeg, fmt); - - *size += sizeof(m->desc); -+ } else if (fmt->type == UVCG_FRAME_FRAME_BASED) { -+ struct uvcg_frame_based_format *h = -+ container_of(fmt, struct uvcg_frame_based_format, fmt); -+ -+ *size += sizeof(h->desc); - } else { - return -EINVAL; - } -@@ -1881,7 +2550,14 @@ - case UVCG_FRAME: { - struct uvcg_frame *frm = priv1; - int sz = sizeof(frm->dw_frame_interval); -+ if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) { -+ struct uvcg_frame_based_frame *fb_frm = priv1; -+ *size += sizeof(fb_frm->frame); -+ *size += fb_frm->frame.b_frame_interval_type * sizeof(fb_frm->dw_frame_interval); - -+ ++*count; -+ return 0; -+ } - *size += sizeof(frm->frame); - *size += frm->frame.b_frame_interval_type * sz; - } -@@ -1949,6 +2625,15 @@ - *dest += sizeof(m->desc); - mjp->bNumFrameDescriptors = fmt->num_frames; - mjp->bFormatIndex = n + 1; -+ } else if (fmt->type == UVCG_FRAME_FRAME_BASED) { -+ struct uvc_frame_based_format_desc *ffb = *dest; -+ struct uvcg_frame_based_format *h = -+ container_of(fmt, struct uvcg_frame_based_format, fmt); -+ -+ memcpy(*dest, &h->desc, sizeof(h->desc)); -+ *dest += sizeof(h->desc); -+ ffb->bNumFrameDescriptors = fmt->num_frames; -+ ffb->bFormatIndex = n + 1; - } else { - return -EINVAL; - } -@@ -1958,6 +2643,19 @@ - struct uvcg_frame *frm = priv1; - struct uvc_descriptor_header *h = *dest; - -+ if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) { -+ struct uvcg_frame_based_frame *fb_frm = priv1; -+ sz = sizeof(fb_frm->frame); -+ memcpy(*dest, &fb_frm->frame, sz); -+ *dest += sz; -+ sz = fb_frm->frame.b_frame_interval_type * -+ sizeof(*fb_frm->dw_frame_interval); -+ memcpy(*dest, fb_frm->dw_frame_interval, sz); -+ *dest += sz; -+ h->bLength = UVC_DT_FRAME_BASED_FRAME_SIZE( -+ fb_frm->frame.b_frame_interval_type); -+ return 0; -+ } - sz = sizeof(frm->frame); - memcpy(*dest, &frm->frame, sz); - *dest += sz; -@@ -2224,6 +2922,13 @@ - configfs_add_default_group(&uvcg_default_processing.group, - &uvcg_processing_grp.group); - -+ config_group_init_type_name(&uvcg_default_extension.group, -+ "default", &uvcg_default_extension_type); -+ config_group_init_type_name(&uvcg_extension_grp.group, -+ "extension", &uvcg_extension_grp_type); -+ configfs_add_default_group(&uvcg_default_extension.group, -+ &uvcg_extension_grp.group); -+ - config_group_init_type_name(&uvcg_default_camera.group, - "default", &uvcg_default_camera_type); - config_group_init_type_name(&uvcg_camera_grp.group, -@@ -2278,6 +2983,9 @@ - config_group_init_type_name(&uvcg_mjpeg_grp.group, - "mjpeg", - &uvcg_mjpeg_grp_type); -+ config_group_init_type_name(&uvcg_frame_based_format_grp.group, -+ "framebased", -+ &uvcg_frame_based_format_grp_type); - config_group_init_type_name(&uvcg_default_color_matching.group, - "default", - &uvcg_default_color_matching_type); -@@ -2310,6 +3018,8 @@ - &uvcg_streaming_grp.group); - configfs_add_default_group(&uvcg_mjpeg_grp.group, - &uvcg_streaming_grp.group); -+ configfs_add_default_group(&uvcg_frame_based_format_grp.group, -+ &uvcg_streaming_grp.group); - configfs_add_default_group(&uvcg_color_matching_grp.group, - &uvcg_streaming_grp.group); - configfs_add_default_group(&uvcg_streaming_class_grp.group, ---- linux-4.9.37/drivers/usb/gadget/function/uvc.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/uvc.h 2021-06-07 13:01:34.000000000 +0300 -@@ -17,6 +17,7 @@ - #include - #include - -+#define UVC_SG_REQ - #define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) - #define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0) - #define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1) -@@ -95,8 +96,11 @@ - /* ------------------------------------------------------------------------ - * Driver specific constants - */ -- --#define UVC_NUM_REQUESTS 4 -+#ifdef UVC_SG_REQ -+#define UVC_NUM_REQUESTS 1 -+#else -+#define UVC_NUM_REQUESTS 32 -+#endif - #define UVC_MAX_REQUEST_SIZE 64 - #define UVC_MAX_EVENTS 4 - -@@ -106,6 +110,7 @@ - - struct uvc_video - { -+ struct uvc_device *uvc; - struct usb_ep *ep; - - /* Frame parameters */ -@@ -116,6 +121,9 @@ - unsigned int imagesize; - struct mutex mutex; /* protects frame parameters */ - -+ unsigned int num_sgs; /* record base */ -+ __u8 *sg_buf; -+ - /* Requests */ - unsigned int req_size; - struct usb_request *req[UVC_NUM_REQUESTS]; ---- linux-4.9.37/drivers/usb/gadget/function/uvc_v4l2.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/uvc_v4l2.c 2021-06-07 13:01:34.000000000 +0300 -@@ -60,8 +60,13 @@ - }; - - static struct uvc_format uvc_formats[] = { -+#ifndef CONFIG_GOKE_MC - { 16, V4L2_PIX_FMT_YUYV }, -+#else -+ { 12, V4L2_PIX_FMT_NV21 }, -+#endif - { 0, V4L2_PIX_FMT_MJPEG }, -+ { 0, V4L2_PIX_FMT_H264 }, - }; - - static int ---- linux-4.9.37/drivers/usb/gadget/function/uvc_video.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/uvc_video.c 2021-06-07 13:01:34.000000000 +0300 -@@ -23,6 +23,8 @@ - #include "uvc_queue.h" - #include "uvc_video.h" - -+#include -+#include - /* -------------------------------------------------------------------------- - * Video codecs - */ -@@ -102,9 +104,45 @@ - uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, - struct uvc_buffer *buf) - { -+ int ret; -+#ifdef UVC_SG_REQ -+ int len; -+ int ttllen = 0; -+ unsigned int sg_idx; -+ u8 *mem = NULL; -+ -+ for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++) { -+ mem = sg_virt(&req->sg[sg_idx]); -+ len = video->req_size; -+ -+ /* Add the header. */ -+ ret = uvc_video_encode_header(video, buf, mem, len); -+ mem += ret; -+ len -= ret; -+ -+ /* Process video data. */ -+ ret = uvc_video_encode_data(video, buf, mem, len); -+ len -= ret; -+ -+ /* Sync sg buffer len , default is 1024 or 3072 */ -+ sg_set_buf(&req->sg[sg_idx], sg_virt(&req->sg[sg_idx]), -+ video->req_size - len); -+ ttllen += video->req_size - len; -+ -+ if (buf->bytesused == video->queue.buf_used) { -+ video->queue.buf_used = 0; -+ buf->state = UVC_BUF_STATE_DONE; -+ uvcg_queue_next_buffer(&video->queue, buf); -+ video->fid ^= UVC_STREAM_FID; -+ break; -+ } -+ } -+ req->num_sgs = sg_idx + 1; -+ sg_mark_end(&req->sg[sg_idx]); -+ req->length = ttllen; -+#else - void *mem = req->buf; - int len = video->req_size; -- int ret; - - /* Add the header. */ - ret = uvc_video_encode_header(video, buf, mem, len); -@@ -123,12 +161,33 @@ - uvcg_queue_next_buffer(&video->queue, buf); - video->fid ^= UVC_STREAM_FID; - } -+#endif - } - - /* -------------------------------------------------------------------------- - * Request handling - */ - -+static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req) -+{ -+ int ret; -+ -+ /* -+ * Fixme, this is just to workaround the warning by udc core when the ep -+ * is disabled, this may happens when the uvc application is still -+ * streaming new data while the uvc gadget driver has already recieved -+ * the streamoff but the streamoff event is not yet received by the app -+ */ -+ if (!video->ep->enabled) -+ return -EINVAL; -+ -+ ret = usb_ep_queue(video->ep, req, GFP_ATOMIC); -+ if (ret < 0) -+ printk(KERN_INFO "Failed to queue request (%d).\n", ret); -+ -+ return ret; -+} -+ - /* - * I somehow feel that synchronisation won't be easy to achieve here. We have - * three events that control USB requests submission: -@@ -190,22 +249,26 @@ - spin_unlock_irqrestore(&video->queue.irqlock, flags); - goto requeue; - } -- -+#ifdef UVC_SG_REQ -+ sg_unmark_end(&req->sg[req->num_sgs - 1]); -+#endif - video->encode(req, video, buf); - -- if ((ret = usb_ep_queue(ep, req, GFP_ATOMIC)) < 0) { -- printk(KERN_INFO "Failed to queue request (%d).\n", ret); -- usb_ep_set_halt(ep); -- spin_unlock_irqrestore(&video->queue.irqlock, flags); -+ ret = uvcg_video_ep_queue(video, req); -+ spin_unlock_irqrestore(&video->queue.irqlock, flags); -+ -+ if (ret < 0) { - uvcg_queue_cancel(queue, 0); - goto requeue; - } -- spin_unlock_irqrestore(&video->queue.irqlock, flags); - - return; - - requeue: - spin_lock_irqsave(&video->req_lock, flags); -+#ifdef UVC_SG_REQ -+ sg_unmark_end(&req->sg[req->num_sgs - 1]); -+#endif - list_add_tail(&req->list, &video->req_free); - spin_unlock_irqrestore(&video->req_lock, flags); - } -@@ -214,9 +277,22 @@ - uvc_video_free_requests(struct uvc_video *video) - { - unsigned int i; -+#ifdef UVC_SG_REQ -+ unsigned int sg_idx; -+#endif - - for (i = 0; i < UVC_NUM_REQUESTS; ++i) { - if (video->req[i]) { -+#ifdef UVC_SG_REQ -+ for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++) -+ if (sg_page(&video->req[i]->sg[sg_idx])) -+ kfree(sg_virt(&video->req[i]->sg[sg_idx])); -+ -+ if (video->req[i]->sg) { -+ kfree(video->req[i]->sg); -+ video->req[i]->sg = NULL; -+ } -+#endif - usb_ep_free_request(video->ep, video->req[i]); - video->req[i] = NULL; - } -@@ -238,6 +314,11 @@ - unsigned int req_size; - unsigned int i; - int ret = -ENOMEM; -+#ifdef UVC_SG_REQ -+ struct scatterlist *sg; -+ unsigned int num_sgs; -+ unsigned int sg_idx; -+#endif - - BUG_ON(video->req_size); - -@@ -245,6 +326,35 @@ - * max_t(unsigned int, video->ep->maxburst, 1) - * (video->ep->mult); - -+#ifdef UVC_SG_REQ -+ num_sgs = ((video->imagesize / (req_size - 2)) + 1); -+ video->num_sgs = num_sgs; -+ -+ for (i = 0; i < UVC_NUM_REQUESTS; ++i) { -+ sg = kmalloc(num_sgs * sizeof(struct scatterlist), GFP_ATOMIC); -+ if (sg == NULL) -+ goto error; -+ sg_init_table(sg, num_sgs); -+ -+ video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL); -+ if (video->req[i] == NULL) -+ goto error; -+ -+ for (sg_idx = 0 ; sg_idx < num_sgs ; sg_idx++) { -+ video->sg_buf = kmalloc(req_size, GFP_KERNEL); -+ if (video->sg_buf == NULL) -+ goto error; -+ sg_set_buf(&sg[sg_idx], video->sg_buf, req_size); -+ } -+ video->req[i]->sg = sg; -+ video->req[i]->num_sgs = num_sgs; -+ video->req[i]->length = 0; -+ video->req[i]->complete = uvc_video_complete; -+ video->req[i]->context = video; -+ -+ list_add_tail(&video->req[i]->list, &video->req_free); -+ } -+#else - for (i = 0; i < UVC_NUM_REQUESTS; ++i) { - video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL); - if (video->req_buffer[i] == NULL) -@@ -261,7 +371,7 @@ - - list_add_tail(&video->req[i]->list, &video->req_free); - } -- -+#endif - video->req_size = req_size; - - return 0; -@@ -320,15 +430,13 @@ - video->encode(req, video, buf); - - /* Queue the USB request */ -- ret = usb_ep_queue(video->ep, req, GFP_ATOMIC); -+ ret = uvcg_video_ep_queue(video, req); -+ spin_unlock_irqrestore(&queue->irqlock, flags); -+ - if (ret < 0) { -- printk(KERN_INFO "Failed to queue request (%d)\n", ret); -- usb_ep_set_halt(video->ep); -- spin_unlock_irqrestore(&queue->irqlock, flags); - uvcg_queue_cancel(queue, 0); - break; - } -- spin_unlock_irqrestore(&queue->irqlock, flags); - } - - spin_lock_irqsave(&video->req_lock, flags); -@@ -379,16 +487,22 @@ - /* - * Initialize the UVC video stream. - */ --int uvcg_video_init(struct uvc_video *video) -+int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) - { - INIT_LIST_HEAD(&video->req_free); - spin_lock_init(&video->req_lock); -- -+#ifndef CONFIG_GOKE_MC - video->fcc = V4L2_PIX_FMT_YUYV; -+ video->imagesize = 320 * 240 * 2; - video->bpp = 16; -+#else -+ video->fcc = V4L2_PIX_FMT_NV21; -+ video->imagesize = 320 * 240 * 3 / 2; /* YUV420: w*h*1.5 */ -+ video->bpp = 12; -+#endif - video->width = 320; - video->height = 240; -- video->imagesize = 320 * 240 * 2; -+ video->uvc = uvc; - - /* Initialize the video buffers queue. */ - uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT, ---- linux-4.9.37/drivers/usb/gadget/function/uvc_video.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/function/uvc_video.h 2021-06-07 13:01:34.000000000 +0300 -@@ -19,6 +19,6 @@ - - int uvcg_video_enable(struct uvc_video *video, int enable); - --int uvcg_video_init(struct uvc_video *video); -+int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc); - - #endif /* __UVC_VIDEO_H__ */ ---- linux-4.9.37/drivers/usb/gadget/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -158,6 +158,9 @@ - config USB_U_ETHER - tristate - -+config USB_U_AUDIO -+ tristate -+ - config USB_F_SERIAL - tristate - -@@ -381,6 +384,7 @@ - depends on SND - select USB_LIBCOMPOSITE - select SND_PCM -+ select USB_U_AUDIO - select USB_F_UAC2 - help - This Audio function is compatible with USB Audio Class ---- linux-4.9.37/drivers/usb/gadget/legacy/audio.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/legacy/audio.c 2021-06-07 13:01:34.000000000 +0300 -@@ -229,6 +229,7 @@ - uac2_opts->c_chmask = c_chmask; - uac2_opts->c_srate = c_srate; - uac2_opts->c_ssize = c_ssize; -+ uac2_opts->req_number = UAC2_DEF_REQ_NUM; - #else - uac1_opts = container_of(fi_uac1, struct f_uac1_opts, func_inst); - uac1_opts->fn_play = fn_play; ---- linux-4.9.37/drivers/usb/gadget/legacy/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/legacy/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -56,6 +56,7 @@ - select SND_PCM - select USB_F_UAC1 if GADGET_UAC1 - select USB_F_UAC2 if !GADGET_UAC1 -+ select USB_U_AUDIO if USB_F_UAC2 - help - This Gadget Audio driver is compatible with USB Audio Class - specification 2.0. It implements 1 AudioControl interface, ---- linux-4.9.37/drivers/usb/gadget/legacy/multi.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/legacy/multi.c 2021-06-07 13:01:34.000000000 +0300 -@@ -162,21 +162,8 @@ - if (ret) - goto err_conf; - -- f_msg_rndis = usb_get_function(fi_msg); -- if (IS_ERR(f_msg_rndis)) { -- ret = PTR_ERR(f_msg_rndis); -- goto err_fsg; -- } -- -- ret = usb_add_function(c, f_msg_rndis); -- if (ret) -- goto err_run; -- - return 0; --err_run: -- usb_put_function(f_msg_rndis); --err_fsg: -- usb_remove_function(c, f_acm_rndis); -+ - err_conf: - usb_put_function(f_acm_rndis); - err_func_acm: -@@ -245,16 +232,6 @@ - if (ret) - goto err_conf; - -- f_msg_multi = usb_get_function(fi_msg); -- if (IS_ERR(f_msg_multi)) { -- ret = PTR_ERR(f_msg_multi); -- goto err_fsg; -- } -- -- ret = usb_add_function(c, f_msg_multi); -- if (ret) -- goto err_run; -- - return 0; - err_run: - usb_put_function(f_msg_multi); -@@ -304,8 +281,7 @@ - #ifdef USB_ETH_RNDIS - struct f_rndis_opts *rndis_opts; - #endif -- struct fsg_opts *fsg_opts; -- struct fsg_config config; -+ - int status; - - if (!can_support_ecm(cdev->gadget)) { -@@ -367,32 +343,6 @@ - goto fail0; - } - -- /* set up mass storage function */ -- fi_msg = usb_get_function_instance("mass_storage"); -- if (IS_ERR(fi_msg)) { -- status = PTR_ERR(fi_msg); -- goto fail1; -- } -- fsg_config_from_params(&config, &fsg_mod_data, fsg_num_buffers); -- fsg_opts = fsg_opts_from_func_inst(fi_msg); -- -- fsg_opts->no_configfs = true; -- status = fsg_common_set_num_buffers(fsg_opts->common, fsg_num_buffers); -- if (status) -- goto fail2; -- -- status = fsg_common_set_cdev(fsg_opts->common, cdev, config.can_stall); -- if (status) -- goto fail_set_cdev; -- -- fsg_common_set_sysfs(fsg_opts->common, true); -- status = fsg_common_create_luns(fsg_opts->common, &config); -- if (status) -- goto fail_set_cdev; -- -- fsg_common_set_inquiry_string(fsg_opts->common, config.vendor_name, -- config.product_name); -- - /* allocate string IDs */ - status = usb_string_ids_tab(cdev, strings_dev); - if (unlikely(status < 0)) -@@ -430,13 +380,6 @@ - kfree(otg_desc[0]); - otg_desc[0] = NULL; - fail_string_ids: -- fsg_common_remove_luns(fsg_opts->common); --fail_set_cdev: -- fsg_common_free_buffers(fsg_opts->common); --fail2: -- usb_put_function_instance(fi_msg); --fail1: -- usb_put_function_instance(fi_acm); - fail0: - #ifdef USB_ETH_RNDIS - usb_put_function_instance(fi_rndis); ---- linux-4.9.37/drivers/usb/gadget/legacy/webcam.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/legacy/webcam.c 2021-06-07 13:01:34.000000000 +0300 -@@ -26,11 +26,11 @@ - module_param(streaming_interval, uint, S_IRUGO|S_IWUSR); - MODULE_PARM_DESC(streaming_interval, "1 - 16"); - --static unsigned int streaming_maxpacket = 1024; -+static unsigned int streaming_maxpacket = 3072; - module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR); - MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)"); - --static unsigned int streaming_maxburst; -+static unsigned int streaming_maxburst = 14; - module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR); - MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); - -@@ -49,6 +49,17 @@ - static char webcam_product_label[] = "Webcam gadget"; - static char webcam_config_label[] = "Video"; - -+/* GUID of the UVC H.264 extension unit: -+{A29E7641-DE04-47E3-8B2B-F4341AFF003B} */ -+#define GUID_UVCX_H264_XU {0x41, 0x76, 0x9E, 0xA2, 0x04, 0xDE, 0xE3, 0x47, \ -+ 0x8B, 0x2B, 0xF4, 0x34, 0x1A, 0xFF, 0x00, 0x3B} -+ -+#define UVC_GUID_BSP_CAMERA {0x91, 0x72, 0x1e, 0x9a, 0x43, 0x68, 0x83, 0x46, \ -+ 0x6d, 0x92, 0x39, 0xbc, 0x79, 0x06, 0xee, 0x49} -+ -+#define UVC_GUID_FORMAT_H264 {0x48, 0x32, 0x36, 0x34, 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -+ - /* string IDs are assigned dynamically */ - - #define STRING_DESCRIPTION_IDX USB_GADGET_FIRST_AVAIL_IDX -@@ -77,7 +88,7 @@ - static struct usb_device_descriptor webcam_device_descriptor = { - .bLength = USB_DT_DEVICE_SIZE, - .bDescriptorType = USB_DT_DEVICE, -- /* .bcdUSB = DYNAMIC */ -+ .bcdUSB = cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_MISC, - .bDeviceSubClass = 0x02, - .bDeviceProtocol = 0x01, -@@ -97,7 +108,7 @@ - .bLength = UVC_DT_HEADER_SIZE(1), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VC_HEADER, -- .bcdUVC = cpu_to_le16(0x0100), -+ .bcdUVC = cpu_to_le16(0x0110), - .wTotalLength = 0, /* dynamic */ - .dwClockFrequency = cpu_to_le32(48000000), - .bInCollection = 0, /* dynamic */ -@@ -108,7 +119,7 @@ - .bLength = UVC_DT_CAMERA_TERMINAL_SIZE(3), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VC_INPUT_TERMINAL, -- .bTerminalID = 1, -+ .bTerminalID = 2, - .wTerminalType = cpu_to_le16(0x0201), - .bAssocTerminal = 0, - .iTerminal = 0, -@@ -116,8 +127,8 @@ - .wObjectiveFocalLengthMax = cpu_to_le16(0), - .wOcularFocalLength = cpu_to_le16(0), - .bControlSize = 3, -- .bmControls[0] = 2, -- .bmControls[1] = 0, -+ .bmControls[0] = 0x1a, -+ .bmControls[1] = 0x00, - .bmControls[2] = 0, - }; - -@@ -125,15 +136,45 @@ - .bLength = UVC_DT_PROCESSING_UNIT_SIZE(2), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VC_PROCESSING_UNIT, -- .bUnitID = 2, -+ .bUnitID = 5, - .bSourceID = 1, - .wMaxMultiplier = cpu_to_le16(16*1024), - .bControlSize = 2, -- .bmControls[0] = 1, -- .bmControls[1] = 0, -+ .bmControls[0] = 0xff, -+ .bmControls[1] = 0xff, - .iProcessing = 0, - }; - -+static const struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_xu_h264_desc = { -+ .bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 2), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VC_EXTENSION_UNIT, -+ .bUnitID = 10, -+ .guidExtensionCode = GUID_UVCX_H264_XU, -+ .bNumControls = 15, -+ .bNrInPins = 1, -+ .baSourceID[0] = 2, -+ .bControlSize = 2, -+ .bmControls[0] = 0xff, -+ .bmControls[1] = 0xff, -+ .iExtension = 0, -+}; -+ -+static const struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_xu_camera_desc = { -+ .bLength = UVC_DT_EXTENSION_UNIT_SIZE(1, 2), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VC_EXTENSION_UNIT, -+ .bUnitID = 0x11, -+ .guidExtensionCode = UVC_GUID_BSP_CAMERA, -+ .bNumControls = 15, -+ .bNrInPins = 1, -+ .baSourceID[0] = 10, -+ .bControlSize = 2, -+ .bmControls[0] = 0xff, -+ .bmControls[1] = 0xff, -+ .iExtension = 0, -+}; -+ - static const struct uvc_output_terminal_descriptor uvc_output_terminal = { - .bLength = UVC_DT_OUTPUT_TERMINAL_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, -@@ -141,7 +182,7 @@ - .bTerminalID = 3, - .wTerminalType = cpu_to_le16(0x0101), - .bAssocTerminal = 0, -- .bSourceID = 2, -+ .bSourceID = 0x11, - .iTerminal = 0, - }; - -@@ -169,11 +210,18 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, - .bFormatIndex = 1, -- .bNumFrameDescriptors = 2, -+ .bNumFrameDescriptors = 3, -+#ifndef CONFIG_GOKE_MC - .guidFormat = - { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, - .bBitsPerPixel = 16, -+#else -+ .guidFormat = { -+ 'N', 'V', '2', '1', 0x00, 0x00, 0x10, 0x00, -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, -+ .bBitsPerPixel = 12, -+#endif - .bDefaultFrameIndex = 1, - .bAspectRatioX = 0, - .bAspectRatioY = 0, -@@ -184,22 +232,24 @@ - DECLARE_UVC_FRAME_UNCOMPRESSED(1); - DECLARE_UVC_FRAME_UNCOMPRESSED(3); - --static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = { -- .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), -+static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_360p = { -+ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, - .bFrameIndex = 1, - .bmCapabilities = 0, - .wWidth = cpu_to_le16(640), - .wHeight = cpu_to_le16(360), -- .dwMinBitRate = cpu_to_le32(18432000), -+ .dwMinBitRate = cpu_to_le32(55296000), - .dwMaxBitRate = cpu_to_le32(55296000), -+#ifndef CONFIG_GOKE_MC - .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), -- .dwDefaultFrameInterval = cpu_to_le32(666666), -- .bFrameIntervalType = 3, -- .dwFrameInterval[0] = cpu_to_le32(666666), -- .dwFrameInterval[1] = cpu_to_le32(1000000), -- .dwFrameInterval[2] = cpu_to_le32(5000000), -+#else -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(345600), -+#endif -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwFrameInterval[0] = cpu_to_le32(333333), - }; - - static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { -@@ -212,10 +262,54 @@ - .wHeight = cpu_to_le16(720), - .dwMinBitRate = cpu_to_le32(29491200), - .dwMaxBitRate = cpu_to_le32(29491200), -+#ifndef CONFIG_GOKE_MC - .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), -- .dwDefaultFrameInterval = cpu_to_le32(5000000), -+#else -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(1382400), -+#endif -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_1080p = { -+ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, -+ .bFrameIndex = 3, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(1920), -+ .wHeight = cpu_to_le16(1080), -+ .dwMinBitRate = cpu_to_le32(29491200), -+ .dwMaxBitRate = cpu_to_le32(29491200), -+#ifndef CONFIG_GOKE_MC -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(4147200), -+#else -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(3110400), -+#endif -+ .dwDefaultFrameInterval = cpu_to_le32(333333), - .bFrameIntervalType = 1, -- .dwFrameInterval[0] = cpu_to_le32(5000000), -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_2160p = { -+ .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, -+ .bFrameIndex = 4, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(3840), -+ .wHeight = cpu_to_le16(2160), -+ .dwMinBitRate = cpu_to_le32(29491200), -+ .dwMaxBitRate = cpu_to_le32(29491200), -+#ifndef CONFIG_GOKE_MC -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(16588800), -+#else -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(12441600), -+#endif -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwFrameInterval[0] = cpu_to_le32(333333), - }; - - static const struct uvc_format_mjpeg uvc_format_mjpg = { -@@ -223,7 +317,7 @@ - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, - .bFormatIndex = 2, -- .bNumFrameDescriptors = 2, -+ .bNumFrameDescriptors = 4, - .bmFlags = 0, - .bDefaultFrameIndex = 1, - .bAspectRatioX = 0, -@@ -235,22 +329,20 @@ - DECLARE_UVC_FRAME_MJPEG(1); - DECLARE_UVC_FRAME_MJPEG(3); - --static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = { -- .bLength = UVC_DT_FRAME_MJPEG_SIZE(3), -+static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_360p = { -+ .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VS_FRAME_MJPEG, - .bFrameIndex = 1, - .bmCapabilities = 0, - .wWidth = cpu_to_le16(640), - .wHeight = cpu_to_le16(360), -- .dwMinBitRate = cpu_to_le32(18432000), -- .dwMaxBitRate = cpu_to_le32(55296000), -+ .dwMinBitRate = cpu_to_le32(10240000), -+ .dwMaxBitRate = cpu_to_le32(10240000), - .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), -- .dwDefaultFrameInterval = cpu_to_le32(666666), -- .bFrameIntervalType = 3, -- .dwFrameInterval[0] = cpu_to_le32(666666), -- .dwFrameInterval[1] = cpu_to_le32(1000000), -- .dwFrameInterval[2] = cpu_to_le32(5000000), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwFrameInterval[0] = cpu_to_le32(333333), - }; - - static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { -@@ -261,12 +353,125 @@ - .bmCapabilities = 0, - .wWidth = cpu_to_le16(1280), - .wHeight = cpu_to_le16(720), -- .dwMinBitRate = cpu_to_le32(29491200), -- .dwMaxBitRate = cpu_to_le32(29491200), -+ .dwMinBitRate = cpu_to_le32(20480000), -+ .dwMaxBitRate = cpu_to_le32(20480000), - .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), -- .dwDefaultFrameInterval = cpu_to_le32(5000000), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), - .bFrameIntervalType = 1, -- .dwFrameInterval[0] = cpu_to_le32(5000000), -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_1080p = { -+ .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_MJPEG, -+ .bFrameIndex = 3, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(1920), -+ .wHeight = cpu_to_le16(1080), -+ .dwMinBitRate = cpu_to_le32(40960000), -+ .dwMaxBitRate = cpu_to_le32(40960000), -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(4147200), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_2160p = { -+ .bLength = UVC_DT_FRAME_MJPEG_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_MJPEG, -+ .bFrameIndex = 4, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(3840), -+ .wHeight = cpu_to_le16(2160), -+ .dwMinBitRate = cpu_to_le32(61440000), -+ .dwMaxBitRate = cpu_to_le32(61440000), -+ .dwMaxVideoFrameBufferSize = cpu_to_le32(16588800), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+static const struct uvc_frame_based_format_desc uvc_frame_based_format_desc = { -+ .bLength = UVC_DT_FRAME_BASED_FORMAT_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED, -+ .bFormatIndex = 3, -+ .bNumFrameDescriptors = 4, -+ .guidFormat = UVC_GUID_FORMAT_H264, -+ .bBitsPerPixel = 16, -+ .bDefaultFrameIndex = 1, -+ .bAspectRatioX = 0, -+ .bAspectRatioY = 0, -+ .bmInterfaceFlags = 0, -+ .bCopyProtect = 0, -+ .bVariableSize = 1, -+}; -+DECLARE_UVC_FRAME_BASED(1); -+static const struct UVC_FRAME_BASED(1) uvc_frame_based_360p = { -+ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, -+ .bFrameIndex = 1, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(640), -+ .wHeight = cpu_to_le16(360), -+ .dwMinBitRate = cpu_to_le32(8192000), -+ .dwMaxBitRate = cpu_to_le32(8192000), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwBytesPerLine = 0, -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+static const struct UVC_FRAME_BASED(1) uvc_frame_based_720p = { -+ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, -+ .bFrameIndex = 2, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(1280), -+ .wHeight = cpu_to_le16(720), -+ .dwMinBitRate = cpu_to_le32(10240000), -+ .dwMaxBitRate = cpu_to_le32(10240000), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwBytesPerLine = 0, -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+static const struct UVC_FRAME_BASED(1) uvc_frame_based_1080p = { -+ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, -+ .bFrameIndex = 3, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(1920), -+ .wHeight = cpu_to_le16(1080), -+ .dwMinBitRate = cpu_to_le32(15360000), -+ .dwMaxBitRate = cpu_to_le32(15360000), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwBytesPerLine = 0, -+ .dwFrameInterval[0] = cpu_to_le32(333333), -+}; -+ -+ -+static const struct UVC_FRAME_BASED(1) uvc_frame_based_2160p = { -+ .bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubType = UVC_VS_FRAME_FRAME_BASED, -+ .bFrameIndex = 4, -+ .bmCapabilities = 0, -+ .wWidth = cpu_to_le16(3840), -+ .wHeight = cpu_to_le16(2160), -+ .dwMinBitRate = cpu_to_le32(30720000), -+ .dwMaxBitRate = cpu_to_le32(30720000), -+ .dwDefaultFrameInterval = cpu_to_le32(333333), -+ .bFrameIntervalType = 1, -+ .dwBytesPerLine = 0, -+ .dwFrameInterval[0] = cpu_to_le32(333333), - }; - - static const struct uvc_color_matching_descriptor uvc_color_matching = { -@@ -282,6 +487,8 @@ - (const struct uvc_descriptor_header *) &uvc_control_header, - (const struct uvc_descriptor_header *) &uvc_camera_terminal, - (const struct uvc_descriptor_header *) &uvc_processing, -+ (const struct uvc_descriptor_header *) &uvc_xu_h264_desc, -+ (const struct uvc_descriptor_header *) &uvc_xu_camera_desc, - (const struct uvc_descriptor_header *) &uvc_output_terminal, - NULL, - }; -@@ -290,6 +497,8 @@ - (const struct uvc_descriptor_header *) &uvc_control_header, - (const struct uvc_descriptor_header *) &uvc_camera_terminal, - (const struct uvc_descriptor_header *) &uvc_processing, -+ (const struct uvc_descriptor_header *) &uvc_xu_h264_desc, -+ (const struct uvc_descriptor_header *) &uvc_xu_camera_desc, - (const struct uvc_descriptor_header *) &uvc_output_terminal, - NULL, - }; -@@ -298,10 +507,19 @@ - (const struct uvc_descriptor_header *) &uvc_input_header, - (const struct uvc_descriptor_header *) &uvc_format_yuv, - (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, -- (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, -+// (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, -+// (const struct uvc_descriptor_header *) &uvc_frame_yuv_1080p, -+// (const struct uvc_descriptor_header *) &uvc_frame_yuv_2160p, - (const struct uvc_descriptor_header *) &uvc_format_mjpg, - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, -+ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_1080p, -+ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_2160p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_format_desc, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_360p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_720p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_1080p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_2160p, - (const struct uvc_descriptor_header *) &uvc_color_matching, - NULL, - }; -@@ -310,22 +528,41 @@ - (const struct uvc_descriptor_header *) &uvc_input_header, - (const struct uvc_descriptor_header *) &uvc_format_yuv, - (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, -- (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, -+// (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, -+// (const struct uvc_descriptor_header *) &uvc_frame_yuv_1080p, -+// (const struct uvc_descriptor_header *) &uvc_frame_yuv_2160p, - (const struct uvc_descriptor_header *) &uvc_format_mjpg, - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, -+ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_1080p, -+ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_2160p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_format_desc, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_360p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_720p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_1080p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_2160p, - (const struct uvc_descriptor_header *) &uvc_color_matching, - NULL, - }; - -+ - static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { - (const struct uvc_descriptor_header *) &uvc_input_header, - (const struct uvc_descriptor_header *) &uvc_format_yuv, - (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, - (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, -+ (const struct uvc_descriptor_header *) &uvc_frame_yuv_1080p, -+// (const struct uvc_descriptor_header *) &uvc_frame_yuv_2160p, - (const struct uvc_descriptor_header *) &uvc_format_mjpg, - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, - (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, -+ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_1080p, -+ (const struct uvc_descriptor_header *) &uvc_frame_mjpg_2160p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_format_desc, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_360p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_720p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_1080p, -+ (const struct uvc_descriptor_header *) &uvc_frame_based_2160p, - (const struct uvc_descriptor_header *) &uvc_color_matching, - NULL, - }; ---- linux-4.9.37/drivers/usb/gadget/udc/core.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/udc/core.c 2021-06-07 13:01:34.000000000 +0300 -@@ -966,15 +966,6 @@ - if (udc) - sysfs_notify(&udc->dev.kobj, NULL, "state"); - } -- --void usb_gadget_set_state(struct usb_gadget *gadget, -- enum usb_device_state state) --{ -- gadget->state = state; -- schedule_work(&gadget->work); --} --EXPORT_SYMBOL_GPL(usb_gadget_set_state); -- - /* ------------------------------------------------------------------------- */ - - static void usb_udc_connect_control(struct usb_udc *udc) -@@ -985,6 +976,24 @@ - usb_gadget_disconnect(udc->gadget); - } - -+/* should be called with udc_lock held */ -+static int check_pending_gadget_drivers(struct usb_udc *udc) -+{ -+ struct usb_gadget_driver *driver; -+ int ret = 0; -+ -+ list_for_each_entry(driver, &gadget_driver_pending_list, pending) -+ if (!driver->udc_name || strcmp(driver->udc_name, -+ dev_name(&udc->dev)) == 0) { -+ ret = udc_bind_to_driver(udc, driver); -+ if (ret != -EPROBE_DEFER) -+ list_del(&driver->pending); -+ break; -+ } -+ -+ return ret; -+} -+ - /** - * usb_udc_vbus_handler - updates the udc core vbus status, and try to - * connect or disconnect gadget -@@ -1005,6 +1014,15 @@ - } - EXPORT_SYMBOL_GPL(usb_udc_vbus_handler); - -+/* ------------------------------------------------------------------------- */ -+void usb_gadget_set_state(struct usb_gadget *gadget, -+ enum usb_device_state state) -+{ -+ gadget->state = state; -+} -+EXPORT_SYMBOL_GPL(usb_gadget_set_state); -+/* ------------------------------------------------------------------------- */ -+ - /** - * usb_gadget_udc_reset - notifies the udc core that bus reset occurs - * @gadget: The gadget which bus reset occurs -@@ -1080,24 +1098,6 @@ - dev_vdbg(dev, "%s\n", __func__); - } - --/* should be called with udc_lock held */ --static int check_pending_gadget_drivers(struct usb_udc *udc) --{ -- struct usb_gadget_driver *driver; -- int ret = 0; -- -- list_for_each_entry(driver, &gadget_driver_pending_list, pending) -- if (!driver->udc_name || strcmp(driver->udc_name, -- dev_name(&udc->dev)) == 0) { -- ret = udc_bind_to_driver(udc, driver); -- if (ret != -EPROBE_DEFER) -- list_del(&driver->pending); -- break; -- } -- -- return ret; --} -- - /** - * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list - * @parent: the parent device to this udc. Usually the controller driver's ---- linux-4.9.37/drivers/usb/gadget/udc/trace.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/gadget/udc/trace.h 2021-06-07 13:01:34.000000000 +0300 -@@ -236,6 +236,7 @@ - __field(unsigned, short_not_ok) - __field(int, status) - __field(int, ret) -+ __field(struct usb_request *, req) - ), - TP_fast_assign( - snprintf(__get_str(name), UDC_TRACE_STR_MAX, "%s", ep->name); -@@ -249,9 +250,10 @@ - __entry->short_not_ok = req->short_not_ok; - __entry->status = req->status; - __entry->ret = ret; -+ __entry->req = req; - ), -- TP_printk("%s: length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", -- __get_str(name), __entry->actual, __entry->length, -+ TP_printk("%s: req %p length %d/%d sgs %d/%d stream %d %s%s%s status %d --> %d", -+ __get_str(name),__entry->req, __entry->actual, __entry->length, - __entry->num_mapped_sgs, __entry->num_sgs, __entry->stream_id, - __entry->zero ? "Z" : "z", - __entry->short_not_ok ? "S" : "s", ---- linux-4.9.37/drivers/usb/host/xhci.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/host/xhci.c 2021-06-07 13:01:34.000000000 +0300 -@@ -4131,7 +4131,7 @@ - xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", - enable ? "enable" : "disable", port_num + 1); - -- if (enable) { -+ if (enable && !(xhci->quirks & XHCI_HW_LPM_DISABLE)) { - /* Host supports BESL timeout instead of HIRD */ - if (udev->usb2_hw_lpm_besl_capable) { - /* if device doesn't have a preferred BESL value use a ---- linux-4.9.37/drivers/usb/host/xhci.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/host/xhci.h 2021-06-07 13:01:34.000000000 +0300 -@@ -1661,6 +1661,7 @@ - #define XHCI_BROKEN_PORT_PED (1 << 25) - #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) - #define XHCI_U2_DISABLE_WAKE (1 << 27) -+#define XHCI_HW_LPM_DISABLE (1 << 29) - - unsigned int num_active_eps; - unsigned int limit_active_eps; ---- linux-4.9.37/drivers/usb/host/xhci-hub.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/host/xhci-hub.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1049,13 +1049,15 @@ - break; - } - -- /* Software should not attempt to set -- * port link state above '3' (U3) and the port -- * must be enabled. -- */ -- if ((temp & PORT_PE) == 0 || -- (link_state > USB_SS_PORT_LS_U3)) { -- xhci_warn(xhci, "Cannot set link state.\n"); -+ /* port must be enabled */ -+ if (!(temp & PORT_PE)) { -+ retval = -ENODEV; -+ break; -+ } -+ /* Can't set port link state above '3' (U3)*/ -+ if (link_state > USB_SS_PORT_LS_U3) { -+ xhci_warn(xhci, "Cannot set port %d link state %d\n", -+ wIndex, link_state); - goto error; - } - ---- linux-4.9.37/drivers/usb/host/xhci-mem.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/host/xhci-mem.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1404,7 +1404,7 @@ - if (udev->speed == USB_SPEED_HIGH && - (usb_endpoint_xfer_isoc(&ep->desc) || - usb_endpoint_xfer_int(&ep->desc))) -- return (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11; -+ return usb_endpoint_maxp_mult(&ep->desc) - 1; - - return 0; - } -@@ -1450,9 +1450,9 @@ - return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); - - max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); -- max_burst = (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11; -+ max_burst = usb_endpoint_maxp_mult(&ep->desc); - /* A 0 in max burst means 1 transfer per ESIT */ -- return max_packet * (max_burst + 1); -+ return max_packet * max_burst; - } - - /* Set up an endpoint with one ring segment. Do not allocate stream rings. ---- linux-4.9.37/drivers/usb/host/xhci-plat.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/host/xhci-plat.c 2021-06-07 13:01:34.000000000 +0300 -@@ -220,6 +220,9 @@ - goto disable_clk; - } - -+ if (device_property_read_bool(&pdev->dev, "usb2-lpm-disable")) -+ xhci->quirks |= XHCI_HW_LPM_DISABLE; -+ - if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) - xhci->quirks |= XHCI_LPM_SUPPORT; - ---- linux-4.9.37/drivers/usb/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/usb/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -7,7 +7,7 @@ - obj-$(CONFIG_USB) += core/ - obj-$(CONFIG_USB_SUPPORT) += phy/ - --obj-$(CONFIG_USB_DWC3) += dwc3/ -+obj-$(CONFIG_ARCH_GOKE) += dwc3/ - obj-$(CONFIG_USB_DWC2) += dwc2/ - obj-$(CONFIG_USB_ISP1760) += isp1760/ - ---- linux-4.9.37/drivers/video/fbdev/core/fbmem.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/drivers/video/fbdev/core/fbmem.c 2021-06-07 13:01:34.000000000 +0300 -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - #include - -@@ -1083,7 +1084,24 @@ - return ret; - } - EXPORT_SYMBOL(fb_blank); -+#ifdef CONFIG_ARCH_GOKE -+#ifdef CONFIG_DMA_SHARED_BUFFER -+int -+fb_get_dmabuf(struct fb_info *info, int flags) -+{ -+ struct dma_buf *dmabuf; -+ -+ if (info->fbops->fb_dmabuf_export == NULL) -+ return -ENOTTY; -+ -+ dmabuf = info->fbops->fb_dmabuf_export(info); -+ if (IS_ERR(dmabuf)) -+ return PTR_ERR(dmabuf); - -+ return dma_buf_fd(dmabuf, flags); -+} -+#endif -+#endif /* CONFIG_ARCH_GOKE */ - static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) - { -@@ -1094,6 +1112,9 @@ - struct fb_cmap cmap_from; - struct fb_cmap_user cmap; - struct fb_event event; -+#if defined(CONFIG_ARCH_GOKE) && defined(CONFIG_DMA_SHARED_BUFFER) -+ struct fb_dmabuf_export dmaexp; -+#endif - void __user *argp = (void __user *)arg; - long ret = 0; - -@@ -1211,6 +1232,23 @@ - unlock_fb_info(info); - console_unlock(); - break; -+#if defined(CONFIG_ARCH_GOKE) && defined(CONFIG_DMA_SHARED_BUFFER) -+ case FBIOGET_DMABUF: -+ if (copy_from_user(&dmaexp, argp, sizeof(dmaexp))) -+ return -EFAULT; -+ -+ if (!lock_fb_info(info)) -+ return -ENODEV; -+ dmaexp.fd = fb_get_dmabuf(info, dmaexp.flags); -+ unlock_fb_info(info); -+ -+ if (dmaexp.fd < 0) -+ return dmaexp.fd; -+ -+ ret = copy_to_user(argp, &dmaexp, sizeof(dmaexp)) -+ ? -EFAULT : 0; -+ break; -+#endif /* CONFIG_ARCH_GOKE */ - default: - if (!lock_fb_info(info)) - return -ENODEV; ---- linux-4.9.37/fs/buffer.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/buffer.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1276,10 +1276,17 @@ - */ - static void bh_lru_install(struct buffer_head *bh) - { -- struct buffer_head *evictee = NULL; -+#ifdef CONFIG_GOKE_MC -+ struct buffer_head *evictee = bh; -+ struct bh_lru *b; -+ int i; -+#else -+ struct buffer_head *evictee = NULL; -+#endif - - check_irqs_on(); - bh_lru_lock(); -+#ifndef CONFIG_GOKE_MC - if (__this_cpu_read(bh_lrus.bhs[0]) != bh) { - struct buffer_head *bhs[BH_LRU_SIZE]; - int in; -@@ -1310,6 +1317,22 @@ - - if (evictee) - __brelse(evictee); -+#endif -+ -+#ifdef CONFIG_GOKE_MC -+ b = this_cpu_ptr(&bh_lrus); -+ for (i = 0; i < BH_LRU_SIZE; i++) { -+ swap(evictee, b->bhs[i]); -+ if (evictee == bh) { -+ bh_lru_unlock(); -+ return; -+ } -+ } -+ -+ get_bh(bh); -+ bh_lru_unlock(); -+ brelse(evictee); -+#endif - } - - /* ---- linux-4.9.37/fs/compat_ioctl.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/compat_ioctl.c 2021-06-07 13:01:34.000000000 +0300 -@@ -750,9 +750,9 @@ - if (!access_ok(VERIFY_READ, udata, sizeof(*udata))) - return -EFAULT; - -- if (__copy_in_user(&tdata->read_write, &udata->read_write, 2 * sizeof(u8))) -+ if (copy_in_user(&tdata->read_write, &udata->read_write, 2 * sizeof(u8))) - return -EFAULT; -- if (__copy_in_user(&tdata->size, &udata->size, 2 * sizeof(u32))) -+ if (copy_in_user(&tdata->size, &udata->size, 2 * sizeof(u32))) - return -EFAULT; - if (__get_user(datap, &udata->data) || - __put_user(compat_ptr(datap), &tdata->data)) ---- linux-4.9.37/fs/dcache.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/dcache.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1137,7 +1137,12 @@ - - this_cpu_sub(nr_dentry_unused, freed); - shrink_dentry_list(&dispose); -- } while (freed > 0); -+#ifdef CONFIG_GOKE_MC -+ cond_resched(); -+ } while (list_lru_count(&sb->s_dentry_lru) > 0); -+#else -+ } while (freed > 0); -+#endif - } - EXPORT_SYMBOL(shrink_dcache_sb); - ---- linux-4.9.37/fs/fat/dir.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/fat/dir.c 2021-06-07 13:01:34.000000000 +0300 -@@ -782,6 +782,388 @@ - ret = buf.result; - return ret; - } -+#ifdef CONFIG_GOKE_MC -+/* -+ * This is the "fatfilldirall_t" function type, -+ * used by fat_ioctl_filldirall to let -+ * the kernel specify what kind of dirent layout it wants to have. -+ * This allows the kernel to read directories into kernel space or -+ * to have different dirent layouts depending on the binary type. -+ */ -+typedef int (*fatfilldirall_t)(void *__buf, const char *name, -+ int name_len, loff_t offset, u64 ino, -+ unsigned int d_type, struct msdos_dir_entry *de, -+ char *d_createtime); -+struct fatdirall_context { -+ const fatfilldirall_t actor; -+ loff_t pos; -+}; -+ -+struct fat_ioctl_filldirall_callback { -+ struct fatdirall_context ctx; -+ struct fat_direntall __user *current_dir; -+ struct fat_direntall __user *previous; -+ int count; -+ int usecount; -+ int error; -+ int result; -+ const char *longname; -+ int long_len; -+ const char *shortname; -+ int short_len; -+}; -+ -+static inline bool fat_dir_emit(struct fatdirall_context *ctx, -+ const char *name, int namelen, -+ u64 ino, unsigned type, -+ struct msdos_dir_entry *de, -+ char *d_createtime) -+{ -+ return ctx->actor(ctx, name, namelen, ctx->pos, ino, -+ type, de, d_createtime) == 0; -+} -+static inline bool fat_dir_emit_dot(struct file *file, -+ struct fatdirall_context *ctx, -+ struct msdos_dir_entry *de, -+ char *d_createtime) -+{ -+ return ctx->actor(ctx, ".", 1, ctx->pos, -+ file->f_path.dentry->d_inode->i_ino, -+ DT_DIR, de, d_createtime) == 0; -+} -+static inline bool fat_dir_emit_dotdot(struct file *file, -+ struct fatdirall_context *ctx, -+ struct msdos_dir_entry *de, -+ char *d_createtime) -+{ -+ return ctx->actor(ctx, "..", 2, ctx->pos, -+ parent_ino(file->f_path.dentry), -+ DT_DIR, de, d_createtime) == 0; -+} -+ -+static inline bool fat_dir_emit_dots(struct file *file, -+ struct fatdirall_context *ctx, -+ struct msdos_dir_entry *de, -+ char *d_createtime) -+{ -+ if (ctx->pos == 0) { -+ if (!fat_dir_emit_dot(file, ctx, de, d_createtime)) -+ return false; -+ ctx->pos = 1; -+ } -+ if (ctx->pos == 1) { -+ if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime)) -+ return false; -+ ctx->pos = 2; -+ } -+ return true; -+} -+ -+ -+static int __fat_readdirall(struct inode *inode, struct file *file, -+ struct fatdirall_context *ctx, int short_only, -+ struct fat_ioctl_filldirall_callback *both) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct msdos_sb_info *sbi = MSDOS_SB(sb); -+ struct buffer_head *bh; -+ struct msdos_dir_entry *de; -+ unsigned char nr_slots; -+ wchar_t *unicode = NULL; -+ unsigned char bufname[FAT_MAX_SHORT_SIZE]; -+ int isvfat = sbi->options.isvfat; -+ const char *fill_name = NULL; -+ int fake_offset = 0; -+ loff_t cpos; -+ int short_len = 0, fill_len = 0; -+ int ret = 0; -+ char d_createtime[8]; -+ -+ mutex_lock(&sbi->s_lock); -+ -+ cpos = ctx->pos; -+ /* Fake . and .. for the root directory. */ -+ if (inode->i_ino == MSDOS_ROOT_INO) { -+ if (!fat_dir_emit_dots(file, ctx, NULL, NULL)) -+ goto out; -+ if (ctx->pos == 2) { -+ fake_offset = 1; -+ cpos = 0; -+ } -+ } -+ if (cpos & (sizeof(struct msdos_dir_entry) - 1)) { -+ ret = -ENOENT; -+ goto out; -+ } -+ -+ bh = NULL; -+get_new: -+ if (fat_get_entry(inode, &cpos, &bh, &de) == -1) -+ goto end_of_dir; -+parse_record: -+ nr_slots = 0; -+ /* -+ * Check for long filename entry, but if short_only, we don't -+ * need to parse long filename. -+ */ -+ if (isvfat && !short_only) { -+ if (de->name[0] == DELETED_FLAG) -+ goto record_end; -+ if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME)) -+ goto record_end; -+ if (de->attr != ATTR_EXT && IS_FREE(de->name)) -+ goto record_end; -+ } else { -+ if ((de->attr & ATTR_VOLUME) || IS_FREE(de->name)) -+ goto record_end; -+ } -+ -+ if (isvfat && de->attr == ATTR_EXT) { -+ int status = fat_parse_long(inode, &cpos, &bh, &de, -+ &unicode, &nr_slots); -+ if (status < 0) { -+ ctx->pos = cpos; -+ ret = status; -+ goto out; -+ } else if (status == PARSE_INVALID) -+ goto record_end; -+ else if (status == PARSE_NOT_LONGNAME) -+ goto parse_record; -+ else if (status == PARSE_EOF) -+ goto end_of_dir; -+ -+ if (nr_slots) { -+ void *longname = unicode + FAT_MAX_UNI_CHARS; -+ int size = PATH_MAX - FAT_MAX_UNI_SIZE; -+ int len = fat_uni_to_x8(sb, unicode, longname, size); -+ -+ fill_name = longname; -+ fill_len = len; -+ -+ short_len = fat_parse_short(sb, de, bufname, -+ sbi->options.dotsOK); -+ if (short_len == 0) -+ goto record_end; -+ -+ /* hack for fat_ioctl_filldir() */ -+ both->longname = fill_name; -+ both->long_len = fill_len; -+ both->shortname = bufname; -+ both->short_len = short_len; -+ fill_name = NULL; -+ fill_len = 0; -+ goto start_filldir; -+ } -+ } -+ -+ short_len = fat_parse_short(sb, de, bufname, sbi->options.dotsOK); -+ if (short_len == 0) -+ goto record_end; -+ -+ fill_name = bufname; -+ fill_len = short_len; -+ -+start_filldir: -+ if (!fake_offset) -+ ctx->pos = cpos - (nr_slots + 1) -+ * sizeof(struct msdos_dir_entry); -+ -+ memset(d_createtime, 0, 8); -+ fat_time_fat2str(sbi, d_createtime, de->ctime, -+ de->cdate, de->ctime_cs); -+ -+ if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME)) { -+ if (!fat_dir_emit_dot(file, ctx, de, d_createtime)) -+ goto fill_failed; -+ } else if (!memcmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) { -+ if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime)) -+ goto fill_failed; -+ } else { -+ unsigned long inum; -+ loff_t i_pos = fat_make_i_pos(sb, bh, de); -+ struct inode *tmp = fat_iget(sb, i_pos); -+ -+ if (tmp) { -+ inum = tmp->i_ino; -+ iput(tmp); -+ } else -+ inum = iunique(sb, MSDOS_ROOT_INO); -+ if (!fat_dir_emit(ctx, fill_name, fill_len, inum, -+ (de->attr & ATTR_DIR) ? DT_DIR : DT_REG, -+ de, d_createtime)) -+ goto fill_failed; -+ } -+ -+record_end: -+ fake_offset = 0; -+ ctx->pos = cpos; -+ goto get_new; -+end_of_dir: -+ ctx->pos = cpos; -+fill_failed: -+ brelse(bh); -+ if (unicode) -+ __putname(unicode); -+out: -+ mutex_unlock(&sbi->s_lock); -+ return ret; -+} -+ -+static int fat_ioctl_filldirall(void *__buf, const char *name, -+ int name_len, loff_t offset, -+ u64 ino, unsigned int d_type, -+ struct msdos_dir_entry *de, -+ char *d_createtime) -+{ -+ struct fat_direntall __user *dirent; -+ struct fat_ioctl_filldirall_callback *buf; -+ unsigned long d_ino; -+ int reclen = 0; -+ const char *longname = NULL; -+ int long_len = 0; -+ const char *shortname = NULL; -+ int short_len = 0; -+ -+ buf = (struct fat_ioctl_filldirall_callback *) __buf; -+ -+ if (name != NULL) { -+ reclen = ALIGN(offsetof(struct fat_direntall, d_name) -+ + name_len + 2, sizeof(long)); -+ } else { -+ longname = buf->longname; -+ long_len = buf->long_len; -+ shortname = buf->shortname; -+ short_len = buf->short_len; -+ reclen = ALIGN(offsetof(struct fat_direntall, d_name) -+ + long_len + 2, sizeof(long)); -+ } -+ -+ buf->error = -EINVAL; /* only used if we fail.. */ -+ -+ if (reclen >= buf->count) -+ return -EINVAL; -+ -+ d_ino = ino; -+ -+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { -+ buf->error = -EOVERFLOW; -+ return -EOVERFLOW; -+ } -+ -+ dirent = buf->previous; -+ -+ if (dirent) { -+ if (__put_user(offset, &dirent->d_off)) -+ goto efault; -+ } -+ -+ dirent = buf->current_dir; -+ -+ if (__put_user(d_ino, &dirent->d_ino)) -+ goto efault; -+ -+ if (__put_user(reclen, &dirent->d_reclen)) -+ goto efault; -+ -+ if (name != NULL) { -+ if (copy_to_user(dirent->d_name, name, name_len)) -+ goto efault; -+ if (__put_user(0, dirent->d_name + name_len)) -+ goto efault; -+ } else { -+ if (copy_to_user(dirent->d_name, longname, long_len)) -+ goto efault; -+ if (__put_user(0, dirent->d_name + long_len)) -+ goto efault; -+ } -+ -+ if (__put_user(d_type, &dirent->d_type)) -+ goto efault; -+ -+ if (de != NULL) { -+ u64 u_size = 0; -+ if (copy_to_user(&dirent->d_size, &u_size, sizeof(u64))) -+ goto efault; -+ if (copy_to_user(&dirent->d_size, &de->size, sizeof(u32))) -+ goto efault; -+ } -+ -+ if (d_createtime != NULL) { -+ if (copy_to_user(dirent->d_createtime, d_createtime, 8)) -+ goto efault; -+ } -+ buf->previous = dirent; -+ dirent = (void __user *)dirent + reclen; -+ buf->current_dir = dirent; -+ buf->count -= reclen; -+ buf->usecount += reclen; -+ return 0; -+efault: -+ buf->error = -EFAULT; -+ return -EFAULT; -+} -+ -+ -+static int fat_ioctl_readdirall(struct inode *inode, struct file *file, -+ void __user *dirent, -+ int short_only, int both) -+{ -+ struct fat_ioctl_filldirall_callback buf = { -+ .ctx.actor = fat_ioctl_filldirall, -+ }; -+ -+ struct fat_direntall_buf __user *userbuf = dirent; -+ int ret; -+ -+ buf.current_dir = &(userbuf->direntall); -+ buf.previous = NULL; -+ buf.error = 0; -+ buf.result = 0; -+ buf.usecount = 0; -+ -+ if (get_user(buf.count, &(userbuf->d_count))) -+ return -EFAULT; -+ -+ up_read(&inode->i_rwsem); -+ buf.ctx.pos = file->f_pos; -+ ret = -ENOENT; -+ if (!IS_DEADDIR(inode)) { -+ ret = __fat_readdirall(inode, file, &buf.ctx, -+ short_only, both ? &buf : NULL); -+ file->f_pos = buf.ctx.pos; -+ } -+ down_read(&inode->i_rwsem); -+ -+ if (__put_user(buf.usecount, &(userbuf->d_usecount))) -+ return -EFAULT; -+ if (ret >= 0) -+ ret = buf.result; -+ return ret; -+} -+ -+static int fat_dir_ioctl_readdirall(struct file *filp, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct inode *inode = filp->f_path.dentry->d_inode; -+ struct fat_direntall_buf __user *direntallbuf; -+ int short_only, both; -+ -+ direntallbuf = (struct fat_direntall_buf __user *)arg; -+ -+ if (!access_ok(VERIFY_WRITE, direntallbuf, -+ sizeof(struct fat_direntall_buf))) -+ return -EFAULT; -+ if (put_user(0, &(direntallbuf->direntall.d_reclen))) -+ return -EFAULT; -+ if (put_user(0, &(direntallbuf->d_usecount))) -+ return -EFAULT; -+ short_only = 0; -+ both = 1; -+ return fat_ioctl_readdirall(inode, filp, direntallbuf, -+ short_only, both); -+} -+#endif -+ - - static long fat_dir_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -@@ -789,7 +1171,10 @@ - struct inode *inode = file_inode(filp); - struct __fat_dirent __user *d1 = (struct __fat_dirent __user *)arg; - int short_only, both; -- -+#ifdef CONFIG_GOKE_MC -+ if (VFAT_IOCTL_READDIR_ALL == cmd) -+ return fat_dir_ioctl_readdirall(filp, cmd, arg); -+#endif - switch (cmd) { - case VFAT_IOCTL_READDIR_SHORT: - short_only = 1; ---- linux-4.9.37/fs/fat/fatent.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/fat/fatent.c 2021-06-07 13:01:34.000000000 +0300 -@@ -380,6 +380,9 @@ - int err, n, copy; - - err = 0; -+#ifdef CONFIG_GOKE_MC -+ return 0; -+#endif - for (copy = 1; copy < sbi->fats; copy++) { - sector_t backup_fat = sbi->fat_length * copy; - ---- linux-4.9.37/fs/fat/fat.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/fat/fat.h 2021-06-07 13:01:34.000000000 +0300 -@@ -409,6 +409,10 @@ - __le16 __time, __le16 __date, u8 time_cs); - extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts, - __le16 *time, __le16 *date, u8 *time_cs); -+#ifdef CONFIG_GOKE_MC -+extern void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime, -+ __le16 __time, __le16 __date, u8 time_cs); -+#endif - extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); - - int fat_cache_init(void); ---- linux-4.9.37/fs/fat/file.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/fat/file.c 2021-06-07 13:01:34.000000000 +0300 -@@ -167,8 +167,17 @@ - - return res ? res : err; - } -+#ifdef CONFIG_GOKE_MC -+int fat_file_flush(struct file *file, fl_owner_t id) -+{ -+ struct address_space * mapping = file->f_mapping; -+ struct inode *inode = mapping->host; - -+ inode->i_sb->s_op->write_inode(inode, NULL); - -+ return 0; -+} -+#endif - const struct file_operations fat_file_operations = { - .llseek = generic_file_llseek, - .read_iter = generic_file_read_iter, -@@ -182,6 +191,9 @@ - .fsync = fat_file_fsync, - .splice_read = generic_file_splice_read, - .fallocate = fat_fallocate, -+#ifdef CONFIG_GOKE_MC -+ .flush = fat_file_flush, -+#endif - }; - - static int fat_cont_expand(struct inode *inode, loff_t size) -@@ -431,7 +443,13 @@ - /* use a default check */ - return 0; - } -- -+#ifdef CONFIG_GOKE_MC -+void reset_mmu_private(struct inode *inode, loff_t offset) -+{ -+ MSDOS_I(inode)->mmu_private = offset; -+ inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; -+} -+#endif - #define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET) - /* valid file mode bits */ - #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO) -@@ -464,6 +482,7 @@ - * hole before it. XXX: this is no longer true with new truncate - * sequence. - */ -+#ifndef CONFIG_GOKE_MC - if (attr->ia_valid & ATTR_SIZE) { - inode_dio_wait(inode); - -@@ -474,7 +493,7 @@ - attr->ia_valid &= ~ATTR_SIZE; - } - } -- -+#endif - if (((attr->ia_valid & ATTR_UID) && - (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) || - ((attr->ia_valid & ATTR_GID) && -@@ -504,6 +523,9 @@ - goto out; - down_write(&MSDOS_I(inode)->truncate_lock); - truncate_setsize(inode, attr->ia_size); -+#ifdef CONFIG_GOKE_MC -+ reset_mmu_private(inode, attr->ia_size); -+#endif - fat_truncate_blocks(inode, attr->ia_size); - up_write(&MSDOS_I(inode)->truncate_lock); - } ---- linux-4.9.37/fs/fat/inode.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/fat/inode.c 2021-06-07 13:01:34.000000000 +0300 -@@ -615,8 +615,9 @@ - round_up(MSDOS_I(inode)->mmu_private, - MSDOS_SB(inode->i_sb)->cluster_size)) { - int err; -- -+#ifndef CONFIG_GOKE_MC - fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private); -+#endif - /* Fallocate results in updating the i_start/iogstart - * for the zero byte file. So, make it return to - * original state during evict and commit it to avoid -@@ -873,15 +874,87 @@ - spin_unlock(&sbi->inode_hash_lock); - mark_buffer_dirty(bh); - err = 0; -- if (wait) -+ if (wait) { - err = sync_dirty_buffer(bh); -+ } - brelse(bh); - return err; - } -+#ifdef CONFIG_GOKE_MC -+static int __fat_write_inode_(struct inode *inode, int wait) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct msdos_sb_info *sbi = MSDOS_SB(sb); -+ struct buffer_head *bh; -+ struct msdos_dir_entry *raw_entry; -+ loff_t i_pos; -+ sector_t blocknr; -+ int err = 0; -+ int offset; -+ -+ if (inode->i_ino == MSDOS_ROOT_INO) -+ return 0; -+ -+retry: -+ i_pos = fat_i_pos_read(sbi, inode); -+ if (!i_pos) -+ return 0; -+ -+ fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset); -+ bh = sb_bread(sb, blocknr); -+ if (!bh) { -+ fat_msg(sb, KERN_ERR, "unable to read inode block " -+ "for updating (i_pos %lld)", i_pos); -+ return -EIO; -+ } -+ spin_lock(&sbi->inode_hash_lock); -+ if (i_pos != MSDOS_I(inode)->i_pos) { -+ spin_unlock(&sbi->inode_hash_lock); -+ brelse(bh); -+ goto retry; -+ } - -+#if 0 -+ dump_stack(); -+ printk("%s :inode %p/%s, size %llx, logstart %x, blocknr %lx, wait %d\n", -+ __func__, inode, S_ISDIR(inode->i_mode)? "dir":"file", inode->i_size, -+ MSDOS_I(inode)->i_logstart, blocknr, wait); -+#endif -+ raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset]; -+ if (S_ISDIR(inode->i_mode)) -+ raw_entry->size = 0; -+ else { -+ //raw_entry->size = cpu_to_le32(inode->i_size); -+ if ((0 != raw_entry->start) || (0 != raw_entry->starthi)) { -+ spin_unlock(&sbi->inode_hash_lock); -+ goto file_out; -+ } -+ raw_entry->size = cpu_to_le32(inode->i_size); -+ } -+ raw_entry->attr = fat_make_attrs(inode); -+ fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart); -+ fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time, -+ &raw_entry->date, NULL); -+ if (sbi->options.isvfat) { -+ __le16 atime; -+ fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime, -+ &raw_entry->cdate, &raw_entry->ctime_cs); -+ fat_time_unix2fat(sbi, &inode->i_atime, &atime, -+ &raw_entry->adate, NULL); -+ } -+ spin_unlock(&sbi->inode_hash_lock); -+ mark_buffer_dirty(bh); -+ if (wait) { -+ err = sync_dirty_buffer(bh); -+ } -+file_out: -+ brelse(bh); -+ return err; -+} -+#endif - static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) - { -- int err; -+ int err = 0; - - if (inode->i_ino == MSDOS_FSINFO_INO) { - struct super_block *sb = inode->i_sb; -@@ -889,8 +962,18 @@ - mutex_lock(&MSDOS_SB(sb)->s_lock); - err = fat_clusters_flush(sb); - mutex_unlock(&MSDOS_SB(sb)->s_lock); -- } else -- err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); -+ } else { -+#ifdef CONFIG_GOKE_MC -+ if (NULL == wbc){ -+ err = __fat_write_inode(inode, 1); -+ } -+ else{ -+ err = __fat_write_inode_(inode, wbc->sync_mode == WB_SYNC_ALL); -+ } -+#else -+ err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); -+#endif -+ } - - return err; - } ---- linux-4.9.37/fs/fat/misc.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/fat/misc.c 2021-06-07 13:01:34.000000000 +0300 -@@ -261,6 +261,37 @@ - *time_cs = (ts->tv_sec & 1) * 100 + ts->tv_nsec / 10000000; - } - EXPORT_SYMBOL_GPL(fat_time_unix2fat); -+#ifdef CONFIG_GOKE_MC -+void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime, -+ __le16 __time, __le16 __date, u8 time_cs) -+{ -+ u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date); -+ time_t day, month, year; -+ -+ year = date >> 9; -+ month = max(1, (date >> 5) & 0xf); -+ day = max(1, date & 0x1f) - 1; -+ -+ d_createtime[0] = year; -+ d_createtime[1] = month; -+ d_createtime[2] = day; -+ d_createtime[3] = (time >> 11); /*hour*/ -+ d_createtime[4] = ((time >> 5) & 0x3f); /*min*/ -+ d_createtime[5] = (time & 0x1f); /*second 2s*/ -+ -+ -+ if (!sbi->options.tz_set) -+ d_createtime[4] += sys_tz.tz_minuteswest; -+ else -+ d_createtime[4] -= sbi->options.time_offset; -+ -+ if (time_cs) { -+ /*second 1s*/ -+ d_createtime[5] += (time_cs / 100); -+ } -+} -+EXPORT_SYMBOL_GPL(fat_time_fat2str); -+#endif - - int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) - { ---- linux-4.9.37/fs/jffs2/compr.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/jffs2/compr.c 2021-06-07 13:01:34.000000000 +0300 -@@ -378,6 +378,9 @@ - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_init(); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_init(); -+#endif - /* Setting default compression mode */ - #ifdef CONFIG_JFFS2_CMODE_NONE - jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; -@@ -401,6 +404,9 @@ - int jffs2_compressors_exit(void) - { - /* Unregistering compressors */ -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_exit(); -+#endif - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_exit(); - #endif ---- linux-4.9.37/fs/jffs2/compr.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/jffs2/compr.h 2021-06-07 13:01:34.000000000 +0300 -@@ -29,9 +29,15 @@ - #define JFFS2_DYNRUBIN_PRIORITY 20 - #define JFFS2_LZARI_PRIORITY 30 - #define JFFS2_RTIME_PRIORITY 50 -+ -+#ifdef CONFIG_GOKE_MC -+#define JFFS2_LZMA_PRIORITY 70 -+#define JFFS2_ZLIB_PRIORITY 80 -+#define JFFS2_LZO_PRIORITY 90 -+#else - #define JFFS2_ZLIB_PRIORITY 60 - #define JFFS2_LZO_PRIORITY 80 -- -+#endif - - #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ - #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ -@@ -101,5 +107,9 @@ - int jffs2_lzo_init(void); - void jffs2_lzo_exit(void); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+int jffs2_lzma_init(void); -+void jffs2_lzma_exit(void); -+#endif - - #endif /* __JFFS2_COMPR_H__ */ ---- linux-4.9.37/fs/jffs2/compr_lzma.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/jffs2/compr_lzma.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,125 @@ -+/* -+ * JFFS2 -- Journalling Flash File System, Version 2. -+ * -+ * For licensing information, see the file 'LICENCE' in this directory. -+ * -+ * JFFS2 wrapper to the LZMA C SDK -+ * -+ */ -+ -+#include -+#include "compr.h" -+ -+#ifdef __KERNEL__ -+ static DEFINE_MUTEX(deflate_mutex); -+#endif -+ -+CLzmaEncHandle *p; -+Byte propsEncoded[LZMA_PROPS_SIZE]; -+SizeT propsSize = sizeof(propsEncoded); -+ -+STATIC void lzma_free_workspace(void) -+{ -+ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); -+} -+ -+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) -+{ -+ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) { -+ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); -+ return -ENOMEM; -+ } -+ -+ if (LzmaEnc_SetProps(p, props) != SZ_OK) { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t *sourcelen, uint32_t *dstlen) -+{ -+ SizeT compress_size = (SizeT)(*dstlen); -+ int ret; -+ -+#ifdef __KERNEL__ -+ mutex_lock(&deflate_mutex); -+#endif -+ -+ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, -+ 0, NULL, &lzma_alloc, &lzma_alloc); -+ -+#ifdef __KERNEL__ -+ mutex_unlock(&deflate_mutex); -+#endif -+ -+ if (ret != SZ_OK) -+ return -1; -+ -+ *dstlen = (uint32_t)compress_size; -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t srclen, uint32_t destlen) -+{ -+ int ret; -+ SizeT dl = (SizeT)destlen; -+ SizeT sl = (SizeT)srclen; -+ ELzmaStatus status; -+ -+ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, -+ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); -+ -+ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) -+ return -1; -+ -+ return 0; -+} -+ -+static struct jffs2_compressor jffs2_lzma_comp = { -+ .priority = JFFS2_LZMA_PRIORITY, -+ .name = "lzma", -+ .compr = JFFS2_COMPR_LZMA, -+ .compress = &jffs2_lzma_compress, -+ .decompress = &jffs2_lzma_decompress, -+ .disabled = 0, -+}; -+ -+int INIT jffs2_lzma_init(void) -+{ -+ int ret; -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ -+ props.dictSize = LZMA_BEST_DICT(0x2000); -+ props.level = LZMA_BEST_LEVEL; -+ props.lc = LZMA_BEST_LC; -+ props.lp = LZMA_BEST_LP; -+ props.pb = LZMA_BEST_PB; -+ props.fb = LZMA_BEST_FB; -+ -+ ret = lzma_alloc_workspace(&props); -+ if (ret < 0) -+ return ret; -+ -+ ret = jffs2_register_compressor(&jffs2_lzma_comp); -+ if (ret) -+ lzma_free_workspace(); -+ -+ return ret; -+} -+ -+void jffs2_lzma_exit(void) -+{ -+ jffs2_unregister_compressor(&jffs2_lzma_comp); -+ lzma_free_workspace(); -+} ---- linux-4.9.37/fs/jffs2/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/jffs2/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -139,6 +139,15 @@ - This feature was added in July, 2007. Say 'N' if you need - compatibility with older bootloaders or kernels. - -+config JFFS2_LZMA -+ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS -+ select LZMA_COMPRESS -+ select LZMA_DECOMPRESS -+ depends on JFFS2_FS -+ default n -+ help -+ JFFS2 wrapper to the LZMA C SDK -+ - config JFFS2_RTIME - bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS - depends on JFFS2_FS ---- linux-4.9.37/fs/jffs2/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/jffs2/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -18,4 +18,7 @@ - jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o - jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o - jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o -+jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o - jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o -+ -+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma ---- linux-4.9.37/fs/jffs2/super.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/jffs2/super.c 2021-06-07 13:01:34.000000000 +0300 -@@ -372,14 +372,41 @@ - BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); - BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); - -- pr_info("version 2.2." -+ pr_info("version 2.2" - #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - " (NAND)" - #endif - #ifdef CONFIG_JFFS2_SUMMARY -- " (SUMMARY) " -+ " (SUMMARY)" - #endif -- " © 2001-2006 Red Hat, Inc.\n"); -+#ifdef CONFIG_JFFS2_ZLIB -+ " (ZLIB)" -+#endif -+#ifdef CONFIG_JFFS2_LZO -+ " (LZO)" -+#endif -+#ifdef CONFIG_JFFS2_LZMA -+ " (LZMA)" -+#endif -+#ifdef CONFIG_JFFS2_RTIME -+ " (RTIME)" -+#endif -+#ifdef CONFIG_JFFS2_RUBIN -+ " (RUBIN)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_NONE -+ " (CMODE_NONE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_PRIORITY -+ " (CMODE_PRIORITY)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_SIZE -+ " (CMODE_SIZE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO -+ " (CMODE_FAVOURLZO)" -+#endif -+ " (c) 2001-2006 Red Hat, Inc.\n"); - - jffs2_inode_cachep = kmem_cache_create("jffs2_i", - sizeof(struct jffs2_inode_info), ---- linux-4.9.37/fs/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -232,6 +232,7 @@ - source "fs/befs/Kconfig" - source "fs/bfs/Kconfig" - source "fs/efs/Kconfig" -+source "fs/yaffs2/Kconfig" - source "fs/jffs2/Kconfig" - # UBIFS File system configuration - source "fs/ubifs/Kconfig" ---- linux-4.9.37/fs/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -129,3 +129,4 @@ - obj-$(CONFIG_CEPH_FS) += ceph/ - obj-$(CONFIG_PSTORE) += pstore/ - obj-$(CONFIG_EFIVAR_FS) += efivarfs/ -+obj-$(CONFIG_YAFFS_FS) += yaffs2/ ---- linux-4.9.37/fs/xfs/xfs_buf.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/xfs/xfs_buf.c 2021-06-07 13:01:34.000000000 +0300 -@@ -116,7 +116,7 @@ - __xfs_buf_ioacct_dec( - struct xfs_buf *bp) - { -- ASSERT(spin_is_locked(&bp->b_lock)); -+ lockdep_assert_held(&bp->b_lock); - - if (bp->b_state & XFS_BSTATE_IN_FLIGHT) { - bp->b_state &= ~XFS_BSTATE_IN_FLIGHT; ---- linux-4.9.37/fs/xfs/xfs_icache.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/fs/xfs/xfs_icache.c 2021-06-07 13:01:34.000000000 +0300 -@@ -66,7 +66,6 @@ - - XFS_STATS_INC(mp, vn_active); - ASSERT(atomic_read(&ip->i_pincount) == 0); -- ASSERT(!spin_is_locked(&ip->i_flags_lock)); - ASSERT(!xfs_isiflocked(ip)); - ASSERT(ip->i_ino == 0); - -@@ -192,7 +191,7 @@ - { - struct xfs_mount *mp = pag->pag_mount; - -- ASSERT(spin_is_locked(&pag->pag_ici_lock)); -+ lockdep_assert_held(&pag->pag_ici_lock); - if (pag->pag_ici_reclaimable++) - return; - -@@ -214,7 +213,7 @@ - { - struct xfs_mount *mp = pag->pag_mount; - -- ASSERT(spin_is_locked(&pag->pag_ici_lock)); -+ lockdep_assert_held(&pag->pag_ici_lock); - if (--pag->pag_ici_reclaimable) - return; - ---- linux-4.9.37/fs/yaffs2/Kconfig 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,171 @@ -+# -+# yaffs file system configurations -+# -+ -+config YAFFS_FS -+ tristate "yaffs2 file system support" -+ default n -+ depends on MTD_BLOCK -+ select YAFFS_YAFFS1 -+ select YAFFS_YAFFS2 -+ help -+ yaffs2, or Yet Another Flash File System, is a file system -+ optimised for NAND Flash chips. -+ -+ To compile the yaffs2 file system support as a module, choose M -+ here: the module will be called yaffs2. -+ -+ If unsure, say N. -+ -+ Further information on yaffs2 is available at -+ . -+ -+config YAFFS_YAFFS1 -+ bool "512 byte / page devices" -+ depends on YAFFS_FS -+ default y -+ help -+ Enable yaffs1 support -- yaffs for 512 byte / page devices -+ -+ Not needed for 2K-page devices. -+ -+ If unsure, say Y. -+ -+config YAFFS_9BYTE_TAGS -+ bool "Use older-style on-NAND data format with pageStatus byte" -+ depends on YAFFS_YAFFS1 -+ default n -+ help -+ -+ Older-style on-NAND data format has a "pageStatus" byte to record -+ chunk/page state. This byte is zero when the page is discarded. -+ Choose this option if you have existing on-NAND data using this -+ format that you need to continue to support. New data written -+ also uses the older-style format. Note: Use of this option -+ generally requires that MTD's oob layout be adjusted to use the -+ older-style format. See notes on tags formats and MTD versions -+ in yaffs_mtdif1.c. -+ -+ If unsure, say N. -+ -+config YAFFS_DOES_ECC -+ bool "Lets yaffs do its own ECC" -+ depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS -+ default n -+ help -+ This enables yaffs to use its own ECC functions instead of using -+ the ones from the generic MTD-NAND driver. -+ -+ If unsure, say N. -+ -+config YAFFS_ECC_WRONG_ORDER -+ bool "Use the same ecc byte order as Steven Hill's nand_ecc.c" -+ depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS -+ default n -+ help -+ This makes yaffs_ecc.c use the same ecc byte order as Steven -+ Hill's nand_ecc.c. If not set, then you get the same ecc byte -+ order as SmartMedia. -+ -+ If unsure, say N. -+ -+config YAFFS_YAFFS2 -+ bool "2048 byte (or larger) / page devices" -+ depends on YAFFS_FS -+ default y -+ help -+ Enable yaffs2 support -- yaffs for >= 2K bytes per page devices -+ -+ If unsure, say Y. -+ -+config YAFFS_AUTO_YAFFS2 -+ bool "Autoselect yaffs2 format" -+ depends on YAFFS_YAFFS2 -+ default y -+ help -+ Without this, you need to explicitely use yaffs2 as the file -+ system type. With this, you can say "yaffs" and yaffs or yaffs2 -+ will be used depending on the device page size (yaffs on -+ 512-byte page devices, yaffs2 on 2K page devices). -+ -+ If unsure, say Y. -+ -+config YAFFS_DISABLE_TAGS_ECC -+ bool "Disable yaffs from doing ECC on tags by default" -+ depends on YAFFS_FS && YAFFS_YAFFS2 -+ default n -+ help -+ This defaults yaffs to using its own ECC calculations on tags instead of -+ just relying on the MTD. -+ This behavior can also be overridden with tags_ecc_on and -+ tags_ecc_off mount options. -+ -+ If unsure, say N. -+ -+config YAFFS_ALWAYS_CHECK_CHUNK_ERASED -+ bool "Force chunk erase check" -+ depends on YAFFS_FS -+ default n -+ help -+ Normally yaffs only checks chunks before writing until an erased -+ chunk is found. This helps to detect any partially written -+ chunks that might have happened due to power loss. -+ -+ Enabling this forces on the test that chunks are erased in flash -+ before writing to them. This takes more time but is potentially -+ a bit more secure. -+ -+ Suggest setting Y during development and ironing out driver -+ issues etc. Suggest setting to N if you want faster writing. -+ -+ If unsure, say Y. -+ -+config YAFFS_EMPTY_LOST_AND_FOUND -+ bool "Empty lost and found on boot" -+ depends on YAFFS_FS -+ default n -+ help -+ If this is enabled then the contents of lost and found is -+ automatically dumped at mount. -+ -+ If unsure, say N. -+ -+config YAFFS_DISABLE_BLOCK_REFRESHING -+ bool "Disable yaffs2 block refreshing" -+ depends on YAFFS_FS -+ default n -+ help -+ If this is set, then block refreshing is disabled. -+ Block refreshing infrequently refreshes the oldest block in -+ a yaffs2 file system. This mechanism helps to refresh flash to -+ mitigate against data loss. This is particularly useful for MLC. -+ -+ If unsure, say N. -+ -+config YAFFS_DISABLE_BACKGROUND -+ bool "Disable yaffs2 background processing" -+ depends on YAFFS_FS -+ default n -+ help -+ If this is set, then background processing is disabled. -+ Background processing makes many foreground activities faster. -+ -+ If unsure, say N. -+ -+config YAFFS_DISABLE_BAD_BLOCK_MARKING -+ bool "Disable yaffs2 bad block marking" -+ depends on YAFFS_FS -+ default n -+ help -+ Useful during early flash bring up to prevent problems causing -+ lots of bad block marking. -+ -+ If unsure, say N. -+ -+config YAFFS_XATTR -+ bool "Enable yaffs2 xattr support" -+ depends on YAFFS_FS -+ default y -+ help -+ If this is set then yaffs2 will provide xattr support. -+ If unsure, say Y. ---- linux-4.9.37/fs/yaffs2/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,19 @@ -+# -+# Makefile for the linux YAFFS filesystem routines. -+# -+ -+obj-$(CONFIG_YAFFS_FS) += yaffs.o -+ -+yaffs-y := yaffs_ecc.o yaffs_vfs.o yaffs_guts.o yaffs_checkptrw.o -+yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o -+yaffs-y += yaffs_tagscompat.o yaffs_tagsmarshall.o -+yaffs-y += yaffs_endian.o -+yaffs-y += yaffs_mtdif.o -+yaffs-y += yaffs_nameval.o yaffs_attribs.o -+yaffs-y += yaffs_allocator.o -+yaffs-y += yaffs_yaffs1.o -+yaffs-y += yaffs_yaffs2.o -+yaffs-y += yaffs_bitmap.o -+yaffs-y += yaffs_summary.o -+yaffs-y += yaffs_verify.o -+ ---- linux-4.9.37/fs/yaffs2/yaffs_allocator.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_allocator.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,357 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_allocator.h" -+#include "yaffs_guts.h" -+#include "yaffs_trace.h" -+#include "yportenv.h" -+ -+/* -+ * Each entry in yaffs_tnode_list and yaffs_obj_list hold blocks -+ * of approx 100 objects that are themn allocated singly. -+ * This is basically a simplified slab allocator. -+ * -+ * We don't use the Linux slab allocator because slab does not allow -+ * us to dump all the objects in one hit when we do a umount and tear -+ * down all the tnodes and objects. slab requires that we first free -+ * the individual objects. -+ * -+ * Once yaffs has been mainlined I shall try to motivate for a change -+ * to slab to provide the extra features we need here. -+ */ -+ -+struct yaffs_tnode_list { -+ struct yaffs_tnode_list *next; -+ struct yaffs_tnode *tnodes; -+}; -+ -+struct yaffs_obj_list { -+ struct yaffs_obj_list *next; -+ struct yaffs_obj *objects; -+}; -+ -+struct yaffs_allocator { -+ int n_tnodes_created; -+ struct yaffs_tnode *free_tnodes; -+ int n_free_tnodes; -+ struct yaffs_tnode_list *alloc_tnode_list; -+ -+ int n_obj_created; -+ struct list_head free_objs; -+ int n_free_objects; -+ -+ struct yaffs_obj_list *allocated_obj_list; -+}; -+ -+static void yaffs_deinit_raw_tnodes(struct yaffs_dev *dev) -+{ -+ struct yaffs_allocator *allocator = -+ (struct yaffs_allocator *)dev->allocator; -+ struct yaffs_tnode_list *tmp; -+ -+ if (!allocator) { -+ BUG(); -+ return; -+ } -+ -+ while (allocator->alloc_tnode_list) { -+ tmp = allocator->alloc_tnode_list->next; -+ -+ kfree(allocator->alloc_tnode_list->tnodes); -+ kfree(allocator->alloc_tnode_list); -+ allocator->alloc_tnode_list = tmp; -+ } -+ -+ allocator->free_tnodes = NULL; -+ allocator->n_free_tnodes = 0; -+ allocator->n_tnodes_created = 0; -+} -+ -+static void yaffs_init_raw_tnodes(struct yaffs_dev *dev) -+{ -+ struct yaffs_allocator *allocator = dev->allocator; -+ -+ if (!allocator) { -+ BUG(); -+ return; -+ } -+ -+ allocator->alloc_tnode_list = NULL; -+ allocator->free_tnodes = NULL; -+ allocator->n_free_tnodes = 0; -+ allocator->n_tnodes_created = 0; -+} -+ -+static int yaffs_create_tnodes(struct yaffs_dev *dev, int n_tnodes) -+{ -+ struct yaffs_allocator *allocator = -+ (struct yaffs_allocator *)dev->allocator; -+ int i; -+ struct yaffs_tnode *new_tnodes; -+ u8 *mem; -+ struct yaffs_tnode *curr; -+ struct yaffs_tnode *next; -+ struct yaffs_tnode_list *tnl; -+ -+ if (!allocator) { -+ BUG(); -+ return YAFFS_FAIL; -+ } -+ -+ if (n_tnodes < 1) -+ return YAFFS_OK; -+ -+ /* make these things */ -+ new_tnodes = kmalloc(n_tnodes * dev->tnode_size, GFP_NOFS); -+ mem = (u8 *) new_tnodes; -+ -+ if (!new_tnodes) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs: Could not allocate Tnodes"); -+ return YAFFS_FAIL; -+ } -+ -+ /* New hookup for wide tnodes */ -+ for (i = 0; i < n_tnodes - 1; i++) { -+ curr = (struct yaffs_tnode *)&mem[i * dev->tnode_size]; -+ next = (struct yaffs_tnode *)&mem[(i + 1) * dev->tnode_size]; -+ curr->internal[0] = next; -+ } -+ -+ curr = (struct yaffs_tnode *)&mem[(n_tnodes - 1) * dev->tnode_size]; -+ curr->internal[0] = allocator->free_tnodes; -+ allocator->free_tnodes = (struct yaffs_tnode *)mem; -+ -+ allocator->n_free_tnodes += n_tnodes; -+ allocator->n_tnodes_created += n_tnodes; -+ -+ /* Now add this bunch of tnodes to a list for freeing up. -+ * NB If we can't add this to the management list it isn't fatal -+ * but it just means we can't free this bunch of tnodes later. -+ */ -+ tnl = kmalloc(sizeof(struct yaffs_tnode_list), GFP_NOFS); -+ if (!tnl) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "Could not add tnodes to management list"); -+ return YAFFS_FAIL; -+ } else { -+ tnl->tnodes = new_tnodes; -+ tnl->next = allocator->alloc_tnode_list; -+ allocator->alloc_tnode_list = tnl; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_ALLOCATE, "Tnodes added"); -+ -+ return YAFFS_OK; -+} -+ -+struct yaffs_tnode *yaffs_alloc_raw_tnode(struct yaffs_dev *dev) -+{ -+ struct yaffs_allocator *allocator = -+ (struct yaffs_allocator *)dev->allocator; -+ struct yaffs_tnode *tn = NULL; -+ -+ if (!allocator) { -+ BUG(); -+ return NULL; -+ } -+ -+ /* If there are none left make more */ -+ if (!allocator->free_tnodes) -+ yaffs_create_tnodes(dev, YAFFS_ALLOCATION_NTNODES); -+ -+ if (allocator->free_tnodes) { -+ tn = allocator->free_tnodes; -+ allocator->free_tnodes = allocator->free_tnodes->internal[0]; -+ allocator->n_free_tnodes--; -+ } -+ -+ return tn; -+} -+ -+/* FreeTnode frees up a tnode and puts it back on the free list */ -+void yaffs_free_raw_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn) -+{ -+ struct yaffs_allocator *allocator = dev->allocator; -+ -+ if (!allocator) { -+ BUG(); -+ return; -+ } -+ -+ if (tn) { -+ tn->internal[0] = allocator->free_tnodes; -+ allocator->free_tnodes = tn; -+ allocator->n_free_tnodes++; -+ } -+ dev->checkpoint_blocks_required = 0; /* force recalculation */ -+} -+ -+/*--------------- yaffs_obj alloaction ------------------------ -+ * -+ * Free yaffs_objs are stored in a list using obj->siblings. -+ * The blocks of allocated objects are stored in a linked list. -+ */ -+ -+static void yaffs_init_raw_objs(struct yaffs_dev *dev) -+{ -+ struct yaffs_allocator *allocator = dev->allocator; -+ -+ if (!allocator) { -+ BUG(); -+ return; -+ } -+ -+ allocator->allocated_obj_list = NULL; -+ INIT_LIST_HEAD(&allocator->free_objs); -+ allocator->n_free_objects = 0; -+} -+ -+static void yaffs_deinit_raw_objs(struct yaffs_dev *dev) -+{ -+ struct yaffs_allocator *allocator = dev->allocator; -+ struct yaffs_obj_list *tmp; -+ -+ if (!allocator) { -+ BUG(); -+ return; -+ } -+ -+ while (allocator->allocated_obj_list) { -+ tmp = allocator->allocated_obj_list->next; -+ kfree(allocator->allocated_obj_list->objects); -+ kfree(allocator->allocated_obj_list); -+ allocator->allocated_obj_list = tmp; -+ } -+ -+ INIT_LIST_HEAD(&allocator->free_objs); -+ allocator->n_free_objects = 0; -+ allocator->n_obj_created = 0; -+} -+ -+static int yaffs_create_free_objs(struct yaffs_dev *dev, int n_obj) -+{ -+ struct yaffs_allocator *allocator = dev->allocator; -+ int i; -+ struct yaffs_obj *new_objs; -+ struct yaffs_obj_list *list; -+ -+ if (!allocator) { -+ BUG(); -+ return YAFFS_FAIL; -+ } -+ -+ if (n_obj < 1) -+ return YAFFS_OK; -+ -+ /* make these things */ -+ new_objs = kmalloc(n_obj * sizeof(struct yaffs_obj), GFP_NOFS); -+ list = kmalloc(sizeof(struct yaffs_obj_list), GFP_NOFS); -+ -+ if (!new_objs || !list) { -+ kfree(new_objs); -+ new_objs = NULL; -+ kfree(list); -+ list = NULL; -+ yaffs_trace(YAFFS_TRACE_ALLOCATE, -+ "Could not allocate more objects"); -+ return YAFFS_FAIL; -+ } -+ -+ /* Hook them into the free list */ -+ for (i = 0; i < n_obj; i++) -+ list_add(&new_objs[i].siblings, &allocator->free_objs); -+ -+ allocator->n_free_objects += n_obj; -+ allocator->n_obj_created += n_obj; -+ -+ /* Now add this bunch of Objects to a list for freeing up. */ -+ -+ list->objects = new_objs; -+ list->next = allocator->allocated_obj_list; -+ allocator->allocated_obj_list = list; -+ -+ return YAFFS_OK; -+} -+ -+struct yaffs_obj *yaffs_alloc_raw_obj(struct yaffs_dev *dev) -+{ -+ struct yaffs_obj *obj = NULL; -+ struct list_head *lh; -+ struct yaffs_allocator *allocator = dev->allocator; -+ -+ if (!allocator) { -+ BUG(); -+ return obj; -+ } -+ -+ /* If there are none left make more */ -+ if (list_empty(&allocator->free_objs)) -+ yaffs_create_free_objs(dev, YAFFS_ALLOCATION_NOBJECTS); -+ -+ if (!list_empty(&allocator->free_objs)) { -+ lh = allocator->free_objs.next; -+ obj = list_entry(lh, struct yaffs_obj, siblings); -+ list_del_init(lh); -+ allocator->n_free_objects--; -+ } -+ -+ return obj; -+} -+ -+void yaffs_free_raw_obj(struct yaffs_dev *dev, struct yaffs_obj *obj) -+{ -+ -+ struct yaffs_allocator *allocator = dev->allocator; -+ -+ if (!allocator) { -+ BUG(); -+ return; -+ } -+ -+ /* Link into the free list. */ -+ list_add(&obj->siblings, &allocator->free_objs); -+ allocator->n_free_objects++; -+} -+ -+void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev) -+{ -+ -+ if (!dev->allocator) { -+ BUG(); -+ return; -+ } -+ -+ yaffs_deinit_raw_tnodes(dev); -+ yaffs_deinit_raw_objs(dev); -+ kfree(dev->allocator); -+ dev->allocator = NULL; -+} -+ -+void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev) -+{ -+ struct yaffs_allocator *allocator; -+ -+ if (dev->allocator) { -+ BUG(); -+ return; -+ } -+ -+ allocator = kmalloc(sizeof(struct yaffs_allocator), GFP_NOFS); -+ if (allocator) { -+ dev->allocator = allocator; -+ yaffs_init_raw_tnodes(dev); -+ yaffs_init_raw_objs(dev); -+ } -+} -+ ---- linux-4.9.37/fs/yaffs2/yaffs_allocator.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_allocator.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,30 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_ALLOCATOR_H__ -+#define __YAFFS_ALLOCATOR_H__ -+ -+#include "yaffs_guts.h" -+ -+void yaffs_init_raw_tnodes_and_objs(struct yaffs_dev *dev); -+void yaffs_deinit_raw_tnodes_and_objs(struct yaffs_dev *dev); -+ -+struct yaffs_tnode *yaffs_alloc_raw_tnode(struct yaffs_dev *dev); -+void yaffs_free_raw_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn); -+ -+struct yaffs_obj *yaffs_alloc_raw_obj(struct yaffs_dev *dev); -+void yaffs_free_raw_obj(struct yaffs_dev *dev, struct yaffs_obj *obj); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_attribs.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_attribs.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,136 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_guts.h" -+#include "yaffs_attribs.h" -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) -+#define IATTR_UID ia_uid -+#define IATTR_GID ia_gid -+#else -+#define IATTR_UID ia_uid.val -+#define IATTR_GID ia_gid.val -+#endif -+ -+/* -+ * Loading attibs from/to object header assumes the object header -+ * is in cpu endian. -+ */ -+void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh) -+{ -+ obj->yst_uid = oh->yst_uid; -+ obj->yst_gid = oh->yst_gid; -+ obj->yst_atime = oh->yst_atime; -+ obj->yst_mtime = oh->yst_mtime; -+ obj->yst_ctime = oh->yst_ctime; -+ obj->yst_rdev = oh->yst_rdev; -+} -+ -+void yaffs_load_attribs_oh(struct yaffs_obj_hdr *oh, struct yaffs_obj *obj) -+{ -+ oh->yst_uid = obj->yst_uid; -+ oh->yst_gid = obj->yst_gid; -+ oh->yst_atime = obj->yst_atime; -+ oh->yst_mtime = obj->yst_mtime; -+ oh->yst_ctime = obj->yst_ctime; -+ oh->yst_rdev = obj->yst_rdev; -+ -+} -+ -+void yaffs_load_current_time(struct yaffs_obj *obj, int do_a, int do_c) -+{ -+ obj->yst_mtime = Y_CURRENT_TIME; -+ if (do_a) -+ obj->yst_atime = obj->yst_mtime; -+ if (do_c) -+ obj->yst_ctime = obj->yst_mtime; -+} -+ -+void yaffs_attribs_init(struct yaffs_obj *obj, u32 gid, u32 uid, u32 rdev) -+{ -+ yaffs_load_current_time(obj, 1, 1); -+ obj->yst_rdev = rdev; -+ obj->yst_uid = uid; -+ obj->yst_gid = gid; -+} -+ -+static loff_t yaffs_get_file_size(struct yaffs_obj *obj) -+{ -+ YCHAR *alias = NULL; -+ obj = yaffs_get_equivalent_obj(obj); -+ -+ switch (obj->variant_type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ return obj->variant.file_variant.file_size; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ alias = obj->variant.symlink_variant.alias; -+ if (!alias) -+ return 0; -+ return strnlen(alias, YAFFS_MAX_ALIAS_LENGTH); -+ default: -+ return 0; -+ } -+} -+ -+int yaffs_set_attribs(struct yaffs_obj *obj, struct iattr *attr) -+{ -+ unsigned int valid = attr->ia_valid; -+ -+ if (valid & ATTR_MODE) -+ obj->yst_mode = attr->ia_mode; -+ if (valid & ATTR_UID) -+ obj->yst_uid = attr->IATTR_UID; -+ if (valid & ATTR_GID) -+ obj->yst_gid = attr->IATTR_GID; -+ -+ if (valid & ATTR_ATIME) -+ obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime); -+ if (valid & ATTR_CTIME) -+ obj->yst_ctime = Y_TIME_CONVERT(attr->ia_ctime); -+ if (valid & ATTR_MTIME) -+ obj->yst_mtime = Y_TIME_CONVERT(attr->ia_mtime); -+ -+ if (valid & ATTR_SIZE) -+ yaffs_resize_file(obj, attr->ia_size); -+ -+ yaffs_update_oh(obj, NULL, 1, 0, 0, NULL); -+ -+ return YAFFS_OK; -+ -+} -+ -+int yaffs_get_attribs(struct yaffs_obj *obj, struct iattr *attr) -+{ -+ unsigned int valid = 0; -+ -+ attr->ia_mode = obj->yst_mode; -+ valid |= ATTR_MODE; -+ attr->IATTR_UID = obj->yst_uid; -+ valid |= ATTR_UID; -+ attr->IATTR_GID = obj->yst_gid; -+ valid |= ATTR_GID; -+ -+ Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime; -+ valid |= ATTR_ATIME; -+ Y_TIME_CONVERT(attr->ia_ctime) = obj->yst_ctime; -+ valid |= ATTR_CTIME; -+ Y_TIME_CONVERT(attr->ia_mtime) = obj->yst_mtime; -+ valid |= ATTR_MTIME; -+ -+ attr->ia_size = yaffs_get_file_size(obj); -+ valid |= ATTR_SIZE; -+ -+ attr->ia_valid = valid; -+ -+ return YAFFS_OK; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_attribs.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_attribs.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,28 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_ATTRIBS_H__ -+#define __YAFFS_ATTRIBS_H__ -+ -+#include "yaffs_guts.h" -+ -+void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh); -+void yaffs_load_attribs_oh(struct yaffs_obj_hdr *oh, struct yaffs_obj *obj); -+void yaffs_attribs_init(struct yaffs_obj *obj, u32 gid, u32 uid, u32 rdev); -+void yaffs_load_current_time(struct yaffs_obj *obj, int do_a, int do_c); -+int yaffs_set_attribs(struct yaffs_obj *obj, struct iattr *attr); -+int yaffs_get_attribs(struct yaffs_obj *obj, struct iattr *attr); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_bitmap.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_bitmap.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,99 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_bitmap.h" -+#include "yaffs_trace.h" -+/* -+ * Chunk bitmap manipulations -+ */ -+ -+static inline u8 *yaffs_block_bits(struct yaffs_dev *dev, int blk) -+{ -+ if (blk < (int)dev->internal_start_block || -+ blk > (int)dev->internal_end_block) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "BlockBits block %d is not valid", -+ blk); -+ BUG(); -+ } -+ return dev->chunk_bits + -+ (dev->chunk_bit_stride * (blk - dev->internal_start_block)); -+} -+ -+void yaffs_verify_chunk_bit_id(struct yaffs_dev *dev, int blk, int chunk) -+{ -+ if (blk < (int)dev->internal_start_block || -+ blk > (int)dev->internal_end_block || -+ chunk < 0 || chunk >= (int)dev->param.chunks_per_block) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "Chunk Id (%d:%d) invalid", -+ blk, chunk); -+ BUG(); -+ } -+} -+ -+void yaffs_clear_chunk_bits(struct yaffs_dev *dev, int blk) -+{ -+ u8 *blk_bits = yaffs_block_bits(dev, blk); -+ -+ memset(blk_bits, 0, dev->chunk_bit_stride); -+} -+ -+void yaffs_clear_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) -+{ -+ u8 *blk_bits = yaffs_block_bits(dev, blk); -+ -+ yaffs_verify_chunk_bit_id(dev, blk, chunk); -+ blk_bits[chunk / 8] &= ~(1 << (chunk & 7)); -+} -+ -+void yaffs_set_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) -+{ -+ u8 *blk_bits = yaffs_block_bits(dev, blk); -+ -+ yaffs_verify_chunk_bit_id(dev, blk, chunk); -+ blk_bits[chunk / 8] |= (1 << (chunk & 7)); -+} -+ -+int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk) -+{ -+ u8 *blk_bits = yaffs_block_bits(dev, blk); -+ -+ yaffs_verify_chunk_bit_id(dev, blk, chunk); -+ return (blk_bits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0; -+} -+ -+int yaffs_still_some_chunks(struct yaffs_dev *dev, int blk) -+{ -+ u8 *blk_bits = yaffs_block_bits(dev, blk); -+ int i; -+ -+ for (i = 0; i < dev->chunk_bit_stride; i++) { -+ if (*blk_bits) -+ return 1; -+ blk_bits++; -+ } -+ return 0; -+} -+ -+int yaffs_count_chunk_bits(struct yaffs_dev *dev, int blk) -+{ -+ u8 *blk_bits = yaffs_block_bits(dev, blk); -+ int i; -+ int n = 0; -+ -+ for (i = 0; i < dev->chunk_bit_stride; i++, blk_bits++) -+ n += hweight8(*blk_bits); -+ -+ return n; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_bitmap.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_bitmap.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,33 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+/* -+ * Chunk bitmap manipulations -+ */ -+ -+#ifndef __YAFFS_BITMAP_H__ -+#define __YAFFS_BITMAP_H__ -+ -+#include "yaffs_guts.h" -+ -+void yaffs_verify_chunk_bit_id(struct yaffs_dev *dev, int blk, int chunk); -+void yaffs_clear_chunk_bits(struct yaffs_dev *dev, int blk); -+void yaffs_clear_chunk_bit(struct yaffs_dev *dev, int blk, int chunk); -+void yaffs_set_chunk_bit(struct yaffs_dev *dev, int blk, int chunk); -+int yaffs_check_chunk_bit(struct yaffs_dev *dev, int blk, int chunk); -+int yaffs_still_some_chunks(struct yaffs_dev *dev, int blk); -+int yaffs_count_chunk_bits(struct yaffs_dev *dev, int blk); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_checkptrw.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_checkptrw.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,481 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_checkptrw.h" -+#include "yaffs_getblockinfo.h" -+#include "yaffs_endian.h" -+ -+struct yaffs_checkpt_chunk_hdr { -+ int version; -+ int seq; -+ u32 sum; -+ u32 xor; -+} ; -+ -+ -+static int apply_chunk_offset(struct yaffs_dev *dev, int chunk) -+{ -+ return chunk - dev->chunk_offset; -+} -+ -+static int apply_block_offset(struct yaffs_dev *dev, int block) -+{ -+ return block - dev->block_offset; -+} -+ -+ -+static void yaffs2_do_endian_hdr(struct yaffs_dev *dev, -+ struct yaffs_checkpt_chunk_hdr *hdr) -+{ -+ if (!dev->swap_endian) -+ return; -+ hdr->version = swap_s32(hdr->version); -+ hdr->seq = swap_s32(hdr->seq); -+ hdr->sum = swap_u32(hdr->sum); -+ hdr->xor = swap_u32(hdr->xor); -+} -+ -+static void yaffs2_checkpt_init_chunk_hdr(struct yaffs_dev *dev) -+{ -+ struct yaffs_checkpt_chunk_hdr hdr; -+ -+ hdr.version = YAFFS_CHECKPOINT_VERSION; -+ hdr.seq = dev->checkpt_page_seq; -+ hdr.sum = dev->checkpt_sum; -+ hdr.xor = dev->checkpt_xor; -+ -+ dev->checkpt_byte_offs = sizeof(hdr); -+ -+ yaffs2_do_endian_hdr(dev, &hdr); -+ memcpy(dev->checkpt_buffer, &hdr, sizeof(hdr)); -+} -+ -+static int yaffs2_checkpt_check_chunk_hdr(struct yaffs_dev *dev) -+{ -+ struct yaffs_checkpt_chunk_hdr hdr; -+ -+ memcpy(&hdr, dev->checkpt_buffer, sizeof(hdr)); -+ yaffs2_do_endian_hdr(dev, &hdr); -+ -+ dev->checkpt_byte_offs = sizeof(hdr); -+ -+ return hdr.version == YAFFS_CHECKPOINT_VERSION && -+ hdr.seq == dev->checkpt_page_seq && -+ hdr.sum == dev->checkpt_sum && -+ hdr.xor == dev->checkpt_xor; -+} -+ -+static int yaffs2_checkpt_space_ok(struct yaffs_dev *dev) -+{ -+ int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks; -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "checkpt blocks_avail = %d", blocks_avail); -+ -+ return (blocks_avail <= 0) ? 0 : 1; -+} -+ -+static int yaffs_checkpt_erase(struct yaffs_dev *dev) -+{ -+ u32 i; -+ -+ if (!dev->drv.drv_erase_fn) -+ return 0; -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "checking blocks %d to %d", -+ dev->internal_start_block, dev->internal_end_block); -+ -+ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, i); -+ int offset_i = apply_block_offset(dev, i); -+ int result; -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "erasing checkpt block %d", i); -+ -+ dev->n_erasures++; -+ -+ result = dev->drv.drv_erase_fn(dev, offset_i); -+ if(result) { -+ bi->block_state = YAFFS_BLOCK_STATE_EMPTY; -+ dev->n_erased_blocks++; -+ dev->n_free_chunks += -+ dev->param.chunks_per_block; -+ } else { -+ dev->drv.drv_mark_bad_fn(dev, offset_i); -+ bi->block_state = YAFFS_BLOCK_STATE_DEAD; -+ } -+ } -+ } -+ -+ dev->blocks_in_checkpt = 0; -+ -+ return 1; -+} -+ -+static void yaffs2_checkpt_find_erased_block(struct yaffs_dev *dev) -+{ -+ u32 i; -+ int blocks_avail = dev->n_erased_blocks - dev->param.n_reserved_blocks; -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "allocating checkpt block: erased %d reserved %d avail %d next %d ", -+ dev->n_erased_blocks, dev->param.n_reserved_blocks, -+ blocks_avail, dev->checkpt_next_block); -+ -+ if (dev->checkpt_next_block >= 0 && -+ dev->checkpt_next_block <= (int)dev->internal_end_block && -+ blocks_avail > 0) { -+ -+ for (i = dev->checkpt_next_block; i <= dev->internal_end_block; -+ i++) { -+ struct yaffs_block_info *bi; -+ -+ bi = yaffs_get_block_info(dev, i); -+ if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) { -+ dev->checkpt_next_block = i + 1; -+ dev->checkpt_cur_block = i; -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "allocating checkpt block %d", i); -+ return; -+ } -+ } -+ } -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, "out of checkpt blocks"); -+ -+ dev->checkpt_next_block = -1; -+ dev->checkpt_cur_block = -1; -+} -+ -+static void yaffs2_checkpt_find_block(struct yaffs_dev *dev) -+{ -+ u32 i; -+ struct yaffs_ext_tags tags; -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "find next checkpt block: start: blocks %d next %d", -+ dev->blocks_in_checkpt, dev->checkpt_next_block); -+ -+ if (dev->blocks_in_checkpt < dev->checkpt_max_blocks) -+ for (i = dev->checkpt_next_block; i <= dev->internal_end_block; -+ i++) { -+ int chunk = i * dev->param.chunks_per_block; -+ enum yaffs_block_state state; -+ u32 seq; -+ -+ dev->tagger.read_chunk_tags_fn(dev, -+ apply_chunk_offset(dev, chunk), -+ NULL, &tags); -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "find next checkpt block: search: block %d state %d oid %d seq %d eccr %d", -+ i, (int) state, -+ tags.obj_id, tags.seq_number, -+ tags.ecc_result); -+ -+ if (tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA) -+ continue; -+ -+ dev->tagger.query_block_fn(dev, -+ apply_block_offset(dev, i), -+ &state, &seq); -+ if (state == YAFFS_BLOCK_STATE_DEAD) -+ continue; -+ -+ /* Right kind of block */ -+ dev->checkpt_next_block = tags.obj_id; -+ dev->checkpt_cur_block = i; -+ dev->checkpt_block_list[dev->blocks_in_checkpt] = i; -+ dev->blocks_in_checkpt++; -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "found checkpt block %d", i); -+ return; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, "found no more checkpt blocks"); -+ -+ dev->checkpt_next_block = -1; -+ dev->checkpt_cur_block = -1; -+} -+ -+int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing) -+{ -+ u32 i; -+ -+ dev->checkpt_open_write = writing; -+ -+ /* Got the functions we need? */ -+ if (!dev->tagger.write_chunk_tags_fn || -+ !dev->tagger.read_chunk_tags_fn || -+ !dev->drv.drv_erase_fn || -+ !dev->drv.drv_mark_bad_fn) -+ return 0; -+ -+ if (writing && !yaffs2_checkpt_space_ok(dev)) -+ return 0; -+ -+ if (!dev->checkpt_buffer) -+ dev->checkpt_buffer = -+ kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); -+ if (!dev->checkpt_buffer) -+ return 0; -+ -+ dev->checkpt_page_seq = 0; -+ dev->checkpt_byte_count = 0; -+ dev->checkpt_sum = 0; -+ dev->checkpt_xor = 0; -+ dev->checkpt_cur_block = -1; -+ dev->checkpt_cur_chunk = -1; -+ dev->checkpt_next_block = dev->internal_start_block; -+ -+ if (writing) { -+ memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk); -+ yaffs2_checkpt_init_chunk_hdr(dev); -+ return yaffs_checkpt_erase(dev); -+ } -+ -+ /* Opening for a read */ -+ /* Set to a value that will kick off a read */ -+ dev->checkpt_byte_offs = dev->data_bytes_per_chunk; -+ /* A checkpoint block list of 1 checkpoint block per 16 block is -+ * (hopefully) going to be way more than we need */ -+ dev->blocks_in_checkpt = 0; -+ dev->checkpt_max_blocks = -+ (dev->internal_end_block - dev->internal_start_block) / 16 + 2; -+ if (!dev->checkpt_block_list) -+ dev->checkpt_block_list = -+ kmalloc(sizeof(int) * dev->checkpt_max_blocks, GFP_NOFS); -+ -+ if (!dev->checkpt_block_list) -+ return 0; -+ -+ for (i = 0; i < dev->checkpt_max_blocks; i++) -+ dev->checkpt_block_list[i] = -1; -+ -+ return 1; -+} -+ -+int yaffs2_get_checkpt_sum(struct yaffs_dev *dev, u32 * sum) -+{ -+ u32 composite_sum; -+ -+ composite_sum = (dev->checkpt_sum << 8) | (dev->checkpt_xor & 0xff); -+ *sum = composite_sum; -+ return 1; -+} -+ -+static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev) -+{ -+ int chunk; -+ int offset_chunk; -+ struct yaffs_ext_tags tags; -+ -+ if (dev->checkpt_cur_block < 0) { -+ yaffs2_checkpt_find_erased_block(dev); -+ dev->checkpt_cur_chunk = 0; -+ } -+ -+ if (dev->checkpt_cur_block < 0) -+ return 0; -+ -+ tags.is_deleted = 0; -+ tags.obj_id = dev->checkpt_next_block; /* Hint to next place to look */ -+ tags.chunk_id = dev->checkpt_page_seq + 1; -+ tags.seq_number = YAFFS_SEQUENCE_CHECKPOINT_DATA; -+ tags.n_bytes = dev->data_bytes_per_chunk; -+ if (dev->checkpt_cur_chunk == 0) { -+ /* First chunk we write for the block? Set block state to -+ checkpoint */ -+ struct yaffs_block_info *bi = -+ yaffs_get_block_info(dev, dev->checkpt_cur_block); -+ bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT; -+ dev->blocks_in_checkpt++; -+ } -+ -+ chunk = -+ dev->checkpt_cur_block * dev->param.chunks_per_block + -+ dev->checkpt_cur_chunk; -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "checkpoint wite buffer nand %d(%d:%d) objid %d chId %d", -+ chunk, dev->checkpt_cur_block, dev->checkpt_cur_chunk, -+ tags.obj_id, tags.chunk_id); -+ -+ offset_chunk = apply_chunk_offset(dev, chunk); -+ -+ dev->n_page_writes++; -+ -+ dev->tagger.write_chunk_tags_fn(dev, offset_chunk, -+ dev->checkpt_buffer, &tags); -+ dev->checkpt_page_seq++; -+ dev->checkpt_cur_chunk++; -+ if (dev->checkpt_cur_chunk >= (int)dev->param.chunks_per_block) { -+ dev->checkpt_cur_chunk = 0; -+ dev->checkpt_cur_block = -1; -+ } -+ memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk); -+ -+ yaffs2_checkpt_init_chunk_hdr(dev); -+ -+ -+ return 1; -+} -+ -+int yaffs2_checkpt_wr(struct yaffs_dev *dev, const void *data, int n_bytes) -+{ -+ int i = 0; -+ int ok = 1; -+ u8 *data_bytes = (u8 *) data; -+ -+ if (!dev->checkpt_buffer) -+ return 0; -+ -+ if (!dev->checkpt_open_write) -+ return -1; -+ -+ while (i < n_bytes && ok) { -+ dev->checkpt_buffer[dev->checkpt_byte_offs] = *data_bytes; -+ dev->checkpt_sum += *data_bytes; -+ dev->checkpt_xor ^= *data_bytes; -+ -+ dev->checkpt_byte_offs++; -+ i++; -+ data_bytes++; -+ dev->checkpt_byte_count++; -+ -+ if (dev->checkpt_byte_offs < 0 || -+ dev->checkpt_byte_offs >= (int)dev->data_bytes_per_chunk) -+ ok = yaffs2_checkpt_flush_buffer(dev); -+ } -+ -+ return i; -+} -+ -+int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes) -+{ -+ int i = 0; -+ struct yaffs_ext_tags tags; -+ int chunk; -+ int offset_chunk; -+ u8 *data_bytes = (u8 *) data; -+ -+ if (!dev->checkpt_buffer) -+ return 0; -+ -+ if (dev->checkpt_open_write) -+ return -1; -+ -+ while (i < n_bytes) { -+ -+ if (dev->checkpt_byte_offs < 0 || -+ dev->checkpt_byte_offs >= (int)dev->data_bytes_per_chunk) { -+ -+ if (dev->checkpt_cur_block < 0) { -+ yaffs2_checkpt_find_block(dev); -+ dev->checkpt_cur_chunk = 0; -+ } -+ -+ /* Bail out if we can't find a checpoint block */ -+ if (dev->checkpt_cur_block < 0) -+ break; -+ -+ chunk = dev->checkpt_cur_block * -+ dev->param.chunks_per_block + -+ dev->checkpt_cur_chunk; -+ -+ offset_chunk = apply_chunk_offset(dev, chunk); -+ dev->n_page_reads++; -+ -+ /* Read in the next chunk */ -+ dev->tagger.read_chunk_tags_fn(dev, -+ offset_chunk, -+ dev->checkpt_buffer, -+ &tags); -+ -+ /* Bail out if the chunk is corrupted. */ -+ if (tags.chunk_id != (u32)(dev->checkpt_page_seq + 1) || -+ tags.ecc_result > YAFFS_ECC_RESULT_FIXED || -+ tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA) -+ break; -+ -+ /* Bail out if it is not a checkpoint chunk. */ -+ if(!yaffs2_checkpt_check_chunk_hdr(dev)) -+ break; -+ -+ dev->checkpt_page_seq++; -+ dev->checkpt_cur_chunk++; -+ -+ if (dev->checkpt_cur_chunk >= -+ (int)dev->param.chunks_per_block) -+ dev->checkpt_cur_block = -1; -+ -+ } -+ -+ *data_bytes = dev->checkpt_buffer[dev->checkpt_byte_offs]; -+ dev->checkpt_sum += *data_bytes; -+ dev->checkpt_xor ^= *data_bytes; -+ dev->checkpt_byte_offs++; -+ i++; -+ data_bytes++; -+ dev->checkpt_byte_count++; -+ } -+ -+ return i; /* Number of bytes read */ -+} -+ -+int yaffs_checkpt_close(struct yaffs_dev *dev) -+{ -+ u32 i; -+ -+ if (dev->checkpt_open_write) { -+ if (dev->checkpt_byte_offs != -+ sizeof(sizeof(struct yaffs_checkpt_chunk_hdr))) -+ yaffs2_checkpt_flush_buffer(dev); -+ } else if (dev->checkpt_block_list) { -+ for (i = 0; -+ i < dev->blocks_in_checkpt && -+ dev->checkpt_block_list[i] >= 0; i++) { -+ int blk = dev->checkpt_block_list[i]; -+ struct yaffs_block_info *bi = NULL; -+ -+ if ((int)dev->internal_start_block <= blk && -+ blk <= (int)dev->internal_end_block) -+ bi = yaffs_get_block_info(dev, blk); -+ if (bi && bi->block_state == YAFFS_BLOCK_STATE_EMPTY) -+ bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT; -+ } -+ } -+ -+ dev->n_free_chunks -= -+ dev->blocks_in_checkpt * dev->param.chunks_per_block; -+ dev->n_erased_blocks -= dev->blocks_in_checkpt; -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, "checkpoint byte count %d", -+ dev->checkpt_byte_count); -+ -+ if (dev->checkpt_buffer) -+ return 1; -+ else -+ return 0; -+} -+ -+int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev) -+{ -+ /* Erase the checkpoint data */ -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "checkpoint invalidate of %d blocks", -+ dev->blocks_in_checkpt); -+ -+ return yaffs_checkpt_erase(dev); -+} ---- linux-4.9.37/fs/yaffs2/yaffs_checkptrw.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_checkptrw.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,33 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_CHECKPTRW_H__ -+#define __YAFFS_CHECKPTRW_H__ -+ -+#include "yaffs_guts.h" -+ -+int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing); -+ -+int yaffs2_checkpt_wr(struct yaffs_dev *dev, const void *data, int n_bytes); -+ -+int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes); -+ -+int yaffs2_get_checkpt_sum(struct yaffs_dev *dev, u32 * sum); -+ -+int yaffs_checkpt_close(struct yaffs_dev *dev); -+ -+int yaffs2_checkpt_invalidate_stream(struct yaffs_dev *dev); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_ecc.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_ecc.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,281 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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. -+ */ -+ -+/* -+ * This code implements the ECC algorithm used in SmartMedia. -+ * -+ * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. -+ * The two unused bit are set to 1. -+ * The ECC can correct single bit errors in a 256-byte page of data. Thus, two -+ * such ECC blocks are used on a 512-byte NAND page. -+ * -+ */ -+ -+#include "yportenv.h" -+ -+#include "yaffs_ecc.h" -+ -+/* Table generated by gen-ecc.c -+ * Using a table means we do not have to calculate p1..p4 and p1'..p4' -+ * for each byte of data. These are instead provided in a table in bits7..2. -+ * Bit 0 of each entry indicates whether the entry has an odd or even parity, -+ * and therefore this bytes influence on the line parity. -+ */ -+ -+static const unsigned char column_parity_table[] = { -+ 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, -+ 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, -+ 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, -+ 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, -+ 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, -+ 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, -+ 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, -+ 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, -+ 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, -+ 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, -+ 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, -+ 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, -+ 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, -+ 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, -+ 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, -+ 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, -+ 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, -+ 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, -+ 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, -+ 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, -+ 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, -+ 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, -+ 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, -+ 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, -+ 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, -+ 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, -+ 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, -+ 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, -+ 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, -+ 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, -+ 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, -+ 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, -+}; -+ -+ -+/* Calculate the ECC for a 256-byte block of data */ -+void yaffs_ecc_calc(const unsigned char *data, unsigned char *ecc) -+{ -+ unsigned int i; -+ unsigned char col_parity = 0; -+ unsigned char line_parity = 0; -+ unsigned char line_parity_prime = 0; -+ unsigned char t; -+ unsigned char b; -+ -+ for (i = 0; i < 256; i++) { -+ b = column_parity_table[*data++]; -+ col_parity ^= b; -+ -+ if (b & 0x01) { /* odd number of bits in the byte */ -+ line_parity ^= i; -+ line_parity_prime ^= ~i; -+ } -+ } -+ -+ ecc[2] = (~col_parity) | 0x03; -+ -+ t = 0; -+ if (line_parity & 0x80) -+ t |= 0x80; -+ if (line_parity_prime & 0x80) -+ t |= 0x40; -+ if (line_parity & 0x40) -+ t |= 0x20; -+ if (line_parity_prime & 0x40) -+ t |= 0x10; -+ if (line_parity & 0x20) -+ t |= 0x08; -+ if (line_parity_prime & 0x20) -+ t |= 0x04; -+ if (line_parity & 0x10) -+ t |= 0x02; -+ if (line_parity_prime & 0x10) -+ t |= 0x01; -+ ecc[1] = ~t; -+ -+ t = 0; -+ if (line_parity & 0x08) -+ t |= 0x80; -+ if (line_parity_prime & 0x08) -+ t |= 0x40; -+ if (line_parity & 0x04) -+ t |= 0x20; -+ if (line_parity_prime & 0x04) -+ t |= 0x10; -+ if (line_parity & 0x02) -+ t |= 0x08; -+ if (line_parity_prime & 0x02) -+ t |= 0x04; -+ if (line_parity & 0x01) -+ t |= 0x02; -+ if (line_parity_prime & 0x01) -+ t |= 0x01; -+ ecc[0] = ~t; -+ -+} -+ -+/* Correct the ECC on a 256 byte block of data */ -+ -+int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc, -+ const unsigned char *test_ecc) -+{ -+ unsigned char d0, d1, d2; /* deltas */ -+ -+ d0 = read_ecc[0] ^ test_ecc[0]; -+ d1 = read_ecc[1] ^ test_ecc[1]; -+ d2 = read_ecc[2] ^ test_ecc[2]; -+ -+ if ((d0 | d1 | d2) == 0) -+ return 0; /* no error */ -+ -+ if (((d0 ^ (d0 >> 1)) & 0x55) == 0x55 && -+ ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 && -+ ((d2 ^ (d2 >> 1)) & 0x54) == 0x54) { -+ /* Single bit (recoverable) error in data */ -+ -+ unsigned byte; -+ unsigned bit; -+ -+ bit = byte = 0; -+ -+ if (d1 & 0x80) -+ byte |= 0x80; -+ if (d1 & 0x20) -+ byte |= 0x40; -+ if (d1 & 0x08) -+ byte |= 0x20; -+ if (d1 & 0x02) -+ byte |= 0x10; -+ if (d0 & 0x80) -+ byte |= 0x08; -+ if (d0 & 0x20) -+ byte |= 0x04; -+ if (d0 & 0x08) -+ byte |= 0x02; -+ if (d0 & 0x02) -+ byte |= 0x01; -+ -+ if (d2 & 0x80) -+ bit |= 0x04; -+ if (d2 & 0x20) -+ bit |= 0x02; -+ if (d2 & 0x08) -+ bit |= 0x01; -+ -+ data[byte] ^= (1 << bit); -+ -+ return 1; /* Corrected the error */ -+ } -+ -+ if ((hweight8(d0) + hweight8(d1) + hweight8(d2)) == 1) { -+ /* Reccoverable error in ecc */ -+ -+ read_ecc[0] = test_ecc[0]; -+ read_ecc[1] = test_ecc[1]; -+ read_ecc[2] = test_ecc[2]; -+ -+ return 1; /* Corrected the error */ -+ } -+ -+ /* Unrecoverable error */ -+ -+ return -1; -+ -+} -+ -+/* -+ * ECCxxxOther does ECC calcs on arbitrary n bytes of data -+ */ -+void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes, -+ struct yaffs_ecc_other *ecc_other) -+{ -+ unsigned int i; -+ unsigned char col_parity = 0; -+ unsigned line_parity = 0; -+ unsigned line_parity_prime = 0; -+ unsigned char b; -+ -+ for (i = 0; i < n_bytes; i++) { -+ b = column_parity_table[*data++]; -+ col_parity ^= b; -+ -+ if (b & 0x01) { -+ /* odd number of bits in the byte */ -+ line_parity ^= i; -+ line_parity_prime ^= ~i; -+ } -+ -+ } -+ -+ ecc_other->col_parity = (col_parity >> 2) & 0x3f; -+ ecc_other->line_parity = line_parity; -+ ecc_other->line_parity_prime = line_parity_prime; -+} -+ -+int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes, -+ struct yaffs_ecc_other *read_ecc, -+ const struct yaffs_ecc_other *test_ecc) -+{ -+ unsigned char delta_col; /* column parity delta */ -+ unsigned delta_line; /* line parity delta */ -+ unsigned delta_line_prime; /* line parity delta */ -+ unsigned bit; -+ -+ delta_col = read_ecc->col_parity ^ test_ecc->col_parity; -+ delta_line = read_ecc->line_parity ^ test_ecc->line_parity; -+ delta_line_prime = -+ read_ecc->line_parity_prime ^ test_ecc->line_parity_prime; -+ -+ if ((delta_col | delta_line | delta_line_prime) == 0) -+ return 0; /* no error */ -+ -+ if (delta_line == ~delta_line_prime && -+ (((delta_col ^ (delta_col >> 1)) & 0x15) == 0x15)) { -+ /* Single bit (recoverable) error in data */ -+ -+ bit = 0; -+ -+ if (delta_col & 0x20) -+ bit |= 0x04; -+ if (delta_col & 0x08) -+ bit |= 0x02; -+ if (delta_col & 0x02) -+ bit |= 0x01; -+ -+ if (delta_line >= n_bytes) -+ return -1; -+ -+ data[delta_line] ^= (1 << bit); -+ -+ return 1; /* corrected */ -+ } -+ -+ if ((hweight32(delta_line) + -+ hweight32(delta_line_prime) + -+ hweight8(delta_col)) == 1) { -+ /* Reccoverable error in ecc */ -+ -+ *read_ecc = *test_ecc; -+ return 1; /* corrected */ -+ } -+ -+ /* Unrecoverable error */ -+ -+ return -1; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_ecc.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_ecc.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,44 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+/* -+ * This code implements the ECC algorithm used in SmartMedia. -+ * -+ * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. -+ * The two unused bit are set to 1. -+ * The ECC can correct single bit errors in a 256-byte page of data. -+ * Thus, two such ECC blocks are used on a 512-byte NAND page. -+ * -+ */ -+ -+#ifndef __YAFFS_ECC_H__ -+#define __YAFFS_ECC_H__ -+ -+struct yaffs_ecc_other { -+ unsigned char col_parity; -+ unsigned line_parity; -+ unsigned line_parity_prime; -+}; -+ -+void yaffs_ecc_calc(const unsigned char *data, unsigned char *ecc); -+int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc, -+ const unsigned char *test_ecc); -+ -+void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes, -+ struct yaffs_ecc_other *ecc); -+int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes, -+ struct yaffs_ecc_other *read_ecc, -+ const struct yaffs_ecc_other *test_ecc); -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_endian.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_endian.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,106 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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. -+ * -+ * Endian processing functions. -+ */ -+ -+#include "yaffs_endian.h" -+#include "yaffs_guts.h" -+ -+ -+void yaffs_do_endian_u32(struct yaffs_dev *dev, u32 *val) -+{ -+ if (!dev->swap_endian) -+ return; -+ *val = swap_u32(*val); -+} -+ -+void yaffs_do_endian_s32(struct yaffs_dev *dev, s32 *val) -+{ -+ if (!dev->swap_endian) -+ return; -+ *val = swap_s32(*val); -+} -+ -+void yaffs_do_endian_oh(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh) -+{ -+ if (!dev->swap_endian) -+ return; -+ /* Change every field */ -+ oh->type = swap_u32(oh->type); -+ oh->parent_obj_id = swap_u32(oh->parent_obj_id); -+ -+ oh->yst_mode = swap_u32(oh->yst_mode); -+ -+ oh->yst_uid = swap_u32(oh->yst_uid); -+ oh->yst_gid = swap_u32(oh->yst_gid); -+ oh->yst_atime = swap_u32(oh->yst_atime); -+ oh->yst_mtime = swap_u32(oh->yst_mtime); -+ oh->yst_ctime = swap_u32(oh->yst_ctime); -+ -+ oh->file_size_low = swap_u32(oh->file_size_low); -+ -+ oh->equiv_id = swap_u32(oh->equiv_id); -+ -+ oh->yst_rdev = swap_u32(oh->yst_rdev); -+ -+ oh->win_ctime[0] = swap_u32(oh->win_ctime[0]); -+ oh->win_ctime[1] = swap_u32(oh->win_ctime[1]); -+ oh->win_atime[0] = swap_u32(oh->win_atime[0]); -+ oh->win_atime[1] = swap_u32(oh->win_atime[1]); -+ oh->win_mtime[0] = swap_u32(oh->win_mtime[0]); -+ oh->win_mtime[1] = swap_u32(oh->win_mtime[1]); -+ -+ oh->inband_shadowed_obj_id = swap_u32(oh->inband_shadowed_obj_id); -+ oh->inband_is_shrink = swap_u32(oh->inband_is_shrink); -+ -+ oh->file_size_high = swap_u32(oh->file_size_high); -+ oh->reserved[0] = swap_u32(oh->reserved[0]); -+ oh->shadows_obj = swap_s32(oh->shadows_obj); -+ -+ oh->is_shrink = swap_u32(oh->is_shrink); -+} -+ -+ -+void yaffs_do_endian_packed_tags2(struct yaffs_dev *dev, -+ struct yaffs_packed_tags2_tags_only *ptt) -+{ -+ if (!dev->swap_endian) -+ return; -+ ptt->seq_number = swap_u32(ptt->seq_number); -+ ptt->obj_id = swap_u32(ptt->obj_id); -+ ptt->chunk_id = swap_u32(ptt->chunk_id); -+ ptt->n_bytes = swap_u32(ptt->n_bytes); -+} -+ -+void yaffs_endian_config(struct yaffs_dev *dev) -+{ -+ u32 x = 1; -+ -+ if (dev->tnode_size < 1) -+ BUG(); -+ -+ dev->swap_endian = 0; -+ -+ if (((char *)&x)[0] == 1) { -+ /* Little Endian. */ -+ if (dev->param.stored_endian == 2 /* big endian */) -+ dev->swap_endian = 1; -+ } else { -+ /* Big Endian. */ -+ if (dev->param.stored_endian == 1 /* little endian */) -+ dev->swap_endian = 1; -+ } -+ -+ if (dev->swap_endian) -+ dev->tn_swap_buffer = kmalloc(dev->tnode_size, GFP_NOFS); -+} ---- linux-4.9.37/fs/yaffs2/yaffs_endian.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_endian.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,55 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_ENDIAN_H__ -+#define __YAFFS_ENDIAN_H__ -+#include "yaffs_guts.h" -+#include "yaffs_packedtags2.h" -+ -+static inline u32 swap_u32(u32 val) -+{ -+ return ((val >>24) & 0x000000ff) | -+ ((val >> 8) & 0x0000ff00) | -+ ((val << 8) & 0x00ff0000) | -+ ((val <<24) & 0xff000000); -+} -+ -+#define swap_s32(val) \ -+ (s32)(swap_u32((u32)(val))) -+ -+static inline loff_t swap_loff_t(loff_t lval) -+{ -+ u32 vall = swap_u32(FSIZE_LOW(lval)); -+ u32 valh; -+ -+ if (sizeof(loff_t) == sizeof(u32)) -+ return (loff_t) vall; -+ -+ valh = swap_u32(FSIZE_HIGH(lval)); -+ -+ return FSIZE_COMBINE(vall, valh); /*NB: h and l are swapped. */ -+} -+ -+ -+ -+struct yaffs_dev; -+void yaffs_do_endian_s32(struct yaffs_dev *dev, s32 *val); -+void yaffs_do_endian_u32(struct yaffs_dev *dev, u32 *val); -+void yaffs_do_endian_oh(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh); -+void yaffs_do_endian_packed_tags2(struct yaffs_dev *dev, -+ struct yaffs_packed_tags2_tags_only *ptt); -+void yaffs_endian_config(struct yaffs_dev *dev); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_getblockinfo.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_getblockinfo.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,36 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_GETBLOCKINFO_H__ -+#define __YAFFS_GETBLOCKINFO_H__ -+ -+#include "yaffs_guts.h" -+#include "yaffs_trace.h" -+ -+/* Function to manipulate block info */ -+static inline struct yaffs_block_info *yaffs_get_block_info(struct yaffs_dev -+ *dev, int blk) -+{ -+ if (blk < (int)dev->internal_start_block || -+ blk > (int)dev->internal_end_block) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "**>> yaffs: get_block_info block %d is not valid", -+ blk); -+ BUG(); -+ } -+ return &dev->block_info[blk - dev->internal_start_block]; -+} -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_guts.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_guts.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,5215 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yportenv.h" -+#include "yaffs_trace.h" -+ -+#include "yaffs_guts.h" -+#include "yaffs_endian.h" -+#include "yaffs_getblockinfo.h" -+#include "yaffs_tagscompat.h" -+#include "yaffs_tagsmarshall.h" -+#include "yaffs_nand.h" -+#include "yaffs_yaffs1.h" -+#include "yaffs_yaffs2.h" -+#include "yaffs_bitmap.h" -+#include "yaffs_verify.h" -+#include "yaffs_nand.h" -+#include "yaffs_packedtags2.h" -+#include "yaffs_nameval.h" -+#include "yaffs_allocator.h" -+#include "yaffs_attribs.h" -+#include "yaffs_summary.h" -+ -+/* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */ -+#define YAFFS_GC_GOOD_ENOUGH 2 -+#define YAFFS_GC_PASSIVE_THRESHOLD 4 -+ -+#include "yaffs_ecc.h" -+ -+/* Forward declarations */ -+ -+static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, -+ const u8 *buffer, int n_bytes, int use_reserve); -+ -+static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name, -+ int buffer_size); -+ -+/* Function to calculate chunk and offset */ -+ -+void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr, -+ int *chunk_out, u32 *offset_out) -+{ -+ int chunk; -+ u32 offset; -+ -+ chunk = (u32) (addr >> dev->chunk_shift); -+ -+ if (dev->chunk_div == 1) { -+ /* easy power of 2 case */ -+ offset = (u32) (addr & dev->chunk_mask); -+ } else { -+ /* Non power-of-2 case */ -+ -+ loff_t chunk_base; -+ -+ chunk /= dev->chunk_div; -+ -+ chunk_base = ((loff_t) chunk) * dev->data_bytes_per_chunk; -+ offset = (u32) (addr - chunk_base); -+ } -+ -+ *chunk_out = chunk; -+ *offset_out = offset; -+} -+ -+/* Function to return the number of shifts for a power of 2 greater than or -+ * equal to the given number -+ * Note we don't try to cater for all possible numbers and this does not have to -+ * be hellishly efficient. -+ */ -+ -+static inline u32 calc_shifts_ceiling(u32 x) -+{ -+ int extra_bits; -+ int shifts; -+ -+ shifts = extra_bits = 0; -+ -+ while (x > 1) { -+ if (x & 1) -+ extra_bits++; -+ x >>= 1; -+ shifts++; -+ } -+ -+ if (extra_bits) -+ shifts++; -+ -+ return shifts; -+} -+ -+/* Function to return the number of shifts to get a 1 in bit 0 -+ */ -+ -+static inline u32 calc_shifts(u32 x) -+{ -+ u32 shifts; -+ -+ shifts = 0; -+ -+ if (!x) -+ return 0; -+ -+ while (!(x & 1)) { -+ x >>= 1; -+ shifts++; -+ } -+ -+ return shifts; -+} -+ -+/* -+ * Temporary buffer manipulations. -+ */ -+ -+static int yaffs_init_tmp_buffers(struct yaffs_dev *dev) -+{ -+ int i; -+ u8 *buf = (u8 *) 1; -+ -+ memset(dev->temp_buffer, 0, sizeof(dev->temp_buffer)); -+ -+ for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) { -+ dev->temp_buffer[i].in_use = 0; -+ buf = kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); -+ dev->temp_buffer[i].buffer = buf; -+ } -+ -+ return buf ? YAFFS_OK : YAFFS_FAIL; -+} -+ -+u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev) -+{ -+ int i; -+ -+ dev->temp_in_use++; -+ if (dev->temp_in_use > dev->max_temp) -+ dev->max_temp = dev->temp_in_use; -+ -+ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { -+ if (dev->temp_buffer[i].in_use == 0) { -+ dev->temp_buffer[i].in_use = 1; -+ return dev->temp_buffer[i].buffer; -+ } -+ } -+ -+ yaffs_trace(YAFFS_TRACE_BUFFERS, "Out of temp buffers"); -+ /* -+ * If we got here then we have to allocate an unmanaged one -+ * This is not good. -+ */ -+ -+ dev->unmanaged_buffer_allocs++; -+ return kmalloc(dev->data_bytes_per_chunk, GFP_NOFS); -+ -+} -+ -+void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer) -+{ -+ int i; -+ -+ dev->temp_in_use--; -+ -+ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { -+ if (dev->temp_buffer[i].buffer == buffer) { -+ dev->temp_buffer[i].in_use = 0; -+ return; -+ } -+ } -+ -+ if (buffer) { -+ /* assume it is an unmanaged one. */ -+ yaffs_trace(YAFFS_TRACE_BUFFERS, -+ "Releasing unmanaged temp buffer"); -+ kfree(buffer); -+ dev->unmanaged_buffer_deallocs++; -+ } -+ -+} -+ -+/* -+ * Functions for robustisizing TODO -+ * -+ */ -+ -+static void yaffs_handle_chunk_wr_ok(struct yaffs_dev *dev, int nand_chunk, -+ const u8 *data, -+ const struct yaffs_ext_tags *tags) -+{ -+ (void) dev; -+ (void) nand_chunk; -+ (void) data; -+ (void) tags; -+} -+ -+static void yaffs_handle_chunk_update(struct yaffs_dev *dev, int nand_chunk, -+ const struct yaffs_ext_tags *tags) -+{ -+ (void) dev; -+ (void) nand_chunk; -+ (void) tags; -+} -+ -+void yaffs_handle_chunk_error(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi) -+{ -+ if (!bi->gc_prioritise) { -+ bi->gc_prioritise = 1; -+ dev->has_pending_prioritised_gc = 1; -+ bi->chunk_error_strikes++; -+ -+ if (bi->chunk_error_strikes > 3) { -+ bi->needs_retiring = 1; /* Too many stikes, so retire */ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs: Block struck out"); -+ -+ } -+ } -+} -+ -+static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, int nand_chunk, -+ int erased_ok) -+{ -+ int flash_block = nand_chunk / dev->param.chunks_per_block; -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block); -+ -+ yaffs_handle_chunk_error(dev, bi); -+ -+ if (erased_ok) { -+ /* Was an actual write failure, -+ * so mark the block for retirement.*/ -+ bi->needs_retiring = 1; -+ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, -+ "**>> Block %d needs retiring", flash_block); -+ } -+ -+ /* Delete the chunk */ -+ yaffs_chunk_del(dev, nand_chunk, 1, __LINE__); -+ yaffs_skip_rest_of_block(dev); -+} -+ -+/* -+ * Verification code -+ */ -+ -+/* -+ * Simple hash function. Needs to have a reasonable spread -+ */ -+ -+static inline int yaffs_hash_fn(int n) -+{ -+ if (n < 0) -+ n = -n; -+ return n % YAFFS_NOBJECT_BUCKETS; -+} -+ -+/* -+ * Access functions to useful fake objects. -+ * Note that root might have a presence in NAND if permissions are set. -+ */ -+ -+struct yaffs_obj *yaffs_root(struct yaffs_dev *dev) -+{ -+ return dev->root_dir; -+} -+ -+struct yaffs_obj *yaffs_lost_n_found(struct yaffs_dev *dev) -+{ -+ return dev->lost_n_found; -+} -+ -+/* -+ * Erased NAND checking functions -+ */ -+ -+int yaffs_check_ff(u8 *buffer, int n_bytes) -+{ -+ /* Horrible, slow implementation */ -+ while (n_bytes--) { -+ if (*buffer != 0xff) -+ return 0; -+ buffer++; -+ } -+ return 1; -+} -+ -+static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk) -+{ -+ int retval = YAFFS_OK; -+ u8 *data = yaffs_get_temp_buffer(dev); -+ struct yaffs_ext_tags tags; -+ int result; -+ -+ result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags); -+ -+ if (result == YAFFS_FAIL || -+ tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR) -+ retval = YAFFS_FAIL; -+ -+ if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) || -+ tags.chunk_used) { -+ yaffs_trace(YAFFS_TRACE_NANDACCESS, -+ "Chunk %d not erased", nand_chunk); -+ retval = YAFFS_FAIL; -+ } -+ -+ yaffs_release_temp_buffer(dev, data); -+ -+ return retval; -+ -+} -+ -+static int yaffs_verify_chunk_written(struct yaffs_dev *dev, -+ int nand_chunk, -+ const u8 *data, -+ struct yaffs_ext_tags *tags) -+{ -+ int retval = YAFFS_OK; -+ struct yaffs_ext_tags temp_tags; -+ u8 *buffer = yaffs_get_temp_buffer(dev); -+ int result; -+ -+ result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags); -+ if (result == YAFFS_FAIL || -+ memcmp(buffer, data, dev->data_bytes_per_chunk) || -+ temp_tags.obj_id != tags->obj_id || -+ temp_tags.chunk_id != tags->chunk_id || -+ temp_tags.n_bytes != tags->n_bytes) -+ retval = YAFFS_FAIL; -+ -+ yaffs_release_temp_buffer(dev, buffer); -+ -+ return retval; -+} -+ -+ -+int yaffs_check_alloc_available(struct yaffs_dev *dev, int n_chunks) -+{ -+ int reserved_chunks; -+ int reserved_blocks = dev->param.n_reserved_blocks; -+ int checkpt_blocks; -+ -+ checkpt_blocks = yaffs_calc_checkpt_blocks_required(dev); -+ -+ reserved_chunks = -+ (reserved_blocks + checkpt_blocks) * dev->param.chunks_per_block; -+ -+ return (dev->n_free_chunks > (reserved_chunks + n_chunks)); -+} -+ -+static int yaffs_find_alloc_block(struct yaffs_dev *dev) -+{ -+ u32 i; -+ struct yaffs_block_info *bi; -+ -+ if (dev->n_erased_blocks < 1) { -+ /* Hoosterman we've got a problem. -+ * Can't get space to gc -+ */ -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs tragedy: no more erased blocks"); -+ -+ return -1; -+ } -+ -+ /* Find an empty block. */ -+ -+ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { -+ dev->alloc_block_finder++; -+ if (dev->alloc_block_finder < (int)dev->internal_start_block -+ || dev->alloc_block_finder > (int)dev->internal_end_block) { -+ dev->alloc_block_finder = dev->internal_start_block; -+ } -+ -+ bi = yaffs_get_block_info(dev, dev->alloc_block_finder); -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) { -+ bi->block_state = YAFFS_BLOCK_STATE_ALLOCATING; -+ dev->seq_number++; -+ bi->seq_number = dev->seq_number; -+ dev->n_erased_blocks--; -+ yaffs_trace(YAFFS_TRACE_ALLOCATE, -+ "Allocated block %d, seq %d, %d left" , -+ dev->alloc_block_finder, dev->seq_number, -+ dev->n_erased_blocks); -+ return dev->alloc_block_finder; -+ } -+ } -+ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs tragedy: no more erased blocks, but there should have been %d", -+ dev->n_erased_blocks); -+ -+ return -1; -+} -+ -+static int yaffs_alloc_chunk(struct yaffs_dev *dev, int use_reserver, -+ struct yaffs_block_info **block_ptr) -+{ -+ int ret_val; -+ struct yaffs_block_info *bi; -+ -+ if (dev->alloc_block < 0) { -+ /* Get next block to allocate off */ -+ dev->alloc_block = yaffs_find_alloc_block(dev); -+ dev->alloc_page = 0; -+ } -+ -+ if (!use_reserver && !yaffs_check_alloc_available(dev, 1)) { -+ /* No space unless we're allowed to use the reserve. */ -+ return -1; -+ } -+ -+ if (dev->n_erased_blocks < (int)dev->param.n_reserved_blocks -+ && dev->alloc_page == 0) -+ yaffs_trace(YAFFS_TRACE_ALLOCATE, "Allocating reserve"); -+ -+ /* Next page please.... */ -+ if (dev->alloc_block >= 0) { -+ bi = yaffs_get_block_info(dev, dev->alloc_block); -+ -+ ret_val = (dev->alloc_block * dev->param.chunks_per_block) + -+ dev->alloc_page; -+ bi->pages_in_use++; -+ yaffs_set_chunk_bit(dev, dev->alloc_block, dev->alloc_page); -+ -+ dev->alloc_page++; -+ -+ dev->n_free_chunks--; -+ -+ /* If the block is full set the state to full */ -+ if (dev->alloc_page >= dev->param.chunks_per_block) { -+ bi->block_state = YAFFS_BLOCK_STATE_FULL; -+ dev->alloc_block = -1; -+ } -+ -+ if (block_ptr) -+ *block_ptr = bi; -+ -+ return ret_val; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!"); -+ -+ return -1; -+} -+ -+static int yaffs_get_erased_chunks(struct yaffs_dev *dev) -+{ -+ int n; -+ -+ n = dev->n_erased_blocks * dev->param.chunks_per_block; -+ -+ if (dev->alloc_block > 0) -+ n += (dev->param.chunks_per_block - dev->alloc_page); -+ -+ return n; -+ -+} -+ -+/* -+ * yaffs_skip_rest_of_block() skips over the rest of the allocation block -+ * if we don't want to write to it. -+ */ -+void yaffs_skip_rest_of_block(struct yaffs_dev *dev) -+{ -+ struct yaffs_block_info *bi; -+ -+ if (dev->alloc_block > 0) { -+ bi = yaffs_get_block_info(dev, dev->alloc_block); -+ if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) { -+ bi->block_state = YAFFS_BLOCK_STATE_FULL; -+ dev->alloc_block = -1; -+ } -+ } -+} -+ -+static int yaffs_write_new_chunk(struct yaffs_dev *dev, -+ const u8 *data, -+ struct yaffs_ext_tags *tags, int use_reserver) -+{ -+ u32 attempts = 0; -+ int write_ok = 0; -+ int chunk; -+ -+ yaffs2_checkpt_invalidate(dev); -+ -+ do { -+ struct yaffs_block_info *bi = 0; -+ int erased_ok = 0; -+ -+ chunk = yaffs_alloc_chunk(dev, use_reserver, &bi); -+ if (chunk < 0) { -+ /* no space */ -+ break; -+ } -+ -+ /* First check this chunk is erased, if it needs -+ * checking. The checking policy (unless forced -+ * always on) is as follows: -+ * -+ * Check the first page we try to write in a block. -+ * If the check passes then we don't need to check any -+ * more. If the check fails, we check again... -+ * If the block has been erased, we don't need to check. -+ * -+ * However, if the block has been prioritised for gc, -+ * then we think there might be something odd about -+ * this block and stop using it. -+ * -+ * Rationale: We should only ever see chunks that have -+ * not been erased if there was a partially written -+ * chunk due to power loss. This checking policy should -+ * catch that case with very few checks and thus save a -+ * lot of checks that are most likely not needed. -+ * -+ * Mods to the above -+ * If an erase check fails or the write fails we skip the -+ * rest of the block. -+ */ -+ -+ /* let's give it a try */ -+ attempts++; -+ -+ if (dev->param.always_check_erased) -+ bi->skip_erased_check = 0; -+ -+ if (!bi->skip_erased_check) { -+ erased_ok = yaffs_check_chunk_erased(dev, chunk); -+ if (erased_ok != YAFFS_OK) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "**>> yaffs chunk %d was not erased", -+ chunk); -+ -+ /* If not erased, delete this one, -+ * skip rest of block and -+ * try another chunk */ -+ yaffs_chunk_del(dev, chunk, 1, __LINE__); -+ yaffs_skip_rest_of_block(dev); -+ continue; -+ } -+ } -+ -+ write_ok = yaffs_wr_chunk_tags_nand(dev, chunk, data, tags); -+ -+ if (!bi->skip_erased_check) -+ write_ok = -+ yaffs_verify_chunk_written(dev, chunk, data, tags); -+ -+ if (write_ok != YAFFS_OK) { -+ /* Clean up aborted write, skip to next block and -+ * try another chunk */ -+ yaffs_handle_chunk_wr_error(dev, chunk, erased_ok); -+ continue; -+ } -+ -+ bi->skip_erased_check = 1; -+ -+ /* Copy the data into the robustification buffer */ -+ yaffs_handle_chunk_wr_ok(dev, chunk, data, tags); -+ -+ } while (write_ok != YAFFS_OK && -+ (yaffs_wr_attempts == 0 || attempts <= yaffs_wr_attempts)); -+ -+ if (!write_ok) -+ chunk = -1; -+ -+ if (attempts > 1) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "**>> yaffs write required %d attempts", -+ attempts); -+ dev->n_retried_writes += (attempts - 1); -+ } -+ -+ return chunk; -+} -+ -+/* -+ * Block retiring for handling a broken block. -+ */ -+ -+static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block) -+{ -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block); -+ -+ yaffs2_checkpt_invalidate(dev); -+ -+ yaffs2_clear_oldest_dirty_seq(dev, bi); -+ -+ if (yaffs_mark_bad(dev, flash_block) != YAFFS_OK) { -+ if (yaffs_erase_block(dev, flash_block) != YAFFS_OK) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs: Failed to mark bad and erase block %d", -+ flash_block); -+ } else { -+ struct yaffs_ext_tags tags; -+ int chunk_id = -+ flash_block * dev->param.chunks_per_block; -+ -+ u8 *buffer = yaffs_get_temp_buffer(dev); -+ -+ memset(buffer, 0xff, dev->data_bytes_per_chunk); -+ memset(&tags, 0, sizeof(tags)); -+ tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK; -+ if (dev->tagger.write_chunk_tags_fn(dev, chunk_id - -+ dev->chunk_offset, -+ buffer, -+ &tags) != YAFFS_OK) -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs: Failed to write bad block marker to block %d", -+ flash_block); -+ -+ yaffs_release_temp_buffer(dev, buffer); -+ } -+ } -+ -+ bi->block_state = YAFFS_BLOCK_STATE_DEAD; -+ bi->gc_prioritise = 0; -+ bi->needs_retiring = 0; -+ -+ dev->n_retired_blocks++; -+} -+ -+/*---------------- Name handling functions ------------*/ -+ -+static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name, -+ const YCHAR *oh_name, int buff_size) -+{ -+#ifdef CONFIG_YAFFS_AUTO_UNICODE -+ if (dev->param.auto_unicode) { -+ if (*oh_name) { -+ /* It is an ASCII name, do an ASCII to -+ * unicode conversion */ -+ const char *ascii_oh_name = (const char *)oh_name; -+ int n = buff_size - 1; -+ while (n > 0 && *ascii_oh_name) { -+ *name = *ascii_oh_name; -+ name++; -+ ascii_oh_name++; -+ n--; -+ } -+ } else { -+ strncpy(name, oh_name + 1, buff_size - 1); -+ } -+ } else { -+#else -+ (void) dev; -+ { -+#endif -+ strncpy(name, oh_name, buff_size - 1); -+ } -+} -+ -+static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name, -+ const YCHAR *name) -+{ -+#ifdef CONFIG_YAFFS_AUTO_UNICODE -+ -+ int is_ascii; -+ const YCHAR *w; -+ -+ if (dev->param.auto_unicode) { -+ -+ is_ascii = 1; -+ w = name; -+ -+ /* Figure out if the name will fit in ascii character set */ -+ while (is_ascii && *w) { -+ if ((*w) & 0xff00) -+ is_ascii = 0; -+ w++; -+ } -+ -+ if (is_ascii) { -+ /* It is an ASCII name, so convert unicode to ascii */ -+ char *ascii_oh_name = (char *)oh_name; -+ int n = YAFFS_MAX_NAME_LENGTH - 1; -+ while (n > 0 && *name) { -+ *ascii_oh_name = *name; -+ name++; -+ ascii_oh_name++; -+ n--; -+ } -+ } else { -+ /* Unicode name, so save starting at the second YCHAR */ -+ *oh_name = 0; -+ strncpy(oh_name + 1, name, YAFFS_MAX_NAME_LENGTH - 2); -+ } -+ } else { -+#else -+ dev = dev; -+ { -+#endif -+ strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1); -+ } -+} -+ -+static u16 yaffs_calc_name_sum(const YCHAR *name) -+{ -+ u16 sum = 0; -+ u16 i = 1; -+ -+ if (!name) -+ return 0; -+ -+ while ((*name) && i < (YAFFS_MAX_NAME_LENGTH / 2)) { -+ -+ /* 0x1f mask is case insensitive */ -+ sum += ((*name) & 0x1f) * i; -+ i++; -+ name++; -+ } -+ return sum; -+} -+ -+ -+void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name) -+{ -+ memset(obj->short_name, 0, sizeof(obj->short_name)); -+ -+ if (name && !name[0]) { -+ yaffs_fix_null_name(obj, obj->short_name, -+ YAFFS_SHORT_NAME_LENGTH); -+ name = obj->short_name; -+ } else if (name && -+ strnlen(name, YAFFS_SHORT_NAME_LENGTH + 1) <= -+ YAFFS_SHORT_NAME_LENGTH) { -+ strcpy(obj->short_name, name); -+ } -+ -+ obj->sum = yaffs_calc_name_sum(name); -+} -+ -+void yaffs_set_obj_name_from_oh(struct yaffs_obj *obj, -+ const struct yaffs_obj_hdr *oh) -+{ -+#ifdef CONFIG_YAFFS_AUTO_UNICODE -+ YCHAR tmp_name[YAFFS_MAX_NAME_LENGTH + 1]; -+ memset(tmp_name, 0, sizeof(tmp_name)); -+ yaffs_load_name_from_oh(obj->my_dev, tmp_name, oh->name, -+ YAFFS_MAX_NAME_LENGTH + 1); -+ yaffs_set_obj_name(obj, tmp_name); -+#else -+ yaffs_set_obj_name(obj, oh->name); -+#endif -+} -+ -+loff_t yaffs_max_file_size(struct yaffs_dev *dev) -+{ -+ if (sizeof(loff_t) < 8) -+ return YAFFS_MAX_FILE_SIZE_32; -+ else -+ return ((loff_t) YAFFS_MAX_CHUNK_ID) * dev->data_bytes_per_chunk; -+} -+ -+/*-------------------- TNODES ------------------- -+ -+ * List of spare tnodes -+ * The list is hooked together using the first pointer -+ * in the tnode. -+ */ -+ -+struct yaffs_tnode *yaffs_get_tnode(struct yaffs_dev *dev) -+{ -+ struct yaffs_tnode *tn = yaffs_alloc_raw_tnode(dev); -+ -+ if (tn) { -+ memset(tn, 0, dev->tnode_size); -+ dev->n_tnodes++; -+ } -+ -+ dev->checkpoint_blocks_required = 0; /* force recalculation */ -+ -+ return tn; -+} -+ -+/* FreeTnode frees up a tnode and puts it back on the free list */ -+static void yaffs_free_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn) -+{ -+ yaffs_free_raw_tnode(dev, tn); -+ dev->n_tnodes--; -+ dev->checkpoint_blocks_required = 0; /* force recalculation */ -+} -+ -+static void yaffs_deinit_tnodes_and_objs(struct yaffs_dev *dev) -+{ -+ yaffs_deinit_raw_tnodes_and_objs(dev); -+ dev->n_obj = 0; -+ dev->n_tnodes = 0; -+} -+ -+static void yaffs_load_tnode_0(struct yaffs_dev *dev, struct yaffs_tnode *tn, -+ unsigned pos, unsigned val) -+{ -+ u32 *map = (u32 *) tn; -+ u32 bit_in_map; -+ u32 bit_in_word; -+ u32 word_in_map; -+ u32 mask; -+ -+ pos &= YAFFS_TNODES_LEVEL0_MASK; -+ val >>= dev->chunk_grp_bits; -+ -+ bit_in_map = pos * dev->tnode_width; -+ word_in_map = bit_in_map / 32; -+ bit_in_word = bit_in_map & (32 - 1); -+ -+ mask = dev->tnode_mask << bit_in_word; -+ -+ map[word_in_map] &= ~mask; -+ map[word_in_map] |= (mask & (val << bit_in_word)); -+ -+ if (dev->tnode_width > (32 - bit_in_word)) { -+ bit_in_word = (32 - bit_in_word); -+ word_in_map++; -+ mask = -+ dev->tnode_mask >> bit_in_word; -+ map[word_in_map] &= ~mask; -+ map[word_in_map] |= (mask & (val >> bit_in_word)); -+ } -+} -+ -+u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn, -+ unsigned pos) -+{ -+ u32 *map = (u32 *) tn; -+ u32 bit_in_map; -+ u32 bit_in_word; -+ u32 word_in_map; -+ u32 val; -+ -+ pos &= YAFFS_TNODES_LEVEL0_MASK; -+ -+ bit_in_map = pos * dev->tnode_width; -+ word_in_map = bit_in_map / 32; -+ bit_in_word = bit_in_map & (32 - 1); -+ -+ val = map[word_in_map] >> bit_in_word; -+ -+ if (dev->tnode_width > (32 - bit_in_word)) { -+ bit_in_word = (32 - bit_in_word); -+ word_in_map++; -+ val |= (map[word_in_map] << bit_in_word); -+ } -+ -+ val &= dev->tnode_mask; -+ val <<= dev->chunk_grp_bits; -+ -+ return val; -+} -+ -+/* ------------------- End of individual tnode manipulation -----------------*/ -+ -+/* ---------Functions to manipulate the look-up tree (made up of tnodes) ------ -+ * The look up tree is represented by the top tnode and the number of top_level -+ * in the tree. 0 means only the level 0 tnode is in the tree. -+ */ -+ -+/* FindLevel0Tnode finds the level 0 tnode, if one exists. */ -+struct yaffs_tnode *yaffs_find_tnode_0(struct yaffs_dev *dev, -+ struct yaffs_file_var *file_struct, -+ u32 chunk_id) -+{ -+ struct yaffs_tnode *tn = file_struct->top; -+ u32 i; -+ int required_depth; -+ int level = file_struct->top_level; -+ -+ (void) dev; -+ -+ /* Check sane level and chunk Id */ -+ if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL) -+ return NULL; -+ -+ if (chunk_id > YAFFS_MAX_CHUNK_ID) -+ return NULL; -+ -+ /* First check we're tall enough (ie enough top_level) */ -+ -+ i = chunk_id >> YAFFS_TNODES_LEVEL0_BITS; -+ required_depth = 0; -+ while (i) { -+ i >>= YAFFS_TNODES_INTERNAL_BITS; -+ required_depth++; -+ } -+ -+ if (required_depth > file_struct->top_level) -+ return NULL; /* Not tall enough, so we can't find it */ -+ -+ /* Traverse down to level 0 */ -+ while (level > 0 && tn) { -+ tn = tn->internal[(chunk_id >> -+ (YAFFS_TNODES_LEVEL0_BITS + -+ (level - 1) * -+ YAFFS_TNODES_INTERNAL_BITS)) & -+ YAFFS_TNODES_INTERNAL_MASK]; -+ level--; -+ } -+ -+ return tn; -+} -+ -+/* add_find_tnode_0 finds the level 0 tnode if it exists, -+ * otherwise first expands the tree. -+ * This happens in two steps: -+ * 1. If the tree isn't tall enough, then make it taller. -+ * 2. Scan down the tree towards the level 0 tnode adding tnodes if required. -+ * -+ * Used when modifying the tree. -+ * -+ * If the tn argument is NULL, then a fresh tnode will be added otherwise the -+ * specified tn will be plugged into the ttree. -+ */ -+ -+struct yaffs_tnode *yaffs_add_find_tnode_0(struct yaffs_dev *dev, -+ struct yaffs_file_var *file_struct, -+ u32 chunk_id, -+ struct yaffs_tnode *passed_tn) -+{ -+ int required_depth; -+ int i; -+ int l; -+ struct yaffs_tnode *tn; -+ u32 x; -+ -+ /* Check sane level and page Id */ -+ if (file_struct->top_level < 0 || -+ file_struct->top_level > YAFFS_TNODES_MAX_LEVEL) -+ return NULL; -+ -+ if (chunk_id > YAFFS_MAX_CHUNK_ID) -+ return NULL; -+ -+ /* First check we're tall enough (ie enough top_level) */ -+ -+ x = chunk_id >> YAFFS_TNODES_LEVEL0_BITS; -+ required_depth = 0; -+ while (x) { -+ x >>= YAFFS_TNODES_INTERNAL_BITS; -+ required_depth++; -+ } -+ -+ if (required_depth > file_struct->top_level) { -+ /* Not tall enough, gotta make the tree taller */ -+ for (i = file_struct->top_level; i < required_depth; i++) { -+ -+ tn = yaffs_get_tnode(dev); -+ -+ if (tn) { -+ tn->internal[0] = file_struct->top; -+ file_struct->top = tn; -+ file_struct->top_level++; -+ } else { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs: no more tnodes"); -+ return NULL; -+ } -+ } -+ } -+ -+ /* Traverse down to level 0, adding anything we need */ -+ -+ l = file_struct->top_level; -+ tn = file_struct->top; -+ -+ if (l > 0) { -+ while (l > 0 && tn) { -+ x = (chunk_id >> -+ (YAFFS_TNODES_LEVEL0_BITS + -+ (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) & -+ YAFFS_TNODES_INTERNAL_MASK; -+ -+ if ((l > 1) && !tn->internal[x]) { -+ /* Add missing non-level-zero tnode */ -+ tn->internal[x] = yaffs_get_tnode(dev); -+ if (!tn->internal[x]) -+ return NULL; -+ } else if (l == 1) { -+ /* Looking from level 1 at level 0 */ -+ if (passed_tn) { -+ /* If we already have one, release it */ -+ if (tn->internal[x]) -+ yaffs_free_tnode(dev, -+ tn->internal[x]); -+ tn->internal[x] = passed_tn; -+ -+ } else if (!tn->internal[x]) { -+ /* Don't have one, none passed in */ -+ tn->internal[x] = yaffs_get_tnode(dev); -+ if (!tn->internal[x]) -+ return NULL; -+ } -+ } -+ -+ tn = tn->internal[x]; -+ l--; -+ } -+ } else { -+ /* top is level 0 */ -+ if (passed_tn) { -+ memcpy(tn, passed_tn, -+ (dev->tnode_width * YAFFS_NTNODES_LEVEL0) / 8); -+ yaffs_free_tnode(dev, passed_tn); -+ } -+ } -+ -+ return tn; -+} -+ -+static int yaffs_tags_match(const struct yaffs_ext_tags *tags, int obj_id, -+ int chunk_obj) -+{ -+ return (tags->chunk_id == (u32)chunk_obj && -+ tags->obj_id == (u32)obj_id && -+ !tags->is_deleted) ? 1 : 0; -+ -+} -+ -+static int yaffs_find_chunk_in_group(struct yaffs_dev *dev, int the_chunk, -+ struct yaffs_ext_tags *tags, int obj_id, -+ int inode_chunk) -+{ -+ int j; -+ -+ for (j = 0; the_chunk && j < dev->chunk_grp_size; j++) { -+ if (yaffs_check_chunk_bit -+ (dev, the_chunk / dev->param.chunks_per_block, -+ the_chunk % dev->param.chunks_per_block)) { -+ -+ if (dev->chunk_grp_size == 1) -+ return the_chunk; -+ else { -+ yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL, -+ tags); -+ if (yaffs_tags_match(tags, -+ obj_id, inode_chunk)) { -+ /* found it; */ -+ return the_chunk; -+ } -+ } -+ } -+ the_chunk++; -+ } -+ return -1; -+} -+ -+int yaffs_find_chunk_in_file(struct yaffs_obj *in, int inode_chunk, -+ struct yaffs_ext_tags *tags) -+{ -+ /*Get the Tnode, then get the level 0 offset chunk offset */ -+ struct yaffs_tnode *tn; -+ int the_chunk = -1; -+ struct yaffs_ext_tags local_tags; -+ int ret_val = -1; -+ struct yaffs_dev *dev = in->my_dev; -+ -+ if (!tags) { -+ /* Passed a NULL, so use our own tags space */ -+ tags = &local_tags; -+ } -+ -+ tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk); -+ -+ if (!tn) -+ return ret_val; -+ -+ the_chunk = yaffs_get_group_base(dev, tn, inode_chunk); -+ -+ ret_val = yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id, -+ inode_chunk); -+ return ret_val; -+} -+ -+static int yaffs_find_del_file_chunk(struct yaffs_obj *in, int inode_chunk, -+ struct yaffs_ext_tags *tags) -+{ -+ /* Get the Tnode, then get the level 0 offset chunk offset */ -+ struct yaffs_tnode *tn; -+ int the_chunk = -1; -+ struct yaffs_ext_tags local_tags; -+ struct yaffs_dev *dev = in->my_dev; -+ int ret_val = -1; -+ -+ if (!tags) { -+ /* Passed a NULL, so use our own tags space */ -+ tags = &local_tags; -+ } -+ -+ tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk); -+ -+ if (!tn) -+ return ret_val; -+ -+ the_chunk = yaffs_get_group_base(dev, tn, inode_chunk); -+ -+ ret_val = yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id, -+ inode_chunk); -+ -+ /* Delete the entry in the filestructure (if found) */ -+ if (ret_val != -1) -+ yaffs_load_tnode_0(dev, tn, inode_chunk, 0); -+ -+ return ret_val; -+} -+ -+int yaffs_put_chunk_in_file(struct yaffs_obj *in, int inode_chunk, -+ int nand_chunk, int in_scan) -+{ -+ /* NB in_scan is zero unless scanning. -+ * For forward scanning, in_scan is > 0; -+ * for backward scanning in_scan is < 0 -+ * -+ * nand_chunk = 0 is a dummy insert to make sure the tnodes are there. -+ */ -+ -+ struct yaffs_tnode *tn; -+ struct yaffs_dev *dev = in->my_dev; -+ int existing_cunk; -+ struct yaffs_ext_tags existing_tags; -+ struct yaffs_ext_tags new_tags; -+ unsigned existing_serial, new_serial; -+ -+ if (in->variant_type != YAFFS_OBJECT_TYPE_FILE) { -+ /* Just ignore an attempt at putting a chunk into a non-file -+ * during scanning. -+ * If it is not during Scanning then something went wrong! -+ */ -+ if (!in_scan) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs tragedy:attempt to put data chunk into a non-file" -+ ); -+ BUG(); -+ } -+ -+ yaffs_chunk_del(dev, nand_chunk, 1, __LINE__); -+ return YAFFS_OK; -+ } -+ -+ tn = yaffs_add_find_tnode_0(dev, -+ &in->variant.file_variant, -+ inode_chunk, NULL); -+ if (!tn) -+ return YAFFS_FAIL; -+ -+ if (!nand_chunk) -+ /* Dummy insert, bail now */ -+ return YAFFS_OK; -+ -+ existing_cunk = yaffs_get_group_base(dev, tn, inode_chunk); -+ -+ if (in_scan != 0) { -+ /* If we're scanning then we need to test for duplicates -+ * NB This does not need to be efficient since it should only -+ * happen when the power fails during a write, then only one -+ * chunk should ever be affected. -+ * -+ * Correction for YAFFS2: This could happen quite a lot and we -+ * need to think about efficiency! TODO -+ * Update: For backward scanning we don't need to re-read tags -+ * so this is quite cheap. -+ */ -+ -+ if (existing_cunk > 0) { -+ /* NB Right now existing chunk will not be real -+ * chunk_id if the chunk group size > 1 -+ * thus we have to do a FindChunkInFile to get the -+ * real chunk id. -+ * -+ * We have a duplicate now we need to decide which -+ * one to use: -+ * -+ * Backwards scanning YAFFS2: The old one is what -+ * we use, dump the new one. -+ * YAFFS1: Get both sets of tags and compare serial -+ * numbers. -+ */ -+ -+ if (in_scan > 0) { -+ /* Only do this for forward scanning */ -+ yaffs_rd_chunk_tags_nand(dev, -+ nand_chunk, -+ NULL, &new_tags); -+ -+ /* Do a proper find */ -+ existing_cunk = -+ yaffs_find_chunk_in_file(in, inode_chunk, -+ &existing_tags); -+ } -+ -+ if (existing_cunk <= 0) { -+ /*Hoosterman - how did this happen? */ -+ -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs tragedy: existing chunk < 0 in scan" -+ ); -+ -+ } -+ -+ /* NB The deleted flags should be false, otherwise -+ * the chunks will not be loaded during a scan -+ */ -+ -+ if (in_scan > 0) { -+ new_serial = new_tags.serial_number; -+ existing_serial = existing_tags.serial_number; -+ } -+ -+ if ((in_scan > 0) && -+ (existing_cunk <= 0 || -+ ((existing_serial + 1) & 3) == new_serial)) { -+ /* Forward scanning. -+ * Use new -+ * Delete the old one and drop through to -+ * update the tnode -+ */ -+ yaffs_chunk_del(dev, existing_cunk, 1, -+ __LINE__); -+ } else { -+ /* Backward scanning or we want to use the -+ * existing one -+ * Delete the new one and return early so that -+ * the tnode isn't changed -+ */ -+ yaffs_chunk_del(dev, nand_chunk, 1, __LINE__); -+ return YAFFS_OK; -+ } -+ } -+ -+ } -+ -+ if (existing_cunk == 0) -+ in->n_data_chunks++; -+ -+ yaffs_load_tnode_0(dev, tn, inode_chunk, nand_chunk); -+ -+ return YAFFS_OK; -+} -+ -+static void yaffs_soft_del_chunk(struct yaffs_dev *dev, int chunk) -+{ -+ struct yaffs_block_info *the_block; -+ unsigned block_no; -+ -+ yaffs_trace(YAFFS_TRACE_DELETION, "soft delete chunk %d", chunk); -+ -+ block_no = chunk / dev->param.chunks_per_block; -+ the_block = yaffs_get_block_info(dev, block_no); -+ if (the_block) { -+ the_block->soft_del_pages++; -+ dev->n_free_chunks++; -+ yaffs2_update_oldest_dirty_seq(dev, block_no, the_block); -+ } -+} -+ -+/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all -+ * the chunks in the file. -+ * All soft deleting does is increment the block's softdelete count and pulls -+ * the chunk out of the tnode. -+ * Thus, essentially this is the same as DeleteWorker except that the chunks -+ * are soft deleted. -+ */ -+ -+static int yaffs_soft_del_worker(struct yaffs_obj *in, struct yaffs_tnode *tn, -+ u32 level, int chunk_offset) -+{ -+ int i; -+ int the_chunk; -+ int all_done = 1; -+ struct yaffs_dev *dev = in->my_dev; -+ -+ if (!tn) -+ return 1; -+ -+ if (level > 0) { -+ for (i = YAFFS_NTNODES_INTERNAL - 1; -+ all_done && i >= 0; -+ i--) { -+ if (tn->internal[i]) { -+ all_done = -+ yaffs_soft_del_worker(in, -+ tn->internal[i], -+ level - 1, -+ (chunk_offset << -+ YAFFS_TNODES_INTERNAL_BITS) -+ + i); -+ if (all_done) { -+ yaffs_free_tnode(dev, -+ tn->internal[i]); -+ tn->internal[i] = NULL; -+ } else { -+ /* Can this happen? */ -+ } -+ } -+ } -+ return (all_done) ? 1 : 0; -+ } -+ -+ /* level 0 */ -+ for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) { -+ the_chunk = yaffs_get_group_base(dev, tn, i); -+ if (the_chunk) { -+ yaffs_soft_del_chunk(dev, the_chunk); -+ yaffs_load_tnode_0(dev, tn, i, 0); -+ } -+ } -+ return 1; -+} -+ -+static void yaffs_remove_obj_from_dir(struct yaffs_obj *obj) -+{ -+ struct yaffs_dev *dev = obj->my_dev; -+ struct yaffs_obj *parent; -+ -+ yaffs_verify_obj_in_dir(obj); -+ parent = obj->parent; -+ -+ yaffs_verify_dir(parent); -+ -+ if (dev && dev->param.remove_obj_fn) -+ dev->param.remove_obj_fn(obj); -+ -+ list_del_init(&obj->siblings); -+ obj->parent = NULL; -+ -+ yaffs_verify_dir(parent); -+} -+ -+void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj) -+{ -+ if (!directory) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "tragedy: Trying to add an object to a null pointer directory" -+ ); -+ BUG(); -+ return; -+ } -+ if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "tragedy: Trying to add an object to a non-directory" -+ ); -+ BUG(); -+ } -+ -+ if (obj->siblings.prev == NULL) { -+ /* Not initialised */ -+ BUG(); -+ } -+ -+ yaffs_verify_dir(directory); -+ -+ yaffs_remove_obj_from_dir(obj); -+ -+ /* Now add it */ -+ list_add(&obj->siblings, &directory->variant.dir_variant.children); -+ obj->parent = directory; -+ -+ if (directory == obj->my_dev->unlinked_dir -+ || directory == obj->my_dev->del_dir) { -+ obj->unlinked = 1; -+ obj->my_dev->n_unlinked_files++; -+ obj->rename_allowed = 0; -+ } -+ -+ yaffs_verify_dir(directory); -+ yaffs_verify_obj_in_dir(obj); -+} -+ -+static int yaffs_change_obj_name(struct yaffs_obj *obj, -+ struct yaffs_obj *new_dir, -+ const YCHAR *new_name, int force, int shadows) -+{ -+ int unlink_op; -+ int del_op; -+ struct yaffs_obj *existing_target; -+ -+ if (new_dir == NULL) -+ new_dir = obj->parent; /* use the old directory */ -+ -+ if (new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "tragedy: yaffs_change_obj_name: new_dir is not a directory" -+ ); -+ BUG(); -+ } -+ -+ unlink_op = (new_dir == obj->my_dev->unlinked_dir); -+ del_op = (new_dir == obj->my_dev->del_dir); -+ -+ existing_target = yaffs_find_by_name(new_dir, new_name); -+ -+ /* If the object is a file going into the unlinked directory, -+ * then it is OK to just stuff it in since duplicate names are OK. -+ * else only proceed if the new name does not exist and we're putting -+ * it into a directory. -+ */ -+ if (!(unlink_op || del_op || force || -+ shadows > 0 || !existing_target) || -+ new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) -+ return YAFFS_FAIL; -+ -+ yaffs_set_obj_name(obj, new_name); -+ obj->dirty = 1; -+ yaffs_add_obj_to_dir(new_dir, obj); -+ -+ if (unlink_op) -+ obj->unlinked = 1; -+ -+ /* If it is a deletion then we mark it as a shrink for gc */ -+ if (yaffs_update_oh(obj, new_name, 0, del_op, shadows, NULL) >= 0) -+ return YAFFS_OK; -+ -+ return YAFFS_FAIL; -+} -+ -+/*------------------------ Short Operations Cache ------------------------------ -+ * In many situations where there is no high level buffering a lot of -+ * reads might be short sequential reads, and a lot of writes may be short -+ * sequential writes. eg. scanning/writing a jpeg file. -+ * In these cases, a short read/write cache can provide a huge perfomance -+ * benefit with dumb-as-a-rock code. -+ * In Linux, the page cache provides read buffering and the short op cache -+ * provides write buffering. -+ * -+ * There are a small number (~10) of cache chunks per device so that we don't -+ * need a very intelligent search. -+ */ -+ -+static int yaffs_obj_cache_dirty(struct yaffs_obj *obj) -+{ -+ struct yaffs_dev *dev = obj->my_dev; -+ int i; -+ struct yaffs_cache *cache; -+ int n_caches = obj->my_dev->param.n_caches; -+ -+ for (i = 0; i < n_caches; i++) { -+ cache = &dev->cache[i]; -+ if (cache->object == obj && cache->dirty) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static void yaffs_flush_single_cache(struct yaffs_cache *cache, int discard) -+{ -+ -+ if (!cache || cache->locked) -+ return; -+ -+ /* Write it out and free it up if need be.*/ -+ if (cache->dirty) { -+ yaffs_wr_data_obj(cache->object, -+ cache->chunk_id, -+ cache->data, -+ cache->n_bytes, -+ 1); -+ -+ cache->dirty = 0; -+ } -+ -+ if (discard) -+ cache->object = NULL; -+} -+ -+static void yaffs_flush_file_cache(struct yaffs_obj *obj, int discard) -+{ -+ struct yaffs_dev *dev = obj->my_dev; -+ int i; -+ struct yaffs_cache *cache; -+ int n_caches = obj->my_dev->param.n_caches; -+ -+ if (n_caches < 1) -+ return; -+ -+ -+ /* Find the chunks for this object and flush them. */ -+ for (i = 0; i < n_caches; i++) { -+ cache = &dev->cache[i]; -+ if (cache->object == obj) -+ yaffs_flush_single_cache(cache, discard); -+ } -+ -+} -+ -+ -+void yaffs_flush_whole_cache(struct yaffs_dev *dev, int discard) -+{ -+ struct yaffs_obj *obj; -+ int n_caches = dev->param.n_caches; -+ int i; -+ -+ /* Find a dirty object in the cache and flush it... -+ * until there are no further dirty objects. -+ */ -+ do { -+ obj = NULL; -+ for (i = 0; i < n_caches && !obj; i++) { -+ if (dev->cache[i].object && dev->cache[i].dirty) -+ obj = dev->cache[i].object; -+ } -+ if (obj) -+ yaffs_flush_file_cache(obj, discard); -+ } while (obj); -+ -+} -+ -+/* Grab us an unused cache chunk for use. -+ * First look for an empty one. -+ * Then look for the least recently used non-dirty one. -+ * Then look for the least recently used dirty one...., flush and look again. -+ */ -+static struct yaffs_cache *yaffs_grab_chunk_worker(struct yaffs_dev *dev) -+{ -+ u32 i; -+ -+ if (dev->param.n_caches > 0) { -+ for (i = 0; i < dev->param.n_caches; i++) { -+ if (!dev->cache[i].object) -+ return &dev->cache[i]; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct yaffs_cache *yaffs_grab_chunk_cache(struct yaffs_dev *dev) -+{ -+ struct yaffs_cache *cache; -+ int usage; -+ u32 i; -+ -+ if (dev->param.n_caches < 1) -+ return NULL; -+ -+ /* First look for an unused cache */ -+ -+ cache = yaffs_grab_chunk_worker(dev); -+ -+ if (cache) -+ return cache; -+ -+ /* -+ * Thery were all in use. -+ * Find the LRU cache and flush it if it is dirty. -+ */ -+ -+ usage = -1; -+ cache = NULL; -+ -+ for (i = 0; i < dev->param.n_caches; i++) { -+ if (dev->cache[i].object && -+ !dev->cache[i].locked && -+ (dev->cache[i].last_use < usage || !cache)) { -+ usage = dev->cache[i].last_use; -+ cache = &dev->cache[i]; -+ } -+ } -+ -+#if 1 -+ yaffs_flush_single_cache(cache, 1); -+#else -+ yaffs_flush_file_cache(cache->object, 1); -+ cache = yaffs_grab_chunk_worker(dev); -+#endif -+ -+ return cache; -+} -+ -+/* Find a cached chunk */ -+static struct yaffs_cache *yaffs_find_chunk_cache(const struct yaffs_obj *obj, -+ int chunk_id) -+{ -+ struct yaffs_dev *dev = obj->my_dev; -+ u32 i; -+ -+ if (dev->param.n_caches < 1) -+ return NULL; -+ -+ for (i = 0; i < dev->param.n_caches; i++) { -+ if (dev->cache[i].object == obj && -+ dev->cache[i].chunk_id == chunk_id) { -+ dev->cache_hits++; -+ -+ return &dev->cache[i]; -+ } -+ } -+ return NULL; -+} -+ -+/* Mark the chunk for the least recently used algorithym */ -+static void yaffs_use_cache(struct yaffs_dev *dev, struct yaffs_cache *cache, -+ int is_write) -+{ -+ u32 i; -+ -+ if (dev->param.n_caches < 1) -+ return; -+ -+ if (dev->cache_last_use < 0 || -+ dev->cache_last_use > 100000000) { -+ /* Reset the cache usages */ -+ for (i = 1; i < dev->param.n_caches; i++) -+ dev->cache[i].last_use = 0; -+ -+ dev->cache_last_use = 0; -+ } -+ dev->cache_last_use++; -+ cache->last_use = dev->cache_last_use; -+ -+ if (is_write) -+ cache->dirty = 1; -+} -+ -+/* Invalidate a single cache page. -+ * Do this when a whole page gets written, -+ * ie the short cache for this page is no longer valid. -+ */ -+static void yaffs_invalidate_chunk_cache(struct yaffs_obj *object, int chunk_id) -+{ -+ struct yaffs_cache *cache; -+ -+ if (object->my_dev->param.n_caches > 0) { -+ cache = yaffs_find_chunk_cache(object, chunk_id); -+ -+ if (cache) -+ cache->object = NULL; -+ } -+} -+ -+/* Invalidate all the cache pages associated with this object -+ * Do this whenever ther file is deleted or resized. -+ */ -+static void yaffs_invalidate_whole_cache(struct yaffs_obj *in) -+{ -+ u32 i; -+ struct yaffs_dev *dev = in->my_dev; -+ -+ if (dev->param.n_caches > 0) { -+ /* Invalidate it. */ -+ for (i = 0; i < dev->param.n_caches; i++) { -+ if (dev->cache[i].object == in) -+ dev->cache[i].object = NULL; -+ } -+ } -+} -+ -+static void yaffs_unhash_obj(struct yaffs_obj *obj) -+{ -+ int bucket; -+ struct yaffs_dev *dev = obj->my_dev; -+ -+ /* If it is still linked into the bucket list, free from the list */ -+ if (!list_empty(&obj->hash_link)) { -+ list_del_init(&obj->hash_link); -+ bucket = yaffs_hash_fn(obj->obj_id); -+ dev->obj_bucket[bucket].count--; -+ } -+} -+ -+/* FreeObject frees up a Object and puts it back on the free list */ -+static void yaffs_free_obj(struct yaffs_obj *obj) -+{ -+ struct yaffs_dev *dev; -+ -+ if (!obj) { -+ BUG(); -+ return; -+ } -+ dev = obj->my_dev; -+ yaffs_trace(YAFFS_TRACE_OS, "FreeObject %p inode %p", -+ obj, obj->my_inode); -+ if (obj->parent) -+ BUG(); -+ if (!list_empty(&obj->siblings)) -+ BUG(); -+ -+ if (obj->my_inode) { -+ /* We're still hooked up to a cached inode. -+ * Don't delete now, but mark for later deletion -+ */ -+ obj->defered_free = 1; -+ return; -+ } -+ -+ yaffs_unhash_obj(obj); -+ -+ yaffs_free_raw_obj(dev, obj); -+ dev->n_obj--; -+ dev->checkpoint_blocks_required = 0; /* force recalculation */ -+} -+ -+void yaffs_handle_defered_free(struct yaffs_obj *obj) -+{ -+ if (obj->defered_free) -+ yaffs_free_obj(obj); -+} -+ -+static int yaffs_generic_obj_del(struct yaffs_obj *in) -+{ -+ /* Iinvalidate the file's data in the cache, without flushing. */ -+ yaffs_invalidate_whole_cache(in); -+ -+ if (in->my_dev->param.is_yaffs2 && in->parent != in->my_dev->del_dir) { -+ /* Move to unlinked directory so we have a deletion record */ -+ yaffs_change_obj_name(in, in->my_dev->del_dir, _Y("deleted"), 0, -+ 0); -+ } -+ -+ yaffs_remove_obj_from_dir(in); -+ yaffs_chunk_del(in->my_dev, in->hdr_chunk, 1, __LINE__); -+ in->hdr_chunk = 0; -+ -+ yaffs_free_obj(in); -+ return YAFFS_OK; -+ -+} -+ -+static void yaffs_soft_del_file(struct yaffs_obj *obj) -+{ -+ if (!obj->deleted || -+ obj->variant_type != YAFFS_OBJECT_TYPE_FILE || -+ obj->soft_del) -+ return; -+ -+ if (obj->n_data_chunks <= 0) { -+ /* Empty file with no duplicate object headers, -+ * just delete it immediately */ -+ yaffs_free_tnode(obj->my_dev, obj->variant.file_variant.top); -+ obj->variant.file_variant.top = NULL; -+ yaffs_trace(YAFFS_TRACE_TRACING, -+ "yaffs: Deleting empty file %d", -+ obj->obj_id); -+ yaffs_generic_obj_del(obj); -+ } else { -+ yaffs_soft_del_worker(obj, -+ obj->variant.file_variant.top, -+ obj->variant. -+ file_variant.top_level, 0); -+ obj->soft_del = 1; -+ } -+} -+ -+/* Pruning removes any part of the file structure tree that is beyond the -+ * bounds of the file (ie that does not point to chunks). -+ * -+ * A file should only get pruned when its size is reduced. -+ * -+ * Before pruning, the chunks must be pulled from the tree and the -+ * level 0 tnode entries must be zeroed out. -+ * Could also use this for file deletion, but that's probably better handled -+ * by a special case. -+ * -+ * This function is recursive. For levels > 0 the function is called again on -+ * any sub-tree. For level == 0 we just check if the sub-tree has data. -+ * If there is no data in a subtree then it is pruned. -+ */ -+ -+static struct yaffs_tnode *yaffs_prune_worker(struct yaffs_dev *dev, -+ struct yaffs_tnode *tn, u32 level, -+ int del0) -+{ -+ int i; -+ int has_data; -+ -+ if (!tn) -+ return tn; -+ -+ has_data = 0; -+ -+ if (level > 0) { -+ for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) { -+ if (tn->internal[i]) { -+ tn->internal[i] = -+ yaffs_prune_worker(dev, -+ tn->internal[i], -+ level - 1, -+ (i == 0) ? del0 : 1); -+ } -+ -+ if (tn->internal[i]) -+ has_data++; -+ } -+ } else { -+ int tnode_size_u32 = dev->tnode_size / sizeof(u32); -+ u32 *map = (u32 *) tn; -+ -+ for (i = 0; !has_data && i < tnode_size_u32; i++) { -+ if (map[i]) -+ has_data++; -+ } -+ } -+ -+ if (has_data == 0 && del0) { -+ /* Free and return NULL */ -+ yaffs_free_tnode(dev, tn); -+ tn = NULL; -+ } -+ return tn; -+} -+ -+static int yaffs_prune_tree(struct yaffs_dev *dev, -+ struct yaffs_file_var *file_struct) -+{ -+ int i; -+ int has_data; -+ int done = 0; -+ struct yaffs_tnode *tn; -+ -+ if (file_struct->top_level < 1) -+ return YAFFS_OK; -+ -+ file_struct->top = -+ yaffs_prune_worker(dev, file_struct->top, file_struct->top_level, 0); -+ -+ /* Now we have a tree with all the non-zero branches NULL but -+ * the height is the same as it was. -+ * Let's see if we can trim internal tnodes to shorten the tree. -+ * We can do this if only the 0th element in the tnode is in use -+ * (ie all the non-zero are NULL) -+ */ -+ -+ while (file_struct->top_level && !done) { -+ tn = file_struct->top; -+ -+ has_data = 0; -+ for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) { -+ if (tn->internal[i]) -+ has_data++; -+ } -+ -+ if (!has_data) { -+ file_struct->top = tn->internal[0]; -+ file_struct->top_level--; -+ yaffs_free_tnode(dev, tn); -+ } else { -+ done = 1; -+ } -+ } -+ -+ return YAFFS_OK; -+} -+ -+/*-------------------- End of File Structure functions.-------------------*/ -+ -+/* alloc_empty_obj gets us a clean Object.*/ -+static struct yaffs_obj *yaffs_alloc_empty_obj(struct yaffs_dev *dev) -+{ -+ struct yaffs_obj *obj = yaffs_alloc_raw_obj(dev); -+ -+ if (!obj) -+ return obj; -+ -+ dev->n_obj++; -+ -+ /* Now sweeten it up... */ -+ -+ memset(obj, 0, sizeof(struct yaffs_obj)); -+ obj->being_created = 1; -+ -+ obj->my_dev = dev; -+ obj->hdr_chunk = 0; -+ obj->variant_type = YAFFS_OBJECT_TYPE_UNKNOWN; -+ INIT_LIST_HEAD(&(obj->hard_links)); -+ INIT_LIST_HEAD(&(obj->hash_link)); -+ INIT_LIST_HEAD(&obj->siblings); -+ -+ /* Now make the directory sane */ -+ if (dev->root_dir) { -+ obj->parent = dev->root_dir; -+ list_add(&(obj->siblings), -+ &dev->root_dir->variant.dir_variant.children); -+ } -+ -+ /* Add it to the lost and found directory. -+ * NB Can't put root or lost-n-found in lost-n-found so -+ * check if lost-n-found exists first -+ */ -+ if (dev->lost_n_found) -+ yaffs_add_obj_to_dir(dev->lost_n_found, obj); -+ -+ obj->being_created = 0; -+ -+ dev->checkpoint_blocks_required = 0; /* force recalculation */ -+ -+ return obj; -+} -+ -+static int yaffs_find_nice_bucket(struct yaffs_dev *dev) -+{ -+ int i; -+ int l = 999; -+ int lowest = 999999; -+ -+ /* Search for the shortest list or one that -+ * isn't too long. -+ */ -+ -+ for (i = 0; i < 10 && lowest > 4; i++) { -+ dev->bucket_finder++; -+ dev->bucket_finder %= YAFFS_NOBJECT_BUCKETS; -+ if (dev->obj_bucket[dev->bucket_finder].count < lowest) { -+ lowest = dev->obj_bucket[dev->bucket_finder].count; -+ l = dev->bucket_finder; -+ } -+ } -+ -+ return l; -+} -+ -+static int yaffs_new_obj_id(struct yaffs_dev *dev) -+{ -+ int bucket = yaffs_find_nice_bucket(dev); -+ int found = 0; -+ struct list_head *i; -+ u32 n = (u32) bucket; -+ -+ /* -+ * Now find an object value that has not already been taken -+ * by scanning the list, incrementing each time by number of buckets. -+ */ -+ while (!found) { -+ found = 1; -+ n += YAFFS_NOBJECT_BUCKETS; -+ list_for_each(i, &dev->obj_bucket[bucket].list) { -+ /* Check if this value is already taken. */ -+ if (i && list_entry(i, struct yaffs_obj, -+ hash_link)->obj_id == n) -+ found = 0; -+ } -+ } -+ return n; -+} -+ -+static void yaffs_hash_obj(struct yaffs_obj *in) -+{ -+ int bucket = yaffs_hash_fn(in->obj_id); -+ struct yaffs_dev *dev = in->my_dev; -+ -+ list_add(&in->hash_link, &dev->obj_bucket[bucket].list); -+ dev->obj_bucket[bucket].count++; -+} -+ -+struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number) -+{ -+ int bucket = yaffs_hash_fn(number); -+ struct list_head *i; -+ struct yaffs_obj *in; -+ -+ list_for_each(i, &dev->obj_bucket[bucket].list) { -+ /* Look if it is in the list */ -+ in = list_entry(i, struct yaffs_obj, hash_link); -+ if (in->obj_id == number) { -+ /* Don't show if it is defered free */ -+ if (in->defered_free) -+ return NULL; -+ return in; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number, -+ enum yaffs_obj_type type) -+{ -+ struct yaffs_obj *the_obj = NULL; -+ struct yaffs_tnode *tn = NULL; -+ -+ if (number < 0) -+ number = yaffs_new_obj_id(dev); -+ -+ if (type == YAFFS_OBJECT_TYPE_FILE) { -+ tn = yaffs_get_tnode(dev); -+ if (!tn) -+ return NULL; -+ } -+ -+ the_obj = yaffs_alloc_empty_obj(dev); -+ if (!the_obj) { -+ if (tn) -+ yaffs_free_tnode(dev, tn); -+ return NULL; -+ } -+ -+ the_obj->fake = 0; -+ the_obj->rename_allowed = 1; -+ the_obj->unlink_allowed = 1; -+ the_obj->obj_id = number; -+ yaffs_hash_obj(the_obj); -+ the_obj->variant_type = type; -+ yaffs_load_current_time(the_obj, 1, 1); -+ -+ switch (type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ the_obj->variant.file_variant.file_size = 0; -+ the_obj->variant.file_variant.stored_size = 0; -+ the_obj->variant.file_variant.shrink_size = -+ yaffs_max_file_size(dev); -+ the_obj->variant.file_variant.top_level = 0; -+ the_obj->variant.file_variant.top = tn; -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ INIT_LIST_HEAD(&the_obj->variant.dir_variant.children); -+ INIT_LIST_HEAD(&the_obj->variant.dir_variant.dirty); -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ /* No action required */ -+ break; -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ /* todo this should not happen */ -+ break; -+ } -+ return the_obj; -+} -+ -+static struct yaffs_obj *yaffs_create_fake_dir(struct yaffs_dev *dev, -+ int number, u32 mode) -+{ -+ -+ struct yaffs_obj *obj = -+ yaffs_new_obj(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY); -+ -+ if (!obj) -+ return NULL; -+ -+ obj->fake = 1; /* it is fake so it might not use NAND */ -+ obj->rename_allowed = 0; -+ obj->unlink_allowed = 0; -+ obj->deleted = 0; -+ obj->unlinked = 0; -+ obj->yst_mode = mode; -+ obj->my_dev = dev; -+ obj->hdr_chunk = 0; /* Not a valid chunk. */ -+ return obj; -+ -+} -+ -+ -+static void yaffs_init_tnodes_and_objs(struct yaffs_dev *dev) -+{ -+ int i; -+ -+ dev->n_obj = 0; -+ dev->n_tnodes = 0; -+ yaffs_init_raw_tnodes_and_objs(dev); -+ -+ for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) { -+ INIT_LIST_HEAD(&dev->obj_bucket[i].list); -+ dev->obj_bucket[i].count = 0; -+ } -+} -+ -+struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev, -+ int number, -+ enum yaffs_obj_type type) -+{ -+ struct yaffs_obj *the_obj = NULL; -+ -+ if (number > 0) -+ the_obj = yaffs_find_by_number(dev, number); -+ -+ if (!the_obj) -+ the_obj = yaffs_new_obj(dev, number, type); -+ -+ return the_obj; -+ -+} -+ -+YCHAR *yaffs_clone_str(const YCHAR *str) -+{ -+ YCHAR *new_str = NULL; -+ int len; -+ -+ if (!str) -+ str = _Y(""); -+ -+ len = strnlen(str, YAFFS_MAX_ALIAS_LENGTH); -+ new_str = kmalloc((len + 1) * sizeof(YCHAR), GFP_NOFS); -+ if (new_str) { -+ strncpy(new_str, str, len); -+ new_str[len] = 0; -+ } -+ return new_str; -+ -+} -+/* -+ *yaffs_update_parent() handles fixing a directories mtime and ctime when a new -+ * link (ie. name) is created or deleted in the directory. -+ * -+ * ie. -+ * create dir/a : update dir's mtime/ctime -+ * rm dir/a: update dir's mtime/ctime -+ * modify dir/a: don't update dir's mtimme/ctime -+ * -+ * This can be handled immediately or defered. Defering helps reduce the number -+ * of updates when many files in a directory are changed within a brief period. -+ * -+ * If the directory updating is defered then yaffs_update_dirty_dirs must be -+ * called periodically. -+ */ -+ -+static void yaffs_update_parent(struct yaffs_obj *obj) -+{ -+ struct yaffs_dev *dev; -+ -+ if (!obj) -+ return; -+ dev = obj->my_dev; -+ obj->dirty = 1; -+ yaffs_load_current_time(obj, 0, 1); -+ if (dev->param.defered_dir_update) { -+ struct list_head *link = &obj->variant.dir_variant.dirty; -+ -+ if (list_empty(link)) { -+ list_add(link, &dev->dirty_dirs); -+ yaffs_trace(YAFFS_TRACE_BACKGROUND, -+ "Added object %d to dirty directories", -+ obj->obj_id); -+ } -+ -+ } else { -+ yaffs_update_oh(obj, NULL, 0, 0, 0, NULL); -+ } -+} -+ -+void yaffs_update_dirty_dirs(struct yaffs_dev *dev) -+{ -+ struct list_head *link; -+ struct yaffs_obj *obj; -+ struct yaffs_dir_var *d_s; -+ union yaffs_obj_var *o_v; -+ -+ yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update dirty directories"); -+ -+ while (!list_empty(&dev->dirty_dirs)) { -+ link = dev->dirty_dirs.next; -+ list_del_init(link); -+ -+ d_s = list_entry(link, struct yaffs_dir_var, dirty); -+ o_v = list_entry(d_s, union yaffs_obj_var, dir_variant); -+ obj = list_entry(o_v, struct yaffs_obj, variant); -+ -+ yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update directory %d", -+ obj->obj_id); -+ -+ if (obj->dirty) -+ yaffs_update_oh(obj, NULL, 0, 0, 0, NULL); -+ } -+} -+ -+/* -+ * Mknod (create) a new object. -+ * equiv_obj only has meaning for a hard link; -+ * alias_str only has meaning for a symlink. -+ * rdev only has meaning for devices (a subset of special objects) -+ */ -+ -+static struct yaffs_obj *yaffs_create_obj(enum yaffs_obj_type type, -+ struct yaffs_obj *parent, -+ const YCHAR *name, -+ u32 mode, -+ u32 uid, -+ u32 gid, -+ struct yaffs_obj *equiv_obj, -+ const YCHAR *alias_str, u32 rdev) -+{ -+ struct yaffs_obj *in; -+ YCHAR *str = NULL; -+ struct yaffs_dev *dev = parent->my_dev; -+ -+ /* Check if the entry exists. -+ * If it does then fail the call since we don't want a dup. */ -+ if (yaffs_find_by_name(parent, name)) -+ return NULL; -+ -+ if (type == YAFFS_OBJECT_TYPE_SYMLINK) { -+ str = yaffs_clone_str(alias_str); -+ if (!str) -+ return NULL; -+ } -+ -+ in = yaffs_new_obj(dev, -1, type); -+ -+ if (!in) { -+ kfree(str); -+ return NULL; -+ } -+ -+ in->hdr_chunk = 0; -+ in->valid = 1; -+ in->variant_type = type; -+ -+ in->yst_mode = mode; -+ -+ yaffs_attribs_init(in, gid, uid, rdev); -+ -+ in->n_data_chunks = 0; -+ -+ yaffs_set_obj_name(in, name); -+ in->dirty = 1; -+ -+ yaffs_add_obj_to_dir(parent, in); -+ -+ in->my_dev = parent->my_dev; -+ -+ switch (type) { -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ in->variant.symlink_variant.alias = str; -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ in->variant.hardlink_variant.equiv_obj = equiv_obj; -+ in->variant.hardlink_variant.equiv_id = equiv_obj->obj_id; -+ list_add(&in->hard_links, &equiv_obj->hard_links); -+ break; -+ case YAFFS_OBJECT_TYPE_FILE: -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ /* do nothing */ -+ break; -+ } -+ -+ if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) { -+ /* Could not create the object header, fail */ -+ yaffs_del_obj(in); -+ in = NULL; -+ } -+ -+ if (in) -+ yaffs_update_parent(parent); -+ -+ return in; -+} -+ -+struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent, -+ const YCHAR *name, u32 mode, u32 uid, -+ u32 gid) -+{ -+ return yaffs_create_obj(YAFFS_OBJECT_TYPE_FILE, parent, name, mode, -+ uid, gid, NULL, NULL, 0); -+} -+ -+struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name, -+ u32 mode, u32 uid, u32 gid) -+{ -+ return yaffs_create_obj(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name, -+ mode, uid, gid, NULL, NULL, 0); -+} -+ -+struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent, -+ const YCHAR *name, u32 mode, u32 uid, -+ u32 gid, u32 rdev) -+{ -+ return yaffs_create_obj(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode, -+ uid, gid, NULL, NULL, rdev); -+} -+ -+struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent, -+ const YCHAR *name, u32 mode, u32 uid, -+ u32 gid, const YCHAR *alias) -+{ -+ return yaffs_create_obj(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode, -+ uid, gid, NULL, alias, 0); -+} -+ -+/* yaffs_link_obj returns the object id of the equivalent object.*/ -+struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR * name, -+ struct yaffs_obj *equiv_obj) -+{ -+ /* Get the real object in case we were fed a hard link obj */ -+ equiv_obj = yaffs_get_equivalent_obj(equiv_obj); -+ -+ if (yaffs_create_obj(YAFFS_OBJECT_TYPE_HARDLINK, -+ parent, name, 0, 0, 0, -+ equiv_obj, NULL, 0)) -+ return equiv_obj; -+ -+ return NULL; -+ -+} -+ -+ -+ -+/*---------------------- Block Management and Page Allocation -------------*/ -+ -+static void yaffs_deinit_blocks(struct yaffs_dev *dev) -+{ -+ if (dev->block_info_alt && dev->block_info) -+ vfree(dev->block_info); -+ else -+ kfree(dev->block_info); -+ -+ dev->block_info_alt = 0; -+ -+ dev->block_info = NULL; -+ -+ if (dev->chunk_bits_alt && dev->chunk_bits) -+ vfree(dev->chunk_bits); -+ else -+ kfree(dev->chunk_bits); -+ dev->chunk_bits_alt = 0; -+ dev->chunk_bits = NULL; -+} -+ -+static int yaffs_init_blocks(struct yaffs_dev *dev) -+{ -+ int n_blocks = dev->internal_end_block - dev->internal_start_block + 1; -+ -+ dev->block_info = NULL; -+ dev->chunk_bits = NULL; -+ dev->alloc_block = -1; /* force it to get a new one */ -+ -+ /* If the first allocation strategy fails, thry the alternate one */ -+ dev->block_info = -+ kmalloc(n_blocks * sizeof(struct yaffs_block_info), GFP_NOFS); -+ if (!dev->block_info) { -+ dev->block_info = -+ vmalloc(n_blocks * sizeof(struct yaffs_block_info)); -+ dev->block_info_alt = 1; -+ } else { -+ dev->block_info_alt = 0; -+ } -+ -+ if (!dev->block_info) -+ goto alloc_error; -+ -+ /* Set up dynamic blockinfo stuff. Round up bytes. */ -+ dev->chunk_bit_stride = (dev->param.chunks_per_block + 7) / 8; -+ dev->chunk_bits = -+ kmalloc(dev->chunk_bit_stride * n_blocks, GFP_NOFS); -+ if (!dev->chunk_bits) { -+ dev->chunk_bits = -+ vmalloc(dev->chunk_bit_stride * n_blocks); -+ dev->chunk_bits_alt = 1; -+ } else { -+ dev->chunk_bits_alt = 0; -+ } -+ if (!dev->chunk_bits) -+ goto alloc_error; -+ -+ -+ memset(dev->block_info, 0, n_blocks * sizeof(struct yaffs_block_info)); -+ memset(dev->chunk_bits, 0, dev->chunk_bit_stride * n_blocks); -+ return YAFFS_OK; -+ -+alloc_error: -+ yaffs_deinit_blocks(dev); -+ return YAFFS_FAIL; -+} -+ -+ -+void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no) -+{ -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, block_no); -+ int erased_ok = 0; -+ u32 i; -+ -+ /* If the block is still healthy erase it and mark as clean. -+ * If the block has had a data failure, then retire it. -+ */ -+ -+ yaffs_trace(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE, -+ "yaffs_block_became_dirty block %d state %d %s", -+ block_no, bi->block_state, -+ (bi->needs_retiring) ? "needs retiring" : ""); -+ -+ yaffs2_clear_oldest_dirty_seq(dev, bi); -+ -+ bi->block_state = YAFFS_BLOCK_STATE_DIRTY; -+ -+ /* If this is the block being garbage collected then stop gc'ing */ -+ if (block_no == (int)dev->gc_block) -+ dev->gc_block = 0; -+ -+ /* If this block is currently the best candidate for gc -+ * then drop as a candidate */ -+ if (block_no == (int)dev->gc_dirtiest) { -+ dev->gc_dirtiest = 0; -+ dev->gc_pages_in_use = 0; -+ } -+ -+ if (!bi->needs_retiring) { -+ yaffs2_checkpt_invalidate(dev); -+ erased_ok = yaffs_erase_block(dev, block_no); -+ if (!erased_ok) { -+ dev->n_erase_failures++; -+ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, -+ "**>> Erasure failed %d", block_no); -+ } -+ } -+ -+ /* Verify erasure if needed */ -+ if (erased_ok && -+ ((yaffs_trace_mask & YAFFS_TRACE_ERASE) || -+ !yaffs_skip_verification(dev))) { -+ for (i = 0; i < dev->param.chunks_per_block; i++) { -+ if (!yaffs_check_chunk_erased(dev, -+ block_no * dev->param.chunks_per_block + i)) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ ">>Block %d erasure supposedly OK, but chunk %d not erased", -+ block_no, i); -+ } -+ } -+ } -+ -+ if (!erased_ok) { -+ /* We lost a block of free space */ -+ dev->n_free_chunks -= dev->param.chunks_per_block; -+ yaffs_retire_block(dev, block_no); -+ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, -+ "**>> Block %d retired", block_no); -+ return; -+ } -+ -+ /* Clean it up... */ -+ bi->block_state = YAFFS_BLOCK_STATE_EMPTY; -+ bi->seq_number = 0; -+ dev->n_erased_blocks++; -+ bi->pages_in_use = 0; -+ bi->soft_del_pages = 0; -+ bi->has_shrink_hdr = 0; -+ bi->skip_erased_check = 1; /* Clean, so no need to check */ -+ bi->gc_prioritise = 0; -+ bi->has_summary = 0; -+ -+ yaffs_clear_chunk_bits(dev, block_no); -+ -+ yaffs_trace(YAFFS_TRACE_ERASE, "Erased block %d", block_no); -+} -+ -+static inline int yaffs_gc_process_chunk(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi, -+ int old_chunk, u8 *buffer) -+{ -+ int new_chunk; -+ int mark_flash = 1; -+ struct yaffs_ext_tags tags; -+ struct yaffs_obj *object; -+ int matching_chunk; -+ int ret_val = YAFFS_OK; -+ -+ memset(&tags, 0, sizeof(tags)); -+ yaffs_rd_chunk_tags_nand(dev, old_chunk, -+ buffer, &tags); -+ object = yaffs_find_by_number(dev, tags.obj_id); -+ -+ yaffs_trace(YAFFS_TRACE_GC_DETAIL, -+ "Collecting chunk in block %d, %d %d %d ", -+ dev->gc_chunk, tags.obj_id, -+ tags.chunk_id, tags.n_bytes); -+ -+ if (object && !yaffs_skip_verification(dev)) { -+ if (tags.chunk_id == 0) -+ matching_chunk = -+ object->hdr_chunk; -+ else if (object->soft_del) -+ /* Defeat the test */ -+ matching_chunk = old_chunk; -+ else -+ matching_chunk = -+ yaffs_find_chunk_in_file -+ (object, tags.chunk_id, -+ NULL); -+ -+ if (old_chunk != matching_chunk) -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "gc: page in gc mismatch: %d %d %d %d", -+ old_chunk, -+ matching_chunk, -+ tags.obj_id, -+ tags.chunk_id); -+ } -+ -+ if (!object) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "page %d in gc has no object: %d %d %d ", -+ old_chunk, -+ tags.obj_id, tags.chunk_id, -+ tags.n_bytes); -+ } -+ -+ if (object && -+ object->deleted && -+ object->soft_del && tags.chunk_id != 0) { -+ /* Data chunk in a soft deleted file, -+ * throw it away. -+ * It's a soft deleted data chunk, -+ * No need to copy this, just forget -+ * about it and fix up the object. -+ */ -+ -+ /* Free chunks already includes -+ * softdeleted chunks, how ever this -+ * chunk is going to soon be really -+ * deleted which will increment free -+ * chunks. We have to decrement free -+ * chunks so this works out properly. -+ */ -+ dev->n_free_chunks--; -+ bi->soft_del_pages--; -+ -+ object->n_data_chunks--; -+ if (object->n_data_chunks <= 0) { -+ /* remeber to clean up obj */ -+ dev->gc_cleanup_list[dev->n_clean_ups] = tags.obj_id; -+ dev->n_clean_ups++; -+ } -+ mark_flash = 0; -+ } else if (object) { -+ /* It's either a data chunk in a live -+ * file or an ObjectHeader, so we're -+ * interested in it. -+ * NB Need to keep the ObjectHeaders of -+ * deleted files until the whole file -+ * has been deleted off -+ */ -+ tags.serial_number++; -+ dev->n_gc_copies++; -+ -+ if (tags.chunk_id == 0) { -+ /* It is an object Id, -+ * We need to nuke the shrinkheader flags since its -+ * work is done. -+ * Also need to clean up shadowing. -+ * NB We don't want to do all the work of translating -+ * object header endianism back and forth so we leave -+ * the oh endian in its stored order. -+ */ -+ -+ struct yaffs_obj_hdr *oh; -+ oh = (struct yaffs_obj_hdr *) buffer; -+ -+ oh->is_shrink = 0; -+ tags.extra_is_shrink = 0; -+ oh->shadows_obj = 0; -+ oh->inband_shadowed_obj_id = 0; -+ tags.extra_shadows = 0; -+ -+ /* Update file size */ -+ if (object->variant_type == YAFFS_OBJECT_TYPE_FILE) { -+ yaffs_oh_size_load(dev, oh, -+ object->variant.file_variant.stored_size, 1); -+ tags.extra_file_size = -+ object->variant.file_variant.stored_size; -+ } -+ -+ yaffs_verify_oh(object, oh, &tags, 1); -+ new_chunk = -+ yaffs_write_new_chunk(dev, (u8 *) oh, &tags, 1); -+ } else { -+ new_chunk = -+ yaffs_write_new_chunk(dev, buffer, &tags, 1); -+ } -+ -+ if (new_chunk < 0) { -+ ret_val = YAFFS_FAIL; -+ } else { -+ -+ /* Now fix up the Tnodes etc. */ -+ -+ if (tags.chunk_id == 0) { -+ /* It's a header */ -+ object->hdr_chunk = new_chunk; -+ object->serial = tags.serial_number; -+ } else { -+ /* It's a data chunk */ -+ yaffs_put_chunk_in_file(object, tags.chunk_id, -+ new_chunk, 0); -+ } -+ } -+ } -+ if (ret_val == YAFFS_OK) -+ yaffs_chunk_del(dev, old_chunk, mark_flash, __LINE__); -+ return ret_val; -+} -+ -+static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block) -+{ -+ int old_chunk; -+ int ret_val = YAFFS_OK; -+ u32 i; -+ int is_checkpt_block; -+ int max_copies; -+ int chunks_before = yaffs_get_erased_chunks(dev); -+ int chunks_after; -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, block); -+ -+ is_checkpt_block = (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT); -+ -+ yaffs_trace(YAFFS_TRACE_TRACING, -+ "Collecting block %d, in use %d, shrink %d, whole_block %d", -+ block, bi->pages_in_use, bi->has_shrink_hdr, -+ whole_block); -+ -+ /*yaffs_verify_free_chunks(dev); */ -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_FULL) -+ bi->block_state = YAFFS_BLOCK_STATE_COLLECTING; -+ -+ bi->has_shrink_hdr = 0; /* clear the flag so that the block can erase */ -+ -+ dev->gc_disable = 1; -+ -+ yaffs_summary_gc(dev, block); -+ -+ if (is_checkpt_block || !yaffs_still_some_chunks(dev, block)) { -+ yaffs_trace(YAFFS_TRACE_TRACING, -+ "Collecting block %d that has no chunks in use", -+ block); -+ yaffs_block_became_dirty(dev, block); -+ } else { -+ -+ u8 *buffer = yaffs_get_temp_buffer(dev); -+ -+ yaffs_verify_blk(dev, bi, block); -+ -+ max_copies = (whole_block) ? dev->param.chunks_per_block : 5; -+ old_chunk = block * dev->param.chunks_per_block + dev->gc_chunk; -+ -+ for (/* init already done */ ; -+ ret_val == YAFFS_OK && -+ dev->gc_chunk < dev->param.chunks_per_block && -+ (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) && -+ max_copies > 0; -+ dev->gc_chunk++, old_chunk++) { -+ if (yaffs_check_chunk_bit(dev, block, dev->gc_chunk)) { -+ /* Page is in use and might need to be copied */ -+ max_copies--; -+ ret_val = yaffs_gc_process_chunk(dev, bi, -+ old_chunk, buffer); -+ } -+ } -+ yaffs_release_temp_buffer(dev, buffer); -+ } -+ -+ yaffs_verify_collected_blk(dev, bi, block); -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) { -+ /* -+ * The gc did not complete. Set block state back to FULL -+ * because checkpointing does not restore gc. -+ */ -+ bi->block_state = YAFFS_BLOCK_STATE_FULL; -+ } else { -+ /* The gc completed. */ -+ /* Do any required cleanups */ -+ for (i = 0; i < dev->n_clean_ups; i++) { -+ /* Time to delete the file too */ -+ struct yaffs_obj *object = -+ yaffs_find_by_number(dev, dev->gc_cleanup_list[i]); -+ if (object) { -+ yaffs_free_tnode(dev, -+ object->variant.file_variant.top); -+ object->variant.file_variant.top = NULL; -+ yaffs_trace(YAFFS_TRACE_GC, -+ "yaffs: About to finally delete object %d", -+ object->obj_id); -+ yaffs_generic_obj_del(object); -+ object->my_dev->n_deleted_files--; -+ } -+ -+ } -+ chunks_after = yaffs_get_erased_chunks(dev); -+ if (chunks_before >= chunks_after) -+ yaffs_trace(YAFFS_TRACE_GC, -+ "gc did not increase free chunks before %d after %d", -+ chunks_before, chunks_after); -+ dev->gc_block = 0; -+ dev->gc_chunk = 0; -+ dev->n_clean_ups = 0; -+ } -+ -+ dev->gc_disable = 0; -+ -+ return ret_val; -+} -+ -+/* -+ * find_gc_block() selects the dirtiest block (or close enough) -+ * for garbage collection. -+ */ -+ -+static unsigned yaffs_find_gc_block(struct yaffs_dev *dev, -+ int aggressive, int background) -+{ -+ u32 i; -+ u32 iterations; -+ u32 selected = 0; -+ int prioritised = 0; -+ int prioritised_exist = 0; -+ struct yaffs_block_info *bi; -+ u32 threshold; -+ -+ /* First let's see if we need to grab a prioritised block */ -+ if (dev->has_pending_prioritised_gc && !aggressive) { -+ dev->gc_dirtiest = 0; -+ bi = dev->block_info; -+ for (i = dev->internal_start_block; -+ i <= dev->internal_end_block && !selected; i++) { -+ -+ if (bi->gc_prioritise) { -+ prioritised_exist = 1; -+ if (bi->block_state == YAFFS_BLOCK_STATE_FULL && -+ yaffs_block_ok_for_gc(dev, bi)) { -+ selected = i; -+ prioritised = 1; -+ } -+ } -+ bi++; -+ } -+ -+ /* -+ * If there is a prioritised block and none was selected then -+ * this happened because there is at least one old dirty block -+ * gumming up the works. Let's gc the oldest dirty block. -+ */ -+ -+ if (prioritised_exist && -+ !selected && dev->oldest_dirty_block > 0) -+ selected = dev->oldest_dirty_block; -+ -+ if (!prioritised_exist) /* None found, so we can clear this */ -+ dev->has_pending_prioritised_gc = 0; -+ } -+ -+ /* If we're doing aggressive GC then we are happy to take a less-dirty -+ * block, and search harder. -+ * else (leasurely gc), then we only bother to do this if the -+ * block has only a few pages in use. -+ */ -+ -+ if (!selected) { -+ u32 pages_used; -+ int n_blocks = -+ dev->internal_end_block - dev->internal_start_block + 1; -+ if (aggressive) { -+ threshold = dev->param.chunks_per_block; -+ iterations = n_blocks; -+ } else { -+ u32 max_threshold; -+ -+ if (background) -+ max_threshold = dev->param.chunks_per_block / 2; -+ else -+ max_threshold = dev->param.chunks_per_block / 8; -+ -+ if (max_threshold < YAFFS_GC_PASSIVE_THRESHOLD) -+ max_threshold = YAFFS_GC_PASSIVE_THRESHOLD; -+ -+ threshold = background ? (dev->gc_not_done + 2) * 2 : 0; -+ if (threshold < YAFFS_GC_PASSIVE_THRESHOLD) -+ threshold = YAFFS_GC_PASSIVE_THRESHOLD; -+ if (threshold > max_threshold) -+ threshold = max_threshold; -+ -+ iterations = n_blocks / 16 + 1; -+ if (iterations > 100) -+ iterations = 100; -+ } -+ -+ for (i = 0; -+ i < iterations && -+ (dev->gc_dirtiest < 1 || -+ dev->gc_pages_in_use > YAFFS_GC_GOOD_ENOUGH); -+ i++) { -+ dev->gc_block_finder++; -+ if (dev->gc_block_finder < dev->internal_start_block || -+ dev->gc_block_finder > dev->internal_end_block) -+ dev->gc_block_finder = -+ dev->internal_start_block; -+ -+ bi = yaffs_get_block_info(dev, dev->gc_block_finder); -+ -+ pages_used = bi->pages_in_use - bi->soft_del_pages; -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_FULL && -+ pages_used < dev->param.chunks_per_block && -+ (dev->gc_dirtiest < 1 || -+ pages_used < dev->gc_pages_in_use) && -+ yaffs_block_ok_for_gc(dev, bi)) { -+ dev->gc_dirtiest = dev->gc_block_finder; -+ dev->gc_pages_in_use = pages_used; -+ } -+ } -+ -+ if (dev->gc_dirtiest > 0 && dev->gc_pages_in_use <= threshold) -+ selected = dev->gc_dirtiest; -+ } -+ -+ /* -+ * If nothing has been selected for a while, try the oldest dirty -+ * because that's gumming up the works. -+ */ -+ -+ if (!selected && dev->param.is_yaffs2 && -+ dev->gc_not_done >= (background ? 10 : 20)) { -+ yaffs2_find_oldest_dirty_seq(dev); -+ if (dev->oldest_dirty_block > 0) { -+ selected = dev->oldest_dirty_block; -+ dev->gc_dirtiest = selected; -+ dev->oldest_dirty_gc_count++; -+ bi = yaffs_get_block_info(dev, selected); -+ dev->gc_pages_in_use = -+ bi->pages_in_use - bi->soft_del_pages; -+ } else { -+ dev->gc_not_done = 0; -+ } -+ } -+ -+ if (selected) { -+ yaffs_trace(YAFFS_TRACE_GC, -+ "GC Selected block %d with %d free, prioritised:%d", -+ selected, -+ dev->param.chunks_per_block - dev->gc_pages_in_use, -+ prioritised); -+ -+ dev->n_gc_blocks++; -+ if (background) -+ dev->bg_gcs++; -+ -+ dev->gc_dirtiest = 0; -+ dev->gc_pages_in_use = 0; -+ dev->gc_not_done = 0; -+ if (dev->refresh_skip > 0) -+ dev->refresh_skip--; -+ } else { -+ dev->gc_not_done++; -+ yaffs_trace(YAFFS_TRACE_GC, -+ "GC none: finder %d skip %d threshold %d dirtiest %d using %d oldest %d%s", -+ dev->gc_block_finder, dev->gc_not_done, threshold, -+ dev->gc_dirtiest, dev->gc_pages_in_use, -+ dev->oldest_dirty_block, background ? " bg" : ""); -+ } -+ -+ return selected; -+} -+ -+/* New garbage collector -+ * If we're very low on erased blocks then we do aggressive garbage collection -+ * otherwise we do "leasurely" garbage collection. -+ * Aggressive gc looks further (whole array) and will accept less dirty blocks. -+ * Passive gc only inspects smaller areas and only accepts more dirty blocks. -+ * -+ * The idea is to help clear out space in a more spread-out manner. -+ * Dunno if it really does anything useful. -+ */ -+static int yaffs_check_gc(struct yaffs_dev *dev, int background) -+{ -+ int aggressive = 0; -+ int gc_ok = YAFFS_OK; -+ int max_tries = 0; -+ int min_erased; -+ int erased_chunks; -+ int checkpt_block_adjust; -+ -+ if (dev->param.gc_control_fn && -+ (dev->param.gc_control_fn(dev) & 1) == 0) -+ return YAFFS_OK; -+ -+ if (dev->gc_disable) -+ /* Bail out so we don't get recursive gc */ -+ return YAFFS_OK; -+ -+ /* This loop should pass the first time. -+ * Only loops here if the collection does not increase space. -+ */ -+ -+ do { -+ max_tries++; -+ -+ checkpt_block_adjust = yaffs_calc_checkpt_blocks_required(dev); -+ -+ min_erased = -+ dev->param.n_reserved_blocks + checkpt_block_adjust + 1; -+ erased_chunks = -+ dev->n_erased_blocks * dev->param.chunks_per_block; -+ -+ /* If we need a block soon then do aggressive gc. */ -+ if (dev->n_erased_blocks < min_erased) -+ aggressive = 1; -+ else { -+ if (!background -+ && erased_chunks > (dev->n_free_chunks / 4)) -+ break; -+ -+ if (dev->gc_skip > 20) -+ dev->gc_skip = 20; -+ if (erased_chunks < dev->n_free_chunks / 2 || -+ dev->gc_skip < 1 || background) -+ aggressive = 0; -+ else { -+ dev->gc_skip--; -+ break; -+ } -+ } -+ -+ dev->gc_skip = 5; -+ -+ /* If we don't already have a block being gc'd then see if we -+ * should start another */ -+ -+ if (dev->gc_block < 1 && !aggressive) { -+ dev->gc_block = yaffs2_find_refresh_block(dev); -+ dev->gc_chunk = 0; -+ dev->n_clean_ups = 0; -+ } -+ if (dev->gc_block < 1) { -+ dev->gc_block = -+ yaffs_find_gc_block(dev, aggressive, background); -+ dev->gc_chunk = 0; -+ dev->n_clean_ups = 0; -+ } -+ -+ if (dev->gc_block > 0) { -+ dev->all_gcs++; -+ if (!aggressive) -+ dev->passive_gc_count++; -+ -+ yaffs_trace(YAFFS_TRACE_GC, -+ "yaffs: GC n_erased_blocks %d aggressive %d", -+ dev->n_erased_blocks, aggressive); -+ -+ gc_ok = yaffs_gc_block(dev, dev->gc_block, aggressive); -+ } -+ -+ if (dev->n_erased_blocks < (int)dev->param.n_reserved_blocks && -+ dev->gc_block > 0) { -+ yaffs_trace(YAFFS_TRACE_GC, -+ "yaffs: GC !!!no reclaim!!! n_erased_blocks %d after try %d block %d", -+ dev->n_erased_blocks, max_tries, -+ dev->gc_block); -+ } -+ } while ((dev->n_erased_blocks < (int)dev->param.n_reserved_blocks) && -+ (dev->gc_block > 0) && (max_tries < 2)); -+ -+ return aggressive ? gc_ok : YAFFS_OK; -+} -+ -+/* -+ * yaffs_bg_gc() -+ * Garbage collects. Intended to be called from a background thread. -+ * Returns non-zero if at least half the free chunks are erased. -+ */ -+int yaffs_bg_gc(struct yaffs_dev *dev, unsigned urgency) -+{ -+ int erased_chunks = dev->n_erased_blocks * dev->param.chunks_per_block; -+ -+ yaffs_trace(YAFFS_TRACE_BACKGROUND, "Background gc %u", urgency); -+ -+ yaffs_check_gc(dev, 1); -+ return erased_chunks > dev->n_free_chunks / 2; -+} -+ -+/*-------------------- Data file manipulation -----------------*/ -+ -+static int yaffs_rd_data_obj(struct yaffs_obj *in, int inode_chunk, u8 * buffer) -+{ -+ int nand_chunk = yaffs_find_chunk_in_file(in, inode_chunk, NULL); -+ -+ if (nand_chunk >= 0) -+ return yaffs_rd_chunk_tags_nand(in->my_dev, nand_chunk, -+ buffer, NULL); -+ else { -+ yaffs_trace(YAFFS_TRACE_NANDACCESS, -+ "Chunk %d not found zero instead", -+ nand_chunk); -+ /* get sane (zero) data if you read a hole */ -+ memset(buffer, 0, in->my_dev->data_bytes_per_chunk); -+ return 0; -+ } -+ -+} -+ -+void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash, -+ int lyn) -+{ -+ int block; -+ int page; -+ struct yaffs_ext_tags tags; -+ struct yaffs_block_info *bi; -+ -+ if (chunk_id <= 0) -+ return; -+ -+ dev->n_deletions++; -+ block = chunk_id / dev->param.chunks_per_block; -+ page = chunk_id % dev->param.chunks_per_block; -+ -+ if (!yaffs_check_chunk_bit(dev, block, page)) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Deleting invalid chunk %d", chunk_id); -+ -+ bi = yaffs_get_block_info(dev, block); -+ -+ yaffs2_update_oldest_dirty_seq(dev, block, bi); -+ -+ yaffs_trace(YAFFS_TRACE_DELETION, -+ "line %d delete of chunk %d", -+ lyn, chunk_id); -+ -+ if (!dev->param.is_yaffs2 && mark_flash && -+ bi->block_state != YAFFS_BLOCK_STATE_COLLECTING) { -+ -+ memset(&tags, 0, sizeof(tags)); -+ tags.is_deleted = 1; -+ yaffs_wr_chunk_tags_nand(dev, chunk_id, NULL, &tags); -+ yaffs_handle_chunk_update(dev, chunk_id, &tags); -+ } else { -+ dev->n_unmarked_deletions++; -+ } -+ -+ /* Pull out of the management area. -+ * If the whole block became dirty, this will kick off an erasure. -+ */ -+ if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING || -+ bi->block_state == YAFFS_BLOCK_STATE_FULL || -+ bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN || -+ bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) { -+ dev->n_free_chunks++; -+ yaffs_clear_chunk_bit(dev, block, page); -+ bi->pages_in_use--; -+ -+ if (bi->pages_in_use == 0 && -+ !bi->has_shrink_hdr && -+ bi->block_state != YAFFS_BLOCK_STATE_ALLOCATING && -+ bi->block_state != YAFFS_BLOCK_STATE_NEEDS_SCAN) { -+ yaffs_block_became_dirty(dev, block); -+ } -+ } -+} -+ -+static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk, -+ const u8 *buffer, int n_bytes, int use_reserve) -+{ -+ /* Find old chunk Need to do this to get serial number -+ * Write new one and patch into tree. -+ * Invalidate old tags. -+ */ -+ -+ int prev_chunk_id; -+ struct yaffs_ext_tags prev_tags; -+ int new_chunk_id; -+ struct yaffs_ext_tags new_tags; -+ struct yaffs_dev *dev = in->my_dev; -+ loff_t endpos; -+ -+ yaffs_check_gc(dev, 0); -+ -+ /* Get the previous chunk at this location in the file if it exists. -+ * If it does not exist then put a zero into the tree. This creates -+ * the tnode now, rather than later when it is harder to clean up. -+ */ -+ prev_chunk_id = yaffs_find_chunk_in_file(in, inode_chunk, &prev_tags); -+ if (prev_chunk_id < 1 && -+ !yaffs_put_chunk_in_file(in, inode_chunk, 0, 0)) -+ return 0; -+ -+ /* Set up new tags */ -+ memset(&new_tags, 0, sizeof(new_tags)); -+ -+ new_tags.chunk_id = inode_chunk; -+ new_tags.obj_id = in->obj_id; -+ new_tags.serial_number = -+ (prev_chunk_id > 0) ? prev_tags.serial_number + 1 : 1; -+ new_tags.n_bytes = n_bytes; -+ -+ if (n_bytes < 1 || n_bytes > (int)dev->data_bytes_per_chunk) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "Writing %d bytes to chunk!!!!!!!!!", -+ n_bytes); -+ BUG(); -+ } -+ -+ /* -+ * If this is a data chunk and the write goes past the end of the stored -+ * size then update the stored_size. -+ */ -+ if (inode_chunk > 0) { -+ endpos = (inode_chunk - 1) * dev->data_bytes_per_chunk + -+ n_bytes; -+ if (in->variant.file_variant.stored_size < endpos) -+ in->variant.file_variant.stored_size = endpos; -+ } -+ -+ new_chunk_id = -+ yaffs_write_new_chunk(dev, buffer, &new_tags, use_reserve); -+ -+ if (new_chunk_id > 0) { -+ yaffs_put_chunk_in_file(in, inode_chunk, new_chunk_id, 0); -+ -+ if (prev_chunk_id > 0) -+ yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__); -+ -+ yaffs_verify_file_sane(in); -+ } -+ return new_chunk_id; -+} -+ -+ -+ -+static int yaffs_do_xattrib_mod(struct yaffs_obj *obj, int set, -+ const YCHAR *name, const void *value, int size, -+ int flags) -+{ -+ struct yaffs_xattr_mod xmod; -+ int result; -+ -+ xmod.set = set; -+ xmod.name = name; -+ xmod.data = value; -+ xmod.size = size; -+ xmod.flags = flags; -+ xmod.result = -ENOSPC; -+ -+ result = yaffs_update_oh(obj, NULL, 0, 0, 0, &xmod); -+ -+ if (result > 0) -+ return xmod.result; -+ else -+ return -ENOSPC; -+} -+ -+static int yaffs_apply_xattrib_mod(struct yaffs_obj *obj, char *buffer, -+ struct yaffs_xattr_mod *xmod) -+{ -+ int retval = 0; -+ int x_offs = sizeof(struct yaffs_obj_hdr); -+ struct yaffs_dev *dev = obj->my_dev; -+ int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr); -+ char *x_buffer = buffer + x_offs; -+ -+ if (xmod->set) -+ retval = -+ nval_set(dev, x_buffer, x_size, xmod->name, xmod->data, -+ xmod->size, xmod->flags); -+ else -+ retval = nval_del(dev, x_buffer, x_size, xmod->name); -+ -+ obj->has_xattr = nval_hasvalues(dev, x_buffer, x_size); -+ obj->xattr_known = 1; -+ xmod->result = retval; -+ -+ return retval; -+} -+ -+static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR *name, -+ void *value, int size) -+{ -+ char *buffer = NULL; -+ int result; -+ struct yaffs_ext_tags tags; -+ struct yaffs_dev *dev = obj->my_dev; -+ int x_offs = sizeof(struct yaffs_obj_hdr); -+ int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr); -+ char *x_buffer; -+ int retval = 0; -+ -+ if (obj->hdr_chunk < 1) -+ return -ENODATA; -+ -+ /* If we know that the object has no xattribs then don't do all the -+ * reading and parsing. -+ */ -+ if (obj->xattr_known && !obj->has_xattr) { -+ if (name) -+ return -ENODATA; -+ else -+ return 0; -+ } -+ -+ buffer = (char *)yaffs_get_temp_buffer(dev); -+ if (!buffer) -+ return -ENOMEM; -+ -+ result = -+ yaffs_rd_chunk_tags_nand(dev, obj->hdr_chunk, (u8 *) buffer, &tags); -+ -+ if (result != YAFFS_OK) -+ retval = -ENOENT; -+ else { -+ x_buffer = buffer + x_offs; -+ -+ if (!obj->xattr_known) { -+ obj->has_xattr = nval_hasvalues(dev, x_buffer, x_size); -+ obj->xattr_known = 1; -+ } -+ -+ if (name) -+ retval = nval_get(dev, x_buffer, x_size, -+ name, value, size); -+ else -+ retval = nval_list(dev, x_buffer, x_size, value, size); -+ } -+ yaffs_release_temp_buffer(dev, (u8 *) buffer); -+ return retval; -+} -+ -+int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR * name, -+ const void *value, int size, int flags) -+{ -+ return yaffs_do_xattrib_mod(obj, 1, name, value, size, flags); -+} -+ -+int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR * name) -+{ -+ return yaffs_do_xattrib_mod(obj, 0, name, NULL, 0, 0); -+} -+ -+int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR * name, void *value, -+ int size) -+{ -+ return yaffs_do_xattrib_fetch(obj, name, value, size); -+} -+ -+int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size) -+{ -+ return yaffs_do_xattrib_fetch(obj, NULL, buffer, size); -+} -+ -+static void yaffs_check_obj_details_loaded(struct yaffs_obj *in) -+{ -+ u8 *buf; -+ struct yaffs_obj_hdr *oh; -+ struct yaffs_dev *dev; -+ struct yaffs_ext_tags tags; -+ int result; -+ -+ if (!in || !in->lazy_loaded || in->hdr_chunk < 1) -+ return; -+ -+ dev = in->my_dev; -+ buf = yaffs_get_temp_buffer(dev); -+ -+ result = yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, buf, &tags); -+ -+ if (result == YAFFS_FAIL) -+ return; -+ -+ oh = (struct yaffs_obj_hdr *)buf; -+ -+ yaffs_do_endian_oh(dev, oh); -+ -+ in->lazy_loaded = 0; -+ in->yst_mode = oh->yst_mode; -+ yaffs_load_attribs(in, oh); -+ yaffs_set_obj_name_from_oh(in, oh); -+ -+ if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) -+ in->variant.symlink_variant.alias = -+ yaffs_clone_str(oh->alias); -+ yaffs_release_temp_buffer(dev, buf); -+} -+ -+/* UpdateObjectHeader updates the header on NAND for an object. -+ * If name is not NULL, then that new name is used. -+ * -+ * We're always creating the obj header from scratch (except reading -+ * the old name) so first set up in cpu endianness then run it through -+ * endian fixing at the end. -+ * -+ * However, a twist: If there are xattribs we leave them as they were. -+ * -+ * Careful! The buffer holds the whole chunk. Part of the chunk holds the -+ * object header and the rest holds the xattribs, therefore we use a buffer -+ * pointer and an oh pointer to point to the same memory. -+ */ -+ -+int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force, -+ int is_shrink, int shadows, struct yaffs_xattr_mod *xmod) -+{ -+ -+ struct yaffs_block_info *bi; -+ struct yaffs_dev *dev = in->my_dev; -+ int prev_chunk_id; -+ int ret_val = 0; -+ int result = 0; -+ int new_chunk_id; -+ struct yaffs_ext_tags new_tags; -+ struct yaffs_ext_tags old_tags; -+ const YCHAR *alias = NULL; -+ u8 *buffer = NULL; -+ YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1]; -+ struct yaffs_obj_hdr *oh = NULL; -+ loff_t file_size = 0; -+ -+ strcpy(old_name, _Y("silly old name")); -+ -+ if (in->fake && in != dev->root_dir && !force && !xmod) -+ return ret_val; -+ -+ yaffs_check_gc(dev, 0); -+ yaffs_check_obj_details_loaded(in); -+ -+ buffer = yaffs_get_temp_buffer(in->my_dev); -+ oh = (struct yaffs_obj_hdr *)buffer; -+ -+ prev_chunk_id = in->hdr_chunk; -+ -+ if (prev_chunk_id > 0) { -+ /* Access the old obj header just to read the name. */ -+ result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id, -+ buffer, &old_tags); -+ if (result == YAFFS_OK) { -+ yaffs_verify_oh(in, oh, &old_tags, 0); -+ memcpy(old_name, oh->name, sizeof(oh->name)); -+ -+ /* -+ * NB We only wipe the object header area because the rest of -+ * the buffer might contain xattribs. -+ */ -+ memset(oh, 0xff, sizeof(*oh)); -+ } -+ } else { -+ memset(buffer, 0xff, dev->data_bytes_per_chunk); -+ } -+ -+ oh->type = in->variant_type; -+ oh->yst_mode = in->yst_mode; -+ oh->shadows_obj = oh->inband_shadowed_obj_id = shadows; -+ -+ yaffs_load_attribs_oh(oh, in); -+ -+ if (in->parent) -+ oh->parent_obj_id = in->parent->obj_id; -+ else -+ oh->parent_obj_id = 0; -+ -+ if (name && *name) { -+ memset(oh->name, 0, sizeof(oh->name)); -+ yaffs_load_oh_from_name(dev, oh->name, name); -+ } else if (prev_chunk_id > 0) { -+ memcpy(oh->name, old_name, sizeof(oh->name)); -+ } else { -+ memset(oh->name, 0, sizeof(oh->name)); -+ } -+ -+ oh->is_shrink = is_shrink; -+ -+ switch (in->variant_type) { -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ /* Should not happen */ -+ break; -+ case YAFFS_OBJECT_TYPE_FILE: -+ if (oh->parent_obj_id != YAFFS_OBJECTID_DELETED && -+ oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED) -+ file_size = in->variant.file_variant.stored_size; -+ yaffs_oh_size_load(dev, oh, file_size, 0); -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ oh->equiv_id = in->variant.hardlink_variant.equiv_id; -+ break; -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ /* Do nothing */ -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ /* Do nothing */ -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ alias = in->variant.symlink_variant.alias; -+ if (!alias) -+ alias = _Y("no alias"); -+ strncpy(oh->alias, alias, YAFFS_MAX_ALIAS_LENGTH); -+ oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0; -+ break; -+ } -+ -+ /* process any xattrib modifications */ -+ if (xmod) -+ yaffs_apply_xattrib_mod(in, (char *)buffer, xmod); -+ -+ /* Tags */ -+ memset(&new_tags, 0, sizeof(new_tags)); -+ in->serial++; -+ new_tags.chunk_id = 0; -+ new_tags.obj_id = in->obj_id; -+ new_tags.serial_number = in->serial; -+ -+ /* Add extra info for file header */ -+ new_tags.extra_available = 1; -+ new_tags.extra_parent_id = oh->parent_obj_id; -+ new_tags.extra_file_size = file_size; -+ new_tags.extra_is_shrink = oh->is_shrink; -+ new_tags.extra_equiv_id = oh->equiv_id; -+ new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0; -+ new_tags.extra_obj_type = in->variant_type; -+ -+ /* Now endian swizzle the oh if needed. */ -+ yaffs_do_endian_oh(dev, oh); -+ -+ yaffs_verify_oh(in, oh, &new_tags, 1); -+ -+ /* Create new chunk in NAND */ -+ new_chunk_id = -+ yaffs_write_new_chunk(dev, buffer, &new_tags, -+ (prev_chunk_id > 0) ? 1 : 0); -+ -+ if (buffer) -+ yaffs_release_temp_buffer(dev, buffer); -+ -+ if (new_chunk_id < 0) -+ return new_chunk_id; -+ -+ in->hdr_chunk = new_chunk_id; -+ -+ if (prev_chunk_id > 0) -+ yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__); -+ -+ if (!yaffs_obj_cache_dirty(in)) -+ in->dirty = 0; -+ -+ /* If this was a shrink, then mark the block -+ * that the chunk lives on */ -+ if (is_shrink) { -+ bi = yaffs_get_block_info(in->my_dev, -+ new_chunk_id / -+ in->my_dev->param.chunks_per_block); -+ bi->has_shrink_hdr = 1; -+ } -+ -+ -+ return new_chunk_id; -+} -+ -+/*--------------------- File read/write ------------------------ -+ * Read and write have very similar structures. -+ * In general the read/write has three parts to it -+ * An incomplete chunk to start with (if the read/write is not chunk-aligned) -+ * Some complete chunks -+ * An incomplete chunk to end off with -+ * -+ * Curve-balls: the first chunk might also be the last chunk. -+ */ -+ -+int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, int n_bytes) -+{ -+ int chunk; -+ u32 start; -+ int n_copy; -+ int n = n_bytes; -+ int n_done = 0; -+ struct yaffs_cache *cache; -+ struct yaffs_dev *dev; -+ -+ dev = in->my_dev; -+ -+ while (n > 0) { -+ yaffs_addr_to_chunk(dev, offset, &chunk, &start); -+ chunk++; -+ -+ /* OK now check for the curveball where the start and end are in -+ * the same chunk. -+ */ -+ if ((start + n) < dev->data_bytes_per_chunk) -+ n_copy = n; -+ else -+ n_copy = dev->data_bytes_per_chunk - start; -+ -+ cache = yaffs_find_chunk_cache(in, chunk); -+ -+ /* If the chunk is already in the cache or it is less than -+ * a whole chunk or we're using inband tags then use the cache -+ * (if there is caching) else bypass the cache. -+ */ -+ if (cache || n_copy != (int)dev->data_bytes_per_chunk || -+ dev->param.inband_tags) { -+ if (dev->param.n_caches > 0) { -+ -+ /* If we can't find the data in the cache, -+ * then load it up. */ -+ -+ if (!cache) { -+ cache = -+ yaffs_grab_chunk_cache(in->my_dev); -+ cache->object = in; -+ cache->chunk_id = chunk; -+ cache->dirty = 0; -+ cache->locked = 0; -+ yaffs_rd_data_obj(in, chunk, -+ cache->data); -+ cache->n_bytes = 0; -+ } -+ -+ yaffs_use_cache(dev, cache, 0); -+ -+ cache->locked = 1; -+ -+ memcpy(buffer, &cache->data[start], n_copy); -+ -+ cache->locked = 0; -+ } else { -+ /* Read into the local buffer then copy.. */ -+ -+ u8 *local_buffer = -+ yaffs_get_temp_buffer(dev); -+ yaffs_rd_data_obj(in, chunk, local_buffer); -+ -+ memcpy(buffer, &local_buffer[start], n_copy); -+ -+ yaffs_release_temp_buffer(dev, local_buffer); -+ } -+ } else { -+ /* A full chunk. Read directly into the buffer. */ -+ yaffs_rd_data_obj(in, chunk, buffer); -+ } -+ n -= n_copy; -+ offset += n_copy; -+ buffer += n_copy; -+ n_done += n_copy; -+ } -+ return n_done; -+} -+ -+int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset, -+ int n_bytes, int write_through) -+{ -+ -+ int chunk; -+ u32 start; -+ int n_copy; -+ int n = n_bytes; -+ int n_done = 0; -+ int n_writeback; -+ loff_t start_write = offset; -+ int chunk_written = 0; -+ u32 n_bytes_read; -+ loff_t chunk_start; -+ struct yaffs_dev *dev; -+ -+ dev = in->my_dev; -+ -+ while (n > 0 && chunk_written >= 0) { -+ yaffs_addr_to_chunk(dev, offset, &chunk, &start); -+ -+ if (((loff_t)chunk) * -+ dev->data_bytes_per_chunk + start != offset || -+ start >= dev->data_bytes_per_chunk) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "AddrToChunk of offset %lld gives chunk %d start %d", -+ (long long)offset, chunk, start); -+ } -+ chunk++; /* File pos to chunk in file offset */ -+ -+ /* OK now check for the curveball where the start and end are in -+ * the same chunk. -+ */ -+ -+ if ((start + n) < dev->data_bytes_per_chunk) { -+ n_copy = n; -+ -+ /* Now calculate how many bytes to write back.... -+ * If we're overwriting and not writing to then end of -+ * file then we need to write back as much as was there -+ * before. -+ */ -+ -+ chunk_start = (((loff_t)(chunk - 1)) * -+ dev->data_bytes_per_chunk); -+ -+ if (chunk_start > in->variant.file_variant.file_size) -+ n_bytes_read = 0; /* Past end of file */ -+ else -+ n_bytes_read = -+ in->variant.file_variant.file_size - -+ chunk_start; -+ -+ if (n_bytes_read > dev->data_bytes_per_chunk) -+ n_bytes_read = dev->data_bytes_per_chunk; -+ -+ n_writeback = -+ (n_bytes_read > -+ (start + n)) ? n_bytes_read : (start + n); -+ -+ if (n_writeback < 0 || -+ n_writeback > (int)dev->data_bytes_per_chunk) -+ BUG(); -+ -+ } else { -+ n_copy = dev->data_bytes_per_chunk - start; -+ n_writeback = dev->data_bytes_per_chunk; -+ } -+ -+ if (n_copy != (int)dev->data_bytes_per_chunk || -+ !dev->param.cache_bypass_aligned || -+ dev->param.inband_tags) { -+ /* An incomplete start or end chunk (or maybe both -+ * start and end chunk), or we're using inband tags, -+ * or we're forcing writes through the cache, -+ * so we want to use the cache buffers. -+ */ -+ if (dev->param.n_caches > 0) { -+ struct yaffs_cache *cache; -+ -+ /* If we can't find the data in the cache, then -+ * load the cache */ -+ cache = yaffs_find_chunk_cache(in, chunk); -+ -+ if (!cache && -+ yaffs_check_alloc_available(dev, 1)) { -+ cache = yaffs_grab_chunk_cache(dev); -+ cache->object = in; -+ cache->chunk_id = chunk; -+ cache->dirty = 0; -+ cache->locked = 0; -+ yaffs_rd_data_obj(in, chunk, -+ cache->data); -+ } else if (cache && -+ !cache->dirty && -+ !yaffs_check_alloc_available(dev, -+ 1)) { -+ /* Drop the cache if it was a read cache -+ * item and no space check has been made -+ * for it. -+ */ -+ cache = NULL; -+ } -+ -+ if (cache) { -+ yaffs_use_cache(dev, cache, 1); -+ cache->locked = 1; -+ -+ memcpy(&cache->data[start], buffer, -+ n_copy); -+ -+ cache->locked = 0; -+ cache->n_bytes = n_writeback; -+ -+ if (write_through) { -+ chunk_written = -+ yaffs_wr_data_obj -+ (cache->object, -+ cache->chunk_id, -+ cache->data, -+ cache->n_bytes, 1); -+ cache->dirty = 0; -+ } -+ } else { -+ chunk_written = -1; /* fail write */ -+ } -+ } else { -+ /* An incomplete start or end chunk (or maybe -+ * both start and end chunk). Read into the -+ * local buffer then copy over and write back. -+ */ -+ -+ u8 *local_buffer = yaffs_get_temp_buffer(dev); -+ -+ yaffs_rd_data_obj(in, chunk, local_buffer); -+ memcpy(&local_buffer[start], buffer, n_copy); -+ -+ chunk_written = -+ yaffs_wr_data_obj(in, chunk, -+ local_buffer, -+ n_writeback, 0); -+ -+ yaffs_release_temp_buffer(dev, local_buffer); -+ } -+ } else { -+ /* A full chunk. Write directly from the buffer. */ -+ -+ chunk_written = -+ yaffs_wr_data_obj(in, chunk, buffer, -+ dev->data_bytes_per_chunk, 0); -+ -+ /* Since we've overwritten the cached data, -+ * we better invalidate it. */ -+ yaffs_invalidate_chunk_cache(in, chunk); -+ } -+ -+ if (chunk_written >= 0) { -+ n -= n_copy; -+ offset += n_copy; -+ buffer += n_copy; -+ n_done += n_copy; -+ } -+ } -+ -+ /* Update file object */ -+ -+ if ((start_write + n_done) > in->variant.file_variant.file_size) -+ in->variant.file_variant.file_size = (start_write + n_done); -+ -+ in->dirty = 1; -+ return n_done; -+} -+ -+int yaffs_wr_file(struct yaffs_obj *in, const u8 *buffer, loff_t offset, -+ int n_bytes, int write_through) -+{ -+ yaffs2_handle_hole(in, offset); -+ return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_through); -+} -+ -+/* ---------------------- File resizing stuff ------------------ */ -+ -+static void yaffs_prune_chunks(struct yaffs_obj *in, loff_t new_size) -+{ -+ -+ struct yaffs_dev *dev = in->my_dev; -+ loff_t old_size = in->variant.file_variant.file_size; -+ int i; -+ int chunk_id; -+ u32 dummy; -+ int last_del; -+ int start_del; -+ -+ if (old_size > 0) -+ yaffs_addr_to_chunk(dev, old_size - 1, &last_del, &dummy); -+ else -+ last_del = 0; -+ -+ yaffs_addr_to_chunk(dev, new_size + dev->data_bytes_per_chunk - 1, -+ &start_del, &dummy); -+ last_del++; -+ start_del++; -+ -+ /* Delete backwards so that we don't end up with holes if -+ * power is lost part-way through the operation. -+ */ -+ for (i = last_del; i >= start_del; i--) { -+ /* NB this could be optimised somewhat, -+ * eg. could retrieve the tags and write them without -+ * using yaffs_chunk_del -+ */ -+ -+ chunk_id = yaffs_find_del_file_chunk(in, i, NULL); -+ -+ if (chunk_id < 1) -+ continue; -+ -+ if ((u32)chunk_id < -+ (dev->internal_start_block * dev->param.chunks_per_block) || -+ (u32)chunk_id >= -+ ((dev->internal_end_block + 1) * -+ dev->param.chunks_per_block)) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "Found daft chunk_id %d for %d", -+ chunk_id, i); -+ } else { -+ in->n_data_chunks--; -+ yaffs_chunk_del(dev, chunk_id, 1, __LINE__); -+ } -+ } -+} -+ -+void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size) -+{ -+ int new_full; -+ u32 new_partial; -+ struct yaffs_dev *dev = obj->my_dev; -+ -+ yaffs_addr_to_chunk(dev, new_size, &new_full, &new_partial); -+ -+ yaffs_prune_chunks(obj, new_size); -+ -+ if (new_partial != 0) { -+ int last_chunk = 1 + new_full; -+ u8 *local_buffer = yaffs_get_temp_buffer(dev); -+ -+ /* Rewrite the last chunk with its new size and zero pad */ -+ yaffs_rd_data_obj(obj, last_chunk, local_buffer); -+ memset(local_buffer + new_partial, 0, -+ dev->data_bytes_per_chunk - new_partial); -+ -+ yaffs_wr_data_obj(obj, last_chunk, local_buffer, -+ new_partial, 1); -+ -+ yaffs_release_temp_buffer(dev, local_buffer); -+ } -+ -+ obj->variant.file_variant.file_size = new_size; -+ obj->variant.file_variant.stored_size = new_size; -+ -+ yaffs_prune_tree(dev, &obj->variant.file_variant); -+} -+ -+int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size) -+{ -+ struct yaffs_dev *dev = in->my_dev; -+ loff_t old_size = in->variant.file_variant.file_size; -+ -+ yaffs_flush_file_cache(in, 1); -+ yaffs_invalidate_whole_cache(in); -+ -+ yaffs_check_gc(dev, 0); -+ -+ if (in->variant_type != YAFFS_OBJECT_TYPE_FILE) -+ return YAFFS_FAIL; -+ -+ if (new_size == old_size) -+ return YAFFS_OK; -+ -+ if (new_size > old_size) { -+ yaffs2_handle_hole(in, new_size); -+ in->variant.file_variant.file_size = new_size; -+ } else { -+ /* new_size < old_size */ -+ yaffs_resize_file_down(in, new_size); -+ } -+ -+ /* Write a new object header to reflect the resize. -+ * show we've shrunk the file, if need be -+ * Do this only if the file is not in the deleted directories -+ * and is not shadowed. -+ */ -+ if (in->parent && -+ !in->is_shadowed && -+ in->parent->obj_id != YAFFS_OBJECTID_UNLINKED && -+ in->parent->obj_id != YAFFS_OBJECTID_DELETED) -+ yaffs_update_oh(in, NULL, 0, 0, 0, NULL); -+ -+ return YAFFS_OK; -+} -+ -+int yaffs_flush_file(struct yaffs_obj *in, -+ int update_time, -+ int data_sync, -+ int discard_cache) -+{ -+ if (!in->dirty) -+ return YAFFS_OK; -+ -+ yaffs_flush_file_cache(in, discard_cache); -+ -+ if (data_sync) -+ return YAFFS_OK; -+ -+ if (update_time) -+ yaffs_load_current_time(in, 0, 0); -+ -+ return (yaffs_update_oh(in, NULL, 0, 0, 0, NULL) >= 0) ? -+ YAFFS_OK : YAFFS_FAIL; -+} -+ -+ -+/* yaffs_del_file deletes the whole file data -+ * and the inode associated with the file. -+ * It does not delete the links associated with the file. -+ */ -+static int yaffs_unlink_file_if_needed(struct yaffs_obj *in) -+{ -+ int ret_val; -+ int del_now = 0; -+ struct yaffs_dev *dev = in->my_dev; -+ -+ if (!in->my_inode) -+ del_now = 1; -+ -+ if (del_now) { -+ ret_val = -+ yaffs_change_obj_name(in, in->my_dev->del_dir, -+ _Y("deleted"), 0, 0); -+ yaffs_trace(YAFFS_TRACE_TRACING, -+ "yaffs: immediate deletion of file %d", -+ in->obj_id); -+ in->deleted = 1; -+ in->my_dev->n_deleted_files++; -+ if (dev->param.disable_soft_del || dev->param.is_yaffs2) -+ yaffs_resize_file(in, 0); -+ yaffs_soft_del_file(in); -+ } else { -+ ret_val = -+ yaffs_change_obj_name(in, in->my_dev->unlinked_dir, -+ _Y("unlinked"), 0, 0); -+ } -+ return ret_val; -+} -+ -+static int yaffs_del_file(struct yaffs_obj *in) -+{ -+ int ret_val = YAFFS_OK; -+ int deleted; /* Need to cache value on stack if in is freed */ -+ struct yaffs_dev *dev = in->my_dev; -+ -+ if (dev->param.disable_soft_del || dev->param.is_yaffs2) -+ yaffs_resize_file(in, 0); -+ -+ if (in->n_data_chunks > 0) { -+ /* Use soft deletion if there is data in the file. -+ * That won't be the case if it has been resized to zero. -+ */ -+ if (!in->unlinked) -+ ret_val = yaffs_unlink_file_if_needed(in); -+ -+ deleted = in->deleted; -+ -+ if (ret_val == YAFFS_OK && in->unlinked && !in->deleted) { -+ in->deleted = 1; -+ deleted = 1; -+ in->my_dev->n_deleted_files++; -+ yaffs_soft_del_file(in); -+ } -+ return deleted ? YAFFS_OK : YAFFS_FAIL; -+ } else { -+ /* The file has no data chunks so we toss it immediately */ -+ yaffs_free_tnode(in->my_dev, in->variant.file_variant.top); -+ in->variant.file_variant.top = NULL; -+ yaffs_generic_obj_del(in); -+ -+ return YAFFS_OK; -+ } -+} -+ -+int yaffs_is_non_empty_dir(struct yaffs_obj *obj) -+{ -+ return (obj && -+ obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) && -+ !(list_empty(&obj->variant.dir_variant.children)); -+} -+ -+static int yaffs_del_dir(struct yaffs_obj *obj) -+{ -+ /* First check that the directory is empty. */ -+ if (yaffs_is_non_empty_dir(obj)) -+ return YAFFS_FAIL; -+ -+ return yaffs_generic_obj_del(obj); -+} -+ -+static int yaffs_del_symlink(struct yaffs_obj *in) -+{ -+ kfree(in->variant.symlink_variant.alias); -+ in->variant.symlink_variant.alias = NULL; -+ -+ return yaffs_generic_obj_del(in); -+} -+ -+static int yaffs_del_link(struct yaffs_obj *in) -+{ -+ /* remove this hardlink from the list associated with the equivalent -+ * object -+ */ -+ list_del_init(&in->hard_links); -+ return yaffs_generic_obj_del(in); -+} -+ -+int yaffs_del_obj(struct yaffs_obj *obj) -+{ -+ int ret_val = -1; -+ -+ switch (obj->variant_type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ ret_val = yaffs_del_file(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ if (!list_empty(&obj->variant.dir_variant.dirty)) { -+ yaffs_trace(YAFFS_TRACE_BACKGROUND, -+ "Remove object %d from dirty directories", -+ obj->obj_id); -+ list_del_init(&obj->variant.dir_variant.dirty); -+ } -+ return yaffs_del_dir(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ ret_val = yaffs_del_symlink(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ ret_val = yaffs_del_link(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ ret_val = yaffs_generic_obj_del(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ ret_val = 0; -+ break; /* should not happen. */ -+ } -+ return ret_val; -+} -+ -+ -+static void yaffs_empty_dir_to_dir(struct yaffs_obj *from_dir, -+ struct yaffs_obj *to_dir) -+{ -+ struct yaffs_obj *obj; -+ struct list_head *lh; -+ struct list_head *n; -+ -+ list_for_each_safe(lh, n, &from_dir->variant.dir_variant.children) { -+ obj = list_entry(lh, struct yaffs_obj, siblings); -+ yaffs_add_obj_to_dir(to_dir, obj); -+ } -+} -+ -+struct yaffs_obj *yaffs_retype_obj(struct yaffs_obj *obj, -+ enum yaffs_obj_type type) -+{ -+ /* Tear down the old variant */ -+ switch (obj->variant_type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ /* Nuke file data */ -+ yaffs_resize_file(obj, 0); -+ yaffs_free_tnode(obj->my_dev, obj->variant.file_variant.top); -+ obj->variant.file_variant.top = NULL; -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ /* Put the children in lost and found. */ -+ yaffs_empty_dir_to_dir(obj, obj->my_dev->lost_n_found); -+ if (!list_empty(&obj->variant.dir_variant.dirty)) -+ list_del_init(&obj->variant.dir_variant.dirty); -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ /* Nuke symplink data */ -+ kfree(obj->variant.symlink_variant.alias); -+ obj->variant.symlink_variant.alias = NULL; -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ list_del_init(&obj->hard_links); -+ break; -+ default: -+ break; -+ } -+ -+ memset(&obj->variant, 0, sizeof(obj->variant)); -+ -+ /*Set up new variant if the memset is not enough. */ -+ switch (type) { -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ INIT_LIST_HEAD(&obj->variant.dir_variant.children); -+ INIT_LIST_HEAD(&obj->variant.dir_variant.dirty); -+ break; -+ case YAFFS_OBJECT_TYPE_FILE: -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ default: -+ break; -+ } -+ -+ obj->variant_type = type; -+ -+ return obj; -+ -+} -+ -+static int yaffs_unlink_worker(struct yaffs_obj *obj) -+{ -+ int del_now = 0; -+ -+ if (!obj) -+ return YAFFS_FAIL; -+ -+ if (!obj->my_inode) -+ del_now = 1; -+ -+ yaffs_update_parent(obj->parent); -+ -+ if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) { -+ return yaffs_del_link(obj); -+ } else if (!list_empty(&obj->hard_links)) { -+ /* Curve ball: We're unlinking an object that has a hardlink. -+ * -+ * This problem arises because we are not strictly following -+ * The Linux link/inode model. -+ * -+ * We can't really delete the object. -+ * Instead, we do the following: -+ * - Select a hardlink. -+ * - Unhook it from the hard links -+ * - Move it from its parent directory so that the rename works. -+ * - Rename the object to the hardlink's name. -+ * - Delete the hardlink -+ */ -+ -+ struct yaffs_obj *hl; -+ struct yaffs_obj *parent; -+ int ret_val; -+ YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; -+ -+ hl = list_entry(obj->hard_links.next, struct yaffs_obj, -+ hard_links); -+ -+ yaffs_get_obj_name(hl, name, YAFFS_MAX_NAME_LENGTH + 1); -+ parent = hl->parent; -+ -+ list_del_init(&hl->hard_links); -+ -+ yaffs_add_obj_to_dir(obj->my_dev->unlinked_dir, hl); -+ -+ ret_val = yaffs_change_obj_name(obj, parent, name, 0, 0); -+ -+ if (ret_val == YAFFS_OK) -+ ret_val = yaffs_generic_obj_del(hl); -+ -+ return ret_val; -+ -+ } else if (del_now) { -+ switch (obj->variant_type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ return yaffs_del_file(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ list_del_init(&obj->variant.dir_variant.dirty); -+ return yaffs_del_dir(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ return yaffs_del_symlink(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ return yaffs_generic_obj_del(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ default: -+ return YAFFS_FAIL; -+ } -+ } else if (yaffs_is_non_empty_dir(obj)) { -+ return YAFFS_FAIL; -+ } else { -+ return yaffs_change_obj_name(obj, obj->my_dev->unlinked_dir, -+ _Y("unlinked"), 0, 0); -+ } -+} -+ -+int yaffs_unlink_obj(struct yaffs_obj *obj) -+{ -+ if (obj && obj->unlink_allowed) -+ return yaffs_unlink_worker(obj); -+ -+ return YAFFS_FAIL; -+} -+ -+int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR *name) -+{ -+ struct yaffs_obj *obj; -+ -+ obj = yaffs_find_by_name(dir, name); -+ return yaffs_unlink_obj(obj); -+} -+ -+/* Note: -+ * If old_name is NULL then we take old_dir as the object to be renamed. -+ */ -+int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR *old_name, -+ struct yaffs_obj *new_dir, const YCHAR *new_name) -+{ -+ struct yaffs_obj *obj = NULL; -+ struct yaffs_obj *existing_target = NULL; -+ int force = 0; -+ int result; -+ struct yaffs_dev *dev; -+ -+ if (!old_dir || old_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ BUG(); -+ return YAFFS_FAIL; -+ } -+ if (!new_dir || new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ BUG(); -+ return YAFFS_FAIL; -+ } -+ -+ dev = old_dir->my_dev; -+ -+#ifdef CONFIG_YAFFS_CASE_INSENSITIVE -+ /* Special case for case insemsitive systems. -+ * While look-up is case insensitive, the name isn't. -+ * Therefore we might want to change x.txt to X.txt -+ */ -+ if (old_dir == new_dir && -+ old_name && new_name && -+ strcmp(old_name, new_name) == 0) -+ force = 1; -+#endif -+ -+ if (strnlen(new_name, YAFFS_MAX_NAME_LENGTH + 1) > -+ YAFFS_MAX_NAME_LENGTH) -+ /* ENAMETOOLONG */ -+ return YAFFS_FAIL; -+ -+ if (old_name) -+ obj = yaffs_find_by_name(old_dir, old_name); -+ else{ -+ obj = old_dir; -+ old_dir = obj->parent; -+ } -+ -+ if (obj && obj->rename_allowed) { -+ /* Now handle an existing target, if there is one */ -+ existing_target = yaffs_find_by_name(new_dir, new_name); -+ if (yaffs_is_non_empty_dir(existing_target)) { -+ return YAFFS_FAIL; /* ENOTEMPTY */ -+ } else if (existing_target && existing_target != obj) { -+ /* Nuke the target first, using shadowing, -+ * but only if it isn't the same object. -+ * -+ * Note we must disable gc here otherwise it can mess -+ * up the shadowing. -+ * -+ */ -+ dev->gc_disable = 1; -+ yaffs_change_obj_name(obj, new_dir, new_name, force, -+ existing_target->obj_id); -+ existing_target->is_shadowed = 1; -+ yaffs_unlink_obj(existing_target); -+ dev->gc_disable = 0; -+ } -+ -+ result = yaffs_change_obj_name(obj, new_dir, new_name, 1, 0); -+ -+ yaffs_update_parent(old_dir); -+ if (new_dir != old_dir) -+ yaffs_update_parent(new_dir); -+ -+ return result; -+ } -+ return YAFFS_FAIL; -+} -+ -+/*----------------------- Initialisation Scanning ---------------------- */ -+ -+void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id, -+ int backward_scanning) -+{ -+ struct yaffs_obj *obj; -+ -+ if (backward_scanning) { -+ /* Handle YAFFS2 case (backward scanning) -+ * If the shadowed object exists then ignore. -+ */ -+ obj = yaffs_find_by_number(dev, obj_id); -+ if (obj) -+ return; -+ } -+ -+ /* Let's create it (if it does not exist) assuming it is a file so that -+ * it can do shrinking etc. -+ * We put it in unlinked dir to be cleaned up after the scanning -+ */ -+ obj = -+ yaffs_find_or_create_by_number(dev, obj_id, YAFFS_OBJECT_TYPE_FILE); -+ if (!obj) -+ return; -+ obj->is_shadowed = 1; -+ yaffs_add_obj_to_dir(dev->unlinked_dir, obj); -+ obj->variant.file_variant.shrink_size = 0; -+ obj->valid = 1; /* So that we don't read any other info. */ -+} -+ -+void yaffs_link_fixup(struct yaffs_dev *dev, struct list_head *hard_list) -+{ -+ struct list_head *lh; -+ struct list_head *save; -+ struct yaffs_obj *hl; -+ struct yaffs_obj *in; -+ -+ list_for_each_safe(lh, save, hard_list) { -+ hl = list_entry(lh, struct yaffs_obj, hard_links); -+ in = yaffs_find_by_number(dev, -+ hl->variant.hardlink_variant.equiv_id); -+ -+ if (in) { -+ /* Add the hardlink pointers */ -+ hl->variant.hardlink_variant.equiv_obj = in; -+ list_add(&hl->hard_links, &in->hard_links); -+ } else { -+ /* Todo Need to report/handle this better. -+ * Got a problem... hardlink to a non-existant object -+ */ -+ hl->variant.hardlink_variant.equiv_obj = NULL; -+ INIT_LIST_HEAD(&hl->hard_links); -+ } -+ } -+} -+ -+static void yaffs_strip_deleted_objs(struct yaffs_dev *dev) -+{ -+ /* -+ * Sort out state of unlinked and deleted objects after scanning. -+ */ -+ struct list_head *i; -+ struct list_head *n; -+ struct yaffs_obj *l; -+ -+ if (dev->read_only) -+ return; -+ -+ /* Soft delete all the unlinked files */ -+ list_for_each_safe(i, n, -+ &dev->unlinked_dir->variant.dir_variant.children) { -+ l = list_entry(i, struct yaffs_obj, siblings); -+ yaffs_del_obj(l); -+ } -+ -+ list_for_each_safe(i, n, &dev->del_dir->variant.dir_variant.children) { -+ l = list_entry(i, struct yaffs_obj, siblings); -+ yaffs_del_obj(l); -+ } -+} -+ -+/* -+ * This code iterates through all the objects making sure that they are rooted. -+ * Any unrooted objects are re-rooted in lost+found. -+ * An object needs to be in one of: -+ * - Directly under deleted, unlinked -+ * - Directly or indirectly under root. -+ * -+ * Note: -+ * This code assumes that we don't ever change the current relationships -+ * between directories: -+ * root_dir->parent == unlinked_dir->parent == del_dir->parent == NULL -+ * lost-n-found->parent == root_dir -+ * -+ * This fixes the problem where directories might have inadvertently been -+ * deleted leaving the object "hanging" without being rooted in the -+ * directory tree. -+ */ -+ -+static int yaffs_has_null_parent(struct yaffs_dev *dev, struct yaffs_obj *obj) -+{ -+ return (obj == dev->del_dir || -+ obj == dev->unlinked_dir || obj == dev->root_dir); -+} -+ -+static void yaffs_fix_hanging_objs(struct yaffs_dev *dev) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_obj *parent; -+ int i; -+ struct list_head *lh; -+ struct list_head *n; -+ int depth_limit; -+ int hanging; -+ -+ if (dev->read_only) -+ return; -+ -+ /* Iterate through the objects in each hash entry, -+ * looking at each object. -+ * Make sure it is rooted. -+ */ -+ -+ for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) { -+ list_for_each_safe(lh, n, &dev->obj_bucket[i].list) { -+ obj = list_entry(lh, struct yaffs_obj, hash_link); -+ parent = obj->parent; -+ -+ if (yaffs_has_null_parent(dev, obj)) { -+ /* These directories are not hanging */ -+ hanging = 0; -+ } else if (!parent || -+ parent->variant_type != -+ YAFFS_OBJECT_TYPE_DIRECTORY) { -+ hanging = 1; -+ } else if (yaffs_has_null_parent(dev, parent)) { -+ hanging = 0; -+ } else { -+ /* -+ * Need to follow the parent chain to -+ * see if it is hanging. -+ */ -+ hanging = 0; -+ depth_limit = 100; -+ -+ while (parent != dev->root_dir && -+ parent->parent && -+ parent->parent->variant_type == -+ YAFFS_OBJECT_TYPE_DIRECTORY && -+ depth_limit > 0) { -+ parent = parent->parent; -+ depth_limit--; -+ } -+ if (parent != dev->root_dir) -+ hanging = 1; -+ } -+ if (hanging) { -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "Hanging object %d moved to lost and found", -+ obj->obj_id); -+ yaffs_add_obj_to_dir(dev->lost_n_found, obj); -+ } -+ } -+ } -+} -+ -+/* -+ * Delete directory contents for cleaning up lost and found. -+ */ -+static void yaffs_del_dir_contents(struct yaffs_obj *dir) -+{ -+ struct yaffs_obj *obj; -+ struct list_head *lh; -+ struct list_head *n; -+ -+ if (dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) -+ BUG(); -+ -+ list_for_each_safe(lh, n, &dir->variant.dir_variant.children) { -+ obj = list_entry(lh, struct yaffs_obj, siblings); -+ if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) -+ yaffs_del_dir_contents(obj); -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "Deleting lost_found object %d", -+ obj->obj_id); -+ yaffs_unlink_obj(obj); -+ } -+} -+ -+static void yaffs_empty_l_n_f(struct yaffs_dev *dev) -+{ -+ yaffs_del_dir_contents(dev->lost_n_found); -+} -+ -+ -+struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *directory, -+ const YCHAR *name) -+{ -+ int sum; -+ struct list_head *i; -+ YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1]; -+ struct yaffs_obj *l; -+ -+ if (!name) -+ return NULL; -+ -+ if (!directory) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "tragedy: yaffs_find_by_name: null pointer directory" -+ ); -+ BUG(); -+ return NULL; -+ } -+ if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "tragedy: yaffs_find_by_name: non-directory" -+ ); -+ BUG(); -+ } -+ -+ sum = yaffs_calc_name_sum(name); -+ -+ list_for_each(i, &directory->variant.dir_variant.children) { -+ l = list_entry(i, struct yaffs_obj, siblings); -+ -+ if (l->parent != directory) -+ BUG(); -+ -+ yaffs_check_obj_details_loaded(l); -+ -+ /* Special case for lost-n-found */ -+ if (l->obj_id == YAFFS_OBJECTID_LOSTNFOUND) { -+ if (!strcmp(name, YAFFS_LOSTNFOUND_NAME)) -+ return l; -+ } else if (l->sum == sum || l->hdr_chunk <= 0) { -+ /* LostnFound chunk called Objxxx -+ * Do a real check -+ */ -+ yaffs_get_obj_name(l, buffer, -+ YAFFS_MAX_NAME_LENGTH + 1); -+ if (!strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH)) -+ return l; -+ } -+ } -+ return NULL; -+} -+ -+/* GetEquivalentObject dereferences any hard links to get to the -+ * actual object. -+ */ -+ -+struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj) -+{ -+ if (obj && obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) { -+ obj = obj->variant.hardlink_variant.equiv_obj; -+ yaffs_check_obj_details_loaded(obj); -+ } -+ return obj; -+} -+ -+/* -+ * A note or two on object names. -+ * * If the object name is missing, we then make one up in the form objnnn -+ * -+ * * ASCII names are stored in the object header's name field from byte zero -+ * * Unicode names are historically stored starting from byte zero. -+ * -+ * Then there are automatic Unicode names... -+ * The purpose of these is to save names in a way that can be read as -+ * ASCII or Unicode names as appropriate, thus allowing a Unicode and ASCII -+ * system to share files. -+ * -+ * These automatic unicode are stored slightly differently... -+ * - If the name can fit in the ASCII character space then they are saved as -+ * ascii names as per above. -+ * - If the name needs Unicode then the name is saved in Unicode -+ * starting at oh->name[1]. -+ -+ */ -+static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name, -+ int buffer_size) -+{ -+ /* Create an object name if we could not find one. */ -+ if (strnlen(name, YAFFS_MAX_NAME_LENGTH) == 0) { -+ YCHAR local_name[20]; -+ YCHAR num_string[20]; -+ YCHAR *x = &num_string[19]; -+ unsigned v = obj->obj_id; -+ num_string[19] = 0; -+ while (v > 0) { -+ x--; -+ *x = '0' + (v % 10); -+ v /= 10; -+ } -+ /* make up a name */ -+ strcpy(local_name, YAFFS_LOSTNFOUND_PREFIX); -+ strcat(local_name, x); -+ strncpy(name, local_name, buffer_size - 1); -+ } -+} -+ -+int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR *name, int buffer_size) -+{ -+ memset(name, 0, buffer_size * sizeof(YCHAR)); -+ yaffs_check_obj_details_loaded(obj); -+ if (obj->obj_id == YAFFS_OBJECTID_LOSTNFOUND) { -+ strncpy(name, YAFFS_LOSTNFOUND_NAME, buffer_size - 1); -+ } else if (obj->short_name[0]) { -+ strcpy(name, obj->short_name); -+ } else if (obj->hdr_chunk > 0) { -+ int result = 0; -+ u8 *buffer = yaffs_get_temp_buffer(obj->my_dev); -+ -+ struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)buffer; -+ -+ memset(buffer, 0, obj->my_dev->data_bytes_per_chunk); -+ -+ if (obj->hdr_chunk > 0) { -+ result = yaffs_rd_chunk_tags_nand(obj->my_dev, -+ obj->hdr_chunk, -+ buffer, NULL); -+ } -+ if (result == YAFFS_OK) -+ yaffs_load_name_from_oh(obj->my_dev, name, oh->name, -+ buffer_size); -+ -+ yaffs_release_temp_buffer(obj->my_dev, buffer); -+ } -+ -+ yaffs_fix_null_name(obj, name, buffer_size); -+ -+ return strnlen(name, YAFFS_MAX_NAME_LENGTH); -+} -+ -+loff_t yaffs_get_obj_length(struct yaffs_obj *obj) -+{ -+ /* Dereference any hard linking */ -+ obj = yaffs_get_equivalent_obj(obj); -+ -+ if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) -+ return obj->variant.file_variant.file_size; -+ if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) { -+ if (!obj->variant.symlink_variant.alias) -+ return 0; -+ return strnlen(obj->variant.symlink_variant.alias, -+ YAFFS_MAX_ALIAS_LENGTH); -+ } else { -+ /* Only a directory should drop through to here */ -+ return obj->my_dev->data_bytes_per_chunk; -+ } -+} -+ -+int yaffs_get_obj_link_count(struct yaffs_obj *obj) -+{ -+ int count = 0; -+ struct list_head *i; -+ -+ if (!obj->unlinked) -+ count++; /* the object itself */ -+ -+ list_for_each(i, &obj->hard_links) -+ count++; /* add the hard links; */ -+ -+ return count; -+} -+ -+int yaffs_get_obj_inode(struct yaffs_obj *obj) -+{ -+ obj = yaffs_get_equivalent_obj(obj); -+ -+ return obj->obj_id; -+} -+ -+unsigned yaffs_get_obj_type(struct yaffs_obj *obj) -+{ -+ obj = yaffs_get_equivalent_obj(obj); -+ -+ switch (obj->variant_type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ return DT_REG; -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ return DT_DIR; -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ return DT_LNK; -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ return DT_REG; -+ break; -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ if (S_ISFIFO(obj->yst_mode)) -+ return DT_FIFO; -+ if (S_ISCHR(obj->yst_mode)) -+ return DT_CHR; -+ if (S_ISBLK(obj->yst_mode)) -+ return DT_BLK; -+ if (S_ISSOCK(obj->yst_mode)) -+ return DT_SOCK; -+ return DT_REG; -+ break; -+ default: -+ return DT_REG; -+ break; -+ } -+} -+ -+YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj) -+{ -+ obj = yaffs_get_equivalent_obj(obj); -+ if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) -+ return yaffs_clone_str(obj->variant.symlink_variant.alias); -+ else -+ return yaffs_clone_str(_Y("")); -+} -+ -+/*--------------------------- Initialisation code -------------------------- */ -+ -+static int yaffs_check_dev_fns(struct yaffs_dev *dev) -+{ -+ struct yaffs_driver *drv = &dev->drv; -+ struct yaffs_tags_handler *tagger = &dev->tagger; -+ -+ /* Common functions, gotta have */ -+ if (!drv->drv_read_chunk_fn || -+ !drv->drv_write_chunk_fn || -+ !drv->drv_erase_fn) -+ return 0; -+ -+ if (dev->param.is_yaffs2 && -+ (!drv->drv_mark_bad_fn || !drv->drv_check_bad_fn)) -+ return 0; -+ -+ /* Install the default tags marshalling functions if needed. */ -+ yaffs_tags_compat_install(dev); -+ yaffs_tags_marshall_install(dev); -+ -+ /* Check we now have the marshalling functions required. */ -+ if (!tagger->write_chunk_tags_fn || -+ !tagger->read_chunk_tags_fn || -+ !tagger->query_block_fn || -+ !tagger->mark_bad_fn) -+ return 0; -+ -+ return 1; -+} -+ -+static int yaffs_create_initial_dir(struct yaffs_dev *dev) -+{ -+ /* Initialise the unlinked, deleted, root and lost+found directories */ -+ dev->lost_n_found = NULL; -+ dev->root_dir = NULL; -+ dev->unlinked_dir = NULL; -+ dev->del_dir = NULL; -+ -+ dev->unlinked_dir = -+ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR); -+ dev->del_dir = -+ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_DELETED, S_IFDIR); -+ dev->root_dir = -+ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_ROOT, -+ YAFFS_ROOT_MODE | S_IFDIR); -+ dev->lost_n_found = -+ yaffs_create_fake_dir(dev, YAFFS_OBJECTID_LOSTNFOUND, -+ YAFFS_LOSTNFOUND_MODE | S_IFDIR); -+ -+ if (dev->lost_n_found && -+ dev->root_dir && -+ dev->unlinked_dir && -+ dev->del_dir) { -+ /* If lost-n-found is hidden then yank it out of the directory tree. */ -+ if (dev->param.hide_lost_n_found) -+ list_del_init(&dev->lost_n_found->siblings); -+ else -+ yaffs_add_obj_to_dir(dev->root_dir, dev->lost_n_found); -+ return YAFFS_OK; -+ } -+ return YAFFS_FAIL; -+} -+ -+/* Low level init. -+ * Typically only used by yaffs_guts_initialise, but also used by the -+ * Low level yaffs driver tests. -+ */ -+ -+int yaffs_guts_ll_init(struct yaffs_dev *dev) -+{ -+ -+ -+ yaffs_trace(YAFFS_TRACE_TRACING, "yaffs: yaffs_ll_init()"); -+ -+ if (!dev) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs: Need a device" -+ ); -+ return YAFFS_FAIL; -+ } -+ -+ if (dev->ll_init) -+ return YAFFS_OK; -+ -+ dev->internal_start_block = dev->param.start_block; -+ dev->internal_end_block = dev->param.end_block; -+ dev->block_offset = 0; -+ dev->chunk_offset = 0; -+ dev->n_free_chunks = 0; -+ -+ dev->gc_block = 0; -+ -+ if (dev->param.start_block == 0) { -+ dev->internal_start_block = dev->param.start_block + 1; -+ dev->internal_end_block = dev->param.end_block + 1; -+ dev->block_offset = 1; -+ dev->chunk_offset = dev->param.chunks_per_block; -+ } -+ -+ /* Check geometry parameters. */ -+ -+ if ((!dev->param.inband_tags && dev->param.is_yaffs2 && -+ dev->param.total_bytes_per_chunk < 1024) || -+ (!dev->param.is_yaffs2 && -+ dev->param.total_bytes_per_chunk < 512) || -+ (dev->param.inband_tags && !dev->param.is_yaffs2) || -+ dev->param.chunks_per_block < 2 || -+ dev->param.n_reserved_blocks < 2 || -+ dev->internal_start_block <= 0 || -+ dev->internal_end_block <= 0 || -+ dev->internal_end_block <= -+ (dev->internal_start_block + dev->param.n_reserved_blocks + 2) -+ ) { -+ /* otherwise it is too small */ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "NAND geometry problems: chunk size %d, type is yaffs%s, inband_tags %d ", -+ dev->param.total_bytes_per_chunk, -+ dev->param.is_yaffs2 ? "2" : "", -+ dev->param.inband_tags); -+ return YAFFS_FAIL; -+ } -+ -+ /* Sort out space for inband tags, if required */ -+ if (dev->param.inband_tags) -+ dev->data_bytes_per_chunk = -+ dev->param.total_bytes_per_chunk - -+ sizeof(struct yaffs_packed_tags2_tags_only); -+ else -+ dev->data_bytes_per_chunk = dev->param.total_bytes_per_chunk; -+ -+ /* Got the right mix of functions? */ -+ if (!yaffs_check_dev_fns(dev)) { -+ /* Function missing */ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "device function(s) missing or wrong"); -+ -+ return YAFFS_FAIL; -+ } -+ -+ if (yaffs_init_nand(dev) != YAFFS_OK) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "InitialiseNAND failed"); -+ return YAFFS_FAIL; -+ } -+ -+ return YAFFS_OK; -+} -+ -+ -+int yaffs_guts_format_dev(struct yaffs_dev *dev) -+{ -+ u32 i; -+ enum yaffs_block_state state; -+ u32 dummy; -+ -+ if(yaffs_guts_ll_init(dev) != YAFFS_OK) -+ return YAFFS_FAIL; -+ -+ if(dev->is_mounted) -+ return YAFFS_FAIL; -+ -+ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { -+ yaffs_query_init_block_state(dev, i, &state, &dummy); -+ if (state != YAFFS_BLOCK_STATE_DEAD) -+ yaffs_erase_block(dev, i); -+ } -+ -+ return YAFFS_OK; -+} -+ -+ -+int yaffs_guts_initialise(struct yaffs_dev *dev) -+{ -+ int init_failed = 0; -+ u32 x; -+ u32 bits; -+ -+ if(yaffs_guts_ll_init(dev) != YAFFS_OK) -+ return YAFFS_FAIL; -+ -+ if (dev->is_mounted) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "device already mounted"); -+ return YAFFS_FAIL; -+ } -+ -+ dev->is_mounted = 1; -+ -+ /* OK now calculate a few things for the device */ -+ -+ /* -+ * Calculate all the chunk size manipulation numbers: -+ */ -+ x = dev->data_bytes_per_chunk; -+ /* We always use dev->chunk_shift and dev->chunk_div */ -+ dev->chunk_shift = calc_shifts(x); -+ x >>= dev->chunk_shift; -+ dev->chunk_div = x; -+ /* We only use chunk mask if chunk_div is 1 */ -+ dev->chunk_mask = (1 << dev->chunk_shift) - 1; -+ -+ /* -+ * Calculate chunk_grp_bits. -+ * We need to find the next power of 2 > than internal_end_block -+ */ -+ -+ x = dev->param.chunks_per_block * (dev->internal_end_block + 1); -+ -+ bits = calc_shifts_ceiling(x); -+ -+ /* Set up tnode width if wide tnodes are enabled. */ -+ if (!dev->param.wide_tnodes_disabled) { -+ /* bits must be even so that we end up with 32-bit words */ -+ if (bits & 1) -+ bits++; -+ if (bits < 16) -+ dev->tnode_width = 16; -+ else -+ dev->tnode_width = bits; -+ } else { -+ dev->tnode_width = 16; -+ } -+ -+ dev->tnode_mask = (1 << dev->tnode_width) - 1; -+ -+ /* Level0 Tnodes are 16 bits or wider (if wide tnodes are enabled), -+ * so if the bitwidth of the -+ * chunk range we're using is greater than 16 we need -+ * to figure out chunk shift and chunk_grp_size -+ */ -+ -+ if (bits <= dev->tnode_width) -+ dev->chunk_grp_bits = 0; -+ else -+ dev->chunk_grp_bits = bits - dev->tnode_width; -+ -+ dev->tnode_size = (dev->tnode_width * YAFFS_NTNODES_LEVEL0) / 8; -+ if (dev->tnode_size < sizeof(struct yaffs_tnode)) -+ dev->tnode_size = sizeof(struct yaffs_tnode); -+ -+ dev->chunk_grp_size = 1 << dev->chunk_grp_bits; -+ -+ if (dev->param.chunks_per_block < dev->chunk_grp_size) { -+ /* We have a problem because the soft delete won't work if -+ * the chunk group size > chunks per block. -+ * This can be remedied by using larger "virtual blocks". -+ */ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "chunk group too large"); -+ -+ return YAFFS_FAIL; -+ } -+ -+ /* Finished verifying the device, continue with initialisation */ -+ -+ /* More device initialisation */ -+ dev->all_gcs = 0; -+ dev->passive_gc_count = 0; -+ dev->oldest_dirty_gc_count = 0; -+ dev->bg_gcs = 0; -+ dev->gc_block_finder = 0; -+ dev->buffered_block = -1; -+ dev->doing_buffered_block_rewrite = 0; -+ dev->n_deleted_files = 0; -+ dev->n_bg_deletions = 0; -+ dev->n_unlinked_files = 0; -+ dev->n_ecc_fixed = 0; -+ dev->n_ecc_unfixed = 0; -+ dev->n_tags_ecc_fixed = 0; -+ dev->n_tags_ecc_unfixed = 0; -+ dev->n_erase_failures = 0; -+ dev->n_erased_blocks = 0; -+ dev->gc_disable = 0; -+ dev->has_pending_prioritised_gc = 1; /* Assume the worst for now, -+ * will get fixed on first GC */ -+ INIT_LIST_HEAD(&dev->dirty_dirs); -+ dev->oldest_dirty_seq = 0; -+ dev->oldest_dirty_block = 0; -+ -+ yaffs_endian_config(dev); -+ -+ /* Initialise temporary buffers and caches. */ -+ if (!yaffs_init_tmp_buffers(dev)) -+ init_failed = 1; -+ -+ dev->cache = NULL; -+ dev->gc_cleanup_list = NULL; -+ -+ if (!init_failed && dev->param.n_caches > 0) { -+ u32 i; -+ void *buf; -+ u32 cache_bytes = -+ dev->param.n_caches * sizeof(struct yaffs_cache); -+ -+ if (dev->param.n_caches > YAFFS_MAX_SHORT_OP_CACHES) -+ dev->param.n_caches = YAFFS_MAX_SHORT_OP_CACHES; -+ -+ dev->cache = kmalloc(cache_bytes, GFP_NOFS); -+ -+ buf = (u8 *) dev->cache; -+ -+ if (dev->cache) -+ memset(dev->cache, 0, cache_bytes); -+ -+ for (i = 0; i < dev->param.n_caches && buf; i++) { -+ dev->cache[i].object = NULL; -+ dev->cache[i].last_use = 0; -+ dev->cache[i].dirty = 0; -+ dev->cache[i].data = buf = -+ kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS); -+ } -+ if (!buf) -+ init_failed = 1; -+ -+ dev->cache_last_use = 0; -+ } -+ -+ dev->cache_hits = 0; -+ -+ if (!init_failed) { -+ dev->gc_cleanup_list = -+ kmalloc(dev->param.chunks_per_block * sizeof(u32), -+ GFP_NOFS); -+ if (!dev->gc_cleanup_list) -+ init_failed = 1; -+ } -+ -+ if (dev->param.is_yaffs2) -+ dev->param.use_header_file_size = 1; -+ -+ if (!init_failed && !yaffs_init_blocks(dev)) -+ init_failed = 1; -+ -+ yaffs_init_tnodes_and_objs(dev); -+ -+ if (!init_failed && !yaffs_create_initial_dir(dev)) -+ init_failed = 1; -+ -+ if (!init_failed && dev->param.is_yaffs2 && -+ !dev->param.disable_summary && -+ !yaffs_summary_init(dev)) -+ init_failed = 1; -+ -+ if (!init_failed) { -+ /* Now scan the flash. */ -+ if (dev->param.is_yaffs2) { -+ if (yaffs2_checkpt_restore(dev)) { -+ yaffs_check_obj_details_loaded(dev->root_dir); -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT | -+ YAFFS_TRACE_MOUNT, -+ "yaffs: restored from checkpoint" -+ ); -+ } else { -+ -+ /* Clean up the mess caused by an aborted -+ * checkpoint load then scan backwards. -+ */ -+ yaffs_deinit_blocks(dev); -+ -+ yaffs_deinit_tnodes_and_objs(dev); -+ -+ dev->n_erased_blocks = 0; -+ dev->n_free_chunks = 0; -+ dev->alloc_block = -1; -+ dev->alloc_page = -1; -+ dev->n_deleted_files = 0; -+ dev->n_unlinked_files = 0; -+ dev->n_bg_deletions = 0; -+ -+ if (!init_failed && !yaffs_init_blocks(dev)) -+ init_failed = 1; -+ -+ yaffs_init_tnodes_and_objs(dev); -+ -+ if (!init_failed -+ && !yaffs_create_initial_dir(dev)) -+ init_failed = 1; -+ -+ if (!init_failed && !yaffs2_scan_backwards(dev)) -+ init_failed = 1; -+ } -+ } else if (!yaffs1_scan(dev)) { -+ init_failed = 1; -+ } -+ -+ yaffs_strip_deleted_objs(dev); -+ yaffs_fix_hanging_objs(dev); -+ if (dev->param.empty_lost_n_found) -+ yaffs_empty_l_n_f(dev); -+ } -+ -+ if (init_failed) { -+ /* Clean up the mess */ -+ yaffs_trace(YAFFS_TRACE_TRACING, -+ "yaffs: yaffs_guts_initialise() aborted."); -+ -+ yaffs_deinitialise(dev); -+ return YAFFS_FAIL; -+ } -+ -+ /* Zero out stats */ -+ dev->n_page_reads = 0; -+ dev->n_page_writes = 0; -+ dev->n_erasures = 0; -+ dev->n_gc_copies = 0; -+ dev->n_retried_writes = 0; -+ -+ dev->n_retired_blocks = 0; -+ -+ yaffs_verify_free_chunks(dev); -+ yaffs_verify_blocks(dev); -+ -+ /* Clean up any aborted checkpoint data */ -+ if (!dev->is_checkpointed && dev->blocks_in_checkpt > 0) -+ yaffs2_checkpt_invalidate(dev); -+ -+ yaffs_trace(YAFFS_TRACE_TRACING, -+ "yaffs: yaffs_guts_initialise() done."); -+ return YAFFS_OK; -+} -+ -+void yaffs_deinitialise(struct yaffs_dev *dev) -+{ -+ if (dev->is_mounted) { -+ u32 i; -+ -+ yaffs_deinit_blocks(dev); -+ yaffs_deinit_tnodes_and_objs(dev); -+ yaffs_summary_deinit(dev); -+ -+ if (dev->param.n_caches > 0 && dev->cache) { -+ -+ for (i = 0; i < dev->param.n_caches; i++) { -+ kfree(dev->cache[i].data); -+ dev->cache[i].data = NULL; -+ } -+ -+ kfree(dev->cache); -+ dev->cache = NULL; -+ } -+ -+ kfree(dev->gc_cleanup_list); -+ -+ for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) { -+ kfree(dev->temp_buffer[i].buffer); -+ dev->temp_buffer[i].buffer = NULL; -+ } -+ -+ kfree(dev->checkpt_buffer); -+ dev->checkpt_buffer = NULL; -+ kfree(dev->checkpt_block_list); -+ dev->checkpt_block_list = NULL; -+ -+ dev->is_mounted = 0; -+ -+ yaffs_deinit_nand(dev); -+ } -+} -+ -+int yaffs_count_free_chunks(struct yaffs_dev *dev) -+{ -+ int n_free = 0; -+ u32 b; -+ struct yaffs_block_info *blk; -+ -+ blk = dev->block_info; -+ for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) { -+ switch (blk->block_state) { -+ case YAFFS_BLOCK_STATE_EMPTY: -+ case YAFFS_BLOCK_STATE_ALLOCATING: -+ case YAFFS_BLOCK_STATE_COLLECTING: -+ case YAFFS_BLOCK_STATE_FULL: -+ n_free += -+ (dev->param.chunks_per_block - blk->pages_in_use + -+ blk->soft_del_pages); -+ break; -+ default: -+ break; -+ } -+ blk++; -+ } -+ return n_free; -+} -+ -+int yaffs_get_n_free_chunks(struct yaffs_dev *dev) -+{ -+ /* This is what we report to the outside world */ -+ int n_free; -+ int n_dirty_caches; -+ int blocks_for_checkpt; -+ u32 i; -+ -+ n_free = dev->n_free_chunks; -+ n_free += dev->n_deleted_files; -+ -+ /* Now count and subtract the number of dirty chunks in the cache. */ -+ -+ for (n_dirty_caches = 0, i = 0; i < dev->param.n_caches; i++) { -+ if (dev->cache[i].dirty) -+ n_dirty_caches++; -+ } -+ -+ n_free -= n_dirty_caches; -+ -+ n_free -= -+ ((dev->param.n_reserved_blocks + 1) * dev->param.chunks_per_block); -+ -+ /* Now figure checkpoint space and report that... */ -+ blocks_for_checkpt = yaffs_calc_checkpt_blocks_required(dev); -+ -+ n_free -= (blocks_for_checkpt * dev->param.chunks_per_block); -+ -+ if (n_free < 0) -+ n_free = 0; -+ -+ return n_free; -+} -+ -+ -+/* -+ * Marshalling functions to get loff_t file sizes into and out of -+ * object headers. -+ */ -+void yaffs_oh_size_load(struct yaffs_dev *dev, -+ struct yaffs_obj_hdr *oh, -+ loff_t fsize, -+ int do_endian) -+{ -+ oh->file_size_low = FSIZE_LOW(fsize); -+ -+ oh->file_size_high = FSIZE_HIGH(fsize); -+ -+ if (do_endian) { -+ yaffs_do_endian_u32(dev, &oh->file_size_low); -+ yaffs_do_endian_u32(dev, &oh->file_size_high); -+ } -+} -+ -+loff_t yaffs_oh_to_size(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh, -+ int do_endian) -+{ -+ loff_t retval; -+ -+ -+ if (sizeof(loff_t) >= 8 && ~(oh->file_size_high)) { -+ u32 low = oh->file_size_low; -+ u32 high = oh->file_size_high; -+ -+ if (do_endian) { -+ yaffs_do_endian_u32 (dev, &low); -+ yaffs_do_endian_u32 (dev, &high); -+ } -+ retval = FSIZE_COMBINE(high, low); -+ } else { -+ u32 low = oh->file_size_low; -+ -+ if (do_endian) -+ yaffs_do_endian_u32(dev, &low); -+ retval = (loff_t)low; -+ } -+ -+ return retval; -+} -+ -+ -+void yaffs_count_blocks_by_state(struct yaffs_dev *dev, int bs[10]) -+{ -+ u32 i; -+ struct yaffs_block_info *bi; -+ int s; -+ -+ for(i = 0; i < 10; i++) -+ bs[i] = 0; -+ -+ for(i = dev->internal_start_block; i <= dev->internal_end_block; i++) { -+ bi = yaffs_get_block_info(dev, i); -+ s = bi->block_state; -+ if(s > YAFFS_BLOCK_STATE_DEAD || s < YAFFS_BLOCK_STATE_UNKNOWN) -+ bs[0]++; -+ else -+ bs[s]++; -+ } -+} ---- linux-4.9.37/fs/yaffs2/yaffs_guts.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_guts.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,1070 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_GUTS_H__ -+#define __YAFFS_GUTS_H__ -+ -+#include "yportenv.h" -+ -+#define YAFFS_OK 1 -+#define YAFFS_FAIL 0 -+ -+/* Give us a Y=0x59, -+ * Give us an A=0x41, -+ * Give us an FF=0xff -+ * Give us an S=0x53 -+ * And what have we got... -+ */ -+#define YAFFS_MAGIC 0x5941ff53 -+ -+/* -+ * Tnodes form a tree with the tnodes in "levels" -+ * Levels greater than 0 hold 8 slots which point to other tnodes. -+ * Those at level 0 hold 16 slots which point to chunks in NAND. -+ * -+ * A maximum level of 8 thust supports files of size up to: -+ * -+ * 2^(3*MAX_LEVEL+4) -+ * -+ * Thus a max level of 8 supports files with up to 2^^28 chunks which gives -+ * a maximum file size of around 512Gbytees with 2k chunks. -+ */ -+#define YAFFS_NTNODES_LEVEL0 16 -+#define YAFFS_TNODES_LEVEL0_BITS 4 -+#define YAFFS_TNODES_LEVEL0_MASK 0xf -+ -+#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2) -+#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1) -+#define YAFFS_TNODES_INTERNAL_MASK 0x7 -+#define YAFFS_TNODES_MAX_LEVEL 8 -+#define YAFFS_TNODES_MAX_BITS (YAFFS_TNODES_LEVEL0_BITS + \ -+ YAFFS_TNODES_INTERNAL_BITS * \ -+ YAFFS_TNODES_MAX_LEVEL) -+#define YAFFS_MAX_CHUNK_ID ((1 << YAFFS_TNODES_MAX_BITS) - 1) -+ -+#define YAFFS_MAX_FILE_SIZE_32 0x7fffffff -+ -+/* Constants for YAFFS1 mode */ -+#define YAFFS_BYTES_PER_SPARE 16 -+#define YAFFS_BYTES_PER_CHUNK 512 -+#define YAFFS_CHUNK_SIZE_SHIFT 9 -+#define YAFFS_CHUNKS_PER_BLOCK 32 -+#define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK) -+ -+#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024 -+#define YAFFS_MIN_YAFFS2_SPARE_SIZE 32 -+ -+ -+ -+#define YAFFS_ALLOCATION_NOBJECTS 100 -+#define YAFFS_ALLOCATION_NTNODES 100 -+#define YAFFS_ALLOCATION_NLINKS 100 -+ -+#define YAFFS_NOBJECT_BUCKETS 256 -+ -+#define YAFFS_OBJECT_SPACE 0x40000 -+#define YAFFS_MAX_OBJECT_ID (YAFFS_OBJECT_SPACE - 1) -+ -+/* Binary data version stamps */ -+#define YAFFS_SUMMARY_VERSION 1 -+ -+#ifdef CONFIG_YAFFS_UNICODE -+#define YAFFS_MAX_NAME_LENGTH 127 -+#define YAFFS_MAX_ALIAS_LENGTH 79 -+#else -+#define YAFFS_MAX_NAME_LENGTH 255 -+#define YAFFS_MAX_ALIAS_LENGTH 159 -+#endif -+ -+#define YAFFS_SHORT_NAME_LENGTH 15 -+ -+/* Some special object ids for pseudo objects */ -+#define YAFFS_OBJECTID_ROOT 1 -+#define YAFFS_OBJECTID_LOSTNFOUND 2 -+#define YAFFS_OBJECTID_UNLINKED 3 -+#define YAFFS_OBJECTID_DELETED 4 -+ -+/* Fake object Id for summary data */ -+#define YAFFS_OBJECTID_SUMMARY 0x10 -+ -+/* Pseudo object ids for checkpointing */ -+#define YAFFS_OBJECTID_CHECKPOINT_DATA 0x20 -+#define YAFFS_SEQUENCE_CHECKPOINT_DATA 0x21 -+ -+#define YAFFS_MAX_SHORT_OP_CACHES 20 -+ -+#define YAFFS_N_TEMP_BUFFERS 6 -+ -+/* We limit the number attempts at sucessfully saving a chunk of data. -+ * Small-page devices have 32 pages per block; large-page devices have 64. -+ * Default to something in the order of 5 to 10 blocks worth of chunks. -+ */ -+#define YAFFS_WR_ATTEMPTS (5*64) -+ -+/* Sequence numbers are used in YAFFS2 to determine block allocation order. -+ * The range is limited slightly to help distinguish bad numbers from good. -+ * This also allows us to perhaps in the future use special numbers for -+ * special purposes. -+ * EFFFFF00 allows the allocation of 8 blocks/second (~1Mbytes) for 15 years, -+ * and is a larger number than the lifetime of a 2GB device. -+ */ -+#define YAFFS_LOWEST_SEQUENCE_NUMBER 0x00001000 -+#define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xefffff00 -+ -+/* Special sequence number for bad block that failed to be marked bad */ -+#define YAFFS_SEQUENCE_BAD_BLOCK 0xffff0000 -+ -+/* ChunkCache is used for short read/write operations.*/ -+struct yaffs_cache { -+ struct yaffs_obj *object; -+ int chunk_id; -+ int last_use; -+ int dirty; -+ int n_bytes; /* Only valid if the cache is dirty */ -+ int locked; /* Can't push out or flush while locked. */ -+ u8 *data; -+}; -+ -+/* yaffs1 tags structures in RAM -+ * NB This uses bitfield. Bitfields should not straddle a u32 boundary -+ * otherwise the structure size will get blown out. -+ */ -+ -+struct yaffs_tags { -+ u32 chunk_id:20; -+ u32 serial_number:2; -+ u32 n_bytes_lsb:10; -+ u32 obj_id:18; -+ u32 ecc:12; -+ u32 n_bytes_msb:2; -+}; -+ -+union yaffs_tags_union { -+ struct yaffs_tags as_tags; -+ u8 as_bytes[8]; -+ u32 as_u32[2]; -+}; -+ -+ -+/* Stuff used for extended tags in YAFFS2 */ -+ -+enum yaffs_ecc_result { -+ YAFFS_ECC_RESULT_UNKNOWN, -+ YAFFS_ECC_RESULT_NO_ERROR, -+ YAFFS_ECC_RESULT_FIXED, -+ YAFFS_ECC_RESULT_UNFIXED -+}; -+ -+/* -+ * Object type enum: -+ * When this is stored in flash we store it as a u32 instead -+ * to prevent any alignment change issues as compiler variants change. -+ */ -+ -+enum yaffs_obj_type { -+ YAFFS_OBJECT_TYPE_UNKNOWN, -+ YAFFS_OBJECT_TYPE_FILE, -+ YAFFS_OBJECT_TYPE_SYMLINK, -+ YAFFS_OBJECT_TYPE_DIRECTORY, -+ YAFFS_OBJECT_TYPE_HARDLINK, -+ YAFFS_OBJECT_TYPE_SPECIAL -+}; -+ -+#define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL -+ -+struct yaffs_ext_tags { -+ unsigned chunk_used; /* Status of the chunk: used or unused */ -+ unsigned obj_id; /* If 0 this is not used */ -+ unsigned chunk_id; /* If 0 this is a header, else a data chunk */ -+ unsigned n_bytes; /* Only valid for data chunks */ -+ -+ /* The following stuff only has meaning when we read */ -+ enum yaffs_ecc_result ecc_result; -+ unsigned block_bad; -+ -+ /* YAFFS 1 stuff */ -+ unsigned is_deleted; /* The chunk is marked deleted */ -+ unsigned serial_number; /* Yaffs1 2-bit serial number */ -+ -+ /* YAFFS2 stuff */ -+ unsigned seq_number; /* The sequence number of this block */ -+ -+ /* Extra info if this is an object header (YAFFS2 only) */ -+ -+ unsigned extra_available; /* Extra info available if not zero */ -+ unsigned extra_parent_id; /* The parent object */ -+ unsigned extra_is_shrink; /* Is it a shrink header? */ -+ unsigned extra_shadows; /* Does this shadow another object? */ -+ -+ enum yaffs_obj_type extra_obj_type; /* What object type? */ -+ -+ loff_t extra_file_size; /* Length if it is a file */ -+ unsigned extra_equiv_id; /* Equivalent object for a hard link */ -+}; -+ -+/* Spare structure for YAFFS1 */ -+struct yaffs_spare { -+ u8 tb0; -+ u8 tb1; -+ u8 tb2; -+ u8 tb3; -+ u8 page_status; /* set to 0 to delete the chunk */ -+ u8 block_status; -+ u8 tb4; -+ u8 tb5; -+ u8 ecc1[3]; -+ u8 tb6; -+ u8 tb7; -+ u8 ecc2[3]; -+}; -+ -+/*Special structure for passing through to mtd */ -+struct yaffs_nand_spare { -+ struct yaffs_spare spare; -+ int eccres1; -+ int eccres2; -+}; -+ -+/* Block data in RAM */ -+ -+enum yaffs_block_state { -+ YAFFS_BLOCK_STATE_UNKNOWN = 0, -+ -+ YAFFS_BLOCK_STATE_SCANNING, -+ /* Being scanned */ -+ -+ YAFFS_BLOCK_STATE_NEEDS_SCAN, -+ /* The block might have something on it (ie it is allocating or full, -+ * perhaps empty) but it needs to be scanned to determine its true -+ * state. -+ * This state is only valid during scanning. -+ * NB We tolerate empty because the pre-scanner might be incapable of -+ * deciding -+ * However, if this state is returned on a YAFFS2 device, -+ * then we expect a sequence number -+ */ -+ -+ YAFFS_BLOCK_STATE_EMPTY, -+ /* This block is empty */ -+ -+ YAFFS_BLOCK_STATE_ALLOCATING, -+ /* This block is partially allocated. -+ * At least one page holds valid data. -+ * This is the one currently being used for page -+ * allocation. Should never be more than one of these. -+ * If a block is only partially allocated at mount it is treated as -+ * full. -+ */ -+ -+ YAFFS_BLOCK_STATE_FULL, -+ /* All the pages in this block have been allocated. -+ * If a block was only partially allocated when mounted we treat -+ * it as fully allocated. -+ */ -+ -+ YAFFS_BLOCK_STATE_DIRTY, -+ /* The block was full and now all chunks have been deleted. -+ * Erase me, reuse me. -+ */ -+ -+ YAFFS_BLOCK_STATE_CHECKPOINT, -+ /* This block is assigned to holding checkpoint data. */ -+ -+ YAFFS_BLOCK_STATE_COLLECTING, -+ /* This block is being garbage collected */ -+ -+ YAFFS_BLOCK_STATE_DEAD -+ /* This block has failed and is not in use */ -+}; -+ -+#define YAFFS_NUMBER_OF_BLOCK_STATES (YAFFS_BLOCK_STATE_DEAD + 1) -+ -+struct yaffs_block_info { -+ -+ s32 soft_del_pages:10; /* number of soft deleted pages */ -+ s32 pages_in_use:10; /* number of pages in use */ -+ u32 block_state:4; /* One of the above block states. */ -+ /* NB use unsigned because enum is sometimes -+ * an int */ -+ u32 needs_retiring:1; /* Data has failed on this block, */ -+ /*need to get valid data off and retire*/ -+ u32 skip_erased_check:1;/* Skip the erased check on this block */ -+ u32 gc_prioritise:1; /* An ECC check or blank check has failed. -+ Block should be prioritised for GC */ -+ u32 chunk_error_strikes:3; /* How many times we've had ecc etc -+ failures on this block and tried to reuse it */ -+ u32 has_summary:1; /* The block has a summary */ -+ -+ u32 has_shrink_hdr:1; /* This block has at least one shrink header */ -+ u32 seq_number; /* block sequence number for yaffs2 */ -+ -+}; -+ -+union yaffs_block_info_union { -+ struct yaffs_block_info bi; -+ u32 as_u32[2]; -+}; -+ -+/* -------------------------- Object structure -------------------------------*/ -+/* This is the object structure as stored on NAND */ -+ -+struct yaffs_obj_hdr { -+ u32 type; /* enum yaffs_obj_type */ -+ -+ /* Apply to everything */ -+ u32 parent_obj_id; -+ u16 sum_no_longer_used; /* checksum of name. No longer used */ -+ YCHAR name[YAFFS_MAX_NAME_LENGTH + 1]; -+ -+ /* The following apply to all object types except for hard links */ -+ u32 yst_mode; /* protection */ -+ -+ u32 yst_uid; -+ u32 yst_gid; -+ u32 yst_atime; -+ u32 yst_mtime; -+ u32 yst_ctime; -+ -+ /* File size applies to files only */ -+ u32 file_size_low; -+ -+ /* Equivalent object id applies to hard links only. */ -+ int equiv_id; -+ -+ /* Alias is for symlinks only. */ -+ YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1]; -+ -+ u32 yst_rdev; /* stuff for block and char devices (major/min) */ -+ -+ u32 win_ctime[2]; -+ u32 win_atime[2]; -+ u32 win_mtime[2]; -+ -+ u32 inband_shadowed_obj_id; -+ u32 inband_is_shrink; -+ -+ u32 file_size_high; -+ u32 reserved[1]; -+ int shadows_obj; /* This object header shadows the -+ specified object if > 0 */ -+ -+ /* is_shrink applies to object headers written when wemake a hole. */ -+ u32 is_shrink; -+ -+}; -+ -+/*--------------------------- Tnode -------------------------- */ -+ -+struct yaffs_tnode { -+ struct yaffs_tnode *internal[YAFFS_NTNODES_INTERNAL]; -+}; -+ -+/*------------------------ Object -----------------------------*/ -+/* An object can be one of: -+ * - a directory (no data, has children links -+ * - a regular file (data.... not prunes :->). -+ * - a symlink [symbolic link] (the alias). -+ * - a hard link -+ */ -+ -+/* The file variant has three file sizes: -+ * - file_size : size of file as written into Yaffs - including data in cache. -+ * - stored_size - size of file as stored on media. -+ * - shrink_size - size of file that has been shrunk back to. -+ * -+ * The stored_size and file_size might be different because the data written -+ * into the cache will increase the file_size but the stored_size will only -+ * change when the data is actually stored. -+ * -+ */ -+struct yaffs_file_var { -+ loff_t file_size; -+ loff_t stored_size; -+ loff_t shrink_size; -+ int top_level; -+ struct yaffs_tnode *top; -+}; -+ -+struct yaffs_dir_var { -+ struct list_head children; /* list of child links */ -+ struct list_head dirty; /* Entry for list of dirty directories */ -+}; -+ -+struct yaffs_symlink_var { -+ YCHAR *alias; -+}; -+ -+struct yaffs_hardlink_var { -+ struct yaffs_obj *equiv_obj; -+ u32 equiv_id; -+}; -+ -+union yaffs_obj_var { -+ struct yaffs_file_var file_variant; -+ struct yaffs_dir_var dir_variant; -+ struct yaffs_symlink_var symlink_variant; -+ struct yaffs_hardlink_var hardlink_variant; -+}; -+ -+struct yaffs_obj { -+ u8 deleted:1; /* This should only apply to unlinked files. */ -+ u8 soft_del:1; /* it has also been soft deleted */ -+ u8 unlinked:1; /* An unlinked file.*/ -+ u8 fake:1; /* A fake object has no presence on NAND. */ -+ u8 rename_allowed:1; /* Some objects cannot be renamed. */ -+ u8 unlink_allowed:1; -+ u8 dirty:1; /* the object needs to be written to flash */ -+ u8 valid:1; /* When the file system is being loaded up, this -+ * object might be created before the data -+ * is available -+ * ie. file data chunks encountered before -+ * the header. -+ */ -+ u8 lazy_loaded:1; /* This object has been lazy loaded and -+ * is missing some detail */ -+ -+ u8 defered_free:1; /* Object is removed from NAND, but is -+ * still in the inode cache. -+ * Free of object is defered. -+ * until the inode is released. -+ */ -+ u8 being_created:1; /* This object is still being created -+ * so skip some verification checks. */ -+ u8 is_shadowed:1; /* This object is shadowed on the way -+ * to being renamed. */ -+ -+ u8 xattr_known:1; /* We know if this has object has xattribs -+ * or not. */ -+ u8 has_xattr:1; /* This object has xattribs. -+ * Only valid if xattr_known. */ -+ -+ u8 serial; /* serial number of chunk in NAND.*/ -+ u16 sum; /* sum of the name to speed searching */ -+ -+ struct yaffs_dev *my_dev; /* The device I'm on */ -+ -+ struct list_head hash_link; /* list of objects in hash bucket */ -+ -+ struct list_head hard_links; /* hard linked object chain*/ -+ -+ /* directory structure stuff */ -+ /* also used for linking up the free list */ -+ struct yaffs_obj *parent; -+ struct list_head siblings; -+ -+ /* Where's my object header in NAND? */ -+ int hdr_chunk; -+ -+ int n_data_chunks; /* Number of data chunks for this file. */ -+ -+ u32 obj_id; /* the object id value */ -+ -+ u32 yst_mode; -+ -+ YCHAR short_name[YAFFS_SHORT_NAME_LENGTH + 1]; -+ -+#ifdef CONFIG_YAFFS_WINCE -+ u32 win_ctime[2]; -+ u32 win_mtime[2]; -+ u32 win_atime[2]; -+#else -+ u32 yst_uid; -+ u32 yst_gid; -+ u32 yst_atime; -+ u32 yst_mtime; -+ u32 yst_ctime; -+#endif -+ -+ u32 yst_rdev; -+ -+ void *my_inode; -+ -+ u32 variant_type; /* enum yaffs_object_type */ -+ -+ union yaffs_obj_var variant; -+ -+}; -+ -+struct yaffs_obj_bucket { -+ struct list_head list; -+ int count; -+}; -+ -+ -+/*--------------------- Temporary buffers ---------------- -+ * -+ * These are chunk-sized working buffers. Each device has a few. -+ */ -+ -+struct yaffs_buffer { -+ u8 *buffer; -+ int in_use; -+}; -+ -+/*----------------- Device ---------------------------------*/ -+ -+struct yaffs_param { -+ const YCHAR *name; -+ -+ /* -+ * Entry parameters set up way early. Yaffs sets up the rest. -+ * The structure should be zeroed out before use so that unused -+ * and default values are zero. -+ */ -+ -+ int inband_tags; /* Use unband tags */ -+ u32 total_bytes_per_chunk; /* Should be >= 512, does not need to -+ be a power of 2 */ -+ u32 chunks_per_block; /* does not need to be a power of 2 */ -+ u32 spare_bytes_per_chunk; /* spare area size */ -+ u32 start_block; /* Start block we're allowed to use */ -+ u32 end_block; /* End block we're allowed to use */ -+ u32 n_reserved_blocks; /* Tuneable so that we can reduce -+ * reserved blocks on NOR and RAM. */ -+ -+ u32 n_caches; /* If == 0, then short op caching is disabled, -+ * else the number of short op caches. -+ */ -+ int cache_bypass_aligned; /* If non-zero then bypass the cache for -+ * aligned writes. -+ */ -+ -+ int use_nand_ecc; /* Flag to decide whether or not to use -+ * NAND driver ECC on data (yaffs1) */ -+ int tags_9bytes; /* Use 9 byte tags */ -+ int no_tags_ecc; /* Flag to decide whether or not to do ECC -+ * on packed tags (yaffs2) */ -+ -+ int is_yaffs2; /* Use yaffs2 mode on this device */ -+ -+ int empty_lost_n_found; /* Auto-empty lost+found directory on mount */ -+ -+ int refresh_period; /* How often to check for a block refresh */ -+ -+ /* Checkpoint control. Can be set before or after initialisation */ -+ u8 skip_checkpt_rd; -+ u8 skip_checkpt_wr; -+ -+ int enable_xattr; /* Enable xattribs */ -+ -+ int max_objects; /* -+ * Set to limit the number of objects created. -+ * 0 = no limit. -+ */ -+ -+ int hide_lost_n_found; /* Set non-zero to hide the lost-n-found dir. */ -+ -+ int stored_endian; /* 0=cpu endian, 1=little endian, 2=big endian */ -+ -+ /* The remove_obj_fn function must be supplied by OS flavours that -+ * need it. -+ * yaffs direct uses it to implement the faster readdir. -+ * Linux uses it to protect the directory during unlocking. -+ */ -+ void (*remove_obj_fn) (struct yaffs_obj *obj); -+ -+ /* Callback to mark the superblock dirty */ -+ void (*sb_dirty_fn) (struct yaffs_dev *dev); -+ -+ /* Callback to control garbage collection. */ -+ unsigned (*gc_control_fn) (struct yaffs_dev *dev); -+ -+ /* Debug control flags. Don't use unless you know what you're doing */ -+ int use_header_file_size; /* Flag to determine if we should use -+ * file sizes from the header */ -+ int disable_lazy_load; /* Disable lazy loading on this device */ -+ int wide_tnodes_disabled; /* Set to disable wide tnodes */ -+ int disable_soft_del; /* yaffs 1 only: Set to disable the use of -+ * softdeletion. */ -+ -+ int defered_dir_update; /* Set to defer directory updates */ -+ -+#ifdef CONFIG_YAFFS_AUTO_UNICODE -+ int auto_unicode; -+#endif -+ int always_check_erased; /* Force chunk erased check always on */ -+ -+ int disable_summary; -+ int disable_bad_block_marking; -+ -+}; -+ -+struct yaffs_driver { -+ int (*drv_write_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, -+ const u8 *data, int data_len, -+ const u8 *oob, int oob_len); -+ int (*drv_read_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, -+ u8 *data, int data_len, -+ u8 *oob, int oob_len, -+ enum yaffs_ecc_result *ecc_result); -+ int (*drv_erase_fn) (struct yaffs_dev *dev, int block_no); -+ int (*drv_mark_bad_fn) (struct yaffs_dev *dev, int block_no); -+ int (*drv_check_bad_fn) (struct yaffs_dev *dev, int block_no); -+ int (*drv_initialise_fn) (struct yaffs_dev *dev); -+ int (*drv_deinitialise_fn) (struct yaffs_dev *dev); -+}; -+ -+struct yaffs_tags_handler { -+ int (*write_chunk_tags_fn) (struct yaffs_dev *dev, -+ int nand_chunk, const u8 *data, -+ const struct yaffs_ext_tags *tags); -+ int (*read_chunk_tags_fn) (struct yaffs_dev *dev, -+ int nand_chunk, u8 *data, -+ struct yaffs_ext_tags *tags); -+ -+ int (*query_block_fn) (struct yaffs_dev *dev, int block_no, -+ enum yaffs_block_state *state, -+ u32 *seq_number); -+ int (*mark_bad_fn) (struct yaffs_dev *dev, int block_no); -+}; -+ -+struct yaffs_dev { -+ struct yaffs_param param; -+ struct yaffs_driver drv; -+ struct yaffs_tags_handler tagger; -+ -+ /* Context storage. Holds extra OS specific data for this device */ -+ -+ void *os_context; -+ void *driver_context; -+ -+ struct list_head dev_list; -+ -+ int ll_init; -+ /* Runtime parameters. Set up by YAFFS. */ -+ u32 data_bytes_per_chunk; -+ -+ /* Non-wide tnode stuff */ -+ u16 chunk_grp_bits; /* Number of bits that need to be resolved if -+ * the tnodes are not wide enough. -+ */ -+ u16 chunk_grp_size; /* == 2^^chunk_grp_bits */ -+ -+ struct yaffs_tnode *tn_swap_buffer; -+ -+ /* Stuff to support wide tnodes */ -+ u32 tnode_width; -+ u32 tnode_mask; -+ u32 tnode_size; -+ -+ /* Stuff for figuring out file offset to chunk conversions */ -+ u32 chunk_shift; /* Shift value */ -+ u32 chunk_div; /* Divisor after shifting: 1 for 2^n sizes */ -+ u32 chunk_mask; /* Mask to use for power-of-2 case */ -+ -+ int is_mounted; -+ int read_only; -+ int is_checkpointed; -+ int swap_endian; /* Stored endian needs endian swap. */ -+ -+ /* Stuff to support block offsetting to support start block zero */ -+ u32 internal_start_block; -+ u32 internal_end_block; -+ int block_offset; -+ int chunk_offset; -+ -+ /* Runtime checkpointing stuff */ -+ int checkpt_page_seq; /* running sequence number of checkpt pages */ -+ int checkpt_byte_count; -+ int checkpt_byte_offs; -+ u8 *checkpt_buffer; -+ int checkpt_open_write; -+ u32 blocks_in_checkpt; -+ int checkpt_cur_chunk; -+ int checkpt_cur_block; -+ int checkpt_next_block; -+ int *checkpt_block_list; -+ u32 checkpt_max_blocks; -+ u32 checkpt_sum; -+ u32 checkpt_xor; -+ -+ int checkpoint_blocks_required; /* Number of blocks needed to store -+ * current checkpoint set */ -+ -+ /* Block Info */ -+ struct yaffs_block_info *block_info; -+ u8 *chunk_bits; /* bitmap of chunks in use */ -+ u8 block_info_alt:1; /* allocated using alternative alloc */ -+ u8 chunk_bits_alt:1; /* allocated using alternative alloc */ -+ int chunk_bit_stride; /* Number of bytes of chunk_bits per block. -+ * Must be consistent with chunks_per_block. -+ */ -+ -+ int n_erased_blocks; -+ int alloc_block; /* Current block being allocated off */ -+ u32 alloc_page; -+ int alloc_block_finder; /* Used to search for next allocation block */ -+ -+ /* Object and Tnode memory management */ -+ void *allocator; -+ int n_obj; -+ int n_tnodes; -+ -+ int n_hardlinks; -+ -+ struct yaffs_obj_bucket obj_bucket[YAFFS_NOBJECT_BUCKETS]; -+ u32 bucket_finder; -+ -+ int n_free_chunks; -+ -+ /* Garbage collection control */ -+ u32 *gc_cleanup_list; /* objects to delete at the end of a GC. */ -+ u32 n_clean_ups; -+ -+ unsigned has_pending_prioritised_gc; /* We think this device might -+ have pending prioritised gcs */ -+ unsigned gc_disable; -+ unsigned gc_block_finder; -+ unsigned gc_dirtiest; -+ unsigned gc_pages_in_use; -+ unsigned gc_not_done; -+ unsigned gc_block; -+ unsigned gc_chunk; -+ unsigned gc_skip; -+ struct yaffs_summary_tags *gc_sum_tags; -+ -+ /* Special directories */ -+ struct yaffs_obj *root_dir; -+ struct yaffs_obj *lost_n_found; -+ -+ int buffered_block; /* Which block is buffered here? */ -+ int doing_buffered_block_rewrite; -+ -+ struct yaffs_cache *cache; -+ int cache_last_use; -+ -+ /* Stuff for background deletion and unlinked files. */ -+ struct yaffs_obj *unlinked_dir; /* Directory where unlinked and deleted -+ files live. */ -+ struct yaffs_obj *del_dir; /* Directory where deleted objects are -+ sent to disappear. */ -+ struct yaffs_obj *unlinked_deletion; /* Current file being -+ background deleted. */ -+ int n_deleted_files; /* Count of files awaiting deletion; */ -+ int n_unlinked_files; /* Count of unlinked files. */ -+ int n_bg_deletions; /* Count of background deletions. */ -+ -+ /* Temporary buffer management */ -+ struct yaffs_buffer temp_buffer[YAFFS_N_TEMP_BUFFERS]; -+ int max_temp; -+ int temp_in_use; -+ int unmanaged_buffer_allocs; -+ int unmanaged_buffer_deallocs; -+ -+ /* yaffs2 runtime stuff */ -+ unsigned seq_number; /* Sequence number of currently -+ allocating block */ -+ unsigned oldest_dirty_seq; -+ unsigned oldest_dirty_block; -+ -+ /* Block refreshing */ -+ int refresh_skip; /* A skip down counter. -+ * Refresh happens when this gets to zero. */ -+ -+ /* Dirty directory handling */ -+ struct list_head dirty_dirs; /* List of dirty directories */ -+ -+ /* Summary */ -+ int chunks_per_summary; -+ struct yaffs_summary_tags *sum_tags; -+ -+ /* Statistics */ -+ u32 n_page_writes; -+ u32 n_page_reads; -+ u32 n_erasures; -+ u32 n_bad_queries; -+ u32 n_bad_markings; -+ u32 n_erase_failures; -+ u32 n_gc_copies; -+ u32 all_gcs; -+ u32 passive_gc_count; -+ u32 oldest_dirty_gc_count; -+ u32 n_gc_blocks; -+ u32 bg_gcs; -+ u32 n_retried_writes; -+ u32 n_retired_blocks; -+ u32 n_ecc_fixed; -+ u32 n_ecc_unfixed; -+ u32 n_tags_ecc_fixed; -+ u32 n_tags_ecc_unfixed; -+ u32 n_deletions; -+ u32 n_unmarked_deletions; -+ u32 refresh_count; -+ u32 cache_hits; -+ u32 tags_used; -+ u32 summary_used; -+ -+}; -+ -+/* -+ * Checkpointing definitions. -+ */ -+ -+#define YAFFS_CHECKPOINT_VERSION 8 -+ -+/* yaffs_checkpt_obj holds the definition of an object as dumped -+ * by checkpointing. -+ */ -+ -+ -+/* Checkpint object bits in bitfield: offset, length */ -+#define CHECKPOINT_VARIANT_BITS 0, 3 -+#define CHECKPOINT_DELETED_BITS 3, 1 -+#define CHECKPOINT_SOFT_DEL_BITS 4, 1 -+#define CHECKPOINT_UNLINKED_BITS 5, 1 -+#define CHECKPOINT_FAKE_BITS 6, 1 -+#define CHECKPOINT_RENAME_ALLOWED_BITS 7, 1 -+#define CHECKPOINT_UNLINK_ALLOWED_BITS 8, 1 -+#define CHECKPOINT_SERIAL_BITS 9, 8 -+ -+struct yaffs_checkpt_obj { -+ int struct_type; -+ u32 obj_id; -+ u32 parent_id; -+ int hdr_chunk; -+ u32 bit_field; -+ int n_data_chunks; -+ loff_t size_or_equiv_obj; -+}; -+ -+/* The CheckpointDevice structure holds the device information that changes -+ *at runtime and must be preserved over unmount/mount cycles. -+ */ -+struct yaffs_checkpt_dev { -+ int struct_type; -+ int n_erased_blocks; -+ int alloc_block; /* Current block being allocated off */ -+ u32 alloc_page; -+ int n_free_chunks; -+ -+ int n_deleted_files; /* Count of files awaiting deletion; */ -+ int n_unlinked_files; /* Count of unlinked files. */ -+ int n_bg_deletions; /* Count of background deletions. */ -+ -+ /* yaffs2 runtime stuff */ -+ unsigned seq_number; /* Sequence number of currently -+ * allocating block */ -+ -+}; -+ -+struct yaffs_checkpt_validity { -+ int struct_type; -+ u32 magic; -+ u32 version; -+ u32 head; -+}; -+ -+struct yaffs_shadow_fixer { -+ int obj_id; -+ int shadowed_id; -+ struct yaffs_shadow_fixer *next; -+}; -+ -+/* Structure for doing xattr modifications */ -+struct yaffs_xattr_mod { -+ int set; /* If 0 then this is a deletion */ -+ const YCHAR *name; -+ const void *data; -+ int size; -+ int flags; -+ int result; -+}; -+ -+/*----------------------- YAFFS Functions -----------------------*/ -+ -+int yaffs_guts_initialise(struct yaffs_dev *dev); -+void yaffs_deinitialise(struct yaffs_dev *dev); -+ -+int yaffs_get_n_free_chunks(struct yaffs_dev *dev); -+ -+int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR * old_name, -+ struct yaffs_obj *new_dir, const YCHAR * new_name); -+ -+int yaffs_unlink_obj(struct yaffs_obj *obj); -+ -+int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR * name); -+int yaffs_del_obj(struct yaffs_obj *obj); -+struct yaffs_obj *yaffs_retype_obj(struct yaffs_obj *obj, -+ enum yaffs_obj_type type); -+ -+ -+int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size); -+loff_t yaffs_get_obj_length(struct yaffs_obj *obj); -+int yaffs_get_obj_inode(struct yaffs_obj *obj); -+unsigned yaffs_get_obj_type(struct yaffs_obj *obj); -+int yaffs_get_obj_link_count(struct yaffs_obj *obj); -+ -+/* File operations */ -+int yaffs_file_rd(struct yaffs_obj *obj, u8 * buffer, loff_t offset, -+ int n_bytes); -+int yaffs_wr_file(struct yaffs_obj *obj, const u8 * buffer, loff_t offset, -+ int n_bytes, int write_trhrough); -+int yaffs_resize_file(struct yaffs_obj *obj, loff_t new_size); -+ -+struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent, -+ const YCHAR *name, u32 mode, u32 uid, -+ u32 gid); -+ -+int yaffs_flush_file(struct yaffs_obj *in, -+ int update_time, -+ int data_sync, -+ int discard_cache); -+ -+/* Flushing and checkpointing */ -+void yaffs_flush_whole_cache(struct yaffs_dev *dev, int discard); -+ -+int yaffs_checkpoint_save(struct yaffs_dev *dev); -+int yaffs_checkpoint_restore(struct yaffs_dev *dev); -+ -+/* Directory operations */ -+struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name, -+ u32 mode, u32 uid, u32 gid); -+struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *the_dir, -+ const YCHAR *name); -+struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number); -+ -+/* Link operations */ -+struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR *name, -+ struct yaffs_obj *equiv_obj); -+ -+struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj); -+ -+/* Symlink operations */ -+struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent, -+ const YCHAR *name, u32 mode, u32 uid, -+ u32 gid, const YCHAR *alias); -+YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj); -+ -+/* Special inodes (fifos, sockets and devices) */ -+struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent, -+ const YCHAR *name, u32 mode, u32 uid, -+ u32 gid, u32 rdev); -+ -+int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR *name, -+ const void *value, int size, int flags); -+int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR *name, void *value, -+ int size); -+int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size); -+int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR *name); -+ -+/* Special directories */ -+struct yaffs_obj *yaffs_root(struct yaffs_dev *dev); -+struct yaffs_obj *yaffs_lost_n_found(struct yaffs_dev *dev); -+ -+void yaffs_handle_defered_free(struct yaffs_obj *obj); -+ -+void yaffs_update_dirty_dirs(struct yaffs_dev *dev); -+ -+int yaffs_bg_gc(struct yaffs_dev *dev, unsigned urgency); -+ -+/* Debug dump */ -+int yaffs_dump_obj(struct yaffs_obj *obj); -+ -+void yaffs_guts_test(struct yaffs_dev *dev); -+int yaffs_guts_ll_init(struct yaffs_dev *dev); -+ -+ -+/* A few useful functions to be used within the core files*/ -+void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash, -+ int lyn); -+int yaffs_check_ff(u8 *buffer, int n_bytes); -+void yaffs_handle_chunk_error(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi); -+ -+u8 *yaffs_get_temp_buffer(struct yaffs_dev *dev); -+void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer); -+ -+struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev, -+ int number, -+ enum yaffs_obj_type type); -+int yaffs_put_chunk_in_file(struct yaffs_obj *in, int inode_chunk, -+ int nand_chunk, int in_scan); -+void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR *name); -+void yaffs_set_obj_name_from_oh(struct yaffs_obj *obj, -+ const struct yaffs_obj_hdr *oh); -+void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj); -+YCHAR *yaffs_clone_str(const YCHAR *str); -+void yaffs_link_fixup(struct yaffs_dev *dev, struct list_head *hard_list); -+void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no); -+int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, -+ int force, int is_shrink, int shadows, -+ struct yaffs_xattr_mod *xop); -+void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id, -+ int backward_scanning); -+int yaffs_check_alloc_available(struct yaffs_dev *dev, int n_chunks); -+struct yaffs_tnode *yaffs_get_tnode(struct yaffs_dev *dev); -+struct yaffs_tnode *yaffs_add_find_tnode_0(struct yaffs_dev *dev, -+ struct yaffs_file_var *file_struct, -+ u32 chunk_id, -+ struct yaffs_tnode *passed_tn); -+ -+int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset, -+ int n_bytes, int write_trhrough); -+void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size); -+void yaffs_skip_rest_of_block(struct yaffs_dev *dev); -+ -+int yaffs_count_free_chunks(struct yaffs_dev *dev); -+ -+struct yaffs_tnode *yaffs_find_tnode_0(struct yaffs_dev *dev, -+ struct yaffs_file_var *file_struct, -+ u32 chunk_id); -+ -+u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn, -+ unsigned pos); -+ -+int yaffs_is_non_empty_dir(struct yaffs_obj *obj); -+ -+int yaffs_guts_format_dev(struct yaffs_dev *dev); -+ -+void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr, -+ int *chunk_out, u32 *offset_out); -+/* -+ * Marshalling functions to get loff_t file sizes into and out of -+ * object headers. -+ */ -+void yaffs_oh_size_load(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh, -+ loff_t fsize, int do_endian); -+loff_t yaffs_oh_to_size(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh, -+ int do_endian); -+loff_t yaffs_max_file_size(struct yaffs_dev *dev); -+ -+/* -+ * Debug function to count number of blocks in each state -+ * NB Needs to be called with correct number of integers -+ */ -+ -+void yaffs_count_blocks_by_state(struct yaffs_dev *dev, int bs[10]); -+ -+int yaffs_find_chunk_in_file(struct yaffs_obj *in, int inode_chunk, -+ struct yaffs_ext_tags *tags); -+ -+/* -+ * Define LOFF_T_32_BIT if a 32-bit LOFF_T is being used. -+ * Not serious if you get this wrong - you might just get some warnings. -+*/ -+ -+#ifdef LOFF_T_32_BIT -+#define FSIZE_LOW(fsize) (fsize) -+#define FSIZE_HIGH(fsize) 0 -+#define FSIZE_COMBINE(high, low) (low) -+#else -+#define FSIZE_LOW(fsize) ((fsize) & 0xffffffff) -+#define FSIZE_HIGH(fsize)(((fsize) >> 32) & 0xffffffff) -+#define FSIZE_COMBINE(high, low) ((((loff_t) (high)) << 32) | \ -+ (((loff_t) (low)) & 0xFFFFFFFF)) -+#endif -+ -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_linux.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_linux.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,48 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_LINUX_H__ -+#define __YAFFS_LINUX_H__ -+ -+#include "yportenv.h" -+ -+struct yaffs_linux_context { -+ struct list_head context_list; /* List of these we have mounted */ -+ struct yaffs_dev *dev; -+ struct super_block *super; -+ struct task_struct *bg_thread; /* Background thread for this device */ -+ int bg_running; -+ struct mutex gross_lock; /* Gross locking mutex*/ -+ u8 *spare_buffer; /* For mtdif2 use. Don't know the buffer size -+ * at compile time so we have to allocate it. -+ */ -+ struct list_head search_contexts; -+ struct task_struct *readdir_process; -+ unsigned mount_id; -+ int dirty; -+}; -+ -+#define yaffs_dev_to_lc(dev) ((struct yaffs_linux_context *)((dev)->os_context)) -+#define yaffs_dev_to_mtd(dev) ((struct mtd_info *)((dev)->driver_context)) -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+#define WRITE_SIZE_STR "writesize" -+#define WRITE_SIZE(mtd) ((mtd)->writesize) -+#else -+#define WRITE_SIZE_STR "oobblock" -+#define WRITE_SIZE(mtd) ((mtd)->oobblock) -+#endif -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_mtdif.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_mtdif.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,310 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yportenv.h" -+ -+#include "yaffs_mtdif.h" -+ -+#include "linux/mtd/mtd.h" -+#include "linux/types.h" -+#include "linux/time.h" -+#include "linux/mtd/nand.h" -+#include "linux/kernel.h" -+#include "linux/version.h" -+#include "linux/types.h" -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) -+#include "uapi/linux/major.h" -+#endif -+ -+#include "yaffs_trace.h" -+#include "yaffs_guts.h" -+#include "yaffs_linux.h" -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) -+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO -+#endif -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) -+#define mtd_erase(m, ei) (m)->erase(m, ei) -+#define mtd_write_oob(m, addr, pops) (m)->write_oob(m, addr, pops) -+#define mtd_read_oob(m, addr, pops) (m)->read_oob(m, addr, pops) -+#define mtd_block_isbad(m, offs) (m)->block_isbad(m, offs) -+#define mtd_block_markbad(m, offs) (m)->block_markbad(m, offs) -+#endif -+ -+ -+ -+int nandmtd_erase_block(struct yaffs_dev *dev, int block_no) -+{ -+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); -+ u32 addr = -+ ((loff_t) block_no) * dev->param.total_bytes_per_chunk * -+ dev->param.chunks_per_block; -+ struct erase_info ei; -+ int retval = 0; -+ -+ ei.mtd = mtd; -+ ei.addr = addr; -+ ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block; -+ ei.time = 1000; -+ ei.retries = 2; -+ ei.callback = NULL; -+ ei.priv = (u_long) dev; -+ -+ retval = mtd_erase(mtd, &ei); -+ -+ if (retval == 0) -+ return YAFFS_OK; -+ -+ return YAFFS_FAIL; -+} -+ -+ -+static int yaffs_mtd_write(struct yaffs_dev *dev, int nand_chunk, -+ const u8 *data, int data_len, -+ const u8 *oob, int oob_len) -+{ -+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); -+ loff_t addr; -+ struct mtd_oob_ops ops; -+ int retval; -+ -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "yaffs_mtd_write(%p, %d, %p, %d, %p, %d)\n", -+ dev, nand_chunk, data, data_len, oob, oob_len); -+ -+ if (!data || !data_len) { -+ data = NULL; -+ data_len = 0; -+ } -+ -+ if (!oob || !oob_len) { -+ oob = NULL; -+ oob_len = 0; -+ } -+ -+ addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk; -+ memset(&ops, 0, sizeof(ops)); -+ ops.mode = MTD_OPS_AUTO_OOB; -+ ops.len = (data) ? data_len : 0; -+ ops.ooblen = oob_len; -+ ops.datbuf = (u8 *)data; -+ ops.oobbuf = (u8 *)oob; -+ -+ retval = mtd_write_oob(mtd, addr, &ops); -+ if (retval) { -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "write_oob failed, chunk %d, mtd error %d", -+ nand_chunk, retval); -+ } -+ return retval ? YAFFS_FAIL : YAFFS_OK; -+} -+ -+static int yaffs_mtd_read(struct yaffs_dev *dev, int nand_chunk, -+ u8 *data, int data_len, -+ u8 *oob, int oob_len, -+ enum yaffs_ecc_result *ecc_result) -+{ -+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); -+ loff_t addr; -+ struct mtd_oob_ops ops; -+ int retval; -+ -+ addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk; -+ memset(&ops, 0, sizeof(ops)); -+ ops.mode = MTD_OPS_AUTO_OOB; -+ ops.len = (data) ? data_len : 0; -+ ops.ooblen = oob_len; -+ ops.datbuf = data; -+ ops.oobbuf = oob; -+ -+#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20)) -+ /* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug; -+ * help it out with ops.len = ops.ooblen when ops.datbuf == NULL. -+ */ -+ ops.len = (ops.datbuf) ? ops.len : ops.ooblen; -+#endif -+ /* Read page and oob using MTD. -+ * Check status and determine ECC result. -+ */ -+ retval = mtd_read_oob(mtd, addr, &ops); -+ if (retval) -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "read_oob failed, chunk %d, mtd error %d", -+ nand_chunk, retval); -+ -+ switch (retval) { -+ case 0: -+ /* no error */ -+ if(ecc_result) -+ *ecc_result = YAFFS_ECC_RESULT_NO_ERROR; -+ break; -+ -+ case -EUCLEAN: -+ /* MTD's ECC fixed the data */ -+ if(ecc_result) -+ *ecc_result = YAFFS_ECC_RESULT_FIXED; -+ dev->n_ecc_fixed++; -+ break; -+ -+ case -EBADMSG: -+ default: -+ /* MTD's ECC could not fix the data */ -+ dev->n_ecc_unfixed++; -+ if(ecc_result) -+ *ecc_result = YAFFS_ECC_RESULT_UNFIXED; -+ return YAFFS_FAIL; -+ } -+ -+ return YAFFS_OK; -+} -+ -+static int yaffs_mtd_erase(struct yaffs_dev *dev, int block_no) -+{ -+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); -+ -+ loff_t addr; -+ struct erase_info ei; -+ int retval = 0; -+ u32 block_size; -+ -+ block_size = dev->param.total_bytes_per_chunk * -+ dev->param.chunks_per_block; -+ addr = ((loff_t) block_no) * block_size; -+ -+ ei.mtd = mtd; -+ ei.addr = addr; -+ ei.len = block_size; -+ ei.time = 1000; -+ ei.retries = 2; -+ ei.callback = NULL; -+ ei.priv = (u_long) dev; -+ -+ retval = mtd_erase(mtd, &ei); -+ -+ if (retval == 0) -+ return YAFFS_OK; -+ -+ return YAFFS_FAIL; -+} -+ -+static int yaffs_mtd_mark_bad(struct yaffs_dev *dev, int block_no) -+{ -+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); -+ int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk; -+ int retval; -+ -+ yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no); -+ -+ retval = mtd_block_markbad(mtd, (loff_t) blocksize * block_no); -+ return (retval) ? YAFFS_FAIL : YAFFS_OK; -+} -+ -+static int yaffs_mtd_check_bad(struct yaffs_dev *dev, int block_no) -+{ -+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); -+ int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk; -+ int retval; -+ -+ yaffs_trace(YAFFS_TRACE_MTD, "checking block %d bad", block_no); -+ -+ retval = mtd_block_isbad(mtd, (loff_t) blocksize * block_no); -+ return (retval) ? YAFFS_FAIL : YAFFS_OK; -+} -+ -+static int yaffs_mtd_initialise(struct yaffs_dev *dev) -+{ -+ return YAFFS_OK; -+} -+ -+static int yaffs_mtd_deinitialise(struct yaffs_dev *dev) -+{ -+ return YAFFS_OK; -+} -+ -+ -+void yaffs_mtd_drv_install(struct yaffs_dev *dev) -+{ -+ struct yaffs_driver *drv = &dev->drv; -+ -+ drv->drv_write_chunk_fn = yaffs_mtd_write; -+ drv->drv_read_chunk_fn = yaffs_mtd_read; -+ drv->drv_erase_fn = yaffs_mtd_erase; -+ drv->drv_mark_bad_fn = yaffs_mtd_mark_bad; -+ drv->drv_check_bad_fn = yaffs_mtd_check_bad; -+ drv->drv_initialise_fn = yaffs_mtd_initialise; -+ drv->drv_deinitialise_fn = yaffs_mtd_deinitialise; -+} -+ -+ -+struct mtd_info * yaffs_get_mtd_device(dev_t sdev) -+{ -+ struct mtd_info *mtd; -+ -+ mtd = yaffs_get_mtd_device(sdev); -+ -+ /* Check it's an mtd device..... */ -+ if (MAJOR(sdev) != MTD_BLOCK_MAJOR) -+ return NULL; /* This isn't an mtd device */ -+ -+ /* Check it's NAND */ -+ if (mtd->type != MTD_NANDFLASH) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs: MTD device is not NAND it's type %d", -+ mtd->type); -+ return NULL; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_OS, " %s %d", WRITE_SIZE_STR, WRITE_SIZE(mtd)); -+ yaffs_trace(YAFFS_TRACE_OS, " oobsize %d", mtd->oobsize); -+ yaffs_trace(YAFFS_TRACE_OS, " erasesize %d", mtd->erasesize); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) -+ yaffs_trace(YAFFS_TRACE_OS, " size %u", mtd->size); -+#else -+ yaffs_trace(YAFFS_TRACE_OS, " size %lld", mtd->size); -+#endif -+ -+ return mtd; -+} -+ -+int yaffs_verify_mtd(struct mtd_info *mtd, int yaffs_version, int inband_tags) -+{ -+ if (yaffs_version == 2) { -+ if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE || -+ mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) && -+ !inband_tags) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "MTD device does not have the right page sizes" -+ ); -+ return -1; -+ } -+ } else { -+ if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK || -+ mtd->oobsize != YAFFS_BYTES_PER_SPARE) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "MTD device does not support have the right page sizes" -+ ); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+ -+void yaffs_put_mtd_device(struct mtd_info *mtd) -+{ -+ if(mtd) -+ put_mtd_device(mtd); -+} ---- linux-4.9.37/fs/yaffs2/yaffs_mtdif.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_mtdif.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,25 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_MTDIF_H__ -+#define __YAFFS_MTDIF_H__ -+ -+#include "yaffs_guts.h" -+ -+void yaffs_mtd_drv_install(struct yaffs_dev *dev); -+struct mtd_info * yaffs_get_mtd_device(dev_t sdev); -+void yaffs_put_mtd_device(struct mtd_info *mtd); -+int yaffs_verify_mtd(struct mtd_info *mtd, int yaffs_version, int inband_tags); -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_nameval.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_nameval.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,230 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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. -+ */ -+ -+/* -+ * This simple implementation of a name-value store assumes a small number of -+* values and fits into a small finite buffer. -+ * -+ * Each attribute is stored as a record: -+ * sizeof(size) bytes record size. -+ * strnlen+1 bytes name null terminated. -+ * nbytes value. -+ * ---------- -+ * total size stored in record size -+ * -+ * This code has not been tested with unicode yet. -+ */ -+ -+#include "yaffs_nameval.h" -+#include "yaffs_guts.h" -+#include "yportenv.h" -+#include "yaffs_endian.h" -+ -+static int nval_find(struct yaffs_dev *dev, -+ const char *xb, int xb_size, const YCHAR *name, -+ int *exist_size) -+{ -+ int pos = 0; -+ s32 size; -+ -+ memcpy(&size, xb, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ -+ while (size > 0 && (size < xb_size) && (pos + size < xb_size)) { -+ if (!strncmp((YCHAR *) (xb + pos + sizeof(size)), -+ name, size)) { -+ if (exist_size) -+ *exist_size = size; -+ return pos; -+ } -+ pos += size; -+ if (pos < (int)(xb_size - sizeof(size))) { -+ memcpy(&size, xb + pos, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ -+ } else -+ size = 0; -+ } -+ if (exist_size) -+ *exist_size = 0; -+ return -ENODATA; -+} -+ -+static int nval_used(struct yaffs_dev *dev, const char *xb, int xb_size) -+{ -+ int pos = 0; -+ s32 size; -+ -+ memcpy(&size, xb + pos, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ -+ while (size > 0 && (size < xb_size) && (pos + size < xb_size)) { -+ pos += size; -+ if (pos < (int)(xb_size - sizeof(size))) { -+ memcpy(&size, xb + pos, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ } else -+ size = 0; -+ } -+ return pos; -+} -+ -+int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR *name) -+{ -+ int pos = nval_find(dev, xb, xb_size, name, NULL); -+ s32 size; -+ -+ if (pos < 0 || pos >= xb_size) -+ return -ENODATA; -+ -+ /* Find size, shift rest over this record, -+ * then zero out the rest of buffer */ -+ memcpy(&size, xb + pos, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ -+ memcpy(xb + pos, xb + pos + size, xb_size - (pos + size)); -+ memset(xb + (xb_size - size), 0, size); -+ return 0; -+} -+ -+int nval_set(struct yaffs_dev *dev, -+ char *xb, int xb_size, const YCHAR *name, const char *buf, -+ int bsize, int flags) -+{ -+ int pos; -+ int namelen = strnlen(name, xb_size); -+ int size_exist = 0; -+ int space; -+ int start; -+ s32 reclen; -+ s32 reclen_endianised; -+ -+ pos = nval_find(dev, xb, xb_size, name, &size_exist); -+ -+ if (flags & XATTR_CREATE && pos >= 0) -+ return -EEXIST; -+ if (flags & XATTR_REPLACE && pos < 0) -+ return -ENODATA; -+ -+ start = nval_used(dev, xb, xb_size); -+ space = xb_size - start + size_exist; -+ -+ reclen = (sizeof(reclen) + namelen + 1 + bsize); -+ -+ if (reclen > space) -+ return -ENOSPC; -+ -+ if (pos >= 0) { -+ /* Exists, so delete it. */ -+ nval_del(dev, xb, xb_size, name); -+ start = nval_used(dev, xb, xb_size); -+ } -+ -+ pos = start; -+ -+ reclen_endianised = reclen; -+ yaffs_do_endian_s32(dev, &reclen_endianised); -+ memcpy(xb + pos, &reclen_endianised, sizeof(reclen_endianised)); -+ pos += sizeof(reclen_endianised); -+ strncpy((YCHAR *) (xb + pos), name, reclen); -+ pos += (namelen + 1); -+ memcpy(xb + pos, buf, bsize); -+ return 0; -+} -+ -+int nval_get(struct yaffs_dev *dev, -+ const char *xb, int xb_size, const YCHAR * name, char *buf, -+ int bsize) -+{ -+ int pos = nval_find(dev, xb, xb_size, name, NULL); -+ s32 size; -+ -+ if (pos >= 0 && pos < xb_size) { -+ -+ memcpy(&size, xb + pos, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ pos += sizeof(size); /* advance past record length */ -+ size -= sizeof(size); -+ -+ /* Advance over name string */ -+ while (xb[pos] && size > 0 && pos < xb_size) { -+ pos++; -+ size--; -+ } -+ /*Advance over NUL */ -+ pos++; -+ size--; -+ -+ /* If bsize is zero then this is a size query. -+ * Return the size, but don't copy. -+ */ -+ if (!bsize) -+ return size; -+ -+ if (size <= bsize) { -+ memcpy(buf, xb + pos, size); -+ return size; -+ } -+ } -+ if (pos >= 0) -+ return -ERANGE; -+ -+ return -ENODATA; -+} -+ -+int nval_list(struct yaffs_dev *dev, const char *xb, int xb_size, char *buf, int bsize) -+{ -+ int pos = 0; -+ s32 size; -+ int name_len; -+ int ncopied = 0; -+ int filled = 0; -+ -+ memcpy(&size, xb + pos, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ -+ while (size > (int)(sizeof(size)) && -+ size <= xb_size && -+ (pos + size) < xb_size && -+ !filled) { -+ pos += sizeof(size); -+ size -= sizeof(size); -+ name_len = strnlen((YCHAR *) (xb + pos), size); -+ if (ncopied + name_len + 1 < bsize) { -+ memcpy(buf, xb + pos, name_len * sizeof(YCHAR)); -+ buf += name_len; -+ *buf = '\0'; -+ buf++; -+ if (sizeof(YCHAR) > 1) { -+ *buf = '\0'; -+ buf++; -+ } -+ ncopied += (name_len + 1); -+ } else { -+ filled = 1; -+ } -+ pos += size; -+ if (pos < (int)(xb_size - sizeof(size))) { -+ memcpy(&size, xb + pos, sizeof(size)); -+ yaffs_do_endian_s32(dev, &size); -+ } -+ else -+ size = 0; -+ } -+ return ncopied; -+} -+ -+int nval_hasvalues(struct yaffs_dev *dev, const char *xb, int xb_size) -+{ -+ return nval_used(dev, xb, xb_size) > 0; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_nameval.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_nameval.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,33 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __NAMEVAL_H__ -+#define __NAMEVAL_H__ -+ -+#include "yportenv.h" -+ -+struct yaffs_dev; -+ -+int nval_del(struct yaffs_dev *dev, char *xb, int xb_size, const YCHAR * name); -+int nval_set(struct yaffs_dev *dev, -+ char *xb, int xb_size, const YCHAR * name, const char *buf, -+ int bsize, int flags); -+int nval_get(struct yaffs_dev *dev, -+ const char *xb, int xb_size, const YCHAR * name, char *buf, -+ int bsize); -+int nval_list(struct yaffs_dev *dev, -+ const char *xb, int xb_size, char *buf, int bsize); -+int nval_hasvalues(struct yaffs_dev *dev, const char *xb, int xb_size); -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_nand.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_nand.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,122 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_nand.h" -+#include "yaffs_tagscompat.h" -+ -+#include "yaffs_getblockinfo.h" -+#include "yaffs_summary.h" -+ -+static int apply_chunk_offset(struct yaffs_dev *dev, int chunk) -+{ -+ return chunk - dev->chunk_offset; -+} -+ -+int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, -+ u8 *buffer, struct yaffs_ext_tags *tags) -+{ -+ int result; -+ struct yaffs_ext_tags local_tags; -+ int flash_chunk = apply_chunk_offset(dev, nand_chunk); -+ -+ dev->n_page_reads++; -+ -+ /* If there are no tags provided use local tags. */ -+ if (!tags) -+ tags = &local_tags; -+ -+ result = dev->tagger.read_chunk_tags_fn(dev, flash_chunk, buffer, tags); -+ if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) { -+ -+ struct yaffs_block_info *bi; -+ bi = yaffs_get_block_info(dev, -+ nand_chunk / -+ dev->param.chunks_per_block); -+ yaffs_handle_chunk_error(dev, bi); -+ } -+ return result; -+} -+ -+int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, -+ int nand_chunk, -+ const u8 *buffer, struct yaffs_ext_tags *tags) -+{ -+ int result; -+ int flash_chunk = apply_chunk_offset(dev, nand_chunk); -+ -+ dev->n_page_writes++; -+ -+ if (!tags) { -+ yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags"); -+ BUG(); -+ return YAFFS_FAIL; -+ } -+ -+ tags->seq_number = dev->seq_number; -+ tags->chunk_used = 1; -+ yaffs_trace(YAFFS_TRACE_WRITE, -+ "Writing chunk %d tags %d %d", -+ nand_chunk, tags->obj_id, tags->chunk_id); -+ -+ result = dev->tagger.write_chunk_tags_fn(dev, flash_chunk, -+ buffer, tags); -+ -+ yaffs_summary_add(dev, tags, nand_chunk); -+ -+ return result; -+} -+ -+int yaffs_mark_bad(struct yaffs_dev *dev, int block_no) -+{ -+ block_no -= dev->block_offset; -+ dev->n_bad_markings++; -+ -+ if (dev->param.disable_bad_block_marking) -+ return YAFFS_OK; -+ -+ return dev->tagger.mark_bad_fn(dev, block_no); -+} -+ -+ -+int yaffs_query_init_block_state(struct yaffs_dev *dev, -+ int block_no, -+ enum yaffs_block_state *state, -+ u32 *seq_number) -+{ -+ block_no -= dev->block_offset; -+ return dev->tagger.query_block_fn(dev, block_no, state, seq_number); -+} -+ -+int yaffs_erase_block(struct yaffs_dev *dev, int block_no) -+{ -+ int result; -+ -+ block_no -= dev->block_offset; -+ dev->n_erasures++; -+ result = dev->drv.drv_erase_fn(dev, block_no); -+ return result; -+} -+ -+int yaffs_init_nand(struct yaffs_dev *dev) -+{ -+ if (dev->drv.drv_initialise_fn) -+ return dev->drv.drv_initialise_fn(dev); -+ return YAFFS_OK; -+} -+ -+int yaffs_deinit_nand(struct yaffs_dev *dev) -+{ -+ if (dev->drv.drv_deinitialise_fn) -+ return dev->drv.drv_deinitialise_fn(dev); -+ return YAFFS_OK; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_nand.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_nand.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,39 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_NAND_H__ -+#define __YAFFS_NAND_H__ -+#include "yaffs_guts.h" -+ -+int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk, -+ u8 *buffer, struct yaffs_ext_tags *tags); -+ -+int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev, -+ int nand_chunk, -+ const u8 *buffer, struct yaffs_ext_tags *tags); -+ -+int yaffs_mark_bad(struct yaffs_dev *dev, int block_no); -+ -+int yaffs_query_init_block_state(struct yaffs_dev *dev, -+ int block_no, -+ enum yaffs_block_state *state, -+ unsigned *seq_number); -+ -+int yaffs_erase_block(struct yaffs_dev *dev, int flash_block); -+ -+int yaffs_init_nand(struct yaffs_dev *dev); -+int yaffs_deinit_nand(struct yaffs_dev *dev); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_packedtags1.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_packedtags1.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,55 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_packedtags1.h" -+#include "yportenv.h" -+ -+static const u8 all_ff[20] = { -+ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff -+}; -+ -+void yaffs_pack_tags1(struct yaffs_packed_tags1 *pt, -+ const struct yaffs_ext_tags *t) -+{ -+ pt->chunk_id = t->chunk_id; -+ pt->serial_number = t->serial_number; -+ pt->n_bytes = t->n_bytes; -+ pt->obj_id = t->obj_id; -+ pt->ecc = 0; -+ pt->deleted = (t->is_deleted) ? 0 : 1; -+ pt->unused_stuff = 0; -+ pt->should_be_ff = 0xffffffff; -+} -+ -+void yaffs_unpack_tags1(struct yaffs_ext_tags *t, -+ const struct yaffs_packed_tags1 *pt) -+{ -+ if (memcmp(all_ff, pt, sizeof(struct yaffs_packed_tags1))) { -+ t->block_bad = 0; -+ if (pt->should_be_ff != 0xffffffff) -+ t->block_bad = 1; -+ t->chunk_used = 1; -+ t->obj_id = pt->obj_id; -+ t->chunk_id = pt->chunk_id; -+ t->n_bytes = pt->n_bytes; -+ t->ecc_result = YAFFS_ECC_RESULT_NO_ERROR; -+ t->is_deleted = (pt->deleted) ? 0 : 1; -+ t->serial_number = pt->serial_number; -+ } else { -+ memset(t, 0, sizeof(struct yaffs_ext_tags)); -+ } -+} ---- linux-4.9.37/fs/yaffs2/yaffs_packedtags1.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_packedtags1.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,39 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+/* This is used to pack YAFFS1 tags, not YAFFS2 tags. */ -+ -+#ifndef __YAFFS_PACKEDTAGS1_H__ -+#define __YAFFS_PACKEDTAGS1_H__ -+ -+#include "yaffs_guts.h" -+ -+struct yaffs_packed_tags1 { -+ u32 chunk_id:20; -+ u32 serial_number:2; -+ u32 n_bytes:10; -+ u32 obj_id:18; -+ u32 ecc:12; -+ u32 deleted:1; -+ u32 unused_stuff:1; -+ unsigned should_be_ff; -+ -+}; -+ -+void yaffs_pack_tags1(struct yaffs_packed_tags1 *pt, -+ const struct yaffs_ext_tags *t); -+void yaffs_unpack_tags1(struct yaffs_ext_tags *t, -+ const struct yaffs_packed_tags1 *pt); -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_packedtags2.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_packedtags2.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,208 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_packedtags2.h" -+#include "yportenv.h" -+#include "yaffs_trace.h" -+#include "yaffs_endian.h" -+ -+/* This code packs a set of extended tags into a binary structure for -+ * NAND storage -+ */ -+ -+/* Some of the information is "extra" struff which can be packed in to -+ * speed scanning -+ * This is defined by having the EXTRA_HEADER_INFO_FLAG set. -+ */ -+ -+/* Extra flags applied to chunk_id */ -+ -+#define EXTRA_HEADER_INFO_FLAG 0x80000000 -+#define EXTRA_SHRINK_FLAG 0x40000000 -+#define EXTRA_SHADOWS_FLAG 0x20000000 -+#define EXTRA_SPARE_FLAGS 0x10000000 -+ -+#define ALL_EXTRA_FLAGS 0xf0000000 -+ -+/* Also, the top 4 bits of the object Id are set to the object type. */ -+#define EXTRA_OBJECT_TYPE_SHIFT (28) -+#define EXTRA_OBJECT_TYPE_MASK ((0x0f) << EXTRA_OBJECT_TYPE_SHIFT) -+ -+static void yaffs_dump_packed_tags2_tags_only( -+ const struct yaffs_packed_tags2_tags_only *ptt) -+{ -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "packed tags obj %d chunk %d byte %d seq %d", -+ ptt->obj_id, ptt->chunk_id, ptt->n_bytes, ptt->seq_number); -+} -+ -+static void yaffs_dump_packed_tags2(const struct yaffs_packed_tags2 *pt) -+{ -+ yaffs_dump_packed_tags2_tags_only(&pt->t); -+} -+ -+static void yaffs_dump_tags2(const struct yaffs_ext_tags *t) -+{ -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d", -+ t->ecc_result, t->block_bad, t->chunk_used, t->obj_id, -+ t->chunk_id, t->n_bytes, t->is_deleted, t->serial_number, -+ t->seq_number); -+ -+} -+ -+static int yaffs_check_tags_extra_packable(const struct yaffs_ext_tags *t) -+{ -+ if (t->chunk_id != 0 || !t->extra_available) -+ return 0; -+ -+ /* Check if the file size is too long to store */ -+ if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE && -+ (t->extra_file_size >> 31) != 0) -+ return 0; -+ return 1; -+} -+ -+void yaffs_pack_tags2_tags_only(struct yaffs_dev *dev, -+ struct yaffs_packed_tags2_tags_only *ptt, -+ const struct yaffs_ext_tags *t) -+{ -+ ptt->chunk_id = t->chunk_id; -+ ptt->seq_number = t->seq_number; -+ ptt->n_bytes = t->n_bytes; -+ ptt->obj_id = t->obj_id; -+ -+ /* Only store extra tags for object headers. -+ * If it is a file then only store if the file size is short\ -+ * enough to fit. -+ */ -+ if (yaffs_check_tags_extra_packable(t)) { -+ /* Store the extra header info instead */ -+ /* We save the parent object in the chunk_id */ -+ ptt->chunk_id = EXTRA_HEADER_INFO_FLAG | t->extra_parent_id; -+ if (t->extra_is_shrink) -+ ptt->chunk_id |= EXTRA_SHRINK_FLAG; -+ if (t->extra_shadows) -+ ptt->chunk_id |= EXTRA_SHADOWS_FLAG; -+ -+ ptt->obj_id &= ~EXTRA_OBJECT_TYPE_MASK; -+ ptt->obj_id |= (t->extra_obj_type << EXTRA_OBJECT_TYPE_SHIFT); -+ -+ if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK) -+ ptt->n_bytes = t->extra_equiv_id; -+ else if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE) -+ ptt->n_bytes = (unsigned) t->extra_file_size; -+ else -+ ptt->n_bytes = 0; -+ } -+ -+ yaffs_dump_packed_tags2_tags_only(ptt); -+ yaffs_dump_tags2(t); -+ yaffs_do_endian_packed_tags2(dev, ptt); -+} -+ -+void yaffs_pack_tags2(struct yaffs_dev *dev, -+ struct yaffs_packed_tags2 *pt, -+ const struct yaffs_ext_tags *t, int tags_ecc) -+{ -+ yaffs_pack_tags2_tags_only(dev, &pt->t, t); -+ -+ if (tags_ecc) -+ yaffs_ecc_calc_other((unsigned char *)&pt->t, -+ sizeof(struct yaffs_packed_tags2_tags_only), -+ &pt->ecc); -+} -+ -+void yaffs_unpack_tags2_tags_only(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *t, -+ struct yaffs_packed_tags2_tags_only *ptt_ptr) -+{ -+ struct yaffs_packed_tags2_tags_only ptt_copy = *ptt_ptr; -+ -+ memset(t, 0, sizeof(struct yaffs_ext_tags)); -+ -+ if (ptt_copy.seq_number == 0xffffffff) -+ return; -+ -+ yaffs_do_endian_packed_tags2(dev, &ptt_copy); -+ -+ t->block_bad = 0; -+ t->chunk_used = 1; -+ t->obj_id = ptt_copy.obj_id; -+ t->chunk_id = ptt_copy.chunk_id; -+ t->n_bytes = ptt_copy.n_bytes; -+ t->is_deleted = 0; -+ t->serial_number = 0; -+ t->seq_number = ptt_copy.seq_number; -+ -+ /* Do extra header info stuff */ -+ if (ptt_copy.chunk_id & EXTRA_HEADER_INFO_FLAG) { -+ t->chunk_id = 0; -+ t->n_bytes = 0; -+ -+ t->extra_available = 1; -+ t->extra_parent_id = ptt_copy.chunk_id & (~(ALL_EXTRA_FLAGS)); -+ t->extra_is_shrink = ptt_copy.chunk_id & EXTRA_SHRINK_FLAG ? 1 : 0; -+ t->extra_shadows = ptt_copy.chunk_id & EXTRA_SHADOWS_FLAG ? 1 : 0; -+ t->extra_obj_type = ptt_copy.obj_id >> EXTRA_OBJECT_TYPE_SHIFT; -+ t->obj_id &= ~EXTRA_OBJECT_TYPE_MASK; -+ -+ if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK) -+ t->extra_equiv_id = ptt_copy.n_bytes; -+ else -+ t->extra_file_size = ptt_copy.n_bytes; -+ } -+ yaffs_dump_packed_tags2_tags_only(ptt_ptr); -+ yaffs_dump_tags2(t); -+} -+ -+void yaffs_unpack_tags2(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *t, -+ struct yaffs_packed_tags2 *pt, -+ int tags_ecc) -+{ -+ enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_NO_ERROR; -+ -+ if (pt->t.seq_number != 0xffffffff && tags_ecc) { -+ /* Chunk is in use and we need to do ECC */ -+ -+ struct yaffs_ecc_other ecc; -+ int result; -+ yaffs_ecc_calc_other((unsigned char *)&pt->t, -+ sizeof(struct yaffs_packed_tags2_tags_only), -+ &ecc); -+ result = -+ yaffs_ecc_correct_other((unsigned char *)&pt->t, -+ sizeof(struct yaffs_packed_tags2_tags_only), -+ &pt->ecc, &ecc); -+ switch (result) { -+ case 0: -+ ecc_result = YAFFS_ECC_RESULT_NO_ERROR; -+ break; -+ case 1: -+ ecc_result = YAFFS_ECC_RESULT_FIXED; -+ break; -+ case -1: -+ ecc_result = YAFFS_ECC_RESULT_UNFIXED; -+ break; -+ default: -+ ecc_result = YAFFS_ECC_RESULT_UNKNOWN; -+ } -+ } -+ yaffs_unpack_tags2_tags_only(dev, t, &pt->t); -+ -+ t->ecc_result = ecc_result; -+ -+ yaffs_dump_packed_tags2(pt); -+ yaffs_dump_tags2(t); -+} ---- linux-4.9.37/fs/yaffs2/yaffs_packedtags2.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_packedtags2.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,51 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+/* This is used to pack YAFFS2 tags, not YAFFS1tags. */ -+ -+#ifndef __YAFFS_PACKEDTAGS2_H__ -+#define __YAFFS_PACKEDTAGS2_H__ -+ -+#include "yaffs_guts.h" -+#include "yaffs_ecc.h" -+ -+struct yaffs_packed_tags2_tags_only { -+ unsigned seq_number; -+ unsigned obj_id; -+ unsigned chunk_id; -+ unsigned n_bytes; -+}; -+ -+struct yaffs_packed_tags2 { -+ struct yaffs_packed_tags2_tags_only t; -+ struct yaffs_ecc_other ecc; -+}; -+ -+/* Full packed tags with ECC, used for oob tags */ -+void yaffs_pack_tags2(struct yaffs_dev *dev, -+ struct yaffs_packed_tags2 *pt, -+ const struct yaffs_ext_tags *t, int tags_ecc); -+void yaffs_unpack_tags2(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *t, struct yaffs_packed_tags2 *pt, -+ int tags_ecc); -+ -+/* Only the tags part (no ECC for use with inband tags */ -+void yaffs_pack_tags2_tags_only(struct yaffs_dev *dev, -+ struct yaffs_packed_tags2_tags_only *pt, -+ const struct yaffs_ext_tags *t); -+void yaffs_unpack_tags2_tags_only(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *t, -+ struct yaffs_packed_tags2_tags_only *pt); -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_summary.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_summary.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,310 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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. -+ */ -+ -+/* Summaries write the useful part of the tags for the chunks in a block into an -+ * an array which is written to the last n chunks of the block. -+ * Reading the summaries gives all the tags for the block in one read. Much -+ * faster. -+ * -+ * Chunks holding summaries are marked with tags making it look like -+ * they are part of a fake file. -+ * -+ * The summary could also be used during gc. -+ * -+ */ -+ -+#include "yaffs_summary.h" -+#include "yaffs_packedtags2.h" -+#include "yaffs_nand.h" -+#include "yaffs_getblockinfo.h" -+#include "yaffs_bitmap.h" -+ -+/* -+ * The summary is built up in an array of summary tags. -+ * This gets written to the last one or two (maybe more) chunks in a block. -+ * A summary header is written as the first part of each chunk of summary data. -+ * The summary header must match or the summary is rejected. -+ */ -+ -+/* Summary tags don't need the sequence number because that is redundant. */ -+struct yaffs_summary_tags { -+ unsigned obj_id; -+ unsigned chunk_id; -+ unsigned n_bytes; -+}; -+ -+/* Summary header */ -+struct yaffs_summary_header { -+ unsigned version; /* Must match current version */ -+ unsigned block; /* Must be this block */ -+ unsigned seq; /* Must be this sequence number */ -+ unsigned sum; /* Just add up all the bytes in the tags */ -+}; -+ -+ -+static void yaffs_summary_clear(struct yaffs_dev *dev) -+{ -+ if (!dev->sum_tags) -+ return; -+ memset(dev->sum_tags, 0, dev->chunks_per_summary * -+ sizeof(struct yaffs_summary_tags)); -+} -+ -+ -+void yaffs_summary_deinit(struct yaffs_dev *dev) -+{ -+ kfree(dev->sum_tags); -+ dev->sum_tags = NULL; -+ kfree(dev->gc_sum_tags); -+ dev->gc_sum_tags = NULL; -+ dev->chunks_per_summary = 0; -+} -+ -+int yaffs_summary_init(struct yaffs_dev *dev) -+{ -+ int sum_bytes; -+ int chunks_used; /* Number of chunks used by summary */ -+ int sum_tags_bytes; -+ -+ sum_bytes = dev->param.chunks_per_block * -+ sizeof(struct yaffs_summary_tags); -+ -+ chunks_used = (sum_bytes + dev->data_bytes_per_chunk - 1)/ -+ (dev->data_bytes_per_chunk - -+ sizeof(struct yaffs_summary_header)); -+ -+ dev->chunks_per_summary = dev->param.chunks_per_block - chunks_used; -+ sum_tags_bytes = sizeof(struct yaffs_summary_tags) * -+ dev->chunks_per_summary; -+ dev->sum_tags = kmalloc(sum_tags_bytes, GFP_NOFS); -+ dev->gc_sum_tags = kmalloc(sum_tags_bytes, GFP_NOFS); -+ if (!dev->sum_tags || !dev->gc_sum_tags) { -+ yaffs_summary_deinit(dev); -+ return YAFFS_FAIL; -+ } -+ -+ yaffs_summary_clear(dev); -+ -+ return YAFFS_OK; -+} -+ -+static unsigned yaffs_summary_sum(struct yaffs_dev *dev) -+{ -+ u8 *sum_buffer = (u8 *)dev->sum_tags; -+ int i; -+ unsigned sum = 0; -+ -+ i = sizeof(struct yaffs_summary_tags) * -+ dev->chunks_per_summary; -+ while (i > 0) { -+ sum += *sum_buffer; -+ sum_buffer++; -+ i--; -+ } -+ -+ return sum; -+} -+ -+static int yaffs_summary_write(struct yaffs_dev *dev, int blk) -+{ -+ struct yaffs_ext_tags tags; -+ u8 *buffer; -+ u8 *sum_buffer = (u8 *)dev->sum_tags; -+ int n_bytes; -+ int chunk_in_nand; -+ int chunk_in_block; -+ int result; -+ int this_tx; -+ struct yaffs_summary_header hdr; -+ int sum_bytes_per_chunk = dev->data_bytes_per_chunk - sizeof(hdr); -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk); -+ -+ buffer = yaffs_get_temp_buffer(dev); -+ n_bytes = sizeof(struct yaffs_summary_tags) * -+ dev->chunks_per_summary; -+ memset(&tags, 0, sizeof(struct yaffs_ext_tags)); -+ tags.obj_id = YAFFS_OBJECTID_SUMMARY; -+ tags.chunk_id = 1; -+ chunk_in_block = dev->chunks_per_summary; -+ chunk_in_nand = dev->alloc_block * dev->param.chunks_per_block + -+ dev->chunks_per_summary; -+ hdr.version = YAFFS_SUMMARY_VERSION; -+ hdr.block = blk; -+ hdr.seq = bi->seq_number; -+ hdr.sum = yaffs_summary_sum(dev); -+ -+ do { -+ this_tx = n_bytes; -+ if (this_tx > sum_bytes_per_chunk) -+ this_tx = sum_bytes_per_chunk; -+ memcpy(buffer, &hdr, sizeof(hdr)); -+ memcpy(buffer + sizeof(hdr), sum_buffer, this_tx); -+ tags.n_bytes = this_tx + sizeof(hdr); -+ result = yaffs_wr_chunk_tags_nand(dev, chunk_in_nand, -+ buffer, &tags); -+ -+ if (result != YAFFS_OK) -+ break; -+ yaffs_set_chunk_bit(dev, blk, chunk_in_block); -+ bi->pages_in_use++; -+ dev->n_free_chunks--; -+ -+ n_bytes -= this_tx; -+ sum_buffer += this_tx; -+ chunk_in_nand++; -+ chunk_in_block++; -+ tags.chunk_id++; -+ } while (result == YAFFS_OK && n_bytes > 0); -+ yaffs_release_temp_buffer(dev, buffer); -+ -+ -+ if (result == YAFFS_OK) -+ bi->has_summary = 1; -+ -+ -+ return result; -+} -+ -+int yaffs_summary_read(struct yaffs_dev *dev, -+ struct yaffs_summary_tags *st, -+ int blk) -+{ -+ struct yaffs_ext_tags tags; -+ u8 *buffer; -+ u8 *sum_buffer = (u8 *)st; -+ int n_bytes; -+ u32 chunk_id; -+ int chunk_in_nand; -+ int chunk_in_block; -+ int result; -+ int this_tx; -+ struct yaffs_summary_header hdr; -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk); -+ int sum_bytes_per_chunk = dev->data_bytes_per_chunk - sizeof(hdr); -+ -+ buffer = yaffs_get_temp_buffer(dev); -+ n_bytes = sizeof(struct yaffs_summary_tags) * dev->chunks_per_summary; -+ chunk_in_block = dev->chunks_per_summary; -+ chunk_in_nand = blk * dev->param.chunks_per_block + -+ dev->chunks_per_summary; -+ chunk_id = 1; -+ do { -+ this_tx = n_bytes; -+ if (this_tx > sum_bytes_per_chunk) -+ this_tx = sum_bytes_per_chunk; -+ result = yaffs_rd_chunk_tags_nand(dev, chunk_in_nand, -+ buffer, &tags); -+ -+ if (tags.chunk_id != chunk_id || -+ tags.obj_id != YAFFS_OBJECTID_SUMMARY || -+ tags.chunk_used == 0 || -+ tags.ecc_result > YAFFS_ECC_RESULT_FIXED || -+ tags.n_bytes != (this_tx + sizeof(hdr))) -+ result = YAFFS_FAIL; -+ if (result != YAFFS_OK) -+ break; -+ -+ if (st == dev->sum_tags) { -+ /* If we're scanning then update the block info */ -+ yaffs_set_chunk_bit(dev, blk, chunk_in_block); -+ bi->pages_in_use++; -+ } -+ memcpy(&hdr, buffer, sizeof(hdr)); -+ memcpy(sum_buffer, buffer + sizeof(hdr), this_tx); -+ n_bytes -= this_tx; -+ sum_buffer += this_tx; -+ chunk_in_nand++; -+ chunk_in_block++; -+ chunk_id++; -+ } while (result == YAFFS_OK && n_bytes > 0); -+ yaffs_release_temp_buffer(dev, buffer); -+ -+ if (result == YAFFS_OK) { -+ /* Verify header */ -+ if (hdr.version != YAFFS_SUMMARY_VERSION || -+ hdr.seq != bi->seq_number || -+ hdr.sum != yaffs_summary_sum(dev)) -+ result = YAFFS_FAIL; -+ } -+ -+ if (st == dev->sum_tags && result == YAFFS_OK) -+ bi->has_summary = 1; -+ -+ return result; -+} -+ -+int yaffs_summary_add(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *tags, -+ int chunk_in_nand) -+{ -+ struct yaffs_packed_tags2_tags_only tags_only; -+ struct yaffs_summary_tags *sum_tags; -+ int block_in_nand = chunk_in_nand / dev->param.chunks_per_block; -+ int chunk_in_block = chunk_in_nand % dev->param.chunks_per_block; -+ -+ if (!dev->sum_tags) -+ return YAFFS_OK; -+ -+ if (chunk_in_block >= 0 && chunk_in_block < dev->chunks_per_summary) { -+ yaffs_pack_tags2_tags_only(dev, &tags_only, tags); -+ sum_tags = &dev->sum_tags[chunk_in_block]; -+ -+ sum_tags->chunk_id = tags_only.chunk_id; -+ sum_tags->n_bytes = tags_only.n_bytes; -+ sum_tags->obj_id = tags_only.obj_id; -+ -+ if (chunk_in_block == dev->chunks_per_summary - 1) { -+ /* Time to write out the summary */ -+ yaffs_summary_write(dev, block_in_nand); -+ yaffs_summary_clear(dev); -+ yaffs_skip_rest_of_block(dev); -+ } -+ } -+ return YAFFS_OK; -+} -+ -+int yaffs_summary_fetch(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *tags, -+ int chunk_in_block) -+{ -+ struct yaffs_packed_tags2_tags_only tags_only; -+ struct yaffs_summary_tags *sum_tags; -+ if (chunk_in_block >= 0 && chunk_in_block < dev->chunks_per_summary) { -+ sum_tags = &dev->sum_tags[chunk_in_block]; -+ tags_only.chunk_id = sum_tags->chunk_id; -+ tags_only.n_bytes = sum_tags->n_bytes; -+ tags_only.obj_id = sum_tags->obj_id; -+ yaffs_unpack_tags2_tags_only(dev, tags, &tags_only); -+ return YAFFS_OK; -+ } -+ return YAFFS_FAIL; -+} -+ -+void yaffs_summary_gc(struct yaffs_dev *dev, int blk) -+{ -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, blk); -+ u32 i; -+ -+ if (!bi->has_summary) -+ return; -+ -+ for (i = dev->chunks_per_summary; -+ i < dev->param.chunks_per_block; -+ i++) { -+ if (yaffs_check_chunk_bit(dev, blk, i)) { -+ yaffs_clear_chunk_bit(dev, blk, i); -+ bi->pages_in_use--; -+ dev->n_free_chunks++; -+ } -+ } -+} ---- linux-4.9.37/fs/yaffs2/yaffs_summary.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_summary.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,37 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_SUMMARY_H__ -+#define __YAFFS_SUMMARY_H__ -+ -+#include "yaffs_packedtags2.h" -+ -+ -+int yaffs_summary_init(struct yaffs_dev *dev); -+void yaffs_summary_deinit(struct yaffs_dev *dev); -+ -+int yaffs_summary_add(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *tags, -+ int chunk_in_block); -+int yaffs_summary_fetch(struct yaffs_dev *dev, -+ struct yaffs_ext_tags *tags, -+ int chunk_in_block); -+int yaffs_summary_read(struct yaffs_dev *dev, -+ struct yaffs_summary_tags *st, -+ int blk); -+void yaffs_summary_gc(struct yaffs_dev *dev, int blk); -+ -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_tagscompat.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_tagscompat.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,400 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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. -+ * -+ * This file handles yaffs1-style tags to allow compatibility with Yaffs1 style -+ * flash layouts. -+ */ -+ -+#include "yaffs_guts.h" -+#include "yaffs_tagscompat.h" -+#include "yaffs_ecc.h" -+#include "yaffs_getblockinfo.h" -+#include "yaffs_trace.h" -+#include "yaffs_endian.h" -+ -+static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk); -+ -+ -+/********** Tags ECC calculations *********/ -+ -+void yaffs_calc_tags_ecc(struct yaffs_tags *tags) -+{ -+ /* Calculate an ecc */ -+ unsigned char *b = ((union yaffs_tags_union *)tags)->as_bytes; -+ unsigned i, j; -+ unsigned ecc = 0; -+ unsigned bit = 0; -+ -+ tags->ecc = 0; -+ -+ for (i = 0; i < 8; i++) { -+ for (j = 1; j & 0xff; j <<= 1) { -+ bit++; -+ if (b[i] & j) -+ ecc ^= bit; -+ } -+ } -+ tags->ecc = ecc; -+} -+ -+int yaffs_check_tags_ecc(struct yaffs_tags *tags) -+{ -+ unsigned ecc = tags->ecc; -+ -+ yaffs_calc_tags_ecc(tags); -+ -+ ecc ^= tags->ecc; -+ -+ if (ecc && ecc <= 64) { -+ /* TODO: Handle the failure better. Retire? */ -+ unsigned char *b = ((union yaffs_tags_union *)tags)->as_bytes; -+ -+ ecc--; -+ -+ b[ecc / 8] ^= (1 << (ecc & 7)); -+ -+ /* Now recvalc the ecc */ -+ yaffs_calc_tags_ecc(tags); -+ -+ return 1; /* recovered error */ -+ } else if (ecc) { -+ /* Wierd ecc failure value */ -+ /* TODO Need to do somethiong here */ -+ return -1; /* unrecovered error */ -+ } -+ return 0; -+} -+ -+/********** Tags **********/ -+ -+/* -+ * During tags storing/retireval we use a copy of the tags so that -+ * we can modify the endian etc without damaging the previous structure. -+ */ -+static void yaffs_load_tags_to_spare(struct yaffs_dev *dev, -+ struct yaffs_spare *spare_ptr, -+ struct yaffs_tags *tags_ptr) -+{ -+ union yaffs_tags_union *tu_ptr = (union yaffs_tags_union *)tags_ptr; -+ union yaffs_tags_union tags_stored = *tu_ptr; -+ -+ yaffs_calc_tags_ecc(&tags_stored.as_tags); -+ -+ yaffs_do_endian_u32(dev, &tags_stored.as_u32[0]); -+ yaffs_do_endian_u32(dev, &tags_stored.as_u32[1]); -+ -+ spare_ptr->tb0 = tags_stored.as_bytes[0]; -+ spare_ptr->tb1 = tags_stored.as_bytes[1]; -+ spare_ptr->tb2 = tags_stored.as_bytes[2]; -+ spare_ptr->tb3 = tags_stored.as_bytes[3]; -+ spare_ptr->tb4 = tags_stored.as_bytes[4]; -+ spare_ptr->tb5 = tags_stored.as_bytes[5]; -+ spare_ptr->tb6 = tags_stored.as_bytes[6]; -+ spare_ptr->tb7 = tags_stored.as_bytes[7]; -+} -+ -+static void yaffs_get_tags_from_spare(struct yaffs_dev *dev, -+ struct yaffs_spare *spare_ptr, -+ struct yaffs_tags *tags_ptr) -+{ -+ union yaffs_tags_union *tu = (union yaffs_tags_union *)tags_ptr; -+ union yaffs_tags_union tags_stored; -+ int result; -+ -+ tags_stored.as_bytes[0] = spare_ptr->tb0; -+ tags_stored.as_bytes[1] = spare_ptr->tb1; -+ tags_stored.as_bytes[2] = spare_ptr->tb2; -+ tags_stored.as_bytes[3] = spare_ptr->tb3; -+ tags_stored.as_bytes[4] = spare_ptr->tb4; -+ tags_stored.as_bytes[5] = spare_ptr->tb5; -+ tags_stored.as_bytes[6] = spare_ptr->tb6; -+ tags_stored.as_bytes[7] = spare_ptr->tb7; -+ -+ yaffs_do_endian_u32(dev, &tags_stored.as_u32[0]); -+ yaffs_do_endian_u32(dev, &tags_stored.as_u32[1]); -+ -+ *tu = tags_stored; -+ -+ result = yaffs_check_tags_ecc(tags_ptr); -+ if (result > 0) -+ dev->n_tags_ecc_fixed++; -+ else if (result < 0) -+ dev->n_tags_ecc_unfixed++; -+} -+ -+static void yaffs_spare_init(struct yaffs_spare *spare) -+{ -+ memset(spare, 0xff, sizeof(struct yaffs_spare)); -+} -+ -+static int yaffs_wr_nand(struct yaffs_dev *dev, -+ int nand_chunk, const u8 *data, -+ struct yaffs_spare *spare) -+{ -+ int data_size = dev->data_bytes_per_chunk; -+ -+ return dev->drv.drv_write_chunk_fn(dev, nand_chunk, -+ data, data_size, -+ (u8 *) spare, sizeof(*spare)); -+} -+ -+static int yaffs_rd_chunk_nand(struct yaffs_dev *dev, -+ int nand_chunk, -+ u8 *data, -+ struct yaffs_spare *spare, -+ enum yaffs_ecc_result *ecc_result, -+ int correct_errors) -+{ -+ int ret_val; -+ struct yaffs_spare local_spare; -+ int data_size; -+ int spare_size; -+ int ecc_result1, ecc_result2; -+ u8 calc_ecc[3]; -+ -+ if (!spare) { -+ /* If we don't have a real spare, then we use a local one. */ -+ /* Need this for the calculation of the ecc */ -+ spare = &local_spare; -+ } -+ data_size = dev->data_bytes_per_chunk; -+ spare_size = sizeof(struct yaffs_spare); -+ -+ if (dev->param.use_nand_ecc) -+ return dev->drv.drv_read_chunk_fn(dev, nand_chunk, -+ data, data_size, -+ (u8 *) spare, spare_size, -+ ecc_result); -+ -+ -+ /* Handle the ECC at this level. */ -+ -+ ret_val = dev->drv.drv_read_chunk_fn(dev, nand_chunk, -+ data, data_size, -+ (u8 *)spare, spare_size, -+ NULL); -+ if (!data || !correct_errors) -+ return ret_val; -+ -+ /* Do ECC correction if needed. */ -+ yaffs_ecc_calc(data, calc_ecc); -+ ecc_result1 = yaffs_ecc_correct(data, spare->ecc1, calc_ecc); -+ yaffs_ecc_calc(&data[256], calc_ecc); -+ ecc_result2 = yaffs_ecc_correct(&data[256], spare->ecc2, calc_ecc); -+ -+ if (ecc_result1 > 0) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "**>>yaffs ecc error fix performed on chunk %d:0", -+ nand_chunk); -+ dev->n_ecc_fixed++; -+ } else if (ecc_result1 < 0) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "**>>yaffs ecc error unfixed on chunk %d:0", -+ nand_chunk); -+ dev->n_ecc_unfixed++; -+ } -+ -+ if (ecc_result2 > 0) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "**>>yaffs ecc error fix performed on chunk %d:1", -+ nand_chunk); -+ dev->n_ecc_fixed++; -+ } else if (ecc_result2 < 0) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "**>>yaffs ecc error unfixed on chunk %d:1", -+ nand_chunk); -+ dev->n_ecc_unfixed++; -+ } -+ -+ if (ecc_result1 || ecc_result2) { -+ /* We had a data problem on this page */ -+ yaffs_handle_rd_data_error(dev, nand_chunk); -+ } -+ -+ if (ecc_result1 < 0 || ecc_result2 < 0) -+ *ecc_result = YAFFS_ECC_RESULT_UNFIXED; -+ else if (ecc_result1 > 0 || ecc_result2 > 0) -+ *ecc_result = YAFFS_ECC_RESULT_FIXED; -+ else -+ *ecc_result = YAFFS_ECC_RESULT_NO_ERROR; -+ -+ return ret_val; -+} -+ -+/* -+ * Functions for robustisizing -+ */ -+ -+static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk) -+{ -+ int flash_block = nand_chunk / dev->param.chunks_per_block; -+ -+ /* Mark the block for retirement */ -+ yaffs_get_block_info(dev, flash_block + dev->block_offset)-> -+ needs_retiring = 1; -+ yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS, -+ "**>>Block %d marked for retirement", -+ flash_block); -+ -+ /* TODO: -+ * Just do a garbage collection on the affected block -+ * then retire the block -+ * NB recursion -+ */ -+} -+ -+static int yaffs_tags_compat_wr(struct yaffs_dev *dev, -+ int nand_chunk, -+ const u8 *data, const struct yaffs_ext_tags *ext_tags) -+{ -+ struct yaffs_spare spare; -+ struct yaffs_tags tags; -+ -+ yaffs_spare_init(&spare); -+ -+ if (ext_tags->is_deleted) -+ spare.page_status = 0; -+ else { -+ tags.obj_id = ext_tags->obj_id; -+ tags.chunk_id = ext_tags->chunk_id; -+ -+ tags.n_bytes_lsb = ext_tags->n_bytes & (1024 - 1); -+ -+ if (dev->data_bytes_per_chunk >= 1024) -+ tags.n_bytes_msb = (ext_tags->n_bytes >> 10) & 3; -+ else -+ tags.n_bytes_msb = 3; -+ -+ tags.serial_number = ext_tags->serial_number; -+ -+ if (!dev->param.use_nand_ecc && data) { -+ yaffs_ecc_calc(data, spare.ecc1); -+ yaffs_ecc_calc(&data[256], spare.ecc2); -+ } -+ -+ yaffs_load_tags_to_spare(dev, &spare, &tags); -+ } -+ return yaffs_wr_nand(dev, nand_chunk, data, &spare); -+} -+ -+static int yaffs_tags_compat_rd(struct yaffs_dev *dev, -+ int nand_chunk, -+ u8 *data, struct yaffs_ext_tags *ext_tags) -+{ -+ struct yaffs_spare spare; -+ struct yaffs_tags tags; -+ enum yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_UNKNOWN; -+ static struct yaffs_spare spare_ff; -+ static int init; -+ int deleted; -+ -+ if (!init) { -+ memset(&spare_ff, 0xff, sizeof(spare_ff)); -+ init = 1; -+ } -+ -+ if (!yaffs_rd_chunk_nand(dev, nand_chunk, -+ data, &spare, &ecc_result, 1)) -+ return YAFFS_FAIL; -+ -+ /* ext_tags may be NULL */ -+ if (!ext_tags) -+ return YAFFS_OK; -+ -+ deleted = (hweight8(spare.page_status) < 7) ? 1 : 0; -+ -+ ext_tags->is_deleted = deleted; -+ ext_tags->ecc_result = ecc_result; -+ ext_tags->block_bad = 0; /* We're reading it */ -+ /* therefore it is not a bad block */ -+ ext_tags->chunk_used = -+ memcmp(&spare_ff, &spare, sizeof(spare_ff)) ? 1 : 0; -+ -+ if (ext_tags->chunk_used) { -+ yaffs_get_tags_from_spare(dev, &spare, &tags); -+ -+ ext_tags->obj_id = tags.obj_id; -+ ext_tags->chunk_id = tags.chunk_id; -+ ext_tags->n_bytes = tags.n_bytes_lsb; -+ -+ if (dev->data_bytes_per_chunk >= 1024) -+ ext_tags->n_bytes |= -+ (((unsigned)tags.n_bytes_msb) << 10); -+ -+ ext_tags->serial_number = tags.serial_number; -+ } -+ -+ return YAFFS_OK; -+} -+ -+static int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block) -+{ -+ struct yaffs_spare spare; -+ -+ memset(&spare, 0xff, sizeof(struct yaffs_spare)); -+ -+ spare.block_status = 'Y'; -+ -+ yaffs_wr_nand(dev, flash_block * dev->param.chunks_per_block, NULL, -+ &spare); -+ yaffs_wr_nand(dev, flash_block * dev->param.chunks_per_block + 1, -+ NULL, &spare); -+ -+ return YAFFS_OK; -+} -+ -+static int yaffs_tags_compat_query_block(struct yaffs_dev *dev, -+ int block_no, -+ enum yaffs_block_state *state, -+ u32 *seq_number) -+{ -+ struct yaffs_spare spare0, spare1; -+ static struct yaffs_spare spare_ff; -+ static int init; -+ enum yaffs_ecc_result dummy; -+ -+ if (!init) { -+ memset(&spare_ff, 0xff, sizeof(spare_ff)); -+ init = 1; -+ } -+ -+ *seq_number = 0; -+ -+ /* Look for bad block markers in the first two chunks */ -+ yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block, -+ NULL, &spare0, &dummy, 0); -+ yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block + 1, -+ NULL, &spare1, &dummy, 0); -+ -+ if (hweight8(spare0.block_status & spare1.block_status) < 7) -+ *state = YAFFS_BLOCK_STATE_DEAD; -+ else if (memcmp(&spare_ff, &spare0, sizeof(spare_ff)) == 0) -+ *state = YAFFS_BLOCK_STATE_EMPTY; -+ else -+ *state = YAFFS_BLOCK_STATE_NEEDS_SCAN; -+ -+ return YAFFS_OK; -+} -+ -+void yaffs_tags_compat_install(struct yaffs_dev *dev) -+{ -+ if(dev->param.is_yaffs2) -+ return; -+ if(!dev->tagger.write_chunk_tags_fn) -+ dev->tagger.write_chunk_tags_fn = yaffs_tags_compat_wr; -+ if(!dev->tagger.read_chunk_tags_fn) -+ dev->tagger.read_chunk_tags_fn = yaffs_tags_compat_rd; -+ if(!dev->tagger.query_block_fn) -+ dev->tagger.query_block_fn = yaffs_tags_compat_query_block; -+ if(!dev->tagger.mark_bad_fn) -+ dev->tagger.mark_bad_fn = yaffs_tags_compat_mark_bad; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_tagscompat.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_tagscompat.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,44 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_TAGSCOMPAT_H__ -+#define __YAFFS_TAGSCOMPAT_H__ -+ -+ -+#include "yaffs_guts.h" -+ -+#if 0 -+ -+ -+int yaffs_tags_compat_wr(struct yaffs_dev *dev, -+ int nand_chunk, -+ const u8 *data, const struct yaffs_ext_tags *tags); -+int yaffs_tags_compat_rd(struct yaffs_dev *dev, -+ int nand_chunk, -+ u8 *data, struct yaffs_ext_tags *tags); -+int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int block_no); -+int yaffs_tags_compat_query_block(struct yaffs_dev *dev, -+ int block_no, -+ enum yaffs_block_state *state, -+ u32 *seq_number); -+ -+#endif -+ -+ -+void yaffs_tags_compat_install(struct yaffs_dev *dev); -+void yaffs_calc_tags_ecc(struct yaffs_tags *tags); -+int yaffs_check_tags_ecc(struct yaffs_tags *tags); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_tagsmarshall.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_tagsmarshall.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,206 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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. -+ * -+ * This file handles the marshalling (ie internal<-->external structure -+ * translation between the internal tags and the stored tags in Yaffs2-style -+ * tags storage. -+ */ -+ -+#include "yaffs_guts.h" -+#include "yaffs_trace.h" -+#include "yaffs_packedtags2.h" -+ -+static int yaffs_tags_marshall_write(struct yaffs_dev *dev, -+ int nand_chunk, const u8 *data, -+ const struct yaffs_ext_tags *tags) -+{ -+ struct yaffs_packed_tags2 pt; -+ int retval; -+ -+ int packed_tags_size = -+ dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt); -+ void *packed_tags_ptr = -+ dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt; -+ -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "yaffs_tags_marshall_write chunk %d data %p tags %p", -+ nand_chunk, data, tags); -+ -+ /* For yaffs2 writing there must be both data and tags. -+ * If we're using inband tags, then the tags are stuffed into -+ * the end of the data buffer. -+ */ -+ if (!data || !tags) -+ BUG(); -+ else if (dev->param.inband_tags) { -+ struct yaffs_packed_tags2_tags_only *pt2tp; -+ pt2tp = -+ (struct yaffs_packed_tags2_tags_only *)(data + -+ dev-> -+ data_bytes_per_chunk); -+ yaffs_pack_tags2_tags_only(dev, pt2tp, tags); -+ } else { -+ yaffs_pack_tags2(dev, &pt, tags, !dev->param.no_tags_ecc); -+ } -+ -+ retval = dev->drv.drv_write_chunk_fn(dev, nand_chunk, -+ data, dev->param.total_bytes_per_chunk, -+ (dev->param.inband_tags) ? NULL : packed_tags_ptr, -+ (dev->param.inband_tags) ? 0 : packed_tags_size); -+ -+ return retval; -+} -+ -+static int yaffs_tags_marshall_read(struct yaffs_dev *dev, -+ int nand_chunk, u8 *data, -+ struct yaffs_ext_tags *tags) -+{ -+ int retval = 0; -+ int local_data = 0; -+ u8 spare_buffer[100]; -+ enum yaffs_ecc_result ecc_result; -+ -+ struct yaffs_packed_tags2 pt; -+ -+ int packed_tags_size = -+ dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt); -+ void *packed_tags_ptr = -+ dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt; -+ -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "yaffs_tags_marshall_read chunk %d data %p tags %p", -+ nand_chunk, data, tags); -+ -+ if (dev->param.inband_tags) { -+ if (!data) { -+ local_data = 1; -+ data = yaffs_get_temp_buffer(dev); -+ } -+ } -+ -+ if (dev->param.inband_tags || (data && !tags)) -+ retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk, -+ data, dev->param.total_bytes_per_chunk, -+ NULL, 0, -+ &ecc_result); -+ else if (tags) -+ retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk, -+ data, dev->param.total_bytes_per_chunk, -+ spare_buffer, packed_tags_size, -+ &ecc_result); -+ else -+ BUG(); -+ -+ -+ if (retval == YAFFS_FAIL) -+ return YAFFS_FAIL; -+ -+ if (dev->param.inband_tags) { -+ if (tags) { -+ struct yaffs_packed_tags2_tags_only *pt2tp; -+ pt2tp = -+ (struct yaffs_packed_tags2_tags_only *) -+ &data[dev->data_bytes_per_chunk]; -+ yaffs_unpack_tags2_tags_only(dev, tags, pt2tp); -+ } -+ } else if (tags) { -+ memcpy(packed_tags_ptr, spare_buffer, packed_tags_size); -+ yaffs_unpack_tags2(dev, tags, &pt, !dev->param.no_tags_ecc); -+ } -+ -+ if (local_data) -+ yaffs_release_temp_buffer(dev, data); -+ -+ if (tags && ecc_result == YAFFS_ECC_RESULT_UNFIXED) { -+ tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED; -+ dev->n_ecc_unfixed++; -+ } -+ -+ if (tags && ecc_result == YAFFS_ECC_RESULT_FIXED) { -+ if (tags->ecc_result <= YAFFS_ECC_RESULT_NO_ERROR) -+ tags->ecc_result = YAFFS_ECC_RESULT_FIXED; -+ dev->n_ecc_fixed++; -+ } -+ -+ if (ecc_result < YAFFS_ECC_RESULT_UNFIXED) -+ return YAFFS_OK; -+ else -+ return YAFFS_FAIL; -+} -+ -+static int yaffs_tags_marshall_query_block(struct yaffs_dev *dev, int block_no, -+ enum yaffs_block_state *state, -+ u32 *seq_number) -+{ -+ int retval; -+ -+ yaffs_trace(YAFFS_TRACE_MTD, "yaffs_tags_marshall_query_block %d", -+ block_no); -+ -+ retval = dev->drv.drv_check_bad_fn(dev, block_no); -+ -+ if (retval== YAFFS_FAIL) { -+ yaffs_trace(YAFFS_TRACE_MTD, "block is bad"); -+ -+ *state = YAFFS_BLOCK_STATE_DEAD; -+ *seq_number = 0; -+ } else { -+ struct yaffs_ext_tags t; -+ -+ yaffs_tags_marshall_read(dev, -+ block_no * dev->param.chunks_per_block, -+ NULL, &t); -+ -+ if (t.chunk_used) { -+ *seq_number = t.seq_number; -+ *state = YAFFS_BLOCK_STATE_NEEDS_SCAN; -+ } else { -+ *seq_number = 0; -+ *state = YAFFS_BLOCK_STATE_EMPTY; -+ } -+ } -+ -+ yaffs_trace(YAFFS_TRACE_MTD, -+ "block query returns seq %d state %d", -+ *seq_number, *state); -+ -+ if (retval == 0) -+ return YAFFS_OK; -+ else -+ return YAFFS_FAIL; -+} -+ -+static int yaffs_tags_marshall_mark_bad(struct yaffs_dev *dev, int block_no) -+{ -+ return dev->drv.drv_mark_bad_fn(dev, block_no); -+ -+} -+ -+ -+void yaffs_tags_marshall_install(struct yaffs_dev *dev) -+{ -+ if (!dev->param.is_yaffs2) -+ return; -+ -+ if (!dev->tagger.write_chunk_tags_fn) -+ dev->tagger.write_chunk_tags_fn = yaffs_tags_marshall_write; -+ -+ if (!dev->tagger.read_chunk_tags_fn) -+ dev->tagger.read_chunk_tags_fn = yaffs_tags_marshall_read; -+ -+ if (!dev->tagger.query_block_fn) -+ dev->tagger.query_block_fn = yaffs_tags_marshall_query_block; -+ -+ if (!dev->tagger.mark_bad_fn) -+ dev->tagger.mark_bad_fn = yaffs_tags_marshall_mark_bad; -+ -+} ---- linux-4.9.37/fs/yaffs2/yaffs_tagsmarshall.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_tagsmarshall.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,22 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_TAGSMARSHALL_H__ -+#define __YAFFS_TAGSMARSHALL_H__ -+ -+#include "yaffs_guts.h" -+void yaffs_tags_marshall_install(struct yaffs_dev *dev); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_trace.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_trace.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,57 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YTRACE_H__ -+#define __YTRACE_H__ -+ -+extern unsigned int yaffs_trace_mask; -+extern unsigned int yaffs_wr_attempts; -+ -+/* -+ * Tracing flags. -+ * The flags masked in YAFFS_TRACE_ALWAYS are always traced. -+ */ -+ -+#define YAFFS_TRACE_OS 0x00000002 -+#define YAFFS_TRACE_ALLOCATE 0x00000004 -+#define YAFFS_TRACE_SCAN 0x00000008 -+#define YAFFS_TRACE_BAD_BLOCKS 0x00000010 -+#define YAFFS_TRACE_ERASE 0x00000020 -+#define YAFFS_TRACE_GC 0x00000040 -+#define YAFFS_TRACE_WRITE 0x00000080 -+#define YAFFS_TRACE_TRACING 0x00000100 -+#define YAFFS_TRACE_DELETION 0x00000200 -+#define YAFFS_TRACE_BUFFERS 0x00000400 -+#define YAFFS_TRACE_NANDACCESS 0x00000800 -+#define YAFFS_TRACE_GC_DETAIL 0x00001000 -+#define YAFFS_TRACE_SCAN_DEBUG 0x00002000 -+#define YAFFS_TRACE_MTD 0x00004000 -+#define YAFFS_TRACE_CHECKPOINT 0x00008000 -+ -+#define YAFFS_TRACE_VERIFY 0x00010000 -+#define YAFFS_TRACE_VERIFY_NAND 0x00020000 -+#define YAFFS_TRACE_VERIFY_FULL 0x00040000 -+#define YAFFS_TRACE_VERIFY_ALL 0x000f0000 -+ -+#define YAFFS_TRACE_SYNC 0x00100000 -+#define YAFFS_TRACE_BACKGROUND 0x00200000 -+#define YAFFS_TRACE_LOCK 0x00400000 -+#define YAFFS_TRACE_MOUNT 0x00800000 -+ -+#define YAFFS_TRACE_ERROR 0x40000000 -+#define YAFFS_TRACE_BUG 0x80000000 -+#define YAFFS_TRACE_ALWAYS 0xf0000000 -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_verify.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_verify.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,540 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_verify.h" -+#include "yaffs_trace.h" -+#include "yaffs_bitmap.h" -+#include "yaffs_getblockinfo.h" -+#include "yaffs_nand.h" -+ -+int yaffs_skip_verification(struct yaffs_dev *dev) -+{ -+ (void) dev; -+ return !(yaffs_trace_mask & -+ (YAFFS_TRACE_VERIFY | YAFFS_TRACE_VERIFY_FULL)); -+} -+ -+static int yaffs_skip_full_verification(struct yaffs_dev *dev) -+{ -+ (void) dev; -+ return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_FULL)); -+} -+ -+static int yaffs_skip_nand_verification(struct yaffs_dev *dev) -+{ -+ (void) dev; -+ return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_NAND)); -+} -+ -+static const char * const block_state_name[] = { -+ "Unknown", -+ "Needs scan", -+ "Scanning", -+ "Empty", -+ "Allocating", -+ "Full", -+ "Dirty", -+ "Checkpoint", -+ "Collecting", -+ "Dead" -+}; -+ -+void yaffs_verify_blk(struct yaffs_dev *dev, struct yaffs_block_info *bi, int n) -+{ -+ int actually_used; -+ int in_use; -+ -+ if (yaffs_skip_verification(dev)) -+ return; -+ -+ /* Report illegal runtime states */ -+ if (bi->block_state >= YAFFS_NUMBER_OF_BLOCK_STATES) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Block %d has undefined state %d", -+ n, bi->block_state); -+ -+ switch (bi->block_state) { -+ case YAFFS_BLOCK_STATE_UNKNOWN: -+ case YAFFS_BLOCK_STATE_SCANNING: -+ case YAFFS_BLOCK_STATE_NEEDS_SCAN: -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Block %d has bad run-state %s", -+ n, block_state_name[bi->block_state]); -+ } -+ -+ /* Check pages in use and soft deletions are legal */ -+ -+ actually_used = bi->pages_in_use - bi->soft_del_pages; -+ -+ if (bi->pages_in_use < 0 || -+ bi->pages_in_use > (int)dev->param.chunks_per_block || -+ bi->soft_del_pages < 0 || -+ bi->soft_del_pages > (int)dev->param.chunks_per_block || -+ actually_used < 0 || actually_used > (int)dev->param.chunks_per_block) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Block %d has illegal values pages_in_used %d soft_del_pages %d", -+ n, bi->pages_in_use, bi->soft_del_pages); -+ -+ /* Check chunk bitmap legal */ -+ in_use = yaffs_count_chunk_bits(dev, n); -+ if (in_use != bi->pages_in_use) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Block %d has inconsistent values pages_in_use %d counted chunk bits %d", -+ n, bi->pages_in_use, in_use); -+} -+ -+void yaffs_verify_collected_blk(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi, int n) -+{ -+ yaffs_verify_blk(dev, bi, n); -+ -+ /* After collection the block should be in the erased state */ -+ -+ if (bi->block_state != YAFFS_BLOCK_STATE_COLLECTING && -+ bi->block_state != YAFFS_BLOCK_STATE_EMPTY) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "Block %d is in state %d after gc, should be erased", -+ n, bi->block_state); -+ } -+} -+ -+void yaffs_verify_blocks(struct yaffs_dev *dev) -+{ -+ u32 i; -+ u32 state_count[YAFFS_NUMBER_OF_BLOCK_STATES]; -+ int illegal_states = 0; -+ -+ if (yaffs_skip_verification(dev)) -+ return; -+ -+ memset(state_count, 0, sizeof(state_count)); -+ -+ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { -+ struct yaffs_block_info *bi = yaffs_get_block_info(dev, i); -+ yaffs_verify_blk(dev, bi, i); -+ -+ if (bi->block_state < YAFFS_NUMBER_OF_BLOCK_STATES) -+ state_count[bi->block_state]++; -+ else -+ illegal_states++; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_VERIFY, "Block summary"); -+ -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "%d blocks have illegal states", -+ illegal_states); -+ if (state_count[YAFFS_BLOCK_STATE_ALLOCATING] > 1) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Too many allocating blocks"); -+ -+ for (i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "%s %d blocks", -+ block_state_name[i], state_count[i]); -+ -+ if (dev->blocks_in_checkpt != state_count[YAFFS_BLOCK_STATE_CHECKPOINT]) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Checkpoint block count wrong dev %d count %d", -+ dev->blocks_in_checkpt, -+ state_count[YAFFS_BLOCK_STATE_CHECKPOINT]); -+ -+ if (dev->n_erased_blocks != (int)state_count[YAFFS_BLOCK_STATE_EMPTY]) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Erased block count wrong dev %d count %d", -+ dev->n_erased_blocks, -+ state_count[YAFFS_BLOCK_STATE_EMPTY]); -+ -+ if (state_count[YAFFS_BLOCK_STATE_COLLECTING] > 1) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Too many collecting blocks %d (max is 1)", -+ state_count[YAFFS_BLOCK_STATE_COLLECTING]); -+} -+ -+/* -+ * Verify the object header. oh must be valid, but obj and tags may be NULL in -+ * which case those tests will not be performed. -+ */ -+void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh, -+ struct yaffs_ext_tags *tags, int parent_check) -+{ -+ if (obj && yaffs_skip_verification(obj->my_dev)) -+ return; -+ -+ if (!(tags && obj && oh)) { -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Verifying object header tags %p obj %p oh %p", -+ tags, obj, oh); -+ return; -+ } -+ -+ if (oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN || -+ oh->type > YAFFS_OBJECT_TYPE_MAX) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d header type is illegal value 0x%x", -+ tags->obj_id, oh->type); -+ -+ if (tags->obj_id != obj->obj_id) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d header mismatch obj_id %d", -+ tags->obj_id, obj->obj_id); -+ -+ /* -+ * Check that the object's parent ids match if parent_check requested. -+ * -+ * Tests do not apply to the root object. -+ */ -+ -+ if (parent_check && tags->obj_id > 1 && !obj->parent) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d header mismatch parent_id %d obj->parent is NULL", -+ tags->obj_id, oh->parent_obj_id); -+ -+ if (parent_check && obj->parent && -+ oh->parent_obj_id != obj->parent->obj_id && -+ (oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED || -+ obj->parent->obj_id != YAFFS_OBJECTID_DELETED)) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d header mismatch parent_id %d parent_obj_id %d", -+ tags->obj_id, oh->parent_obj_id, -+ obj->parent->obj_id); -+ -+ if (tags->obj_id > 1 && oh->name[0] == 0) /* Null name */ -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d header name is NULL", -+ obj->obj_id); -+ -+ if (tags->obj_id > 1 && ((u8) (oh->name[0])) == 0xff) /* Junk name */ -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d header name is 0xff", -+ obj->obj_id); -+} -+ -+void yaffs_verify_file(struct yaffs_obj *obj) -+{ -+ u32 x; -+ int required_depth; -+ int last_chunk; -+ u32 offset_in_chunk; -+ u32 the_chunk; -+ -+ int i; -+ struct yaffs_dev *dev; -+ struct yaffs_ext_tags tags; -+ struct yaffs_tnode *tn; -+ u32 obj_id; -+ -+ if (!obj) -+ return; -+ -+ if (yaffs_skip_verification(obj->my_dev)) -+ return; -+ -+ dev = obj->my_dev; -+ obj_id = obj->obj_id; -+ -+ -+ /* Check file size is consistent with tnode depth */ -+ yaffs_addr_to_chunk(dev, obj->variant.file_variant.file_size, -+ &last_chunk, &offset_in_chunk); -+ last_chunk++; -+ x = last_chunk >> YAFFS_TNODES_LEVEL0_BITS; -+ required_depth = 0; -+ while (x > 0) { -+ x >>= YAFFS_TNODES_INTERNAL_BITS; -+ required_depth++; -+ } -+ -+ /* Check that the chunks in the tnode tree are all correct. -+ * We do this by scanning through the tnode tree and -+ * checking the tags for every chunk match. -+ */ -+ -+ if (yaffs_skip_nand_verification(dev)) -+ return; -+ -+ for (i = 1; i <= last_chunk; i++) { -+ tn = yaffs_find_tnode_0(dev, &obj->variant.file_variant, i); -+ -+ if (!tn) -+ continue; -+ -+ the_chunk = yaffs_get_group_base(dev, tn, i); -+ if (the_chunk > 0) { -+ yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL, -+ &tags); -+ if (tags.obj_id != obj_id || tags.chunk_id != (u32)i) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Object %d chunk_id %d NAND mismatch chunk %d tags (%d:%d)", -+ obj_id, i, the_chunk, -+ tags.obj_id, tags.chunk_id); -+ } -+ } -+} -+ -+void yaffs_verify_link(struct yaffs_obj *obj) -+{ -+ if (obj && yaffs_skip_verification(obj->my_dev)) -+ return; -+ -+ /* Verify sane equivalent object */ -+} -+ -+void yaffs_verify_symlink(struct yaffs_obj *obj) -+{ -+ if (obj && yaffs_skip_verification(obj->my_dev)) -+ return; -+ -+ /* Verify symlink string */ -+} -+ -+void yaffs_verify_special(struct yaffs_obj *obj) -+{ -+ if (obj && yaffs_skip_verification(obj->my_dev)) -+ return; -+} -+ -+void yaffs_verify_obj(struct yaffs_obj *obj) -+{ -+ struct yaffs_dev *dev; -+ u32 chunk_min; -+ u32 chunk_max; -+ u32 chunk_id_ok; -+ u32 chunk_in_range; -+ u32 chunk_wrongly_deleted; -+ u32 chunk_valid; -+ -+ if (!obj) -+ return; -+ -+ if (obj->being_created) -+ return; -+ -+ dev = obj->my_dev; -+ -+ if (yaffs_skip_verification(dev)) -+ return; -+ -+ /* Check sane object header chunk */ -+ -+ chunk_min = dev->internal_start_block * dev->param.chunks_per_block; -+ chunk_max = -+ (dev->internal_end_block + 1) * dev->param.chunks_per_block - 1; -+ -+ chunk_in_range = (((unsigned)(obj->hdr_chunk)) >= chunk_min && -+ ((unsigned)(obj->hdr_chunk)) <= chunk_max); -+ chunk_id_ok = chunk_in_range || (obj->hdr_chunk == 0); -+ chunk_valid = chunk_in_range && -+ yaffs_check_chunk_bit(dev, -+ obj->hdr_chunk / dev->param.chunks_per_block, -+ obj->hdr_chunk % dev->param.chunks_per_block); -+ chunk_wrongly_deleted = chunk_in_range && !chunk_valid; -+ -+ if (!obj->fake && (!chunk_id_ok || chunk_wrongly_deleted)) -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d has chunk_id %d %s %s", -+ obj->obj_id, obj->hdr_chunk, -+ chunk_id_ok ? "" : ",out of range", -+ chunk_wrongly_deleted ? ",marked as deleted" : ""); -+ -+ if (chunk_valid && !yaffs_skip_nand_verification(dev)) { -+ struct yaffs_ext_tags tags; -+ struct yaffs_obj_hdr *oh; -+ u8 *buffer = yaffs_get_temp_buffer(dev); -+ -+ oh = (struct yaffs_obj_hdr *)buffer; -+ -+ yaffs_rd_chunk_tags_nand(dev, obj->hdr_chunk, buffer, &tags); -+ -+ yaffs_verify_oh(obj, oh, &tags, 1); -+ -+ yaffs_release_temp_buffer(dev, buffer); -+ } -+ -+ /* Verify it has a parent */ -+ if (obj && !obj->fake && (!obj->parent || obj->parent->my_dev != dev)) { -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d has parent pointer %p which does not look like an object", -+ obj->obj_id, obj->parent); -+ } -+ -+ /* Verify parent is a directory */ -+ if (obj->parent && -+ obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d's parent is not a directory (type %d)", -+ obj->obj_id, obj->parent->variant_type); -+ } -+ -+ switch (obj->variant_type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ yaffs_verify_file(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ yaffs_verify_symlink(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ yaffs_verify_dir(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ yaffs_verify_link(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ yaffs_verify_special(obj); -+ break; -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ default: -+ yaffs_trace(YAFFS_TRACE_VERIFY, -+ "Obj %d has illegaltype %d", -+ obj->obj_id, obj->variant_type); -+ break; -+ } -+} -+ -+void yaffs_verify_objects(struct yaffs_dev *dev) -+{ -+ struct yaffs_obj *obj; -+ int i; -+ struct list_head *lh; -+ -+ if (yaffs_skip_verification(dev)) -+ return; -+ -+ /* Iterate through the objects in each hash entry */ -+ -+ for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) { -+ list_for_each(lh, &dev->obj_bucket[i].list) { -+ obj = list_entry(lh, struct yaffs_obj, hash_link); -+ yaffs_verify_obj(obj); -+ } -+ } -+} -+ -+void yaffs_verify_obj_in_dir(struct yaffs_obj *obj) -+{ -+ struct list_head *lh; -+ struct yaffs_obj *list_obj; -+ int count = 0; -+ -+ if (!obj) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "No object to verify"); -+ BUG(); -+ return; -+ } -+ -+ if (yaffs_skip_verification(obj->my_dev)) -+ return; -+ -+ if (!obj->parent) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "Object does not have parent"); -+ BUG(); -+ return; -+ } -+ -+ if (obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "Parent is not directory"); -+ BUG(); -+ } -+ -+ /* Iterate through the objects in each hash entry */ -+ -+ list_for_each(lh, &obj->parent->variant.dir_variant.children) { -+ list_obj = list_entry(lh, struct yaffs_obj, siblings); -+ yaffs_verify_obj(list_obj); -+ if (obj == list_obj) -+ count++; -+ } -+ -+ if (count != 1) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "Object in directory %d times", -+ count); -+ BUG(); -+ } -+} -+ -+void yaffs_verify_dir(struct yaffs_obj *directory) -+{ -+ struct list_head *lh; -+ struct yaffs_obj *list_obj; -+ struct yaffs_dev *dev; -+ -+ if (!directory) { -+ BUG(); -+ return; -+ } -+ -+ dev = directory->my_dev; -+ -+ if (!dev) { -+ BUG(); -+ return; -+ } -+ -+ if (directory == dev->root_dir || -+ directory == dev->lost_n_found || -+ directory == dev->unlinked_dir || -+ directory == dev->del_dir) -+ return; -+ -+ if (yaffs_skip_full_verification(directory->my_dev)) -+ return; -+ -+ if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "Directory has wrong type: %d", -+ directory->variant_type); -+ BUG(); -+ } -+ -+ /* Iterate through the objects in each hash entry */ -+ -+ list_for_each(lh, &directory->variant.dir_variant.children) { -+ list_obj = list_entry(lh, struct yaffs_obj, siblings); -+ if (list_obj->parent != directory) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "Object in directory list has wrong parent %p", -+ list_obj->parent); -+ BUG(); -+ } -+ yaffs_verify_obj_in_dir(list_obj); -+ } -+} -+ -+static int yaffs_free_verification_failures; -+ -+void yaffs_verify_free_chunks(struct yaffs_dev *dev) -+{ -+ int counted; -+ int difference; -+ -+ if (yaffs_skip_verification(dev)) -+ return; -+ -+ counted = yaffs_count_free_chunks(dev); -+ -+ difference = dev->n_free_chunks - counted; -+ -+ if (difference) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "Freechunks verification failure %d %d %d", -+ dev->n_free_chunks, counted, difference); -+ yaffs_free_verification_failures++; -+ } -+} -+ -+int yaffs_verify_file_sane(struct yaffs_obj *in) -+{ -+ (void) in; -+ return YAFFS_OK; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_verify.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_verify.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,43 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_VERIFY_H__ -+#define __YAFFS_VERIFY_H__ -+ -+#include "yaffs_guts.h" -+ -+void yaffs_verify_blk(struct yaffs_dev *dev, struct yaffs_block_info *bi, -+ int n); -+void yaffs_verify_collected_blk(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi, int n); -+void yaffs_verify_blocks(struct yaffs_dev *dev); -+ -+void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh, -+ struct yaffs_ext_tags *tags, int parent_check); -+void yaffs_verify_file(struct yaffs_obj *obj); -+void yaffs_verify_link(struct yaffs_obj *obj); -+void yaffs_verify_symlink(struct yaffs_obj *obj); -+void yaffs_verify_special(struct yaffs_obj *obj); -+void yaffs_verify_obj(struct yaffs_obj *obj); -+void yaffs_verify_objects(struct yaffs_dev *dev); -+void yaffs_verify_obj_in_dir(struct yaffs_obj *obj); -+void yaffs_verify_dir(struct yaffs_obj *directory); -+void yaffs_verify_free_chunks(struct yaffs_dev *dev); -+ -+int yaffs_verify_file_sane(struct yaffs_obj *obj); -+ -+int yaffs_skip_verification(struct yaffs_dev *dev); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_vfs.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_vfs.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,3751 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * Acknowledgements: -+ * Luc van OostenRyck for numerous patches. -+ * Nick Bane for numerous patches. -+ * Nick Bane for 2.5/2.6 integration. -+ * Andras Toth for mknod rdev issue. -+ * Michael Fischer for finding the problem with inode inconsistency. -+ * Some code bodily lifted from JFFS -+ * -+ * 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. -+ */ -+ -+/* -+ * -+ * This is the file system front-end to YAFFS that hooks it up to -+ * the VFS. -+ * -+ * Special notes: -+ * >> 2.4: sb->u.generic_sbp points to the struct yaffs_dev associated with -+ * this superblock -+ * >> 2.6: sb->s_fs_info points to the struct yaffs_dev associated with this -+ * superblock -+ * >> inode->u.generic_ip points to the associated struct yaffs_obj. -+ */ -+ -+/* -+ * There are two variants of the VFS glue code. This variant should compile -+ * for any version of Linux. -+ */ -+#include -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)) -+#define YAFFS_COMPILE_BACKGROUND -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)) -+#define YAFFS_COMPILE_FREEZER -+#endif -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) -+#define YAFFS_COMPILE_EXPORTFS -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) -+#define YAFFS_USE_SETATTR_COPY -+#define YAFFS_USE_TRUNCATE_SETSIZE -+#endif -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) -+#define YAFFS_HAS_EVICT_INODE -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13)) && \ -+ (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)) -+#define YAFFS_NEW_FOLLOW_LINK 1 -+#else -+#define YAFFS_NEW_FOLLOW_LINK 0 -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) -+#define YAFFS_HAS_WRITE_SUPER -+#endif -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+ -+#if (YAFFS_NEW_FOLLOW_LINK == 1) -+#include -+#endif -+ -+#ifdef YAFFS_COMPILE_EXPORTFS -+#include -+#endif -+ -+#ifdef YAFFS_COMPILE_BACKGROUND -+#include -+#include -+#endif -+#ifdef YAFFS_COMPILE_FREEZER -+#include -+#endif -+ -+#include -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+ -+#include -+ -+#define UnlockPage(p) unlock_page(p) -+#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) -+ -+/* FIXME: use sb->s_id instead ? */ -+#define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) -+ -+#else -+ -+#include -+#define BDEVNAME_SIZE 0 -+#define yaffs_devname(sb, buf) kdevname(sb->s_dev) -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)) -+/* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */ -+#define __user -+#endif -+ -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)) -+#define YPROC_ROOT (&proc_root) -+#else -+#define YPROC_ROOT NULL -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)) -+#define Y_INIT_TIMER(a) init_timer(a) -+#else -+#define Y_INIT_TIMER(a) init_timer_on_stack(a) -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27)) -+#define YAFFS_USE_WRITE_BEGIN_END 1 -+#else -+#define YAFFS_USE_WRITE_BEGIN_END 0 -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) -+#define YAFFS_SUPER_HAS_DIRTY -+#endif -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) -+#define set_nlink(inode, count) do { (inode)->i_nlink = (count); } while(0) -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)) -+static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size) -+{ -+ uint64_t result = partition_size; -+ do_div(result, block_size); -+ return (uint32_t) result; -+} -+#else -+#define YCALCBLOCKS(s, b) ((s)/(b)) -+#endif -+ -+#include -+#include -+ -+#include "yportenv.h" -+#include "yaffs_trace.h" -+#include "yaffs_guts.h" -+#include "yaffs_attribs.h" -+ -+#include "yaffs_linux.h" -+ -+#include "yaffs_mtdif.h" -+#include "yaffs_packedtags2.h" -+#include "yaffs_getblockinfo.h" -+ -+unsigned int yaffs_trace_mask = -+ YAFFS_TRACE_BAD_BLOCKS | -+ YAFFS_TRACE_ALWAYS | -+ 0; -+ -+unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; -+unsigned int yaffs_auto_checkpoint = 1; -+unsigned int yaffs_gc_control = 1; -+unsigned int yaffs_bg_enable = 1; -+unsigned int yaffs_auto_select = 1; -+/* Module Parameters */ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+module_param(yaffs_trace_mask, uint, 0644); -+module_param(yaffs_wr_attempts, uint, 0644); -+module_param(yaffs_auto_checkpoint, uint, 0644); -+module_param(yaffs_gc_control, uint, 0644); -+module_param(yaffs_bg_enable, uint, 0644); -+#else -+MODULE_PARM(yaffs_trace_mask, "i"); -+MODULE_PARM(yaffs_wr_attempts, "i"); -+MODULE_PARM(yaffs_auto_checkpoint, "i"); -+MODULE_PARM(yaffs_gc_control, "i"); -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)) -+/* use iget and read_inode */ -+#define Y_IGET(sb, inum) iget((sb), (inum)) -+ -+#else -+/* Call local equivalent */ -+#define YAFFS_USE_OWN_IGET -+#define Y_IGET(sb, inum) yaffs_iget((sb), (inum)) -+ -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)) -+#define yaffs_inode_to_obj_lv(iptr) ((iptr)->i_private) -+#else -+#define yaffs_inode_to_obj_lv(iptr) ((iptr)->u.generic_ip) -+#endif -+ -+#define yaffs_inode_to_obj(iptr) \ -+ ((struct yaffs_obj *)(yaffs_inode_to_obj_lv(iptr))) -+#define yaffs_dentry_to_obj(dptr) yaffs_inode_to_obj((dptr)->d_inode) -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+#define yaffs_super_to_dev(sb) ((struct yaffs_dev *)sb->s_fs_info) -+#else -+#define yaffs_super_to_dev(sb) ((struct yaffs_dev *)sb->u.generic_sbp) -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) -+#define Y_CLEAR_INODE(i) clear_inode(i) -+#else -+#define Y_CLEAR_INODE(i) end_writeback(i) -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) -+#define YAFFS_USE_DIR_ITERATE -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) -+#define YAFFS_USE_XATTR -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) -+#define YAFFS_NEW_PROCFS -+#include -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)) -+#define PAGE_CACHE_SIZE PAGE_SIZE -+#define PAGE_CACHE_SHIFT PAGE_SHIFT -+#define Y_GET_DENTRY(f) ((f)->f_path.dentry) -+#define page_cache_release put_page -+#define YAFFS_NEW_XATTR 1 -+#define YAFFS_NEW_GET_LINK 1 -+#else -+#define Y_GET_DENTRY(f) ((f)->f_dentry) -+#define YAFFS_NEW_XATTR 0 -+#define YAFFS_NEW_GET_LINK 0 -+#endif -+ -+#define update_dir_time(dir) do {\ -+ (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \ -+ } while (0) -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) -+static inline int setattr_prepare(struct dentry *dentry, struct iattr *attr) -+{ -+ return inode_change_ok(dentry->d_inode, attr); -+} -+#endif -+ -+static void yaffs_fill_inode_from_obj(struct inode *inode, -+ struct yaffs_obj *obj); -+ -+ -+static void yaffs_gross_lock(struct yaffs_dev *dev) -+{ -+ yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locking %p", current); -+ mutex_lock(&(yaffs_dev_to_lc(dev)->gross_lock)); -+ yaffs_trace(YAFFS_TRACE_LOCK, "yaffs locked %p", current); -+} -+ -+static void yaffs_gross_unlock(struct yaffs_dev *dev) -+{ -+ yaffs_trace(YAFFS_TRACE_LOCK, "yaffs unlocking %p", current); -+ mutex_unlock(&(yaffs_dev_to_lc(dev)->gross_lock)); -+} -+ -+ -+static int yaffs_readpage_nolock(struct file *f, struct page *pg) -+{ -+ /* Lifted from jffs2 */ -+ -+ struct yaffs_obj *obj; -+ unsigned char *pg_buf; -+ int ret; -+ loff_t pos = ((loff_t) pg->index) << PAGE_SHIFT; -+ struct yaffs_dev *dev; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_readpage_nolock at %lld, size %08x", -+ (long long)pos, -+ (unsigned)PAGE_SIZE); -+ -+ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); -+ -+ dev = obj->my_dev; -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+ BUG_ON(!PageLocked(pg)); -+#else -+ if (!PageLocked(pg)) -+ PAGE_BUG(pg); -+#endif -+ -+ pg_buf = kmap(pg); -+ /* FIXME: Can kmap fail? */ -+ -+ yaffs_gross_lock(dev); -+ -+ ret = yaffs_file_rd(obj, pg_buf, pos, PAGE_CACHE_SIZE); -+ -+ yaffs_gross_unlock(dev); -+ -+ if (ret >= 0) -+ ret = 0; -+ -+ if (ret) { -+ ClearPageUptodate(pg); -+ SetPageError(pg); -+ } else { -+ SetPageUptodate(pg); -+ ClearPageError(pg); -+ } -+ -+ flush_dcache_page(pg); -+ kunmap(pg); -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage_nolock done"); -+ return ret; -+} -+ -+static int yaffs_readpage_unlock(struct file *f, struct page *pg) -+{ -+ int ret = yaffs_readpage_nolock(f, pg); -+ UnlockPage(pg); -+ return ret; -+} -+ -+static int yaffs_readpage(struct file *f, struct page *pg) -+{ -+ int ret; -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage"); -+ ret = yaffs_readpage_unlock(f, pg); -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_readpage done"); -+ return ret; -+} -+ -+ -+static void yaffs_set_super_dirty_val(struct yaffs_dev *dev, int val) -+{ -+ struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev); -+ -+ if (lc) -+ lc->dirty = val; -+ -+# ifdef YAFFS_SUPER_HAS_DIRTY -+ { -+ struct super_block *sb = lc->super; -+ -+ if (sb) -+ sb->s_dirt = val; -+ } -+#endif -+ -+} -+ -+static void yaffs_set_super_dirty(struct yaffs_dev *dev) -+{ -+ yaffs_set_super_dirty_val(dev, 1); -+} -+ -+static void yaffs_clear_super_dirty(struct yaffs_dev *dev) -+{ -+ yaffs_set_super_dirty_val(dev, 0); -+} -+ -+static int yaffs_check_super_dirty(struct yaffs_dev *dev) -+{ -+ struct yaffs_linux_context *lc = yaffs_dev_to_lc(dev); -+ -+ if (lc && lc->dirty) -+ return 1; -+ -+# ifdef YAFFS_SUPER_HAS_DIRTY -+ { -+ struct super_block *sb = lc->super; -+ -+ if (sb && sb->s_dirt) -+ return 1; -+ } -+#endif -+ return 0; -+ -+} -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+static int yaffs_writepage(struct page *page, struct writeback_control *wbc) -+#else -+static int yaffs_writepage(struct page *page) -+#endif -+{ -+ struct yaffs_dev *dev; -+ struct address_space *mapping = page->mapping; -+ struct inode *inode; -+ unsigned long end_index; -+ char *buffer; -+ struct yaffs_obj *obj; -+ int n_written = 0; -+ unsigned n_bytes; -+ loff_t i_size; -+ -+ if (!mapping) -+ BUG(); -+ inode = mapping->host; -+ if (!inode) -+ BUG(); -+ i_size = i_size_read(inode); -+ -+ end_index = i_size >> PAGE_CACHE_SHIFT; -+ -+ if (page->index < end_index) -+ n_bytes = PAGE_CACHE_SIZE; -+ else { -+ n_bytes = i_size & (PAGE_CACHE_SIZE - 1); -+ -+ if (page->index > end_index || !n_bytes) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_writepage at %lld, inode size = %lld!!", -+ ((loff_t)page->index) << PAGE_CACHE_SHIFT, -+ inode->i_size); -+ yaffs_trace(YAFFS_TRACE_OS, -+ " -> don't care!!"); -+ -+ zero_user_segment(page, 0, PAGE_CACHE_SIZE); -+ set_page_writeback(page); -+ unlock_page(page); -+ end_page_writeback(page); -+ return 0; -+ } -+ } -+ -+ if (n_bytes != PAGE_CACHE_SIZE) -+ zero_user_segment(page, n_bytes, PAGE_CACHE_SIZE); -+ -+ get_page(page); -+ -+ buffer = kmap(page); -+ -+ obj = yaffs_inode_to_obj(inode); -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_writepage at %lld, size %08x", -+ ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes); -+ yaffs_trace(YAFFS_TRACE_OS, -+ "writepag0: obj = %lld, ino = %lld", -+ obj->variant.file_variant.file_size, inode->i_size); -+ -+ n_written = yaffs_wr_file(obj, buffer, -+ ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes, 0); -+ -+ yaffs_set_super_dirty(dev); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "writepag1: obj = %lld, ino = %lld", -+ obj->variant.file_variant.file_size, inode->i_size); -+ -+ yaffs_gross_unlock(dev); -+ -+ kunmap(page); -+ set_page_writeback(page); -+ unlock_page(page); -+ end_page_writeback(page); -+ put_page(page); -+ -+ return (n_written == n_bytes) ? 0 : -ENOSPC; -+} -+ -+/* Space holding and freeing is done to ensure we have space available for write_begin/end */ -+/* For now we just assume few parallel writes and check against a small number. */ -+/* Todo: need to do this with a counter to handle parallel reads better */ -+ -+static ssize_t yaffs_hold_space(struct file *f) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+ -+ int n_free_chunks; -+ -+ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); -+ -+ dev = obj->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ n_free_chunks = yaffs_get_n_free_chunks(dev); -+ -+ yaffs_gross_unlock(dev); -+ -+ return (n_free_chunks > 20) ? 1 : 0; -+} -+ -+static void yaffs_release_space(struct file *f) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+ -+ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); -+ -+ dev = obj->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ yaffs_gross_unlock(dev); -+} -+ -+#if (YAFFS_USE_WRITE_BEGIN_END > 0) -+static int yaffs_write_begin(struct file *filp, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned flags, -+ struct page **pagep, void **fsdata) -+{ -+ struct page *pg = NULL; -+ pgoff_t index = pos >> PAGE_CACHE_SHIFT; -+ -+ int ret = 0; -+ int space_held = 0; -+ -+ /* Get a page */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+ pg = grab_cache_page_write_begin(mapping, index, flags); -+#else -+ pg = __grab_cache_page(mapping, index); -+#endif -+ -+ *pagep = pg; -+ if (!pg) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ yaffs_trace(YAFFS_TRACE_OS, -+ "start yaffs_write_begin index %d(%x) uptodate %d", -+ (int)index, (int)index, Page_Uptodate(pg) ? 1 : 0); -+ -+ /* Get fs space */ -+ space_held = yaffs_hold_space(filp); -+ -+ if (!space_held) { -+ ret = -ENOSPC; -+ goto out; -+ } -+ -+ /* Update page if required */ -+ -+ if (!Page_Uptodate(pg)) -+ ret = yaffs_readpage_nolock(filp, pg); -+ -+ if (ret) -+ goto out; -+ -+ /* Happy path return */ -+ yaffs_trace(YAFFS_TRACE_OS, "end yaffs_write_begin - ok"); -+ -+ return 0; -+ -+out: -+ yaffs_trace(YAFFS_TRACE_OS, -+ "end yaffs_write_begin fail returning %d", ret); -+ if (space_held) -+ yaffs_release_space(filp); -+ if (pg) { -+ unlock_page(pg); -+ page_cache_release(pg); -+ } -+ return ret; -+} -+ -+#else -+ -+static int yaffs_prepare_write(struct file *f, struct page *pg, -+ unsigned offset, unsigned to) -+{ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_prepair_write"); -+ -+ if (!Page_Uptodate(pg)) -+ return yaffs_readpage_nolock(f, pg); -+ return 0; -+} -+#endif -+ -+ -+static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, -+ loff_t * pos) -+{ -+ struct yaffs_obj *obj; -+ int n_written; -+ loff_t ipos; -+ struct inode *inode; -+ struct yaffs_dev *dev; -+ -+ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); -+ -+ if (!obj) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_file_write: hey obj is null!"); -+ return -EINVAL; -+ } -+ -+ dev = obj->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ inode = Y_GET_DENTRY(f)->d_inode; -+ -+ if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) -+ ipos = inode->i_size; -+ else -+ ipos = *pos; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_file_write about to write writing %u(%x) bytes to object %d at %lld", -+ (unsigned)n, (unsigned)n, obj->obj_id, ipos); -+ -+ n_written = yaffs_wr_file(obj, buf, ipos, n, 0); -+ -+ yaffs_set_super_dirty(dev); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_file_write: %d(%x) bytes written", -+ (unsigned)n, (unsigned)n); -+ -+ if (n_written > 0) { -+ ipos += n_written; -+ *pos = ipos; -+ if (ipos > inode->i_size) { -+ inode->i_size = ipos; -+ inode->i_blocks = (ipos + 511) >> 9; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_file_write size updated to %lld bytes, %d blocks", -+ ipos, (int)(inode->i_blocks)); -+ } -+ -+ } -+ yaffs_gross_unlock(dev); -+ return (n_written == 0) && (n > 0) ? -ENOSPC : n_written; -+} -+ -+ -+#if (YAFFS_USE_WRITE_BEGIN_END > 0) -+static int yaffs_write_end(struct file *filp, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned copied, -+ struct page *pg, void *fsdadata) -+{ -+ int ret = 0; -+ void *addr, *kva; -+ uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1); -+ -+ kva = kmap(pg); -+ addr = kva + offset_into_page; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_write_end addr %p pos %lld n_bytes %d", -+ addr, pos, copied); -+ -+ ret = yaffs_file_write(filp, addr, copied, &pos); -+ -+ if (ret != copied) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_write_end not same size ret %d copied %d", -+ ret, copied); -+ SetPageError(pg); -+ } -+ -+ kunmap(pg); -+ -+ yaffs_release_space(filp); -+ unlock_page(pg); -+ page_cache_release(pg); -+ return ret; -+} -+#else -+ -+static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, -+ unsigned to) -+{ -+ void *addr, *kva; -+ -+ loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset; -+ int n_bytes = to - offset; -+ int n_written; -+ -+ kva = kmap(pg); -+ addr = kva + offset; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_commit_write addr %p pos %lld n_bytes %d", -+ addr, pos, n_bytes); -+ -+ n_written = yaffs_file_write(f, addr, n_bytes, &pos); -+ -+ if (n_written != n_bytes) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_commit_write not same size n_written %d n_bytes %d", -+ n_written, n_bytes); -+ SetPageError(pg); -+ } -+ kunmap(pg); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_commit_write returning %d", -+ n_written == n_bytes ? 0 : n_written); -+ -+ return n_written == n_bytes ? 0 : n_written; -+} -+#endif -+ -+static struct address_space_operations yaffs_file_address_operations = { -+ .readpage = yaffs_readpage, -+ .writepage = yaffs_writepage, -+#if (YAFFS_USE_WRITE_BEGIN_END > 0) -+ .write_begin = yaffs_write_begin, -+ .write_end = yaffs_write_end, -+#else -+ .prepare_write = yaffs_prepare_write, -+ .commit_write = yaffs_commit_write, -+#endif -+}; -+ -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+static int yaffs_file_flush(struct file *file, fl_owner_t id) -+#else -+static int yaffs_file_flush(struct file *file) -+#endif -+{ -+ struct yaffs_obj *obj = yaffs_dentry_to_obj(Y_GET_DENTRY(file)); -+ -+ struct yaffs_dev *dev = obj->my_dev; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_file_flush object %d (%s)", -+ obj->obj_id, -+ obj->dirty ? "dirty" : "clean"); -+ -+ yaffs_gross_lock(dev); -+ -+ yaffs_flush_file(obj, 1, 0, 0); -+ -+ yaffs_gross_unlock(dev); -+ -+ return 0; -+} -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -+static int yaffs_sync_object(struct file *file, loff_t start, loff_t end, int datasync) -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)) -+static int yaffs_sync_object(struct file *file, int datasync) -+#else -+static int yaffs_sync_object(struct file *file, struct dentry *dentry, -+ int datasync) -+#endif -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34)) -+ struct dentry *dentry = file->f_path.dentry; -+#endif -+ -+ obj = yaffs_dentry_to_obj(dentry); -+ -+ dev = obj->my_dev; -+ -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC, -+ "yaffs_sync_object"); -+ yaffs_gross_lock(dev); -+ yaffs_flush_file(obj, 1, datasync, 0); -+ yaffs_gross_unlock(dev); -+ return 0; -+} -+ -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)) -+static const struct file_operations yaffs_file_operations = { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0) -+ .read = new_sync_read, -+ .write = new_sync_write, -+#endif -+ .read_iter = generic_file_read_iter, -+ .write_iter = generic_file_write_iter, -+#else -+ .read = do_sync_read, -+ .write = do_sync_write, -+ .aio_read = generic_file_aio_read, -+ .aio_write = generic_file_aio_write, -+#endif -+ .mmap = generic_file_mmap, -+ .flush = yaffs_file_flush, -+ .fsync = yaffs_sync_object, -+ .splice_read = generic_file_splice_read, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) -+ .splice_write = iter_file_splice_write, -+#else -+ .splice_write = generic_file_splice_write, -+#endif -+ .llseek = generic_file_llseek, -+}; -+ -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18)) -+ -+static const struct file_operations yaffs_file_operations = { -+ .read = do_sync_read, -+ .write = do_sync_write, -+ .aio_read = generic_file_aio_read, -+ .aio_write = generic_file_aio_write, -+ .mmap = generic_file_mmap, -+ .flush = yaffs_file_flush, -+ .fsync = yaffs_sync_object, -+ .sendfile = generic_file_sendfile, -+}; -+ -+#else -+ -+static const struct file_operations yaffs_file_operations = { -+ .read = generic_file_read, -+ .write = generic_file_write, -+ .mmap = generic_file_mmap, -+ .flush = yaffs_file_flush, -+ .fsync = yaffs_sync_object, -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+ .sendfile = generic_file_sendfile, -+#endif -+}; -+#endif -+ -+ -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)) -+static void zero_user_segment(struct page *page, unsigned start, unsigned end) -+{ -+ void *kaddr = kmap_atomic(page, KM_USER0); -+ memset(kaddr + start, 0, end - start); -+ kunmap_atomic(kaddr, KM_USER0); -+ flush_dcache_page(page); -+} -+#endif -+ -+ -+static int yaffs_vfs_setsize(struct inode *inode, loff_t newsize) -+{ -+#ifdef YAFFS_USE_TRUNCATE_SETSIZE -+ truncate_setsize(inode, newsize); -+ return 0; -+#else -+ truncate_inode_pages(&inode->i_data, newsize); -+ return 0; -+#endif -+ -+} -+ -+ -+static int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr) -+{ -+#ifdef YAFFS_USE_SETATTR_COPY -+ setattr_copy(inode, attr); -+ return 0; -+#else -+ return inode_setattr(inode, attr); -+#endif -+ -+} -+ -+static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) -+{ -+ struct inode *inode = dentry->d_inode; -+ int error = 0; -+ struct yaffs_dev *dev; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_setattr of object %d", -+ yaffs_inode_to_obj(inode)->obj_id); -+#if 0 -+ /* Fail if a requested resize >= 2GB */ -+ if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31)) -+ error = -EINVAL; -+#endif -+ -+ if (error == 0) -+ error = setattr_prepare(dentry, attr); -+ if (error == 0) { -+ int result; -+ if (!error) { -+ error = yaffs_vfs_setattr(inode, attr); -+ yaffs_trace(YAFFS_TRACE_OS, "inode_setattr called"); -+ if (attr->ia_valid & ATTR_SIZE) { -+ yaffs_vfs_setsize(inode, attr->ia_size); -+ inode->i_blocks = (inode->i_size + 511) >> 9; -+ } -+ } -+ dev = yaffs_inode_to_obj(inode)->my_dev; -+ if (attr->ia_valid & ATTR_SIZE) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "resize to %d(%x)", -+ (int)(attr->ia_size), -+ (int)(attr->ia_size)); -+ } -+ yaffs_gross_lock(dev); -+ result = yaffs_set_attribs(yaffs_inode_to_obj(inode), attr); -+ if (result == YAFFS_OK) { -+ error = 0; -+ } else { -+ error = -EPERM; -+ } -+ yaffs_gross_unlock(dev); -+ -+ } -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_setattr done returning %d", error); -+ -+ return error; -+} -+ -+#ifdef YAFFS_USE_XATTR -+#if (YAFFS_NEW_XATTR > 0) -+static int yaffs_setxattr(struct dentry *dentry, struct inode *inode, -+ const char *name, const void *value, size_t size, int flags) -+{ -+#else -+static int yaffs_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ struct inode *inode = dentry->d_inode; -+#endif -+ int error = 0; -+ struct yaffs_dev *dev; -+ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr of object %d", obj->obj_id); -+ -+ if (error == 0) { -+ int result; -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ result = yaffs_set_xattrib(obj, name, value, size, flags); -+ if (result == YAFFS_OK) -+ error = 0; -+ else if (result < 0) -+ error = result; -+ yaffs_gross_unlock(dev); -+ -+ } -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_setxattr done returning %d", error); -+ -+ return error; -+} -+ -+#ifdef YAFFS_NEW_XATTR -+static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode, -+ const char *name, void *buff, size_t size) -+{ -+#else -+static ssize_t yaffs_getxattr(struct dentry * dentry, const char *name, -+ void *buff, size_t size) -+{ -+ struct inode *inode = dentry->d_inode; -+#endif -+ int error = 0; -+ struct yaffs_dev *dev; -+ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_getxattr \"%s\" from object %d", -+ name, obj->obj_id); -+ -+ if (error == 0) { -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ error = yaffs_get_xattrib(obj, name, buff, size); -+ yaffs_gross_unlock(dev); -+ -+ } -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_getxattr done returning %d", error); -+ -+ return error; -+} -+ -+static int yaffs_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct inode *inode = dentry->d_inode; -+ int error = 0; -+ struct yaffs_dev *dev; -+ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_removexattr of object %d", obj->obj_id); -+ -+ if (error == 0) { -+ int result; -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ result = yaffs_remove_xattrib(obj, name); -+ if (result == YAFFS_OK) -+ error = 0; -+ else if (result < 0) -+ error = result; -+ yaffs_gross_unlock(dev); -+ -+ } -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_removexattr done returning %d", error); -+ -+ return error; -+} -+#endif -+ -+static ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size) -+{ -+ struct inode *inode = dentry->d_inode; -+ int error = 0; -+ struct yaffs_dev *dev; -+ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_listxattr of object %d", obj->obj_id); -+ -+ if (error == 0) { -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ error = yaffs_list_xattrib(obj, buff, size); -+ yaffs_gross_unlock(dev); -+ -+ } -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_listxattr done returning %d", error); -+ -+ return error; -+} -+ -+ -+static const struct inode_operations yaffs_file_inode_operations = { -+ .setattr = yaffs_setattr, -+#ifdef YAFFS_USE_XATTR -+ .setxattr = yaffs_setxattr, -+ .getxattr = yaffs_getxattr, -+ .removexattr = yaffs_removexattr, -+#endif -+ .listxattr = yaffs_listxattr, -+}; -+ -+ -+static int yaffs_readlink(struct dentry *dentry, char __user * buffer, -+ int buflen) -+{ -+ unsigned char *alias; -+ int ret; -+ -+ struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry)); -+ -+ yaffs_gross_unlock(dev); -+ -+ if (!alias) -+ return -ENOMEM; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) -+ ret = vfs_readlink(dentry, buffer, buflen, alias); -+#else -+ ret = readlink_copy(buffer, buflen, alias); -+#endif -+ kfree(alias); -+ return ret; -+} -+ -+#if (YAFFS_NEW_GET_LINK == 0) -+#if (YAFFS_NEW_FOLLOW_LINK == 1) -+static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) -+{ -+ void *ret; -+#else -+static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) -+{ -+ int ret -+#endif -+ unsigned char *alias; -+ int ret_int = 0; -+ struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry)); -+ yaffs_gross_unlock(dev); -+ -+ if (!alias) { -+ ret_int = -ENOMEM; -+ goto out; -+ } -+#if (YAFFS_NEW_FOLLOW_LINK == 1) -+ nd_set_link(nd, alias); -+ ret = alias; -+out: -+ if (ret_int) -+ ret = ERR_PTR(ret_int); -+ return ret; -+#else -+ ret = vfs_follow_link(nd, alias); -+ kfree(alias); -+out: -+ if (ret_int) -+ ret = ret_int; -+ return ret; -+#endif -+} -+#else -+static const char *yaffs_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) -+{ -+ unsigned char *alias; -+ struct yaffs_dev *dev; -+ -+ if (!dentry) -+ return ERR_PTR(-ECHILD); -+ -+ dev = yaffs_dentry_to_obj(dentry)->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry)); -+ yaffs_gross_unlock(dev); -+ -+ if (!alias) -+ return ERR_PTR(-ENOMEM); -+ set_delayed_call(done, kfree_link, alias); -+ return alias; -+} -+#endif -+ -+#ifdef YAFFS_HAS_PUT_INODE -+ -+/* For now put inode is just for debugging -+ * Put inode is called when the inode **structure** is put. -+ */ -+static void yaffs_put_inode(struct inode *inode) -+{ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_put_inode: ino %d, count %d"), -+ (int)inode->i_ino, atomic_read(&inode->i_count); -+ -+} -+#endif -+ -+#if (YAFFS_NEW_FOLLOW_LINK == 1) -+void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias) -+{ -+ kfree(alias); -+} -+#endif -+ -+static const struct inode_operations yaffs_symlink_inode_operations = { -+ .readlink = yaffs_readlink, -+#if (YAFFS_NEW_GET_LINK == 1) -+ .get_link = yaffs_get_link, -+#else -+ .follow_link = yaffs_follow_link, -+#endif -+#if (YAFFS_NEW_FOLLOW_LINK == 1) -+ .put_link = yaffs_put_link, -+#endif -+ .setattr = yaffs_setattr, -+#ifdef YAFFS_USE_XATTR -+ .setxattr = yaffs_setxattr, -+ .getxattr = yaffs_getxattr, -+ .removexattr = yaffs_removexattr, -+#endif -+ .listxattr = yaffs_listxattr, -+}; -+ -+#ifdef YAFFS_USE_OWN_IGET -+ -+static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino) -+{ -+ struct inode *inode; -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev = yaffs_super_to_dev(sb); -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_iget for %lu", ino); -+ -+ inode = iget_locked(sb, ino); -+ if (!inode) -+ return ERR_PTR(-ENOMEM); -+ if (!(inode->i_state & I_NEW)) -+ return inode; -+ -+ /* NB This is called as a side effect of other functions, but -+ * we had to release the lock to prevent deadlocks, so -+ * need to lock again. -+ */ -+ -+ yaffs_gross_lock(dev); -+ -+ obj = yaffs_find_by_number(dev, inode->i_ino); -+ -+ yaffs_fill_inode_from_obj(inode, obj); -+ -+ yaffs_gross_unlock(dev); -+ -+ unlock_new_inode(inode); -+ return inode; -+} -+ -+#else -+ -+static void yaffs_read_inode(struct inode *inode) -+{ -+ /* NB This is called as a side effect of other functions, but -+ * we had to release the lock to prevent deadlocks, so -+ * need to lock again. -+ */ -+ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev = yaffs_super_to_dev(inode->i_sb); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_read_inode for %d", (int)inode->i_ino); -+ -+ if (current != yaffs_dev_to_lc(dev)->readdir_process) -+ yaffs_gross_lock(dev); -+ -+ obj = yaffs_find_by_number(dev, inode->i_ino); -+ -+ yaffs_fill_inode_from_obj(inode, obj); -+ -+ if (current != yaffs_dev_to_lc(dev)->readdir_process) -+ yaffs_gross_unlock(dev); -+} -+ -+#endif -+ -+ -+ -+struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, -+ struct yaffs_obj *obj) -+{ -+ struct inode *inode; -+ -+ if (!sb) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_get_inode for NULL super_block!!"); -+ return NULL; -+ -+ } -+ -+ if (!obj) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_get_inode for NULL object!!"); -+ return NULL; -+ -+ } -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_get_inode for object %d", obj->obj_id); -+ -+ inode = Y_IGET(sb, obj->obj_id); -+ if (IS_ERR(inode)) -+ return NULL; -+ -+ /* NB Side effect: iget calls back to yaffs_read_inode(). */ -+ /* iget also increments the inode's i_count */ -+ /* NB You can't be holding gross_lock or deadlock will happen! */ -+ -+ return inode; -+} -+ -+ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) -+#define YCRED(x) x -+#else -+#define YCRED(x) (x->cred) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) -+#define YPROC_uid(p) (YCRED(p)->fsuid) -+#define YPROC_gid(p) (YCRED(p)->fsgid) -+#define EXTRACT_gid(x) x -+#define EXTRACT_uid(x) x -+#define MAKE_gid(x) x -+#define MAKE_uid(x) x -+#else -+#define YPROC_uid(p) from_kuid(&init_user_ns, YCRED(p)->fsuid) -+#define YPROC_gid(p) from_kgid(&init_user_ns, YCRED(p)->fsgid) -+#define EXTRACT_gid(x) from_kgid(&init_user_ns, x) -+#define EXTRACT_uid(x) from_kuid(&init_user_ns, x) -+#define MAKE_gid(x) make_kgid(&init_user_ns, x) -+#define MAKE_uid(x) make_kuid(&init_user_ns, x) -+#endif -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) -+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t rdev) -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, -+ dev_t rdev) -+#else -+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, -+ int rdev) -+#endif -+{ -+ struct inode *inode; -+ -+ struct yaffs_obj *obj = NULL; -+ struct yaffs_dev *dev; -+ -+ struct yaffs_obj *parent = yaffs_inode_to_obj(dir); -+ -+ int error = -ENOSPC; -+ uid_t uid = YPROC_uid(current); -+ gid_t gid = -+ (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current); -+ -+ if ((dir->i_mode & S_ISGID) && S_ISDIR(mode)) -+ mode |= S_ISGID; -+ -+ if (parent) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_mknod: parent object %d type %d", -+ parent->obj_id, parent->variant_type); -+ } else { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_mknod: could not get parent object"); -+ return -EPERM; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_mknod: making oject for %s, mode %x dev %x", -+ dentry->d_name.name, mode, rdev); -+ -+ dev = parent->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ switch (mode & S_IFMT) { -+ default: -+ /* Special (socket, fifo, device...) */ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making special"); -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+ obj = -+ yaffs_create_special(parent, dentry->d_name.name, mode, uid, -+ gid, old_encode_dev(rdev)); -+#else -+ obj = -+ yaffs_create_special(parent, dentry->d_name.name, mode, uid, -+ gid, rdev); -+#endif -+ break; -+ case S_IFREG: /* file */ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making file"); -+ obj = yaffs_create_file(parent, dentry->d_name.name, mode, uid, -+ gid); -+ break; -+ case S_IFDIR: /* directory */ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making directory"); -+ obj = yaffs_create_dir(parent, dentry->d_name.name, mode, -+ uid, gid); -+ break; -+ case S_IFLNK: /* symlink */ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod: making symlink"); -+ obj = NULL; /* Do we ever get here? */ -+ break; -+ } -+ -+ /* Can not call yaffs_get_inode() with gross lock held */ -+ yaffs_gross_unlock(dev); -+ -+ if (obj) { -+ inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); -+ d_instantiate(dentry, inode); -+ update_dir_time(dir); -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_mknod created object %d count = %d", -+ obj->obj_id, atomic_read(&inode->i_count)); -+ error = 0; -+ yaffs_fill_inode_from_obj(dir, parent); -+ } else { -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mknod failed making object"); -+ error = -ENOMEM; -+ } -+ -+ return error; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) -+static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -+#else -+static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -+#endif -+{ -+ int ret_val; -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_mkdir"); -+ ret_val = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0); -+ return ret_val; -+} -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) -+static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool dummy) -+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) -+static int yaffs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ struct nameidata *n) -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, -+ struct nameidata *n) -+#else -+static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) -+#endif -+{ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_create"); -+ return yaffs_mknod(dir, dentry, mode | S_IFREG, 0); -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) -+static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, -+ unsigned int dummy) -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, -+ struct nameidata *n) -+#else -+static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) -+#endif -+{ -+ struct yaffs_obj *obj; -+ struct inode *inode = NULL; /* NCB 2.5/2.6 needs NULL here */ -+ -+ struct yaffs_dev *dev = yaffs_inode_to_obj(dir)->my_dev; -+ -+ if (current != yaffs_dev_to_lc(dev)->readdir_process) -+ yaffs_gross_lock(dev); -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup for %d:%s", -+ yaffs_inode_to_obj(dir)->obj_id, dentry->d_name.name); -+ -+ obj = yaffs_find_by_name(yaffs_inode_to_obj(dir), dentry->d_name.name); -+ -+ obj = yaffs_get_equivalent_obj(obj); /* in case it was a hardlink */ -+ -+ /* Can't hold gross lock when calling yaffs_get_inode() */ -+ if (current != yaffs_dev_to_lc(dev)->readdir_process) -+ yaffs_gross_unlock(dev); -+ -+ if (obj) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_lookup found %d", obj->obj_id); -+ -+ inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); -+ } else { -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_lookup not found"); -+ -+ } -+ -+/* added NCB for 2.5/6 compatability - forces add even if inode is -+ * NULL which creates dentry hash */ -+ d_add(dentry, inode); -+ -+ return NULL; -+} -+ -+/* -+ * Create a link... -+ */ -+static int yaffs_link(struct dentry *old_dentry, struct inode *dir, -+ struct dentry *dentry) -+{ -+ struct inode *inode = old_dentry->d_inode; -+ struct yaffs_obj *obj = NULL; -+ struct yaffs_obj *link = NULL; -+ struct yaffs_dev *dev; -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_link"); -+ -+ obj = yaffs_inode_to_obj(inode); -+ dev = obj->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ if (!S_ISDIR(inode->i_mode)) /* Don't link directories */ -+ link = -+ yaffs_link_obj(yaffs_inode_to_obj(dir), dentry->d_name.name, -+ obj); -+ -+ if (link) { -+ set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj)); -+ d_instantiate(dentry, old_dentry->d_inode); -+ atomic_inc(&old_dentry->d_inode->i_count); -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_link link count %d i_count %d", -+ old_dentry->d_inode->i_nlink, -+ atomic_read(&old_dentry->d_inode->i_count)); -+ } -+ -+ yaffs_gross_unlock(dev); -+ -+ if (link) { -+ update_dir_time(dir); -+ return 0; -+ } -+ -+ return -EPERM; -+} -+ -+static int yaffs_symlink(struct inode *dir, struct dentry *dentry, -+ const char *symname) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+ uid_t uid = YPROC_uid(current); -+ gid_t gid = -+ (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current); -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink"); -+ -+ if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) > -+ YAFFS_MAX_NAME_LENGTH) -+ return -ENAMETOOLONG; -+ -+ if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) > -+ YAFFS_MAX_ALIAS_LENGTH) -+ return -ENAMETOOLONG; -+ -+ dev = yaffs_inode_to_obj(dir)->my_dev; -+ yaffs_gross_lock(dev); -+ obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name, -+ S_IFLNK | S_IRWXUGO, uid, gid, symname); -+ yaffs_gross_unlock(dev); -+ -+ if (obj) { -+ struct inode *inode; -+ -+ inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); -+ d_instantiate(dentry, inode); -+ update_dir_time(dir); -+ yaffs_trace(YAFFS_TRACE_OS, "symlink created OK"); -+ return 0; -+ } else { -+ yaffs_trace(YAFFS_TRACE_OS, "symlink not created"); -+ } -+ -+ return -ENOMEM; -+} -+ -+/* -+ * The VFS layer already does all the dentry stuff for rename. -+ * -+ * NB: POSIX says you can rename an object over an old object of the same name -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) -+static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, unsigned int unused) -+#else -+static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry) -+#endif -+{ -+ struct yaffs_dev *dev; -+ int ret_val = YAFFS_FAIL; -+ struct yaffs_obj *target; -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_rename"); -+ dev = yaffs_inode_to_obj(old_dir)->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ /* Check if the target is an existing directory that is not empty. */ -+ target = yaffs_find_by_name(yaffs_inode_to_obj(new_dir), -+ new_dentry->d_name.name); -+ -+ if (target && target->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY && -+ !list_empty(&target->variant.dir_variant.children)) { -+ -+ yaffs_trace(YAFFS_TRACE_OS, "target is non-empty dir"); -+ -+ ret_val = YAFFS_FAIL; -+ } else { -+ /* Now does unlinking internally using shadowing mechanism */ -+ yaffs_trace(YAFFS_TRACE_OS, "calling yaffs_rename_obj"); -+ -+ ret_val = yaffs_rename_obj(yaffs_inode_to_obj(old_dir), -+ old_dentry->d_name.name, -+ yaffs_inode_to_obj(new_dir), -+ new_dentry->d_name.name); -+ } -+ yaffs_gross_unlock(dev); -+ -+ if (ret_val == YAFFS_OK) { -+ if (target) -+ inode_dec_link_count(new_dentry->d_inode); -+ -+ update_dir_time(old_dir); -+ if (old_dir != new_dir) -+ update_dir_time(new_dir); -+ return 0; -+ } else { -+ return -ENOTEMPTY; -+ } -+} -+ -+ -+ -+ -+static int yaffs_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ int ret_val; -+ -+ struct yaffs_dev *dev; -+ struct yaffs_obj *obj; -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_unlink %d:%s", -+ (int)(dir->i_ino), dentry->d_name.name); -+ obj = yaffs_inode_to_obj(dir); -+ dev = obj->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ ret_val = yaffs_unlinker(obj, dentry->d_name.name); -+ -+ if (ret_val == YAFFS_OK) { -+ inode_dec_link_count(dentry->d_inode); -+ dir->i_version++; -+ yaffs_gross_unlock(dev); -+ update_dir_time(dir); -+ return 0; -+ } -+ yaffs_gross_unlock(dev); -+ return -ENOTEMPTY; -+} -+ -+ -+ -+static const struct inode_operations yaffs_dir_inode_operations = { -+ .create = yaffs_create, -+ .lookup = yaffs_lookup, -+ .link = yaffs_link, -+ .unlink = yaffs_unlink, -+ .symlink = yaffs_symlink, -+ .mkdir = yaffs_mkdir, -+ .rmdir = yaffs_unlink, -+ .mknod = yaffs_mknod, -+ .rename = yaffs_rename, -+ .setattr = yaffs_setattr, -+ .listxattr = yaffs_listxattr, -+#ifdef YAFFS_USE_XATTR -+ .setxattr = yaffs_setxattr, -+ .getxattr = yaffs_getxattr, -+ .removexattr = yaffs_removexattr, -+#endif -+}; -+ -+/*-----------------------------------------------------------------*/ -+/* Directory search context allows us to unlock access to yaffs during -+ * filldir without causing problems with the directory being modified. -+ * This is similar to the tried and tested mechanism used in yaffs direct. -+ * -+ * A search context iterates along a doubly linked list of siblings in the -+ * directory. If the iterating object is deleted then this would corrupt -+ * the list iteration, likely causing a crash. The search context avoids -+ * this by using the remove_obj_fn to move the search context to the -+ * next object before the object is deleted. -+ * -+ * Many readdirs (and thus seach conexts) may be alive simulateously so -+ * each struct yaffs_dev has a list of these. -+ * -+ * A seach context lives for the duration of a readdir. -+ * -+ * All these functions must be called while yaffs is locked. -+ */ -+ -+struct yaffs_search_context { -+ struct yaffs_dev *dev; -+ struct yaffs_obj *dir_obj; -+ struct yaffs_obj *next_return; -+ struct list_head others; -+}; -+ -+/* -+ * yaffs_new_search() creates a new search context, initialises it and -+ * adds it to the device's search context list. -+ * -+ * Called at start of readdir. -+ */ -+static struct yaffs_search_context *yaffs_new_search(struct yaffs_obj *dir) -+{ -+ struct yaffs_dev *dev = dir->my_dev; -+ struct yaffs_search_context *sc = -+ kmalloc(sizeof(struct yaffs_search_context), GFP_NOFS); -+ if (sc) { -+ sc->dir_obj = dir; -+ sc->dev = dev; -+ if (list_empty(&sc->dir_obj->variant.dir_variant.children)) -+ sc->next_return = NULL; -+ else -+ sc->next_return = -+ list_entry(dir->variant.dir_variant.children.next, -+ struct yaffs_obj, siblings); -+ INIT_LIST_HEAD(&sc->others); -+ list_add(&sc->others, &(yaffs_dev_to_lc(dev)->search_contexts)); -+ } -+ return sc; -+} -+ -+/* -+ * yaffs_search_end() disposes of a search context and cleans up. -+ */ -+static void yaffs_search_end(struct yaffs_search_context *sc) -+{ -+ if (sc) { -+ list_del(&sc->others); -+ kfree(sc); -+ } -+} -+ -+/* -+ * yaffs_search_advance() moves a search context to the next object. -+ * Called when the search iterates or when an object removal causes -+ * the search context to be moved to the next object. -+ */ -+static void yaffs_search_advance(struct yaffs_search_context *sc) -+{ -+ if (!sc) -+ return; -+ -+ if (sc->next_return == NULL || -+ list_empty(&sc->dir_obj->variant.dir_variant.children)) -+ sc->next_return = NULL; -+ else { -+ struct list_head *next = sc->next_return->siblings.next; -+ -+ if (next == &sc->dir_obj->variant.dir_variant.children) -+ sc->next_return = NULL; /* end of list */ -+ else -+ sc->next_return = -+ list_entry(next, struct yaffs_obj, siblings); -+ } -+} -+ -+/* -+ * yaffs_remove_obj_callback() is called when an object is unlinked. -+ * We check open search contexts and advance any which are currently -+ * on the object being iterated. -+ */ -+static void yaffs_remove_obj_callback(struct yaffs_obj *obj) -+{ -+ -+ struct list_head *i; -+ struct yaffs_search_context *sc; -+ struct list_head *search_contexts = -+ &(yaffs_dev_to_lc(obj->my_dev)->search_contexts); -+ -+ /* Iterate through the directory search contexts. -+ * If any are currently on the object being removed, then advance -+ * the search context to the next object to prevent a hanging pointer. -+ */ -+ list_for_each(i, search_contexts) { -+ sc = list_entry(i, struct yaffs_search_context, others); -+ if (sc->next_return == obj) -+ yaffs_search_advance(sc); -+ } -+ -+} -+ -+ -+/*-----------------------------------------------------------------*/ -+ -+#ifdef YAFFS_USE_DIR_ITERATE -+static int yaffs_iterate(struct file *f, struct dir_context *dc) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+ struct yaffs_search_context *sc; -+ unsigned long curoffs; -+ struct yaffs_obj *l; -+ int ret_val = 0; -+ -+ char name[YAFFS_MAX_NAME_LENGTH + 1]; -+ -+ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); -+ dev = obj->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ yaffs_dev_to_lc(dev)->readdir_process = current; -+ -+ sc = yaffs_new_search(obj); -+ if (!sc) { -+ ret_val = -ENOMEM; -+ goto out; -+ } -+ -+ if (!dir_emit_dots(f, dc)) -+ return 0; -+ -+ curoffs = 1; -+ -+ while (sc->next_return) { -+ curoffs++; -+ l = sc->next_return; -+ if (curoffs >= dc->pos) { -+ int this_inode = yaffs_get_obj_inode(l); -+ int this_type = yaffs_get_obj_type(l); -+ -+ yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1); -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_readdir: %s inode %d", -+ name, yaffs_get_obj_inode(l)); -+ -+ yaffs_gross_unlock(dev); -+ -+ if (!dir_emit(dc, -+ name, -+ strlen(name), -+ this_inode, -+ this_type)) { -+ yaffs_gross_lock(dev); -+ goto out; -+ } -+ -+ yaffs_gross_lock(dev); -+ -+ dc->pos++; -+ f->f_pos++; -+ } -+ yaffs_search_advance(sc); -+ } -+ -+out: -+ yaffs_search_end(sc); -+ yaffs_dev_to_lc(dev)->readdir_process = NULL; -+ yaffs_gross_unlock(dev); -+ -+ return ret_val; -+} -+ -+#else -+ -+static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+ struct yaffs_search_context *sc; -+ struct inode *inode = Y_GET_DENTRY(f)->d_inode; -+ unsigned long offset, curoffs; -+ struct yaffs_obj *l; -+ int ret_val = 0; -+ -+ char name[YAFFS_MAX_NAME_LENGTH + 1]; -+ -+ obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f)); -+ dev = obj->my_dev; -+ -+ yaffs_gross_lock(dev); -+ -+ yaffs_dev_to_lc(dev)->readdir_process = current; -+ -+ offset = f->f_pos; -+ -+ sc = yaffs_new_search(obj); -+ if (!sc) { -+ ret_val = -ENOMEM; -+ goto out; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_readdir: starting at %d", (int)offset); -+ -+ if (offset == 0) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_readdir: entry . ino %d", -+ (int)inode->i_ino); -+ yaffs_gross_unlock(dev); -+ if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0) { -+ yaffs_gross_lock(dev); -+ goto out; -+ } -+ yaffs_gross_lock(dev); -+ offset++; -+ f->f_pos++; -+ } -+ if (offset == 1) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_readdir: entry .. ino %d", -+ (int)f->f_dentry->d_parent->d_inode->i_ino); -+ yaffs_gross_unlock(dev); -+ if (filldir(dirent, "..", 2, offset, -+ f->f_dentry->d_parent->d_inode->i_ino, -+ DT_DIR) < 0) { -+ yaffs_gross_lock(dev); -+ goto out; -+ } -+ yaffs_gross_lock(dev); -+ offset++; -+ f->f_pos++; -+ } -+ -+ curoffs = 1; -+ -+ /* If the directory has changed since the open or last call to -+ readdir, rewind to after the 2 canned entries. */ -+ if (f->f_version != inode->i_version) { -+ offset = 2; -+ f->f_pos = offset; -+ f->f_version = inode->i_version; -+ } -+ -+ while (sc->next_return) { -+ curoffs++; -+ l = sc->next_return; -+ if (curoffs >= offset) { -+ int this_inode = yaffs_get_obj_inode(l); -+ int this_type = yaffs_get_obj_type(l); -+ -+ yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1); -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_readdir: %s inode %d", -+ name, yaffs_get_obj_inode(l)); -+ -+ yaffs_gross_unlock(dev); -+ -+ if (filldir(dirent, -+ name, -+ strlen(name), -+ offset, this_inode, this_type) < 0) { -+ yaffs_gross_lock(dev); -+ goto out; -+ } -+ -+ yaffs_gross_lock(dev); -+ -+ offset++; -+ f->f_pos++; -+ } -+ yaffs_search_advance(sc); -+ } -+ -+out: -+ yaffs_search_end(sc); -+ yaffs_dev_to_lc(dev)->readdir_process = NULL; -+ yaffs_gross_unlock(dev); -+ -+ return ret_val; -+} -+ -+#endif -+ -+static const struct file_operations yaffs_dir_operations = { -+ .read = generic_read_dir, -+#ifdef YAFFS_USE_DIR_ITERATE -+ .iterate = yaffs_iterate, -+#else -+ .readdir = yaffs_readdir, -+#endif -+ .fsync = yaffs_sync_object, -+ .llseek = generic_file_llseek, -+}; -+ -+static void yaffs_fill_inode_from_obj(struct inode *inode, -+ struct yaffs_obj *obj) -+{ -+ if (inode && obj) { -+ -+ /* Check mode against the variant type and attempt to repair if broken. */ -+ u32 mode = obj->yst_mode; -+ switch (obj->variant_type) { -+ case YAFFS_OBJECT_TYPE_FILE: -+ if (!S_ISREG(mode)) { -+ obj->yst_mode &= ~S_IFMT; -+ obj->yst_mode |= S_IFREG; -+ } -+ -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ if (!S_ISLNK(mode)) { -+ obj->yst_mode &= ~S_IFMT; -+ obj->yst_mode |= S_IFLNK; -+ } -+ -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ if (!S_ISDIR(mode)) { -+ obj->yst_mode &= ~S_IFMT; -+ obj->yst_mode |= S_IFDIR; -+ } -+ -+ break; -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ default: -+ /* TODO? */ -+ break; -+ } -+ -+ inode->i_flags |= S_NOATIME; -+ -+ inode->i_ino = obj->obj_id; -+ inode->i_mode = obj->yst_mode; -+ inode->i_uid = MAKE_uid(obj->yst_uid); -+ inode->i_gid = MAKE_gid(obj->yst_gid); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) -+ inode->i_blksize = inode->i_sb->s_blocksize; -+#endif -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+ -+ inode->i_rdev = old_decode_dev(obj->yst_rdev); -+ inode->i_atime.tv_sec = (time_t) (obj->yst_atime); -+ inode->i_atime.tv_nsec = 0; -+ inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; -+ inode->i_mtime.tv_nsec = 0; -+ inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; -+ inode->i_ctime.tv_nsec = 0; -+#else -+ inode->i_rdev = obj->yst_rdev; -+ inode->i_atime = obj->yst_atime; -+ inode->i_mtime = obj->yst_mtime; -+ inode->i_ctime = obj->yst_ctime; -+#endif -+ inode->i_size = yaffs_get_obj_length(obj); -+ inode->i_blocks = (inode->i_size + 511) >> 9; -+ -+ set_nlink(inode, yaffs_get_obj_link_count(obj)); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d", -+ inode->i_mode, obj->yst_uid, obj->yst_gid, -+ inode->i_size, atomic_read(&inode->i_count)); -+ -+ switch (obj->yst_mode & S_IFMT) { -+ default: /* fifo, device or socket */ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+ init_special_inode(inode, obj->yst_mode, -+ old_decode_dev(obj->yst_rdev)); -+#else -+ init_special_inode(inode, obj->yst_mode, -+ (dev_t) (obj->yst_rdev)); -+#endif -+ break; -+ case S_IFREG: /* file */ -+ inode->i_op = &yaffs_file_inode_operations; -+ inode->i_fop = &yaffs_file_operations; -+ inode->i_mapping->a_ops = -+ &yaffs_file_address_operations; -+ break; -+ case S_IFDIR: /* directory */ -+ inode->i_op = &yaffs_dir_inode_operations; -+ inode->i_fop = &yaffs_dir_operations; -+ break; -+ case S_IFLNK: /* symlink */ -+ inode->i_op = &yaffs_symlink_inode_operations; -+ break; -+ } -+ -+ yaffs_inode_to_obj_lv(inode) = obj; -+ -+ obj->my_inode = inode; -+ -+ } else { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_fill_inode invalid parameters"); -+ } -+ -+} -+ -+ -+ -+/* -+ * yaffs background thread functions . -+ * yaffs_bg_thread_fn() the thread function -+ * yaffs_bg_start() launches the background thread. -+ * yaffs_bg_stop() cleans up the background thread. -+ * -+ * NB: -+ * The thread should only run after the yaffs is initialised -+ * The thread should be stopped before yaffs is unmounted. -+ * The thread should not do any writing while the fs is in read only. -+ */ -+ -+static unsigned yaffs_bg_gc_urgency(struct yaffs_dev *dev) -+{ -+ unsigned erased_chunks = -+ dev->n_erased_blocks * dev->param.chunks_per_block; -+ struct yaffs_linux_context *context = yaffs_dev_to_lc(dev); -+ unsigned scattered = 0; /* Free chunks not in an erased block */ -+ -+ if (erased_chunks < dev->n_free_chunks) -+ scattered = (dev->n_free_chunks - erased_chunks); -+ -+ if (!context->bg_running) -+ return 0; -+ else if (scattered < (dev->param.chunks_per_block * 2)) -+ return 0; -+ else if (erased_chunks > dev->n_free_chunks / 2) -+ return 0; -+ else if (erased_chunks > dev->n_free_chunks / 4) -+ return 1; -+ else -+ return 2; -+} -+ -+#ifdef YAFFS_COMPILE_BACKGROUND -+ -+void yaffs_background_waker(unsigned long data) -+{ -+ wake_up_process((struct task_struct *)data); -+} -+ -+static int yaffs_bg_thread_fn(void *data) -+{ -+ struct yaffs_dev *dev = (struct yaffs_dev *)data; -+ struct yaffs_linux_context *context = yaffs_dev_to_lc(dev); -+ unsigned long now = jiffies; -+ unsigned long next_dir_update = now; -+ unsigned long next_gc = now; -+ unsigned long expires; -+ unsigned int urgency; -+ -+ int gc_result; -+ struct timer_list timer; -+ -+ yaffs_trace(YAFFS_TRACE_BACKGROUND, -+ "yaffs_background starting for dev %p", (void *)dev); -+ -+#ifdef YAFFS_COMPILE_FREEZER -+ set_freezable(); -+#endif -+ while (context->bg_running) { -+ yaffs_trace(YAFFS_TRACE_BACKGROUND, "yaffs_background"); -+ -+ if (kthread_should_stop()) -+ break; -+ -+#ifdef YAFFS_COMPILE_FREEZER -+ if (try_to_freeze()) -+ continue; -+#endif -+ yaffs_gross_lock(dev); -+ -+ now = jiffies; -+ -+ if (time_after(now, next_dir_update) && yaffs_bg_enable) { -+ yaffs_update_dirty_dirs(dev); -+ next_dir_update = now + HZ; -+ } -+ -+ if (time_after(now, next_gc) && yaffs_bg_enable) { -+ if (!dev->is_checkpointed) { -+ urgency = yaffs_bg_gc_urgency(dev); -+ gc_result = yaffs_bg_gc(dev, urgency); -+ if (urgency > 1) -+ next_gc = now + HZ / 20 + 1; -+ else if (urgency > 0) -+ next_gc = now + HZ / 10 + 1; -+ else -+ next_gc = now + HZ * 2; -+ } else { -+ /* -+ * gc not running so set to next_dir_update -+ * to cut down on wake ups -+ */ -+ next_gc = next_dir_update; -+ } -+ } -+ yaffs_gross_unlock(dev); -+#if 1 -+ expires = next_dir_update; -+ if (time_before(next_gc, expires)) -+ expires = next_gc; -+ if (time_before(expires, now)) -+ expires = now + HZ; -+ -+ Y_INIT_TIMER(&timer); -+ timer.expires = expires + 1; -+ timer.data = (unsigned long)current; -+ timer.function = yaffs_background_waker; -+ -+ set_current_state(TASK_INTERRUPTIBLE); -+ add_timer(&timer); -+ schedule(); -+ del_timer_sync(&timer); -+#else -+ msleep(10); -+#endif -+ } -+ -+ return 0; -+} -+ -+static int yaffs_bg_start(struct yaffs_dev *dev) -+{ -+ int retval = 0; -+ struct yaffs_linux_context *context = yaffs_dev_to_lc(dev); -+ -+ if (dev->read_only) -+ return -1; -+ -+ context->bg_running = 1; -+ -+ context->bg_thread = kthread_run(yaffs_bg_thread_fn, -+ (void *)dev, "yaffs-bg-%d", -+ context->mount_id); -+ -+ if (IS_ERR(context->bg_thread)) { -+ retval = PTR_ERR(context->bg_thread); -+ context->bg_thread = NULL; -+ context->bg_running = 0; -+ } -+ return retval; -+} -+ -+static void yaffs_bg_stop(struct yaffs_dev *dev) -+{ -+ struct yaffs_linux_context *ctxt = yaffs_dev_to_lc(dev); -+ -+ ctxt->bg_running = 0; -+ -+ if (ctxt->bg_thread) { -+ kthread_stop(ctxt->bg_thread); -+ ctxt->bg_thread = NULL; -+ } -+} -+#else -+static int yaffs_bg_thread_fn(void *data) -+{ -+ return 0; -+} -+ -+static int yaffs_bg_start(struct yaffs_dev *dev) -+{ -+ return 0; -+} -+ -+static void yaffs_bg_stop(struct yaffs_dev *dev) -+{ -+} -+#endif -+ -+ -+static void yaffs_flush_inodes(struct super_block *sb) -+{ -+ struct inode *iptr; -+ struct yaffs_obj *obj; -+ -+ list_for_each_entry(iptr, &sb->s_inodes, i_sb_list) { -+ obj = yaffs_inode_to_obj(iptr); -+ if (obj) { -+ yaffs_trace(YAFFS_TRACE_OS, -+ "flushing obj %d", -+ obj->obj_id); -+ yaffs_flush_file(obj, 1, 0, 0); -+ } -+ } -+} -+ -+static void yaffs_flush_super(struct super_block *sb, int do_checkpoint) -+{ -+ struct yaffs_dev *dev = yaffs_super_to_dev(sb); -+ if (!dev) -+ return; -+ -+ yaffs_flush_inodes(sb); -+ yaffs_update_dirty_dirs(dev); -+ yaffs_flush_whole_cache(dev, 1); -+ if (do_checkpoint) -+ yaffs_checkpoint_save(dev); -+} -+ -+static LIST_HEAD(yaffs_context_list); -+struct mutex yaffs_context_lock; -+ -+static void yaffs_put_super(struct super_block *sb) -+{ -+ struct yaffs_dev *dev = yaffs_super_to_dev(sb); -+ struct mtd_info *mtd = yaffs_dev_to_mtd(dev); -+ -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS, -+ "yaffs_put_super"); -+ -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND, -+ "Shutting down yaffs background thread"); -+ yaffs_bg_stop(dev); -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND, -+ "yaffs background thread shut down"); -+ -+ yaffs_gross_lock(dev); -+ -+ yaffs_flush_super(sb, 1); -+ -+ yaffs_deinitialise(dev); -+ -+ yaffs_gross_unlock(dev); -+ -+ mutex_lock(&yaffs_context_lock); -+ list_del_init(&(yaffs_dev_to_lc(dev)->context_list)); -+ mutex_unlock(&yaffs_context_lock); -+ -+ if (yaffs_dev_to_lc(dev)->spare_buffer) { -+ kfree(yaffs_dev_to_lc(dev)->spare_buffer); -+ yaffs_dev_to_lc(dev)->spare_buffer = NULL; -+ } -+ -+ kfree(dev); -+ -+ yaffs_put_mtd_device(mtd); -+ -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS, -+ "yaffs_put_super done"); -+} -+ -+ -+static unsigned yaffs_gc_control_callback(struct yaffs_dev *dev) -+{ -+ return yaffs_gc_control; -+} -+ -+ -+#ifdef YAFFS_COMPILE_EXPORTFS -+ -+static struct inode *yaffs2_nfs_get_inode(struct super_block *sb, uint64_t ino, -+ uint32_t generation) -+{ -+ return Y_IGET(sb, ino); -+} -+ -+static struct dentry *yaffs2_fh_to_dentry(struct super_block *sb, -+ struct fid *fid, int fh_len, -+ int fh_type) -+{ -+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type, -+ yaffs2_nfs_get_inode); -+} -+ -+static struct dentry *yaffs2_fh_to_parent(struct super_block *sb, -+ struct fid *fid, int fh_len, -+ int fh_type) -+{ -+ return generic_fh_to_parent(sb, fid, fh_len, fh_type, -+ yaffs2_nfs_get_inode); -+} -+ -+struct dentry *yaffs2_get_parent(struct dentry *dentry) -+{ -+ -+ struct super_block *sb = dentry->d_inode->i_sb; -+ struct dentry *parent = ERR_PTR(-ENOENT); -+ struct inode *inode; -+ unsigned long parent_ino; -+ struct yaffs_obj *d_obj; -+ struct yaffs_obj *parent_obj; -+ -+ d_obj = yaffs_inode_to_obj(dentry->d_inode); -+ -+ if (d_obj) { -+ parent_obj = d_obj->parent; -+ if (parent_obj) { -+ parent_ino = yaffs_get_obj_inode(parent_obj); -+ inode = Y_IGET(sb, parent_ino); -+ -+ if (IS_ERR(inode)) { -+ parent = ERR_CAST(inode); -+ } else { -+ parent = d_obtain_alias(inode); -+ if (!IS_ERR(parent)) { -+ parent = ERR_PTR(-ENOMEM); -+ iput(inode); -+ } -+ } -+ } -+ } -+ -+ return parent; -+} -+ -+/* Just declare a zero structure as a NULL value implies -+ * using the default functions of exportfs. -+ */ -+ -+static struct export_operations yaffs_export_ops = { -+ .fh_to_dentry = yaffs2_fh_to_dentry, -+ .fh_to_parent = yaffs2_fh_to_parent, -+ .get_parent = yaffs2_get_parent, -+}; -+ -+#endif -+ -+static void yaffs_unstitch_obj(struct inode *inode, struct yaffs_obj *obj) -+{ -+ /* Clear the association between the inode and -+ * the struct yaffs_obj. -+ */ -+ obj->my_inode = NULL; -+ yaffs_inode_to_obj_lv(inode) = NULL; -+ -+ /* If the object freeing was deferred, then the real -+ * free happens now. -+ * This should fix the inode inconsistency problem. -+ */ -+ yaffs_handle_defered_free(obj); -+} -+ -+#ifdef YAFFS_HAS_EVICT_INODE -+/* yaffs_evict_inode combines into one operation what was previously done in -+ * yaffs_clear_inode() and yaffs_delete_inode() -+ * -+ */ -+static void yaffs_evict_inode(struct inode *inode) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+ int deleteme = 0; -+ -+ obj = yaffs_inode_to_obj(inode); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_evict_inode: ino %d, count %d %s", -+ (int)inode->i_ino, atomic_read(&inode->i_count), -+ obj ? "object exists" : "null object"); -+ -+ if (!inode->i_nlink && !is_bad_inode(inode)) -+ deleteme = 1; -+ truncate_inode_pages(&inode->i_data, 0); -+ Y_CLEAR_INODE(inode); -+ -+ if (deleteme && obj) { -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ yaffs_del_obj(obj); -+ yaffs_gross_unlock(dev); -+ } -+ if (obj) { -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ yaffs_unstitch_obj(inode, obj); -+ yaffs_gross_unlock(dev); -+ } -+} -+#else -+ -+/* clear is called to tell the fs to release any per-inode data it holds. -+ * The object might still exist on disk and is just being thrown out of the cache -+ * or else the object has actually been deleted and we're being called via -+ * the chain -+ * yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode() -+ */ -+ -+static void yaffs_clear_inode(struct inode *inode) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_dev *dev; -+ -+ obj = yaffs_inode_to_obj(inode); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_clear_inode: ino %d, count %d %s", -+ (int)inode->i_ino, atomic_read(&inode->i_count), -+ obj ? "object exists" : "null object"); -+ -+ if (obj) { -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ yaffs_unstitch_obj(inode, obj); -+ yaffs_gross_unlock(dev); -+ } -+ -+} -+ -+/* delete is called when the link count is zero and the inode -+ * is put (ie. nobody wants to know about it anymore, time to -+ * delete the file). -+ * NB Must call clear_inode() -+ */ -+static void yaffs_delete_inode(struct inode *inode) -+{ -+ struct yaffs_obj *obj = yaffs_inode_to_obj(inode); -+ struct yaffs_dev *dev; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_delete_inode: ino %d, count %d %s", -+ (int)inode->i_ino, atomic_read(&inode->i_count), -+ obj ? "object exists" : "null object"); -+ -+ if (obj) { -+ dev = obj->my_dev; -+ yaffs_gross_lock(dev); -+ yaffs_del_obj(obj); -+ yaffs_gross_unlock(dev); -+ } -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13)) -+ truncate_inode_pages(&inode->i_data, 0); -+#endif -+ clear_inode(inode); -+} -+#endif -+ -+ -+ -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ struct yaffs_dev *dev = yaffs_dentry_to_obj(dentry)->my_dev; -+ struct super_block *sb = dentry->d_sb; -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf) -+{ -+ struct yaffs_dev *dev = yaffs_super_to_dev(sb); -+#else -+static int yaffs_statfs(struct super_block *sb, struct statfs *buf) -+{ -+ struct yaffs_dev *dev = yaffs_super_to_dev(sb); -+#endif -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_statfs"); -+ -+ yaffs_gross_lock(dev); -+ -+ buf->f_type = YAFFS_MAGIC; -+ buf->f_bsize = sb->s_blocksize; -+ buf->f_namelen = 255; -+ -+ if (dev->data_bytes_per_chunk & (dev->data_bytes_per_chunk - 1)) { -+ /* Do this if chunk size is not a power of 2 */ -+ -+ uint64_t bytes_in_dev; -+ uint64_t bytes_free; -+ -+ bytes_in_dev = -+ ((uint64_t) -+ ((dev->param.end_block - dev->param.start_block + -+ 1))) * ((uint64_t) (dev->param.chunks_per_block * -+ dev->data_bytes_per_chunk)); -+ -+ do_div(bytes_in_dev, sb->s_blocksize); /* bytes_in_dev becomes the number of blocks */ -+ buf->f_blocks = bytes_in_dev; -+ -+ bytes_free = ((uint64_t) (yaffs_get_n_free_chunks(dev))) * -+ ((uint64_t) (dev->data_bytes_per_chunk)); -+ -+ do_div(bytes_free, sb->s_blocksize); -+ -+ buf->f_bfree = bytes_free; -+ -+ } else if (sb->s_blocksize > dev->data_bytes_per_chunk) { -+ -+ buf->f_blocks = -+ (dev->param.end_block - dev->param.start_block + 1) * -+ dev->param.chunks_per_block / -+ (sb->s_blocksize / dev->data_bytes_per_chunk); -+ buf->f_bfree = -+ yaffs_get_n_free_chunks(dev) / -+ (sb->s_blocksize / dev->data_bytes_per_chunk); -+ } else { -+ buf->f_blocks = -+ (dev->param.end_block - dev->param.start_block + 1) * -+ dev->param.chunks_per_block * -+ (dev->data_bytes_per_chunk / sb->s_blocksize); -+ -+ buf->f_bfree = -+ yaffs_get_n_free_chunks(dev) * -+ (dev->data_bytes_per_chunk / sb->s_blocksize); -+ } -+ -+ buf->f_files = 0; -+ buf->f_ffree = 0; -+ buf->f_bavail = buf->f_bfree; -+ -+ yaffs_gross_unlock(dev); -+ return 0; -+} -+ -+ -+ -+static int yaffs_do_sync_fs(struct super_block *sb, int request_checkpoint) -+{ -+ -+ struct yaffs_dev *dev = yaffs_super_to_dev(sb); -+ unsigned int oneshot_checkpoint = (yaffs_auto_checkpoint & 4); -+ unsigned gc_urgent = yaffs_bg_gc_urgency(dev); -+ int do_checkpoint; -+ int dirty = yaffs_check_super_dirty(dev); -+ -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND, -+ "yaffs_do_sync_fs: gc-urgency %d %s %s%s", -+ gc_urgent, -+ dirty ? "dirty" : "clean", -+ request_checkpoint ? "checkpoint requested" : "no checkpoint", -+ oneshot_checkpoint ? " one-shot" : ""); -+ -+ yaffs_gross_lock(dev); -+ do_checkpoint = ((request_checkpoint && !gc_urgent) || -+ oneshot_checkpoint) && !dev->is_checkpointed; -+ -+ if (dirty || do_checkpoint) { -+ yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint); -+ yaffs_clear_super_dirty(dev); -+ if (oneshot_checkpoint) -+ yaffs_auto_checkpoint &= ~4; -+ } -+ yaffs_gross_unlock(dev); -+ -+ return 0; -+} -+ -+ -+#ifdef YAFFS_HAS_WRITE_SUPER -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+static void yaffs_write_super(struct super_block *sb) -+#else -+static int yaffs_write_super(struct super_block *sb) -+#endif -+{ -+ unsigned request_checkpoint = (yaffs_auto_checkpoint >= 2); -+ -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND, -+ "yaffs_write_super %s", -+ request_checkpoint ? " checkpt" : ""); -+ -+ yaffs_do_sync_fs(sb, request_checkpoint); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)) -+ return 0; -+#endif -+} -+#endif -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+static int yaffs_sync_fs(struct super_block *sb, int wait) -+#else -+static int yaffs_sync_fs(struct super_block *sb) -+#endif -+{ -+ unsigned request_checkpoint = (yaffs_auto_checkpoint >= 1); -+ -+ yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC, -+ "yaffs_sync_fs%s", request_checkpoint ? " checkpt" : ""); -+ -+ yaffs_do_sync_fs(sb, request_checkpoint); -+ -+ return 0; -+} -+ -+/* the function only is used to change dev->read_only when this file system -+ * is remounted. -+ */ -+static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data) -+{ -+ int read_only = 0; -+ struct mtd_info *mtd; -+ struct yaffs_dev *dev = 0; -+ -+ /* Get the device */ -+ mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); -+ if (!mtd) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "MTD device #%u doesn't appear to exist", -+ MINOR(sb->s_dev)); -+ return 1; -+ } -+ -+ /* Check it's NAND */ -+ if (mtd->type != MTD_NANDFLASH) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "MTD device is not NAND it's type %d", -+ mtd->type); -+ return 1; -+ } -+ -+ read_only = ((*flags & MS_RDONLY) != 0); -+ if (!read_only && !(mtd->flags & MTD_WRITEABLE)) { -+ read_only = 1; -+ printk(KERN_INFO -+ "yaffs: mtd is read only, setting superblock read only"); -+ *flags |= MS_RDONLY; -+ } -+ -+ dev = sb->s_fs_info; -+ dev->read_only = read_only; -+ -+ return 0; -+} -+ -+static const struct super_operations yaffs_super_ops = { -+ .statfs = yaffs_statfs, -+ -+#ifndef YAFFS_USE_OWN_IGET -+ .read_inode = yaffs_read_inode, -+#endif -+#ifdef YAFFS_HAS_PUT_INODE -+ .put_inode = yaffs_put_inode, -+#endif -+ .put_super = yaffs_put_super, -+#ifdef YAFFS_HAS_EVICT_INODE -+ .evict_inode = yaffs_evict_inode, -+#else -+ .delete_inode = yaffs_delete_inode, -+ .clear_inode = yaffs_clear_inode, -+#endif -+ .sync_fs = yaffs_sync_fs, -+#ifdef YAFFS_HAS_WRITE_SUPER -+ .write_super = yaffs_write_super, -+#endif -+ .remount_fs = yaffs_remount_fs, -+}; -+ -+struct yaffs_options { -+ int inband_tags; -+ int skip_checkpoint_read; -+ int skip_checkpoint_write; -+ int no_cache; -+ int tags_ecc_on; -+ int tags_ecc_overridden; -+ int lazy_loading_enabled; -+ int lazy_loading_overridden; -+ int empty_lost_and_found; -+ int empty_lost_and_found_overridden; -+ int disable_summary; -+}; -+ -+#define MAX_OPT_LEN 30 -+static int yaffs_parse_options(struct yaffs_options *options, -+ const char *options_str) -+{ -+ char cur_opt[MAX_OPT_LEN + 1]; -+ int p; -+ int error = 0; -+ -+ /* Parse through the options which is a comma seperated list */ -+ -+ while (options_str && *options_str && !error) { -+ memset(cur_opt, 0, MAX_OPT_LEN + 1); -+ p = 0; -+ -+ while (*options_str == ',') -+ options_str++; -+ -+ while (*options_str && *options_str != ',') { -+ if (p < MAX_OPT_LEN) { -+ cur_opt[p] = *options_str; -+ p++; -+ } -+ options_str++; -+ } -+ -+ if (!strcmp(cur_opt, "inband-tags")) { -+ options->inband_tags = 1; -+ } else if (!strcmp(cur_opt, "tags-ecc-off")) { -+ options->tags_ecc_on = 0; -+ options->tags_ecc_overridden = 1; -+ } else if (!strcmp(cur_opt, "tags-ecc-on")) { -+ options->tags_ecc_on = 1; -+ options->tags_ecc_overridden = 1; -+ } else if (!strcmp(cur_opt, "lazy-loading-off")) { -+ options->lazy_loading_enabled = 0; -+ options->lazy_loading_overridden = 1; -+ } else if (!strcmp(cur_opt, "lazy-loading-on")) { -+ options->lazy_loading_enabled = 1; -+ options->lazy_loading_overridden = 1; -+ } else if (!strcmp(cur_opt, "disable-summary")) { -+ options->disable_summary = 1; -+ } else if (!strcmp(cur_opt, "empty-lost-and-found-off")) { -+ options->empty_lost_and_found = 0; -+ options->empty_lost_and_found_overridden = 1; -+ } else if (!strcmp(cur_opt, "empty-lost-and-found-on")) { -+ options->empty_lost_and_found = 1; -+ options->empty_lost_and_found_overridden = 1; -+ } else if (!strcmp(cur_opt, "no-cache")) { -+ options->no_cache = 1; -+ } else if (!strcmp(cur_opt, "no-checkpoint-read")) { -+ options->skip_checkpoint_read = 1; -+ } else if (!strcmp(cur_opt, "no-checkpoint-write")) { -+ options->skip_checkpoint_write = 1; -+ } else if (!strcmp(cur_opt, "no-checkpoint")) { -+ options->skip_checkpoint_read = 1; -+ options->skip_checkpoint_write = 1; -+ } else { -+ printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n", -+ cur_opt); -+ error = 1; -+ } -+ } -+ -+ return error; -+} -+ -+ -+static struct dentry *yaffs_make_root(struct inode *inode) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) -+ struct dentry *root = d_alloc_root(inode); -+ -+ if (!root) -+ iput(inode); -+ -+ return root; -+#else -+ return d_make_root(inode); -+#endif -+} -+ -+ -+ -+ -+static struct super_block *yaffs_internal_read_super(int yaffs_version, -+ struct super_block *sb, -+ void *data, int silent) -+{ -+ int n_blocks; -+ struct inode *inode = NULL; -+ struct dentry *root; -+ struct yaffs_dev *dev = 0; -+ char devname_buf[BDEVNAME_SIZE + 1]; -+ struct mtd_info *mtd; -+ int err; -+ char *data_str = (char *)data; -+ struct yaffs_linux_context *context = NULL; -+ struct yaffs_param *param; -+ -+ int read_only = 0; -+ int inband_tags = 0; -+ -+ struct yaffs_options options; -+ -+ unsigned mount_id; -+ int found; -+ struct yaffs_linux_context *context_iterator; -+ struct list_head *l; -+ -+ if (!sb) { -+ printk(KERN_INFO "yaffs: sb is NULL\n"); -+ return NULL; -+ } -+ -+ sb->s_magic = YAFFS_MAGIC; -+ sb->s_op = &yaffs_super_ops; -+ sb->s_flags |= MS_NOATIME; -+ -+ read_only = ((sb->s_flags & MS_RDONLY) != 0); -+ -+#ifdef YAFFS_COMPILE_EXPORTFS -+ sb->s_export_op = &yaffs_export_ops; -+#endif -+ -+ if (!sb->s_dev) -+ printk(KERN_INFO "yaffs: sb->s_dev is NULL\n"); -+ else if (!yaffs_devname(sb, devname_buf)) -+ printk(KERN_INFO "yaffs: devname is NULL\n"); -+ else -+ printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n", -+ sb->s_dev, -+ yaffs_devname(sb, devname_buf), read_only ? "ro" : "rw"); -+ -+ if (!data_str) -+ data_str = ""; -+ -+ printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str); -+ -+ memset(&options, 0, sizeof(options)); -+ -+ if (yaffs_parse_options(&options, data_str)) { -+ /* Option parsing failed */ -+ return NULL; -+ } -+ -+ sb->s_blocksize = PAGE_CACHE_SIZE; -+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT; -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_read_super: Using yaffs%d", yaffs_version); -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_read_super: block size %d", (int)(sb->s_blocksize)); -+ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs: Attempting MTD mount of %u.%u,\"%s\"", -+ MAJOR(sb->s_dev), MINOR(sb->s_dev), -+ yaffs_devname(sb, devname_buf)); -+ -+ /* Get the device */ -+ mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); -+ if (IS_ERR(mtd)) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs: MTD device %u either not valid or unavailable", -+ MINOR(sb->s_dev)); -+ return NULL; -+ } -+ -+ if (yaffs_auto_select && yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs2"); -+ yaffs_version = 2; -+ } -+ -+ /* Added NCB 26/5/2006 for completeness */ -+ if (yaffs_version == 2 && !options.inband_tags -+ && WRITE_SIZE(mtd) == 512) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "auto selecting yaffs1"); -+ yaffs_version = 1; -+ } -+ -+ if (mtd->oobavail < sizeof(struct yaffs_packed_tags2) || -+ options.inband_tags) -+ inband_tags = 1; -+ -+ if(yaffs_verify_mtd(mtd, yaffs_version, inband_tags) < 0) -+ return NULL; -+ -+ /* OK, so if we got here, we have an MTD that's NAND and looks -+ * like it has the right capabilities -+ * Set the struct yaffs_dev up for mtd -+ */ -+ -+ if (!read_only && !(mtd->flags & MTD_WRITEABLE)) { -+ read_only = 1; -+ printk(KERN_INFO -+ "yaffs: mtd is read only, setting superblock read only\n" -+ ); -+ sb->s_flags |= MS_RDONLY; -+ } -+ -+ dev = kmalloc(sizeof(struct yaffs_dev), GFP_KERNEL); -+ context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL); -+ -+ if (!dev || !context) { -+ kfree(dev); -+ kfree(context); -+ dev = NULL; -+ context = NULL; -+ -+ /* Deep shit could not allocate device structure */ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs_read_super: Failed trying to allocate struct yaffs_dev." -+ ); -+ return NULL; -+ } -+ memset(dev, 0, sizeof(struct yaffs_dev)); -+ param = &(dev->param); -+ -+ memset(context, 0, sizeof(struct yaffs_linux_context)); -+ dev->os_context = context; -+ INIT_LIST_HEAD(&(context->context_list)); -+ context->dev = dev; -+ context->super = sb; -+ -+ dev->read_only = read_only; -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+ sb->s_fs_info = dev; -+#else -+ sb->u.generic_sbp = dev; -+#endif -+ -+ -+ dev->driver_context = mtd; -+ param->name = mtd->name; -+ -+ /* Set up the memory size parameters.... */ -+ -+ -+ param->n_reserved_blocks = 5; -+ param->n_caches = (options.no_cache) ? 0 : 10; -+ param->inband_tags = inband_tags; -+ -+ param->enable_xattr = 1; -+ if (options.lazy_loading_overridden) -+ param->disable_lazy_load = !options.lazy_loading_enabled; -+ -+ param->defered_dir_update = 1; -+ -+ if (options.tags_ecc_overridden) -+ param->no_tags_ecc = !options.tags_ecc_on; -+ -+ param->empty_lost_n_found = 1; -+ param->refresh_period = 500; -+ param->disable_summary = options.disable_summary; -+ -+ -+#ifdef CONFIG_YAFFS_DISABLE_BAD_BLOCK_MARKING -+ param->disable_bad_block_marking = 1; -+#endif -+ if (options.empty_lost_and_found_overridden) -+ param->empty_lost_n_found = options.empty_lost_and_found; -+ -+ /* ... and the functions. */ -+ if (yaffs_version == 2) { -+ param->is_yaffs2 = 1; -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+ param->total_bytes_per_chunk = mtd->writesize; -+ param->chunks_per_block = mtd->erasesize / mtd->writesize; -+#else -+ param->total_bytes_per_chunk = mtd->oobblock; -+ param->chunks_per_block = mtd->erasesize / mtd->oobblock; -+#endif -+ n_blocks = YCALCBLOCKS(mtd->size, mtd->erasesize); -+ -+ param->start_block = 0; -+ param->end_block = n_blocks - 1; -+ } else { -+ param->is_yaffs2 = 0; -+ n_blocks = YCALCBLOCKS(mtd->size, -+ YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); -+ -+ param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK; -+ param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK; -+ } -+ -+ param->start_block = 0; -+ param->end_block = n_blocks - 1; -+ -+ yaffs_mtd_drv_install(dev); -+ -+ param->sb_dirty_fn = yaffs_set_super_dirty; -+ param->gc_control_fn = yaffs_gc_control_callback; -+ -+ yaffs_dev_to_lc(dev)->super = sb; -+ -+ param->use_nand_ecc = 1; -+ -+ param->skip_checkpt_rd = options.skip_checkpoint_read; -+ param->skip_checkpt_wr = options.skip_checkpoint_write; -+ -+ mutex_lock(&yaffs_context_lock); -+ /* Get a mount id */ -+ found = 0; -+ for (mount_id = 0; !found; mount_id++) { -+ found = 1; -+ list_for_each(l, &yaffs_context_list) { -+ context_iterator = -+ list_entry(l, struct yaffs_linux_context, -+ context_list); -+ if (context_iterator->mount_id == mount_id) -+ found = 0; -+ } -+ } -+ context->mount_id = mount_id; -+ -+ list_add_tail(&(yaffs_dev_to_lc(dev)->context_list), -+ &yaffs_context_list); -+ mutex_unlock(&yaffs_context_lock); -+ -+ /* Directory search handling... */ -+ INIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->search_contexts)); -+ param->remove_obj_fn = yaffs_remove_obj_callback; -+ -+ mutex_init(&(yaffs_dev_to_lc(dev)->gross_lock)); -+ -+ yaffs_gross_lock(dev); -+ -+ err = yaffs_guts_initialise(dev); -+ -+ yaffs_trace(YAFFS_TRACE_OS, -+ "yaffs_read_super: guts initialised %s", -+ (err == YAFFS_OK) ? "OK" : "FAILED"); -+ -+ if (err == YAFFS_OK) -+ yaffs_bg_start(dev); -+ -+ if (!context->bg_thread) -+ param->defered_dir_update = 0; -+ -+ sb->s_maxbytes = yaffs_max_file_size(dev); -+ -+ /* Release lock before yaffs_get_inode() */ -+ yaffs_gross_unlock(dev); -+ -+ /* Create root inode */ -+ if (err == YAFFS_OK) -+ inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, yaffs_root(dev)); -+ -+ if (!inode) -+ return NULL; -+ -+ inode->i_op = &yaffs_dir_inode_operations; -+ inode->i_fop = &yaffs_dir_operations; -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: got root inode"); -+ -+ root = yaffs_make_root(inode); -+ -+ if (!root) -+ return NULL; -+ -+ sb->s_root = root; -+ if(!dev->is_checkpointed) -+ yaffs_set_super_dirty(dev); -+ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs_read_super: is_checkpointed %d", -+ dev->is_checkpointed); -+ -+ yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: done"); -+ return sb; -+} -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data, -+ int silent) -+{ -+ return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -+static struct dentry *yaffs_mount(struct file_system_type *fs_type, int flags, -+ const char *dev_name, void *data) -+{ -+ return mount_bdev(fs_type, flags, dev_name, data, yaffs_internal_read_super_mtd); -+} -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+static int yaffs_read_super(struct file_system_type *fs, -+ int flags, const char *dev_name, -+ void *data, struct vfsmount *mnt) -+{ -+ -+ return get_sb_bdev(fs, flags, dev_name, data, -+ yaffs_internal_read_super_mtd, mnt); -+} -+#else -+static struct super_block *yaffs_read_super(struct file_system_type *fs, -+ int flags, const char *dev_name, -+ void *data) -+{ -+ -+ return get_sb_bdev(fs, flags, dev_name, data, -+ yaffs_internal_read_super_mtd); -+} -+#endif -+ -+static struct file_system_type yaffs_fs_type = { -+ .owner = THIS_MODULE, -+ .name = "yaffs", -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -+ .mount = yaffs_mount, -+#else -+ .get_sb = yaffs_read_super, -+#endif -+ .kill_sb = kill_block_super, -+ .fs_flags = FS_REQUIRES_DEV, -+}; -+#else -+static struct super_block *yaffs_read_super(struct super_block *sb, void *data, -+ int silent) -+{ -+ return yaffs_internal_read_super(1, sb, data, silent); -+} -+ -+static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, -+ FS_REQUIRES_DEV); -+#endif -+ -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data, -+ int silent) -+{ -+ return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -+static struct dentry *yaffs2_mount(struct file_system_type *fs_type, int flags, -+ const char *dev_name, void *data) -+{ -+ return mount_bdev(fs_type, flags, dev_name, data, yaffs2_internal_read_super_mtd); -+} -+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) -+static int yaffs2_read_super(struct file_system_type *fs, -+ int flags, const char *dev_name, void *data, -+ struct vfsmount *mnt) -+{ -+ return get_sb_bdev(fs, flags, dev_name, data, -+ yaffs2_internal_read_super_mtd, mnt); -+} -+#else -+static struct super_block *yaffs2_read_super(struct file_system_type *fs, -+ int flags, const char *dev_name, -+ void *data) -+{ -+ -+ return get_sb_bdev(fs, flags, dev_name, data, -+ yaffs2_internal_read_super_mtd); -+} -+#endif -+ -+static struct file_system_type yaffs2_fs_type = { -+ .owner = THIS_MODULE, -+ .name = "yaffs2", -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) -+ .mount = yaffs2_mount, -+#else -+ .get_sb = yaffs2_read_super, -+#endif -+ .kill_sb = kill_block_super, -+ .fs_flags = FS_REQUIRES_DEV, -+}; -+#else -+static struct super_block *yaffs2_read_super(struct super_block *sb, -+ void *data, int silent) -+{ -+ return yaffs_internal_read_super(2, sb, data, silent); -+} -+ -+static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, -+ FS_REQUIRES_DEV); -+#endif -+ -+ -+static struct proc_dir_entry *my_proc_entry; -+ -+static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev) -+{ -+ struct yaffs_param *param = &dev->param; -+ int bs[10]; -+ -+ yaffs_count_blocks_by_state(dev,bs); -+ -+ buf += sprintf(buf, "start_block.......... %d\n", param->start_block); -+ buf += sprintf(buf, "end_block............ %d\n", param->end_block); -+ buf += sprintf(buf, "total_bytes_per_chunk %d\n", -+ param->total_bytes_per_chunk); -+ buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc); -+ buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc); -+ buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2); -+ buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags); -+ buf += sprintf(buf, "empty_lost_n_found... %d\n", -+ param->empty_lost_n_found); -+ buf += sprintf(buf, "disable_lazy_load.... %d\n", -+ param->disable_lazy_load); -+ buf += sprintf(buf, "disable_bad_block_mrk %d\n", -+ param->disable_bad_block_marking); -+ buf += sprintf(buf, "refresh_period....... %d\n", -+ param->refresh_period); -+ buf += sprintf(buf, "n_caches............. %d\n", param->n_caches); -+ buf += sprintf(buf, "n_reserved_blocks.... %d\n", -+ param->n_reserved_blocks); -+ buf += sprintf(buf, "always_check_erased.. %d\n", -+ param->always_check_erased); -+ buf += sprintf(buf, "\n"); -+ buf += sprintf(buf, "block count by state\n"); -+ buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n", -+ bs[0], bs[1], bs[2], bs[3], bs[4]); -+ buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n", -+ bs[5], bs[6], bs[7], bs[8], bs[9]); -+ -+ return buf; -+} -+ -+static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev) -+{ -+ buf += sprintf(buf, "max file size....... %lld\n", -+ (long long) yaffs_max_file_size(dev)); -+ buf += sprintf(buf, "data_bytes_per_chunk. %d\n", -+ dev->data_bytes_per_chunk); -+ buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits); -+ buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size); -+ buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks); -+ buf += sprintf(buf, "blocks_in_checkpt.... %d\n", -+ dev->blocks_in_checkpt); -+ buf += sprintf(buf, "\n"); -+ buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes); -+ buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj); -+ buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks); -+ buf += sprintf(buf, "\n"); -+ buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes); -+ buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads); -+ buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures); -+ buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies); -+ buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs); -+ buf += sprintf(buf, "passive_gc_count..... %u\n", -+ dev->passive_gc_count); -+ buf += sprintf(buf, "oldest_dirty_gc_count %u\n", -+ dev->oldest_dirty_gc_count); -+ buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks); -+ buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs); -+ buf += sprintf(buf, "n_retried_writes..... %u\n", -+ dev->n_retried_writes); -+ buf += sprintf(buf, "n_retired_blocks..... %u\n", -+ dev->n_retired_blocks); -+ buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed); -+ buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed); -+ buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n", -+ dev->n_tags_ecc_fixed); -+ buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n", -+ dev->n_tags_ecc_unfixed); -+ buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits); -+ buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files); -+ buf += sprintf(buf, "n_unlinked_files..... %u\n", -+ dev->n_unlinked_files); -+ buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count); -+ buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions); -+ buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used); -+ buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used); -+ -+ return buf; -+} -+ -+static int yaffs_proc_read(char *page, -+ char **start, -+ off_t offset, int count, int *eof, void *data) -+{ -+ struct list_head *item; -+ char *buf = page; -+ int step = offset; -+ int n = 0; -+ -+ /* Get proc_file_read() to step 'offset' by one on each sucessive call. -+ * We use 'offset' (*ppos) to indicate where we are in dev_list. -+ * This also assumes the user has posted a read buffer large -+ * enough to hold the complete output; but that's life in /proc. -+ */ -+ -+ *(int *)start = 1; -+ -+ /* Print header first */ -+ if (step == 0) -+ buf += -+ sprintf(buf, "Multi-version YAFFS\n"); -+ else if (step == 1) -+ buf += sprintf(buf, "\n"); -+ else { -+ step -= 2; -+ -+ mutex_lock(&yaffs_context_lock); -+ -+ /* Locate and print the Nth entry. Order N-squared but N is small. */ -+ list_for_each(item, &yaffs_context_list) { -+ struct yaffs_linux_context *dc = -+ list_entry(item, struct yaffs_linux_context, -+ context_list); -+ struct yaffs_dev *dev = dc->dev; -+ -+ if (n < (step & ~1)) { -+ n += 2; -+ continue; -+ } -+ if ((step & 1) == 0) { -+ buf += -+ sprintf(buf, "\nDevice %d \"%s\"\n", n, -+ dev->param.name); -+ buf = yaffs_dump_dev_part0(buf, dev); -+ } else { -+ buf = yaffs_dump_dev_part1(buf, dev); -+ } -+ -+ break; -+ } -+ mutex_unlock(&yaffs_context_lock); -+ } -+ -+ return buf - page < count ? buf - page : count; -+} -+ -+/** -+ * Set the verbosity of the warnings and error messages. -+ * -+ * Note that the names can only be a..z or _ with the current code. -+ */ -+ -+static struct { -+ char *mask_name; -+ unsigned mask_bitfield; -+} mask_flags[] = { -+ {"allocate", YAFFS_TRACE_ALLOCATE}, -+ {"always", YAFFS_TRACE_ALWAYS}, -+ {"background", YAFFS_TRACE_BACKGROUND}, -+ {"bad_blocks", YAFFS_TRACE_BAD_BLOCKS}, -+ {"buffers", YAFFS_TRACE_BUFFERS}, -+ {"bug", YAFFS_TRACE_BUG}, -+ {"checkpt", YAFFS_TRACE_CHECKPOINT}, -+ {"deletion", YAFFS_TRACE_DELETION}, -+ {"erase", YAFFS_TRACE_ERASE}, -+ {"error", YAFFS_TRACE_ERROR}, -+ {"gc_detail", YAFFS_TRACE_GC_DETAIL}, -+ {"gc", YAFFS_TRACE_GC}, -+ {"lock", YAFFS_TRACE_LOCK}, -+ {"mtd", YAFFS_TRACE_MTD}, -+ {"nandaccess", YAFFS_TRACE_NANDACCESS}, -+ {"os", YAFFS_TRACE_OS}, -+ {"scan_debug", YAFFS_TRACE_SCAN_DEBUG}, -+ {"scan", YAFFS_TRACE_SCAN}, -+ {"mount", YAFFS_TRACE_MOUNT}, -+ {"tracing", YAFFS_TRACE_TRACING}, -+ {"sync", YAFFS_TRACE_SYNC}, -+ {"write", YAFFS_TRACE_WRITE}, -+ {"verify", YAFFS_TRACE_VERIFY}, -+ {"verify_nand", YAFFS_TRACE_VERIFY_NAND}, -+ {"verify_full", YAFFS_TRACE_VERIFY_FULL}, -+ {"verify_all", YAFFS_TRACE_VERIFY_ALL}, -+ {"all", 0xffffffff}, -+ {"none", 0}, -+ {NULL, 0}, -+}; -+ -+#define MAX_MASK_NAME_LENGTH 40 -+static int yaffs_proc_write_trace_options(struct file *file, const char *buf, -+ unsigned long count) -+{ -+ unsigned rg = 0, mask_bitfield; -+ char *end; -+ char *mask_name; -+ const char *x; -+ char substring[MAX_MASK_NAME_LENGTH + 1]; -+ int i; -+ int done = 0; -+ int add, len = 0; -+ int pos = 0; -+ -+ rg = yaffs_trace_mask; -+ -+ while (!done && (pos < count)) { -+ done = 1; -+ while ((pos < count) && isspace(buf[pos])) -+ pos++; -+ -+ switch (buf[pos]) { -+ case '+': -+ case '-': -+ case '=': -+ add = buf[pos]; -+ pos++; -+ break; -+ -+ default: -+ add = ' '; -+ break; -+ } -+ mask_name = NULL; -+ -+ mask_bitfield = simple_strtoul(buf + pos, &end, 0); -+ -+ if (end > buf + pos) { -+ mask_name = "numeral"; -+ len = end - (buf + pos); -+ pos += len; -+ done = 0; -+ } else { -+ for (x = buf + pos, i = 0; -+ (*x == '_' || (*x >= 'a' && *x <= 'z')) && -+ i < MAX_MASK_NAME_LENGTH; x++, i++, pos++) -+ substring[i] = *x; -+ substring[i] = '\0'; -+ -+ for (i = 0; mask_flags[i].mask_name != NULL; i++) { -+ if (strcmp(substring, mask_flags[i].mask_name) -+ == 0) { -+ mask_name = mask_flags[i].mask_name; -+ mask_bitfield = -+ mask_flags[i].mask_bitfield; -+ done = 0; -+ break; -+ } -+ } -+ } -+ -+ if (mask_name != NULL) { -+ done = 0; -+ switch (add) { -+ case '-': -+ rg &= ~mask_bitfield; -+ break; -+ case '+': -+ rg |= mask_bitfield; -+ break; -+ case '=': -+ rg = mask_bitfield; -+ break; -+ default: -+ rg |= mask_bitfield; -+ break; -+ } -+ } -+ } -+ -+ yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS; -+ -+ printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask); -+ -+ if (rg & YAFFS_TRACE_ALWAYS) { -+ for (i = 0; mask_flags[i].mask_name != NULL; i++) { -+ char flag; -+ flag = ((rg & mask_flags[i].mask_bitfield) == -+ mask_flags[i].mask_bitfield) ? '+' : '-'; -+ printk(KERN_DEBUG "%c%s\n", flag, -+ mask_flags[i].mask_name); -+ } -+ } -+ -+ return count; -+} -+ -+/* Debug strings are of the form: -+ * .bnnn print info on block n -+ * .cobjn,chunkn print nand chunk id for objn:chunkn -+ */ -+ -+static int yaffs_proc_debug_write(struct file *file, const char *buf, -+ unsigned long count) -+{ -+ -+ char str[100]; -+ char *p0; -+ char *p1; -+ long p1_val; -+ long p0_val; -+ char cmd; -+ struct list_head *item; -+ -+ memset(str, 0, sizeof(str)); -+ memcpy(str, buf, min((size_t)count, sizeof(str) -1)); -+ -+ cmd = str[1]; -+ -+ p0 = str + 2; -+ -+ p1 = p0; -+ -+ while (*p1 && *p1 != ',') { -+ p1++; -+ } -+ *p1 = '\0'; -+ p1++; -+ -+ p0_val = simple_strtol(p0, NULL, 0); -+ p1_val = simple_strtol(p1, NULL, 0); -+ -+ -+ mutex_lock(&yaffs_context_lock); -+ -+ /* Locate and print the Nth entry. Order N-squared but N is small. */ -+ list_for_each(item, &yaffs_context_list) { -+ struct yaffs_linux_context *dc = -+ list_entry(item, struct yaffs_linux_context, -+ context_list); -+ struct yaffs_dev *dev = dc->dev; -+ -+ if (cmd == 'b') { -+ struct yaffs_block_info *bi; -+ -+ bi = yaffs_get_block_info(dev,p0_val); -+ -+ if(bi) { -+ printk("Block %d: state %d, retire %d, use %d, seq %d\n", -+ (int)p0_val, bi->block_state, -+ bi->needs_retiring, bi->pages_in_use, -+ bi->seq_number); -+ } -+ } else if (cmd == 'c') { -+ struct yaffs_obj *obj; -+ int nand_chunk; -+ -+ obj = yaffs_find_by_number(dev, p0_val); -+ if (!obj) -+ printk("No obj %d\n", (int)p0_val); -+ else { -+ if(p1_val == 0) -+ nand_chunk = obj->hdr_chunk; -+ else -+ nand_chunk = -+ yaffs_find_chunk_in_file(obj, -+ p1_val, NULL); -+ printk("Nand chunk for %d:%d is %d\n", -+ (int)p0_val, (int)p1_val, nand_chunk); -+ } -+ } -+ } -+ -+ mutex_unlock(&yaffs_context_lock); -+ -+ return count; -+} -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) -+static int yaffs_proc_write(struct file *file, const char *buf, -+ unsigned long count, void *ppos) -+#else -+static ssize_t yaffs_proc_write(struct file *file, const char __user *buf, -+ size_t count, loff_t *ppos) -+#endif -+{ -+ if (buf[0] == '.') -+ return yaffs_proc_debug_write(file, buf, count); -+ return yaffs_proc_write_trace_options(file, buf, count); -+} -+ -+/* Stuff to handle installation of file systems */ -+struct file_system_to_install { -+ struct file_system_type *fst; -+ int installed; -+}; -+ -+static struct file_system_to_install fs_to_install[] = { -+ {&yaffs_fs_type, 0}, -+ {&yaffs2_fs_type, 0}, -+ {NULL, 0} -+}; -+ -+ -+#ifdef YAFFS_NEW_PROCFS -+static int yaffs_proc_show(struct seq_file *m, void *v) -+{ -+ /* FIXME: Unify in a better way? */ -+ char buffer[512]; -+ char *start; -+ int len; -+ -+ len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL); -+ seq_puts(m, buffer); -+ return 0; -+} -+ -+static int yaffs_proc_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, yaffs_proc_show, NULL); -+} -+ -+static struct file_operations procfs_ops = { -+ .owner = THIS_MODULE, -+ .open = yaffs_proc_open, -+ .read = seq_read, -+ .write = yaffs_proc_write, -+}; -+ -+static int yaffs_procfs_init(void) -+{ -+ /* Install the proc_fs entries */ -+ my_proc_entry = proc_create("yaffs", -+ S_IRUGO | S_IFREG, -+ YPROC_ROOT, -+ &procfs_ops); -+ -+ if (my_proc_entry) { -+ return 0; -+ } else { -+ return -ENOMEM; -+ } -+} -+ -+#else -+ -+ -+static int yaffs_procfs_init(void) -+{ -+ /* Install the proc_fs entries */ -+ my_proc_entry = create_proc_entry("yaffs", -+ S_IRUGO | S_IFREG, YPROC_ROOT); -+ -+ if (my_proc_entry) { -+ my_proc_entry->write_proc = yaffs_proc_write; -+ my_proc_entry->read_proc = yaffs_proc_read; -+ my_proc_entry->data = NULL; -+ return 0; -+ } else { -+ return -ENOMEM; -+ } -+} -+ -+#endif -+ -+ -+static int __init init_yaffs_fs(void) -+{ -+ int error = 0; -+ struct file_system_to_install *fsinst; -+ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs Installing."); -+ -+ mutex_init(&yaffs_context_lock); -+ -+ error = yaffs_procfs_init(); -+ if (error) -+ return error; -+ -+ /* Now add the file system entries */ -+ -+ fsinst = fs_to_install; -+ -+ while (fsinst->fst && !error) { -+ error = register_filesystem(fsinst->fst); -+ if (!error) -+ fsinst->installed = 1; -+ fsinst++; -+ } -+ -+ /* Any errors? uninstall */ -+ if (error) { -+ fsinst = fs_to_install; -+ -+ while (fsinst->fst) { -+ if (fsinst->installed) { -+ unregister_filesystem(fsinst->fst); -+ fsinst->installed = 0; -+ } -+ fsinst++; -+ } -+ } -+ -+ return error; -+} -+ -+static void __exit exit_yaffs_fs(void) -+{ -+ -+ struct file_system_to_install *fsinst; -+ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "yaffs removing."); -+ -+ remove_proc_entry("yaffs", YPROC_ROOT); -+ -+ fsinst = fs_to_install; -+ -+ while (fsinst->fst) { -+ if (fsinst->installed) { -+ unregister_filesystem(fsinst->fst); -+ fsinst->installed = 0; -+ } -+ fsinst++; -+ } -+} -+ -+module_init(init_yaffs_fs) -+ module_exit(exit_yaffs_fs) -+ -+ MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system"); -+MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2011"); -+MODULE_LICENSE("GPL"); ---- linux-4.9.37/fs/yaffs2/yaffs_yaffs1.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_yaffs1.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,424 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_yaffs1.h" -+#include "yportenv.h" -+#include "yaffs_trace.h" -+#include "yaffs_bitmap.h" -+#include "yaffs_getblockinfo.h" -+#include "yaffs_nand.h" -+#include "yaffs_attribs.h" -+ -+int yaffs1_scan(struct yaffs_dev *dev) -+{ -+ struct yaffs_ext_tags tags; -+ u32 blk; -+ int result; -+ int chunk; -+ u32 c; -+ int deleted; -+ enum yaffs_block_state state; -+ LIST_HEAD(hard_list); -+ struct yaffs_block_info *bi; -+ u32 seq_number; -+ struct yaffs_obj_hdr *oh; -+ struct yaffs_obj *in; -+ struct yaffs_obj *parent; -+ int alloc_failed = 0; -+ struct yaffs_shadow_fixer *shadow_fixers = NULL; -+ u8 *chunk_data; -+ -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "yaffs1_scan starts intstartblk %d intendblk %d...", -+ dev->internal_start_block, dev->internal_end_block); -+ -+ chunk_data = yaffs_get_temp_buffer(dev); -+ -+ dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER; -+ -+ /* Scan all the blocks to determine their state */ -+ bi = dev->block_info; -+ for (blk = dev->internal_start_block; blk <= dev->internal_end_block; -+ blk++) { -+ yaffs_clear_chunk_bits(dev, blk); -+ bi->pages_in_use = 0; -+ bi->soft_del_pages = 0; -+ -+ yaffs_query_init_block_state(dev, blk, &state, &seq_number); -+ -+ bi->block_state = state; -+ bi->seq_number = seq_number; -+ -+ if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK) -+ bi->block_state = state = YAFFS_BLOCK_STATE_DEAD; -+ -+ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, -+ "Block scanning block %d state %d seq %d", -+ blk, state, seq_number); -+ -+ if (state == YAFFS_BLOCK_STATE_DEAD) { -+ yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, -+ "block %d is bad", blk); -+ } else if (state == YAFFS_BLOCK_STATE_EMPTY) { -+ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty "); -+ dev->n_erased_blocks++; -+ dev->n_free_chunks += dev->param.chunks_per_block; -+ } -+ bi++; -+ } -+ -+ /* For each block.... */ -+ for (blk = dev->internal_start_block; -+ !alloc_failed && blk <= dev->internal_end_block; blk++) { -+ -+ cond_resched(); -+ -+ bi = yaffs_get_block_info(dev, blk); -+ state = bi->block_state; -+ -+ deleted = 0; -+ -+ /* For each chunk in each block that needs scanning.... */ -+ for (c = 0; -+ !alloc_failed && c < dev->param.chunks_per_block && -+ state == YAFFS_BLOCK_STATE_NEEDS_SCAN; c++) { -+ /* Read the tags and decide what to do */ -+ chunk = blk * dev->param.chunks_per_block + c; -+ -+ result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, -+ &tags); -+ -+ if (result != YAFFS_OK) -+ continue; -+ /* Let's have a good look at this chunk... */ -+ -+ if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED || -+ tags.is_deleted) { -+ /* YAFFS1 only... -+ * A deleted chunk -+ */ -+ deleted++; -+ dev->n_free_chunks++; -+ } else if (!tags.chunk_used) { -+ /* An unassigned chunk in the block -+ * This means that either the block is empty or -+ * this is the one being allocated from -+ */ -+ -+ if (c == 0) { -+ /* We're looking at the first chunk in -+ *the block so the block is unused */ -+ state = YAFFS_BLOCK_STATE_EMPTY; -+ dev->n_erased_blocks++; -+ } else { -+ /* this is the block being allocated */ -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ " Allocating from %d %d", -+ blk, c); -+ state = YAFFS_BLOCK_STATE_ALLOCATING; -+ dev->alloc_block = blk; -+ dev->alloc_page = c; -+ dev->alloc_block_finder = blk; -+ -+ } -+ -+ dev->n_free_chunks += -+ (dev->param.chunks_per_block - c); -+ } else if (tags.chunk_id > 0) { -+ /* chunk_id > 0 so it is a data chunk... */ -+ unsigned int endpos; -+ -+ yaffs_set_chunk_bit(dev, blk, c); -+ bi->pages_in_use++; -+ -+ in = yaffs_find_or_create_by_number(dev, -+ tags.obj_id, -+ YAFFS_OBJECT_TYPE_FILE); -+ /* PutChunkIntoFile checks for a clash -+ * (two data chunks with the same chunk_id). -+ */ -+ -+ if (!in) -+ alloc_failed = 1; -+ -+ if (in) { -+ if (!yaffs_put_chunk_in_file -+ (in, tags.chunk_id, chunk, 1)) -+ alloc_failed = 1; -+ } -+ -+ endpos = -+ (tags.chunk_id - 1) * -+ dev->data_bytes_per_chunk + -+ tags.n_bytes; -+ if (in && -+ in->variant_type == -+ YAFFS_OBJECT_TYPE_FILE && -+ in->variant.file_variant.stored_size < -+ endpos) { -+ in->variant.file_variant.stored_size = -+ endpos; -+ if (!dev->param.use_header_file_size) { -+ in->variant. -+ file_variant.file_size = -+ in->variant. -+ file_variant.stored_size; -+ } -+ -+ } -+ } else { -+ /* chunk_id == 0, so it is an ObjectHeader. -+ * Make the object -+ */ -+ yaffs_set_chunk_bit(dev, blk, c); -+ bi->pages_in_use++; -+ -+ result = yaffs_rd_chunk_tags_nand(dev, chunk, -+ chunk_data, -+ NULL); -+ -+ oh = (struct yaffs_obj_hdr *)chunk_data; -+ -+ in = yaffs_find_by_number(dev, tags.obj_id); -+ if (in && in->variant_type != oh->type) { -+ /* This should not happen, but somehow -+ * Wev'e ended up with an obj_id that -+ * has been reused but not yet deleted, -+ * and worse still it has changed type. -+ * Delete the old object. -+ */ -+ -+ yaffs_del_obj(in); -+ in = NULL; -+ } -+ -+ in = yaffs_find_or_create_by_number(dev, -+ tags.obj_id, -+ oh->type); -+ -+ if (!in) -+ alloc_failed = 1; -+ -+ if (in && oh->shadows_obj > 0) { -+ -+ struct yaffs_shadow_fixer *fixer; -+ fixer = -+ kmalloc(sizeof -+ (struct yaffs_shadow_fixer), -+ GFP_NOFS); -+ if (fixer) { -+ fixer->next = shadow_fixers; -+ shadow_fixers = fixer; -+ fixer->obj_id = tags.obj_id; -+ fixer->shadowed_id = -+ oh->shadows_obj; -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ " Shadow fixer: %d shadows %d", -+ fixer->obj_id, -+ fixer->shadowed_id); -+ -+ } -+ -+ } -+ -+ if (in && in->valid) { -+ /* We have already filled this one. -+ * We have a duplicate and need to -+ * resolve it. */ -+ -+ unsigned existing_serial = in->serial; -+ unsigned new_serial = -+ tags.serial_number; -+ -+ if (((existing_serial + 1) & 3) == -+ new_serial) { -+ /* Use new one - destroy the -+ * exisiting one */ -+ yaffs_chunk_del(dev, -+ in->hdr_chunk, -+ 1, __LINE__); -+ in->valid = 0; -+ } else { -+ /* Use existing - destroy -+ * this one. */ -+ yaffs_chunk_del(dev, chunk, 1, -+ __LINE__); -+ } -+ } -+ -+ if (in && !in->valid && -+ (tags.obj_id == YAFFS_OBJECTID_ROOT || -+ tags.obj_id == -+ YAFFS_OBJECTID_LOSTNFOUND)) { -+ /* We only load some info, don't fiddle -+ * with directory structure */ -+ in->valid = 1; -+ in->variant_type = oh->type; -+ -+ in->yst_mode = oh->yst_mode; -+ yaffs_load_attribs(in, oh); -+ in->hdr_chunk = chunk; -+ in->serial = tags.serial_number; -+ -+ } else if (in && !in->valid) { -+ /* we need to load this info */ -+ -+ in->valid = 1; -+ in->variant_type = oh->type; -+ -+ in->yst_mode = oh->yst_mode; -+ yaffs_load_attribs(in, oh); -+ in->hdr_chunk = chunk; -+ in->serial = tags.serial_number; -+ -+ yaffs_set_obj_name_from_oh(in, oh); -+ in->dirty = 0; -+ -+ /* directory stuff... -+ * hook up to parent -+ */ -+ -+ parent = -+ yaffs_find_or_create_by_number -+ (dev, oh->parent_obj_id, -+ YAFFS_OBJECT_TYPE_DIRECTORY); -+ if (!parent) -+ alloc_failed = 1; -+ if (parent && parent->variant_type == -+ YAFFS_OBJECT_TYPE_UNKNOWN) { -+ /* Set up as a directory */ -+ parent->variant_type = -+ YAFFS_OBJECT_TYPE_DIRECTORY; -+ INIT_LIST_HEAD(&parent-> -+ variant.dir_variant. -+ children); -+ } else if (!parent || -+ parent->variant_type != -+ YAFFS_OBJECT_TYPE_DIRECTORY) { -+ /* Hoosterman, a problem.... -+ * We're trying to use a -+ * non-directory as a directory -+ */ -+ -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found." -+ ); -+ parent = dev->lost_n_found; -+ } -+ -+ yaffs_add_obj_to_dir(parent, in); -+ -+ switch (in->variant_type) { -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ /* Todo got a problem */ -+ break; -+ case YAFFS_OBJECT_TYPE_FILE: -+ if (dev->param. -+ use_header_file_size) -+ in->variant. -+ file_variant.file_size -+ = yaffs_oh_to_size(dev, oh, 0); -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ in->variant. -+ hardlink_variant.equiv_id = -+ oh->equiv_id; -+ list_add(&in->hard_links, -+ &hard_list); -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ /* Do nothing */ -+ break; -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ /* Do nothing */ -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ in->variant.symlink_variant. -+ alias = -+ yaffs_clone_str(oh->alias); -+ if (!in->variant. -+ symlink_variant.alias) -+ alloc_failed = 1; -+ break; -+ } -+ } -+ } -+ } -+ -+ if (state == YAFFS_BLOCK_STATE_NEEDS_SCAN) { -+ /* If we got this far while scanning, -+ * then the block is fully allocated. */ -+ state = YAFFS_BLOCK_STATE_FULL; -+ } -+ -+ if (state == YAFFS_BLOCK_STATE_ALLOCATING) { -+ /* If the block was partially allocated then -+ * treat it as fully allocated. */ -+ state = YAFFS_BLOCK_STATE_FULL; -+ dev->alloc_block = -1; -+ } -+ -+ bi->block_state = state; -+ -+ /* Now let's see if it was dirty */ -+ if (bi->pages_in_use == 0 && -+ !bi->has_shrink_hdr && -+ bi->block_state == YAFFS_BLOCK_STATE_FULL) -+ yaffs_block_became_dirty(dev, blk); -+ } -+ -+ /* Ok, we've done all the scanning. -+ * Fix up the hard link chains. -+ * We should now have scanned all the objects, now it's time to add -+ * these hardlinks. -+ */ -+ -+ yaffs_link_fixup(dev, &hard_list); -+ -+ /* -+ * Fix up any shadowed objects. -+ * There should not be more than one of these. -+ */ -+ { -+ struct yaffs_shadow_fixer *fixer; -+ struct yaffs_obj *obj; -+ -+ while (shadow_fixers) { -+ fixer = shadow_fixers; -+ shadow_fixers = fixer->next; -+ /* Complete the rename transaction by deleting the -+ * shadowed object then setting the object header -+ to unshadowed. -+ */ -+ obj = yaffs_find_by_number(dev, fixer->shadowed_id); -+ if (obj) -+ yaffs_del_obj(obj); -+ -+ obj = yaffs_find_by_number(dev, fixer->obj_id); -+ -+ if (obj) -+ yaffs_update_oh(obj, NULL, 1, 0, 0, NULL); -+ -+ kfree(fixer); -+ } -+ } -+ -+ yaffs_release_temp_buffer(dev, chunk_data); -+ -+ if (alloc_failed) -+ return YAFFS_FAIL; -+ -+ yaffs_trace(YAFFS_TRACE_SCAN, "yaffs1_scan ends"); -+ -+ return YAFFS_OK; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_yaffs1.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_yaffs1.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,22 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_YAFFS1_H__ -+#define __YAFFS_YAFFS1_H__ -+ -+#include "yaffs_guts.h" -+int yaffs1_scan(struct yaffs_dev *dev); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yaffs_yaffs2.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_yaffs2.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,1712 @@ -+/* -+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * 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 "yaffs_guts.h" -+#include "yaffs_trace.h" -+#include "yaffs_yaffs2.h" -+#include "yaffs_checkptrw.h" -+#include "yaffs_bitmap.h" -+#include "yaffs_nand.h" -+#include "yaffs_getblockinfo.h" -+#include "yaffs_verify.h" -+#include "yaffs_attribs.h" -+#include "yaffs_summary.h" -+#include "yaffs_endian.h" -+ -+/* -+ * Checkpoints are really no benefit on very small partitions. -+ * -+ * To save space on small partitions don't bother with checkpoints unless -+ * the partition is at least this big. -+ */ -+#define YAFFS_CHECKPOINT_MIN_BLOCKS 60 -+#define YAFFS_SMALL_HOLE_THRESHOLD 4 -+ -+/* -+ * Oldest Dirty Sequence Number handling. -+ */ -+ -+/* yaffs_calc_oldest_dirty_seq() -+ * yaffs2_find_oldest_dirty_seq() -+ * Calculate the oldest dirty sequence number if we don't know it. -+ */ -+void yaffs_calc_oldest_dirty_seq(struct yaffs_dev *dev) -+{ -+ u32 i; -+ unsigned seq; -+ unsigned block_no = 0; -+ struct yaffs_block_info *b; -+ -+ if (!dev->param.is_yaffs2) -+ return; -+ -+ /* Find the oldest dirty sequence number. */ -+ seq = dev->seq_number + 1; -+ b = dev->block_info; -+ for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) { -+ if (b->block_state == YAFFS_BLOCK_STATE_FULL && -+ (u32)(b->pages_in_use - b->soft_del_pages) < -+ dev->param.chunks_per_block && -+ b->seq_number < seq) { -+ seq = b->seq_number; -+ block_no = i; -+ } -+ b++; -+ } -+ -+ if (block_no) { -+ dev->oldest_dirty_seq = seq; -+ dev->oldest_dirty_block = block_no; -+ } -+} -+ -+void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev) -+{ -+ if (!dev->param.is_yaffs2) -+ return; -+ -+ if (!dev->oldest_dirty_seq) -+ yaffs_calc_oldest_dirty_seq(dev); -+} -+ -+/* -+ * yaffs_clear_oldest_dirty_seq() -+ * Called when a block is erased or marked bad. (ie. when its seq_number -+ * becomes invalid). If the value matches the oldest then we clear -+ * dev->oldest_dirty_seq to force its recomputation. -+ */ -+void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi) -+{ -+ -+ if (!dev->param.is_yaffs2) -+ return; -+ -+ if (!bi || bi->seq_number == dev->oldest_dirty_seq) { -+ dev->oldest_dirty_seq = 0; -+ dev->oldest_dirty_block = 0; -+ } -+} -+ -+/* -+ * yaffs2_update_oldest_dirty_seq() -+ * Update the oldest dirty sequence number whenever we dirty a block. -+ * Only do this if the oldest_dirty_seq is actually being tracked. -+ */ -+void yaffs2_update_oldest_dirty_seq(struct yaffs_dev *dev, unsigned block_no, -+ struct yaffs_block_info *bi) -+{ -+ if (!dev->param.is_yaffs2) -+ return; -+ -+ if (dev->oldest_dirty_seq) { -+ if (dev->oldest_dirty_seq > bi->seq_number) { -+ dev->oldest_dirty_seq = bi->seq_number; -+ dev->oldest_dirty_block = block_no; -+ } -+ } -+} -+ -+int yaffs_block_ok_for_gc(struct yaffs_dev *dev, struct yaffs_block_info *bi) -+{ -+ -+ if (!dev->param.is_yaffs2) -+ return 1; /* disqualification only applies to yaffs2. */ -+ -+ if (!bi->has_shrink_hdr) -+ return 1; /* can gc */ -+ -+ yaffs2_find_oldest_dirty_seq(dev); -+ -+ /* Can't do gc of this block if there are any blocks older than this -+ * one that have discarded pages. -+ */ -+ return (bi->seq_number <= dev->oldest_dirty_seq); -+} -+ -+/* -+ * yaffs2_find_refresh_block() -+ * periodically finds the oldest full block by sequence number for refreshing. -+ * Only for yaffs2. -+ */ -+u32 yaffs2_find_refresh_block(struct yaffs_dev *dev) -+{ -+ u32 b; -+ u32 oldest = 0; -+ u32 oldest_seq = 0; -+ struct yaffs_block_info *bi; -+ -+ if (!dev->param.is_yaffs2) -+ return oldest; -+ -+ /* -+ * If refresh period < 10 then refreshing is disabled. -+ */ -+ if (dev->param.refresh_period < 10) -+ return oldest; -+ -+ /* -+ * Fix broken values. -+ */ -+ if (dev->refresh_skip > dev->param.refresh_period) -+ dev->refresh_skip = dev->param.refresh_period; -+ -+ if (dev->refresh_skip > 0) -+ return oldest; -+ -+ /* -+ * Refresh skip is now zero. -+ * We'll do a refresh this time around.... -+ * Update the refresh skip and find the oldest block. -+ */ -+ dev->refresh_skip = dev->param.refresh_period; -+ dev->refresh_count++; -+ bi = dev->block_info; -+ for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) { -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_FULL) { -+ -+ if (oldest < 1 || bi->seq_number < oldest_seq) { -+ oldest = b; -+ oldest_seq = bi->seq_number; -+ } -+ } -+ bi++; -+ } -+ -+ if (oldest > 0) { -+ yaffs_trace(YAFFS_TRACE_GC, -+ "GC refresh count %d selected block %d with seq_number %d", -+ dev->refresh_count, oldest, oldest_seq); -+ } -+ -+ return oldest; -+} -+ -+int yaffs2_checkpt_required(struct yaffs_dev *dev) -+{ -+ int nblocks; -+ -+ if (!dev->param.is_yaffs2) -+ return 0; -+ -+ nblocks = dev->internal_end_block - dev->internal_start_block + 1; -+ -+ return !dev->param.skip_checkpt_wr && -+ !dev->read_only && (nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS); -+} -+ -+int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev) -+{ -+ int retval; -+ int n_bytes = 0; -+ int n_blocks; -+ int dev_blocks; -+ -+ if (!dev->param.is_yaffs2) -+ return 0; -+ -+ if (!dev->checkpoint_blocks_required && yaffs2_checkpt_required(dev)) { -+ /* Not a valid value so recalculate */ -+ dev_blocks = dev->param.end_block - dev->param.start_block + 1; -+ n_bytes += sizeof(struct yaffs_checkpt_validity); -+ n_bytes += sizeof(struct yaffs_checkpt_dev); -+ n_bytes += dev_blocks * sizeof(struct yaffs_block_info); -+ n_bytes += dev_blocks * dev->chunk_bit_stride; -+ n_bytes += -+ (sizeof(struct yaffs_checkpt_obj) + sizeof(u32)) * -+ dev->n_obj; -+ n_bytes += (dev->tnode_size + sizeof(u32)) * dev->n_tnodes; -+ n_bytes += sizeof(struct yaffs_checkpt_validity); -+ n_bytes += sizeof(u32); /* checksum */ -+ -+ /* Round up and add 2 blocks to allow for some bad blocks, -+ * so add 3 */ -+ -+ n_blocks = -+ (n_bytes / -+ (dev->data_bytes_per_chunk * -+ dev->param.chunks_per_block)) + 3; -+ -+ dev->checkpoint_blocks_required = n_blocks; -+ } -+ -+ retval = dev->checkpoint_blocks_required - dev->blocks_in_checkpt; -+ if (retval < 0) -+ retval = 0; -+ return retval; -+} -+ -+/*--------------------- Checkpointing --------------------*/ -+ -+static void yaffs2_do_endian_validity_marker(struct yaffs_dev *dev, -+ struct yaffs_checkpt_validity *v) -+{ -+ -+ if (!dev->swap_endian) -+ return; -+ v->struct_type = swap_s32(v->struct_type); -+ v->magic = swap_u32(v->magic); -+ v->version = swap_u32(v->version); -+ v->head = swap_u32(v->head); -+} -+ -+static int yaffs2_wr_checkpt_validity_marker(struct yaffs_dev *dev, int head) -+{ -+ struct yaffs_checkpt_validity cp; -+ -+ memset(&cp, 0, sizeof(cp)); -+ -+ cp.struct_type = sizeof(cp); -+ cp.magic = YAFFS_MAGIC; -+ cp.version = YAFFS_CHECKPOINT_VERSION; -+ cp.head = (head) ? 1 : 0; -+ -+ yaffs2_do_endian_validity_marker(dev, &cp); -+ -+ return (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)) ? 1 : 0; -+} -+ -+static int yaffs2_rd_checkpt_validity_marker(struct yaffs_dev *dev, int head) -+{ -+ struct yaffs_checkpt_validity cp; -+ int ok; -+ -+ ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp)); -+ yaffs2_do_endian_validity_marker(dev, &cp); -+ -+ if (ok) -+ ok = (cp.struct_type == sizeof(cp)) && -+ (cp.magic == YAFFS_MAGIC) && -+ (cp.version == YAFFS_CHECKPOINT_VERSION) && -+ (cp.head == ((head) ? 1 : 0)); -+ return ok ? 1 : 0; -+} -+ -+static void yaffs2_dev_to_checkpt_dev(struct yaffs_checkpt_dev *cp, -+ struct yaffs_dev *dev) -+{ -+ cp->struct_type = sizeof(*cp); -+ -+ cp->n_erased_blocks = dev->n_erased_blocks; -+ cp->alloc_block = dev->alloc_block; -+ cp->alloc_page = dev->alloc_page; -+ cp->n_free_chunks = dev->n_free_chunks; -+ -+ cp->n_deleted_files = dev->n_deleted_files; -+ cp->n_unlinked_files = dev->n_unlinked_files; -+ cp->n_bg_deletions = dev->n_bg_deletions; -+ cp->seq_number = dev->seq_number; -+ -+} -+ -+static void yaffs_checkpt_dev_to_dev(struct yaffs_dev *dev, -+ struct yaffs_checkpt_dev *cp) -+{ -+ dev->n_erased_blocks = cp->n_erased_blocks; -+ dev->alloc_block = cp->alloc_block; -+ dev->alloc_page = cp->alloc_page; -+ dev->n_free_chunks = cp->n_free_chunks; -+ -+ dev->n_deleted_files = cp->n_deleted_files; -+ dev->n_unlinked_files = cp->n_unlinked_files; -+ dev->n_bg_deletions = cp->n_bg_deletions; -+ dev->seq_number = cp->seq_number; -+} -+ -+static void yaffs2_do_endian_checkpt_dev(struct yaffs_dev *dev, -+ struct yaffs_checkpt_dev *cp) -+{ -+ if (!dev->swap_endian) -+ return; -+ cp->struct_type = swap_s32(cp->struct_type); -+ cp->n_erased_blocks = swap_s32(cp->n_erased_blocks); -+ cp->alloc_block = swap_s32(cp->alloc_block); -+ cp->alloc_page = swap_u32(cp->alloc_page); -+ cp->n_free_chunks = swap_s32(cp->n_free_chunks); -+ cp->n_deleted_files = swap_s32(cp->n_deleted_files); -+ cp->n_unlinked_files = swap_s32(cp->n_unlinked_files); -+ cp->n_bg_deletions = swap_s32(cp->n_bg_deletions); -+} -+ -+static int yaffs2_wr_checkpt_dev(struct yaffs_dev *dev) -+{ -+ struct yaffs_checkpt_dev cp; -+ u32 n_bytes; -+ u32 n_blocks = dev->internal_end_block - dev->internal_start_block + 1; -+ int ok; -+ u32 i; -+ union yaffs_block_info_union bu; -+ -+ /* Write device runtime values */ -+ yaffs2_dev_to_checkpt_dev(&cp, dev); -+ yaffs2_do_endian_checkpt_dev(dev, &cp); -+ -+ ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)); -+ if (!ok) -+ return 0; -+ -+ /* Write block info. */ -+ if (!dev->swap_endian) { -+ n_bytes = n_blocks * sizeof(struct yaffs_block_info); -+ ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) == -+ (int)n_bytes); -+ } else { -+ /* -+ * Need to swap the endianisms. We can't do this in place -+ * since that would damage live data, -+ * so write one block info at a time using a copy. -+ */ -+ for (i = 0; i < n_blocks && ok; i++) { -+ bu.bi = dev->block_info[i]; -+ bu.as_u32[0] = swap_u32(bu.as_u32[0]); -+ bu.as_u32[1] = swap_u32(bu.as_u32[1]); -+ ok = (yaffs2_checkpt_wr(dev, &bu, sizeof(bu)) == sizeof(bu)); -+ } -+ } -+ -+ if (!ok) -+ return 0; -+ -+ /* -+ * Write chunk bits. Chunk bits are in bytes so -+ * no endian conversion is needed. -+ */ -+ n_bytes = n_blocks * dev->chunk_bit_stride; -+ ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) == -+ (int)n_bytes); -+ -+ return ok ? 1 : 0; -+} -+ -+static int yaffs2_rd_checkpt_dev(struct yaffs_dev *dev) -+{ -+ struct yaffs_checkpt_dev cp; -+ u32 n_bytes; -+ u32 n_blocks = -+ (dev->internal_end_block - dev->internal_start_block + 1); -+ int ok; -+ -+ ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp)); -+ if (!ok) -+ return 0; -+ yaffs2_do_endian_checkpt_dev(dev, &cp); -+ -+ if (cp.struct_type != sizeof(cp)) -+ return 0; -+ -+ yaffs_checkpt_dev_to_dev(dev, &cp); -+ -+ n_bytes = n_blocks * sizeof(struct yaffs_block_info); -+ -+ ok = (yaffs2_checkpt_rd(dev, dev->block_info, n_bytes) == -+ (int)n_bytes); -+ -+ if (!ok) -+ return 0; -+ -+ if (dev->swap_endian) { -+ /* The block info can just be handled as a list of u32s. */ -+ u32 *as_u32 = (u32 *) dev->block_info; -+ u32 n_u32s = n_bytes/sizeof(u32); -+ u32 i; -+ -+ for (i=0; i < n_u32s; i++) -+ as_u32[i] = swap_u32(as_u32[i]); -+ } -+ -+ n_bytes = n_blocks * dev->chunk_bit_stride; -+ -+ ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == -+ (int)n_bytes); -+ -+ -+ return ok ? 1 : 0; -+} -+ -+ -+static void yaffs2_checkpt_obj_bit_assign(struct yaffs_checkpt_obj *cp, -+ int bit_offset, -+ int bit_width, -+ u32 value) -+{ -+ u32 and_mask; -+ -+ and_mask = ((1<bit_field &= ~and_mask; -+ cp->bit_field |= ((value << bit_offset) & and_mask); -+} -+ -+static u32 yaffs2_checkpt_obj_bit_get(struct yaffs_checkpt_obj *cp, -+ int bit_offset, -+ int bit_width) -+{ -+ u32 and_mask; -+ -+ and_mask = ((1<bit_field >> bit_offset) & and_mask; -+} -+ -+static void yaffs2_obj_checkpt_obj(struct yaffs_checkpt_obj *cp, -+ struct yaffs_obj *obj) -+{ -+ cp->obj_id = obj->obj_id; -+ cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0; -+ cp->hdr_chunk = obj->hdr_chunk; -+ -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_VARIANT_BITS, obj->variant_type); -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_DELETED_BITS, obj->deleted); -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_SOFT_DEL_BITS, obj->soft_del); -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_UNLINKED_BITS, obj->unlinked); -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_FAKE_BITS, obj->fake); -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_RENAME_ALLOWED_BITS, obj->rename_allowed); -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_UNLINK_ALLOWED_BITS, obj->unlink_allowed); -+ yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_SERIAL_BITS, obj->serial); -+ -+ cp->n_data_chunks = obj->n_data_chunks; -+ -+ if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) -+ cp->size_or_equiv_obj = obj->variant.file_variant.file_size; -+ else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) -+ cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id; -+} -+ -+static int yaffs2_checkpt_obj_to_obj(struct yaffs_obj *obj, -+ struct yaffs_checkpt_obj *cp) -+{ -+ struct yaffs_obj *parent; -+ u32 cp_variant_type = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_VARIANT_BITS); -+ -+ if (obj->variant_type != cp_variant_type) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "Checkpoint read object %d type %d chunk %d does not match existing object type %d", -+ cp->obj_id, cp_variant_type, cp->hdr_chunk, -+ obj->variant_type); -+ return 0; -+ } -+ -+ obj->obj_id = cp->obj_id; -+ -+ if (cp->parent_id) -+ parent = yaffs_find_or_create_by_number(obj->my_dev, -+ cp->parent_id, -+ YAFFS_OBJECT_TYPE_DIRECTORY); -+ else -+ parent = NULL; -+ -+ if (parent) { -+ if (parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) { -+ yaffs_trace(YAFFS_TRACE_ALWAYS, -+ "Checkpoint read object %d parent %d type %d chunk %d Parent type, %d, not directory", -+ cp->obj_id, cp->parent_id, -+ cp_variant_type, cp->hdr_chunk, -+ parent->variant_type); -+ return 0; -+ } -+ yaffs_add_obj_to_dir(parent, obj); -+ } -+ -+ obj->hdr_chunk = cp->hdr_chunk; -+ -+ obj->variant_type = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_VARIANT_BITS); -+ obj->deleted = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_DELETED_BITS); -+ obj->soft_del = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_SOFT_DEL_BITS); -+ obj->unlinked = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_UNLINKED_BITS); -+ obj->fake = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_FAKE_BITS); -+ obj->rename_allowed = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_RENAME_ALLOWED_BITS); -+ obj->unlink_allowed = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_UNLINK_ALLOWED_BITS); -+ obj->serial = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_SERIAL_BITS); -+ -+ obj->n_data_chunks = cp->n_data_chunks; -+ -+ if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) { -+ obj->variant.file_variant.file_size = cp->size_or_equiv_obj; -+ obj->variant.file_variant.stored_size = cp->size_or_equiv_obj; -+ } else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) { -+ obj->variant.hardlink_variant.equiv_id = cp->size_or_equiv_obj; -+ } -+ if (obj->hdr_chunk > 0) -+ obj->lazy_loaded = 1; -+ return 1; -+} -+ -+static void yaffs2_do_endian_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn) -+{ -+ int i; -+ u32 *as_u32 = (u32 *)tn; -+ int tnode_size_u32 = dev->tnode_size / sizeof(u32); -+ -+ if (!dev->swap_endian) -+ return; -+ /* Swap all the tnode data as u32s to fix endianisms. */ -+ for (i = 0; iswap_endian) -+ return tn; -+ -+ memcpy(dev->tn_swap_buffer, tn, dev->tnode_size); -+ tn = dev->tn_swap_buffer; -+ -+ yaffs2_do_endian_tnode(dev, tn); -+ -+ return tn; -+} -+ -+static int yaffs2_checkpt_tnode_worker(struct yaffs_obj *in, -+ struct yaffs_tnode *tn, u32 level, -+ int chunk_offset) -+{ -+ int i; -+ struct yaffs_dev *dev = in->my_dev; -+ int ok = 1; -+ u32 base_offset; -+ -+ if (!tn) -+ return 1; -+ -+ if (level > 0) { -+ for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) { -+ if (!tn->internal[i]) -+ continue; -+ ok = yaffs2_checkpt_tnode_worker(in, -+ tn->internal[i], -+ level - 1, -+ (chunk_offset << -+ YAFFS_TNODES_INTERNAL_BITS) + i); -+ } -+ return ok; -+ } -+ -+ /* Level 0 tnode */ -+ base_offset = chunk_offset << YAFFS_TNODES_LEVEL0_BITS; -+ yaffs_do_endian_u32(dev, &base_offset); -+ -+ ok = (yaffs2_checkpt_wr(dev, &base_offset, sizeof(base_offset)) == -+ sizeof(base_offset)); -+ if (ok) { -+ /* -+ * NB Can't do an in-place endian swizzle since that would -+ * damage current tnode data. -+ * If a tnode endian conversion is required we do a copy. -+ */ -+ tn = yaffs2_do_endian_tnode_copy(dev, tn); -+ ok = (yaffs2_checkpt_wr(dev, tn, dev->tnode_size) == -+ (int)dev->tnode_size); -+ } -+ return ok; -+} -+ -+static int yaffs2_wr_checkpt_tnodes(struct yaffs_obj *obj) -+{ -+ u32 end_marker = ~0; -+ int ok = 1; -+ -+ if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE) -+ return ok; -+ -+ ok = yaffs2_checkpt_tnode_worker(obj, -+ obj->variant.file_variant.top, -+ obj->variant.file_variant. -+ top_level, 0); -+ if (ok) -+ ok = (yaffs2_checkpt_wr(obj->my_dev, &end_marker, -+ sizeof(end_marker)) == sizeof(end_marker)); -+ -+ return ok ? 1 : 0; -+} -+ -+static int yaffs2_rd_checkpt_tnodes(struct yaffs_obj *obj) -+{ -+ u32 base_chunk; -+ int ok = 1; -+ struct yaffs_dev *dev = obj->my_dev; -+ struct yaffs_file_var *file_stuct_ptr = &obj->variant.file_variant; -+ struct yaffs_tnode *tn; -+ int nread = 0; -+ -+ ok = (yaffs2_checkpt_rd(dev, &base_chunk, sizeof(base_chunk)) == -+ sizeof(base_chunk)); -+ -+ yaffs_do_endian_u32(dev, &base_chunk); -+ -+ while (ok && (~base_chunk)) { -+ nread++; -+ /* Read level 0 tnode */ -+ -+ tn = yaffs_get_tnode(dev); -+ if (tn) { -+ ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) == -+ (int)dev->tnode_size); -+ yaffs2_do_endian_tnode(dev, tn); -+ } -+ else -+ ok = 0; -+ -+ if (tn && ok) -+ ok = yaffs_add_find_tnode_0(dev, -+ file_stuct_ptr, -+ base_chunk, tn) ? 1 : 0; -+ -+ if (ok) { -+ ok = (yaffs2_checkpt_rd -+ (dev, &base_chunk, -+ sizeof(base_chunk)) == sizeof(base_chunk)); -+ yaffs_do_endian_u32(dev, &base_chunk); -+ } -+ -+ } -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "Checkpoint read tnodes %d records, last %d. ok %d", -+ nread, base_chunk, ok); -+ -+ return ok ? 1 : 0; -+} -+ -+ -+static void yaffs2_do_endian_checkpt_obj(struct yaffs_dev *dev, -+ struct yaffs_checkpt_obj *cp) -+{ -+ if (!dev->swap_endian) -+ return; -+ cp->struct_type = swap_s32(cp->struct_type); -+ cp->obj_id = swap_u32(cp->obj_id); -+ cp->parent_id = swap_u32(cp->parent_id); -+ cp->hdr_chunk = swap_s32(cp->hdr_chunk); -+ cp->bit_field = swap_u32(cp->bit_field); -+ cp->n_data_chunks = swap_s32(cp->n_data_chunks); -+ cp->size_or_equiv_obj = swap_loff_t(cp->size_or_equiv_obj); -+} -+ -+static int yaffs2_wr_checkpt_objs(struct yaffs_dev *dev) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_checkpt_obj cp; -+ int i; -+ int ok = 1; -+ struct list_head *lh; -+ u32 cp_variant_type; -+ -+ /* Iterate through the objects in each hash entry, -+ * dumping them to the checkpointing stream. -+ */ -+ -+ for (i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++) { -+ list_for_each(lh, &dev->obj_bucket[i].list) { -+ obj = list_entry(lh, struct yaffs_obj, hash_link); -+ if (!obj->defered_free) { -+ yaffs2_obj_checkpt_obj(&cp, obj); -+ cp.struct_type = sizeof(cp); -+ cp_variant_type = yaffs2_checkpt_obj_bit_get( -+ &cp, CHECKPOINT_VARIANT_BITS); -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "Checkpoint write object %d parent %d type %d chunk %d obj addr %p", -+ cp.obj_id, cp.parent_id, -+ cp_variant_type, cp.hdr_chunk, obj); -+ -+ yaffs2_do_endian_checkpt_obj (dev, &cp); -+ ok = (yaffs2_checkpt_wr(dev, &cp, -+ sizeof(cp)) == sizeof(cp)); -+ -+ if (ok && -+ obj->variant_type == -+ YAFFS_OBJECT_TYPE_FILE) -+ ok = yaffs2_wr_checkpt_tnodes(obj); -+ } -+ } -+ } -+ -+ /* Dump end of list */ -+ memset(&cp, 0xff, sizeof(struct yaffs_checkpt_obj)); -+ cp.struct_type = sizeof(cp); -+ yaffs2_do_endian_checkpt_obj (dev, &cp); -+ -+ if (ok) -+ ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)); -+ -+ return ok ? 1 : 0; -+} -+ -+static int yaffs2_rd_checkpt_objs(struct yaffs_dev *dev) -+{ -+ struct yaffs_obj *obj; -+ struct yaffs_checkpt_obj cp; -+ int ok = 1; -+ int done = 0; -+ u32 cp_variant_type; -+ LIST_HEAD(hard_list); -+ -+ -+ while (ok && !done) { -+ ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp)); -+ yaffs2_do_endian_checkpt_obj (dev, &cp); -+ -+ if (cp.struct_type != sizeof(cp)) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "struct size %d instead of %d ok %d", -+ cp.struct_type, (int)sizeof(cp), ok); -+ ok = 0; -+ } -+ -+ cp_variant_type = yaffs2_checkpt_obj_bit_get( -+ &cp, CHECKPOINT_VARIANT_BITS); -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "Checkpoint read object %d parent %d type %d chunk %d ", -+ cp.obj_id, cp.parent_id, cp_variant_type, -+ cp.hdr_chunk); -+ -+ if (ok && cp.obj_id == (u32)(~0)) { -+ done = 1; -+ } else if (ok) { -+ obj = -+ yaffs_find_or_create_by_number(dev, cp.obj_id, -+ cp_variant_type); -+ if (obj) { -+ ok = yaffs2_checkpt_obj_to_obj(obj, &cp); -+ if (!ok) -+ break; -+ if (obj->variant_type == -+ YAFFS_OBJECT_TYPE_FILE) { -+ ok = yaffs2_rd_checkpt_tnodes(obj); -+ } else if (obj->variant_type == -+ YAFFS_OBJECT_TYPE_HARDLINK) { -+ list_add(&obj->hard_links, &hard_list); -+ } -+ } else { -+ ok = 0; -+ } -+ } -+ } -+ -+ if (ok) -+ yaffs_link_fixup(dev, &hard_list); -+ -+ return ok ? 1 : 0; -+} -+ -+static int yaffs2_wr_checkpt_sum(struct yaffs_dev *dev) -+{ -+ u32 checkpt_sum; -+ int ok; -+ -+ yaffs2_get_checkpt_sum(dev, &checkpt_sum); -+ -+ yaffs_do_endian_u32(dev, &checkpt_sum); -+ -+ ok = (yaffs2_checkpt_wr(dev, &checkpt_sum, sizeof(checkpt_sum)) == -+ sizeof(checkpt_sum)); -+ -+ if (!ok) -+ return 0; -+ -+ return 1; -+} -+ -+static int yaffs2_rd_checkpt_sum(struct yaffs_dev *dev) -+{ -+ u32 checkpt_sum0; -+ u32 checkpt_sum1; -+ int ok; -+ -+ yaffs2_get_checkpt_sum(dev, &checkpt_sum0); -+ -+ ok = (yaffs2_checkpt_rd(dev, &checkpt_sum1, sizeof(checkpt_sum1)) == -+ sizeof(checkpt_sum1)); -+ -+ if (!ok) -+ return 0; -+ yaffs_do_endian_u32(dev, &checkpt_sum1); -+ -+ if (checkpt_sum0 != checkpt_sum1) -+ return 0; -+ -+ return 1; -+} -+ -+static int yaffs2_wr_checkpt_data(struct yaffs_dev *dev) -+{ -+ int ok = 1; -+ -+ if (!yaffs2_checkpt_required(dev)) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "skipping checkpoint write"); -+ ok = 0; -+ } -+ -+ if (ok) -+ ok = yaffs2_checkpt_open(dev, 1); -+ -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "write checkpoint validity"); -+ ok = yaffs2_wr_checkpt_validity_marker(dev, 1); -+ } -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "write checkpoint device"); -+ ok = yaffs2_wr_checkpt_dev(dev); -+ } -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "write checkpoint objects"); -+ ok = yaffs2_wr_checkpt_objs(dev); -+ } -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "write checkpoint validity"); -+ ok = yaffs2_wr_checkpt_validity_marker(dev, 0); -+ } -+ -+ if (ok) -+ ok = yaffs2_wr_checkpt_sum(dev); -+ -+ if (!yaffs_checkpt_close(dev)) -+ ok = 0; -+ -+ if (ok) -+ dev->is_checkpointed = 1; -+ else -+ dev->is_checkpointed = 0; -+ -+ return dev->is_checkpointed; -+} -+ -+static int yaffs2_rd_checkpt_data(struct yaffs_dev *dev) -+{ -+ int ok = 1; -+ -+ if (!dev->param.is_yaffs2) -+ ok = 0; -+ -+ if (ok && dev->param.skip_checkpt_rd) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "skipping checkpoint read"); -+ ok = 0; -+ } -+ -+ if (ok) -+ ok = yaffs2_checkpt_open(dev, 0); /* open for read */ -+ -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "read checkpoint validity"); -+ ok = yaffs2_rd_checkpt_validity_marker(dev, 1); -+ } -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "read checkpoint device"); -+ ok = yaffs2_rd_checkpt_dev(dev); -+ } -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "read checkpoint objects"); -+ ok = yaffs2_rd_checkpt_objs(dev); -+ } -+ if (ok) { -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "read checkpoint validity"); -+ ok = yaffs2_rd_checkpt_validity_marker(dev, 0); -+ } -+ -+ if (ok) { -+ ok = yaffs2_rd_checkpt_sum(dev); -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "read checkpoint checksum %d", ok); -+ } -+ -+ if (!yaffs_checkpt_close(dev)) -+ ok = 0; -+ -+ if (ok) -+ dev->is_checkpointed = 1; -+ else -+ dev->is_checkpointed = 0; -+ -+ return ok ? 1 : 0; -+} -+ -+void yaffs2_checkpt_invalidate(struct yaffs_dev *dev) -+{ -+ if (dev->is_checkpointed || dev->blocks_in_checkpt > 0) { -+ dev->is_checkpointed = 0; -+ yaffs2_checkpt_invalidate_stream(dev); -+ } -+ if (dev->param.sb_dirty_fn) -+ dev->param.sb_dirty_fn(dev); -+} -+ -+int yaffs_checkpoint_save(struct yaffs_dev *dev) -+{ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "save entry: is_checkpointed %d", -+ dev->is_checkpointed); -+ -+ yaffs_verify_objects(dev); -+ yaffs_verify_blocks(dev); -+ yaffs_verify_free_chunks(dev); -+ -+ if (!dev->is_checkpointed) { -+ yaffs2_checkpt_invalidate(dev); -+ yaffs2_wr_checkpt_data(dev); -+ } -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT | YAFFS_TRACE_MOUNT, -+ "save exit: is_checkpointed %d", -+ dev->is_checkpointed); -+ -+ return dev->is_checkpointed; -+} -+ -+int yaffs2_checkpt_restore(struct yaffs_dev *dev) -+{ -+ int retval; -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "restore entry: is_checkpointed %d", -+ dev->is_checkpointed); -+ -+ retval = yaffs2_rd_checkpt_data(dev); -+ -+ if (dev->is_checkpointed) { -+ yaffs_verify_objects(dev); -+ yaffs_verify_blocks(dev); -+ yaffs_verify_free_chunks(dev); -+ } -+ -+ yaffs_trace(YAFFS_TRACE_CHECKPOINT, -+ "restore exit: is_checkpointed %d", -+ dev->is_checkpointed); -+ -+ return retval; -+} -+ -+/* End of checkpointing */ -+ -+/* Hole handling logic for truncate past end of file */ -+ -+int yaffs2_handle_hole(struct yaffs_obj *obj, loff_t new_size) -+{ -+ /* if new_size > old_file_size. -+ * We're going to be writing a hole. -+ * If the hole is small then write zeros otherwise write a start -+ * of hole marker. -+ */ -+ loff_t old_file_size; -+ loff_t increase; -+ int small_hole; -+ int result = YAFFS_OK; -+ struct yaffs_dev *dev = NULL; -+ u8 *local_buffer = NULL; -+ int small_increase_ok = 0; -+ -+ if (!obj) -+ return YAFFS_FAIL; -+ -+ if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE) -+ return YAFFS_FAIL; -+ -+ dev = obj->my_dev; -+ -+ /* Bail out if not yaffs2 mode */ -+ if (!dev->param.is_yaffs2) -+ return YAFFS_OK; -+ -+ old_file_size = obj->variant.file_variant.file_size; -+ -+ if (new_size <= old_file_size) -+ return YAFFS_OK; -+ -+ increase = new_size - old_file_size; -+ -+ if (increase < YAFFS_SMALL_HOLE_THRESHOLD * dev->data_bytes_per_chunk && -+ yaffs_check_alloc_available(dev, YAFFS_SMALL_HOLE_THRESHOLD + 1)) -+ small_hole = 1; -+ else -+ small_hole = 0; -+ -+ if (small_hole) -+ local_buffer = yaffs_get_temp_buffer(dev); -+ -+ if (local_buffer) { -+ /* fill hole with zero bytes */ -+ loff_t pos = old_file_size; -+ int this_write; -+ int written; -+ memset(local_buffer, 0, dev->data_bytes_per_chunk); -+ small_increase_ok = 1; -+ -+ while (increase > 0 && small_increase_ok) { -+ this_write = increase; -+ if (this_write > (int)dev->data_bytes_per_chunk) -+ this_write = dev->data_bytes_per_chunk; -+ written = -+ yaffs_do_file_wr(obj, local_buffer, pos, this_write, -+ 0); -+ if (written == this_write) { -+ pos += this_write; -+ increase -= this_write; -+ } else { -+ small_increase_ok = 0; -+ } -+ } -+ -+ yaffs_release_temp_buffer(dev, local_buffer); -+ -+ /* If out of space then reverse any chunks we've added */ -+ if (!small_increase_ok) -+ yaffs_resize_file_down(obj, old_file_size); -+ } -+ -+ if (!small_increase_ok && -+ obj->parent && -+ obj->parent->obj_id != YAFFS_OBJECTID_UNLINKED && -+ obj->parent->obj_id != YAFFS_OBJECTID_DELETED) { -+ /* Write a hole start header with the old file size */ -+ yaffs_update_oh(obj, NULL, 0, 1, 0, NULL); -+ } -+ -+ return result; -+} -+ -+/* Yaffs2 scanning */ -+ -+struct yaffs_block_index { -+ int seq; -+ int block; -+}; -+ -+static int yaffs2_ybicmp(const void *a, const void *b) -+{ -+ int aseq = ((struct yaffs_block_index *)a)->seq; -+ int bseq = ((struct yaffs_block_index *)b)->seq; -+ int ablock = ((struct yaffs_block_index *)a)->block; -+ int bblock = ((struct yaffs_block_index *)b)->block; -+ -+ if (aseq == bseq) -+ return ablock - bblock; -+ -+ return aseq - bseq; -+} -+ -+static inline int yaffs2_scan_chunk(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi, -+ int blk, int chunk_in_block, -+ int *found_chunks, -+ u8 *chunk_data, -+ struct list_head *hard_list, -+ int summary_available) -+{ -+ struct yaffs_obj_hdr *oh; -+ struct yaffs_obj *in; -+ struct yaffs_obj *parent; -+ int equiv_id; -+ loff_t file_size; -+ int is_shrink; -+ int is_unlinked; -+ struct yaffs_ext_tags tags; -+ int result; -+ int alloc_failed = 0; -+ int chunk = blk * dev->param.chunks_per_block + chunk_in_block; -+ struct yaffs_file_var *file_var; -+ struct yaffs_hardlink_var *hl_var; -+ struct yaffs_symlink_var *sl_var; -+ -+ if (summary_available) { -+ result = yaffs_summary_fetch(dev, &tags, chunk_in_block); -+ tags.seq_number = bi->seq_number; -+ } -+ -+ if (!summary_available || tags.obj_id == 0) { -+ result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags); -+ dev->tags_used++; -+ } else { -+ dev->summary_used++; -+ } -+ -+ if (result == YAFFS_FAIL) -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "Could not get tags for chunk %d\n", chunk); -+ /* Let's have a good look at this chunk... */ -+ -+ if (!tags.chunk_used) { -+ /* An unassigned chunk in the block. -+ * If there are used chunks after this one, then -+ * it is a chunk that was skipped due to failing -+ * the erased check. Just skip it so that it can -+ * be deleted. -+ * But, more typically, We get here when this is -+ * an unallocated chunk and his means that -+ * either the block is empty or this is the one -+ * being allocated from -+ */ -+ -+ if (*found_chunks) { -+ /* This is a chunk that was skipped due -+ * to failing the erased check */ -+ } else if (chunk_in_block == 0) { -+ /* We're looking at the first chunk in -+ * the block so the block is unused */ -+ bi->block_state = YAFFS_BLOCK_STATE_EMPTY; -+ dev->n_erased_blocks++; -+ } else { -+ if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN || -+ bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) { -+ if (dev->seq_number == bi->seq_number) { -+ /* Allocating from this block*/ -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ " Allocating from %d %d", -+ blk, chunk_in_block); -+ -+ bi->block_state = -+ YAFFS_BLOCK_STATE_ALLOCATING; -+ dev->alloc_block = blk; -+ dev->alloc_page = chunk_in_block; -+ dev->alloc_block_finder = blk; -+ } else { -+ /* This is a partially written block -+ * that is not the current -+ * allocation block. -+ */ -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "Partially written block %d detected. gc will fix this.", -+ blk); -+ } -+ } -+ } -+ -+ dev->n_free_chunks++; -+ -+ } else if (tags.ecc_result == -+ YAFFS_ECC_RESULT_UNFIXED) { -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ " Unfixed ECC in chunk(%d:%d), chunk ignored", -+ blk, chunk_in_block); -+ dev->n_free_chunks++; -+ } else if (tags.obj_id > YAFFS_MAX_OBJECT_ID || -+ tags.chunk_id > YAFFS_MAX_CHUNK_ID || -+ tags.obj_id == YAFFS_OBJECTID_SUMMARY || -+ (tags.chunk_id > 0 && -+ tags.n_bytes > dev->data_bytes_per_chunk) || -+ tags.seq_number != bi->seq_number) { -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored", -+ blk, chunk_in_block, tags.obj_id, -+ tags.chunk_id, tags.n_bytes); -+ dev->n_free_chunks++; -+ } else if (tags.chunk_id > 0) { -+ /* chunk_id > 0 so it is a data chunk... */ -+ loff_t endpos; -+ loff_t chunk_base = (tags.chunk_id - 1) * -+ dev->data_bytes_per_chunk; -+ -+ *found_chunks = 1; -+ -+ yaffs_set_chunk_bit(dev, blk, chunk_in_block); -+ bi->pages_in_use++; -+ -+ in = yaffs_find_or_create_by_number(dev, -+ tags.obj_id, -+ YAFFS_OBJECT_TYPE_FILE); -+ if (!in) -+ /* Out of memory */ -+ alloc_failed = 1; -+ -+ if (in && -+ in->variant_type == YAFFS_OBJECT_TYPE_FILE && -+ chunk_base < in->variant.file_variant.shrink_size) { -+ /* This has not been invalidated by -+ * a resize */ -+ if (!yaffs_put_chunk_in_file(in, tags.chunk_id, -+ chunk, -1)) -+ alloc_failed = 1; -+ -+ /* File size is calculated by looking at -+ * the data chunks if we have not -+ * seen an object header yet. -+ * Stop this practice once we find an -+ * object header. -+ */ -+ endpos = chunk_base + tags.n_bytes; -+ -+ if (!in->valid && -+ in->variant.file_variant.stored_size < endpos) { -+ in->variant.file_variant. -+ stored_size = endpos; -+ in->variant.file_variant. -+ file_size = endpos; -+ } -+ } else if (in) { -+ /* This chunk has been invalidated by a -+ * resize, or a past file deletion -+ * so delete the chunk*/ -+ yaffs_chunk_del(dev, chunk, 1, __LINE__); -+ } -+ } else { -+ /* chunk_id == 0, so it is an ObjectHeader. -+ * Thus, we read in the object header and make -+ * the object -+ */ -+ *found_chunks = 1; -+ -+ yaffs_set_chunk_bit(dev, blk, chunk_in_block); -+ bi->pages_in_use++; -+ -+ oh = NULL; -+ in = NULL; -+ -+ if (tags.extra_available) { -+ in = yaffs_find_or_create_by_number(dev, -+ tags.obj_id, -+ tags.extra_obj_type); -+ if (!in) -+ alloc_failed = 1; -+ } -+ -+ if (!in || -+ (!in->valid && dev->param.disable_lazy_load) || -+ tags.extra_shadows || -+ (!in->valid && (tags.obj_id == YAFFS_OBJECTID_ROOT || -+ tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND))) { -+ -+ /* If we don't have valid info then we -+ * need to read the chunk -+ * TODO In future we can probably defer -+ * reading the chunk and living with -+ * invalid data until needed. -+ */ -+ -+ result = yaffs_rd_chunk_tags_nand(dev, -+ chunk, -+ chunk_data, -+ NULL); -+ -+ oh = (struct yaffs_obj_hdr *)chunk_data; -+ -+ yaffs_do_endian_oh(dev, oh); -+ -+ if (dev->param.inband_tags) { -+ /* Fix up the header if they got -+ * corrupted by inband tags */ -+ oh->shadows_obj = -+ oh->inband_shadowed_obj_id; -+ oh->is_shrink = -+ oh->inband_is_shrink; -+ } -+ -+ if (!in) { -+ in = yaffs_find_or_create_by_number(dev, -+ tags.obj_id, oh->type); -+ if (!in) -+ alloc_failed = 1; -+ } -+ } -+ -+ if (!in) { -+ /* TODO Hoosterman we have a problem! */ -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs tragedy: Could not make object for object %d at chunk %d during scan", -+ tags.obj_id, chunk); -+ return YAFFS_FAIL; -+ } -+ -+ if (in->valid) { -+ /* We have already filled this one. -+ * We have a duplicate that will be -+ * discarded, but we first have to suck -+ * out resize info if it is a file. -+ */ -+ if ((in->variant_type == YAFFS_OBJECT_TYPE_FILE) && -+ ((oh && oh->type == YAFFS_OBJECT_TYPE_FILE) || -+ (tags.extra_available && -+ tags.extra_obj_type == YAFFS_OBJECT_TYPE_FILE) -+ )) { -+ loff_t this_size = (oh) ? -+ yaffs_oh_to_size(dev, oh, 0) : -+ tags.extra_file_size; -+ u32 parent_obj_id = (oh) ? -+ (u32)oh->parent_obj_id : -+ tags.extra_parent_id; -+ -+ is_shrink = (oh) ? -+ oh->is_shrink : -+ tags.extra_is_shrink; -+ -+ /* If it is deleted (unlinked -+ * at start also means deleted) -+ * we treat the file size as -+ * being zeroed at this point. -+ */ -+ if (parent_obj_id == YAFFS_OBJECTID_DELETED || -+ parent_obj_id == YAFFS_OBJECTID_UNLINKED) { -+ this_size = 0; -+ is_shrink = 1; -+ } -+ -+ if (is_shrink && -+ in->variant.file_variant.shrink_size > -+ this_size) -+ in->variant.file_variant.shrink_size = -+ this_size; -+ -+ if (is_shrink) -+ bi->has_shrink_hdr = 1; -+ } -+ /* Use existing - destroy this one. */ -+ yaffs_chunk_del(dev, chunk, 1, __LINE__); -+ } -+ -+ if (!in->valid && in->variant_type != -+ (oh ? oh->type : tags.extra_obj_type)) { -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs tragedy: Bad type, %d != %d, for object %d at chunk %d during scan", -+ oh ? oh->type : tags.extra_obj_type, -+ in->variant_type, tags.obj_id, -+ chunk); -+ in = yaffs_retype_obj(in, oh ? oh->type : tags.extra_obj_type); -+ } -+ -+ if (!in->valid && -+ (tags.obj_id == YAFFS_OBJECTID_ROOT || -+ tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND)) { -+ /* We only load some info, don't fiddle -+ * with directory structure */ -+ in->valid = 1; -+ -+ if (oh) { -+ in->yst_mode = oh->yst_mode; -+ yaffs_load_attribs(in, oh); -+ in->lazy_loaded = 0; -+ } else { -+ in->lazy_loaded = 1; -+ } -+ in->hdr_chunk = chunk; -+ -+ } else if (!in->valid) { -+ /* we need to load this info */ -+ in->valid = 1; -+ in->hdr_chunk = chunk; -+ if (oh) { -+ in->variant_type = oh->type; -+ in->yst_mode = oh->yst_mode; -+ yaffs_load_attribs(in, oh); -+ -+ if (oh->shadows_obj > 0) -+ yaffs_handle_shadowed_obj(dev, -+ oh->shadows_obj, 1); -+ -+ yaffs_set_obj_name_from_oh(in, oh); -+ parent = yaffs_find_or_create_by_number(dev, -+ oh->parent_obj_id, -+ YAFFS_OBJECT_TYPE_DIRECTORY); -+ file_size = yaffs_oh_to_size(dev, oh, 0); -+ is_shrink = oh->is_shrink; -+ equiv_id = oh->equiv_id; -+ } else { -+ in->variant_type = tags.extra_obj_type; -+ parent = yaffs_find_or_create_by_number(dev, -+ tags.extra_parent_id, -+ YAFFS_OBJECT_TYPE_DIRECTORY); -+ file_size = tags.extra_file_size; -+ is_shrink = tags.extra_is_shrink; -+ equiv_id = tags.extra_equiv_id; -+ in->lazy_loaded = 1; -+ } -+ in->dirty = 0; -+ -+ if (!parent) -+ alloc_failed = 1; -+ -+ /* directory stuff... -+ * hook up to parent -+ */ -+ -+ if (parent && -+ parent->variant_type == YAFFS_OBJECT_TYPE_UNKNOWN) { -+ /* Set up as a directory */ -+ parent->variant_type = -+ YAFFS_OBJECT_TYPE_DIRECTORY; -+ INIT_LIST_HEAD(&parent-> -+ variant.dir_variant.children); -+ } else if (!parent || -+ parent->variant_type != -+ YAFFS_OBJECT_TYPE_DIRECTORY) { -+ /* Hoosterman, another problem.... -+ * Trying to use a non-directory as a directory -+ */ -+ -+ yaffs_trace(YAFFS_TRACE_ERROR, -+ "yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found." -+ ); -+ parent = dev->lost_n_found; -+ } -+ yaffs_add_obj_to_dir(parent, in); -+ -+ is_unlinked = (parent == dev->del_dir) || -+ (parent == dev->unlinked_dir); -+ -+ if (is_shrink) -+ /* Mark the block */ -+ bi->has_shrink_hdr = 1; -+ -+ /* Note re hardlinks. -+ * Since we might scan a hardlink before its equivalent -+ * object is scanned we put them all in a list. -+ * After scanning is complete, we should have all the -+ * objects, so we run through this list and fix up all -+ * the chains. -+ */ -+ -+ switch (in->variant_type) { -+ case YAFFS_OBJECT_TYPE_UNKNOWN: -+ /* Todo got a problem */ -+ break; -+ case YAFFS_OBJECT_TYPE_FILE: -+ file_var = &in->variant.file_variant; -+ if (file_var->stored_size < file_size) { -+ /* This covers the case where the file -+ * size is greater than the data held. -+ * This will happen if the file is -+ * resized to be larger than its -+ * current data extents. -+ */ -+ file_var->file_size = file_size; -+ file_var->stored_size = file_size; -+ } -+ -+ if (file_var->shrink_size > file_size) -+ file_var->shrink_size = file_size; -+ -+ break; -+ case YAFFS_OBJECT_TYPE_HARDLINK: -+ hl_var = &in->variant.hardlink_variant; -+ if (!is_unlinked) { -+ hl_var->equiv_id = equiv_id; -+ list_add(&in->hard_links, hard_list); -+ } -+ break; -+ case YAFFS_OBJECT_TYPE_DIRECTORY: -+ /* Do nothing */ -+ break; -+ case YAFFS_OBJECT_TYPE_SPECIAL: -+ /* Do nothing */ -+ break; -+ case YAFFS_OBJECT_TYPE_SYMLINK: -+ sl_var = &in->variant.symlink_variant; -+ if (oh) { -+ sl_var->alias = -+ yaffs_clone_str(oh->alias); -+ if (!sl_var->alias) -+ alloc_failed = 1; -+ } -+ break; -+ } -+ } -+ } -+ return alloc_failed ? YAFFS_FAIL : YAFFS_OK; -+} -+ -+int yaffs2_scan_backwards(struct yaffs_dev *dev) -+{ -+ u32 blk; -+ int block_iter; -+ int start_iter; -+ int end_iter; -+ int n_to_scan = 0; -+ enum yaffs_block_state state; -+ int c; -+ LIST_HEAD(hard_list); -+ struct yaffs_block_info *bi; -+ u32 seq_number; -+ int n_blocks = dev->internal_end_block - dev->internal_start_block + 1; -+ u8 *chunk_data; -+ int found_chunks; -+ int alloc_failed = 0; -+ struct yaffs_block_index *block_index = NULL; -+ int alt_block_index = 0; -+ int summary_available; -+ -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "yaffs2_scan_backwards starts intstartblk %d intendblk %d...", -+ dev->internal_start_block, dev->internal_end_block); -+ -+ dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER; -+ -+ block_index = -+ kmalloc(n_blocks * sizeof(struct yaffs_block_index), GFP_NOFS); -+ -+ if (!block_index) { -+ block_index = -+ vmalloc(n_blocks * sizeof(struct yaffs_block_index)); -+ alt_block_index = 1; -+ } -+ -+ if (!block_index) { -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "yaffs2_scan_backwards() could not allocate block index!" -+ ); -+ return YAFFS_FAIL; -+ } -+ -+ dev->blocks_in_checkpt = 0; -+ -+ chunk_data = yaffs_get_temp_buffer(dev); -+ -+ /* Scan all the blocks to determine their state */ -+ bi = dev->block_info; -+ for (blk = dev->internal_start_block; blk <= dev->internal_end_block; -+ blk++) { -+ yaffs_clear_chunk_bits(dev, blk); -+ bi->pages_in_use = 0; -+ bi->soft_del_pages = 0; -+ -+ yaffs_query_init_block_state(dev, blk, &state, &seq_number); -+ -+ bi->block_state = state; -+ bi->seq_number = seq_number; -+ -+ if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA) -+ bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT; -+ if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK) -+ bi->block_state = YAFFS_BLOCK_STATE_DEAD; -+ -+ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, -+ "Block scanning block %d state %d seq %d", -+ blk, bi->block_state, seq_number); -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) { -+ dev->blocks_in_checkpt++; -+ -+ } else if (bi->block_state == YAFFS_BLOCK_STATE_DEAD) { -+ yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, -+ "block %d is bad", blk); -+ } else if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) { -+ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty "); -+ dev->n_erased_blocks++; -+ dev->n_free_chunks += dev->param.chunks_per_block; -+ } else if (bi->block_state == -+ YAFFS_BLOCK_STATE_NEEDS_SCAN) { -+ /* Determine the highest sequence number */ -+ if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER && -+ seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) { -+ block_index[n_to_scan].seq = seq_number; -+ block_index[n_to_scan].block = blk; -+ n_to_scan++; -+ if (seq_number >= dev->seq_number) -+ dev->seq_number = seq_number; -+ } else { -+ /* TODO: Nasty sequence number! */ -+ yaffs_trace(YAFFS_TRACE_SCAN, -+ "Block scanning block %d has bad sequence number %d", -+ blk, seq_number); -+ } -+ } -+ bi++; -+ } -+ -+ yaffs_trace(YAFFS_TRACE_ALWAYS, "%d blocks to be sorted...", n_to_scan); -+ -+ cond_resched(); -+ -+ /* Sort the blocks by sequence number */ -+ sort(block_index, n_to_scan, sizeof(struct yaffs_block_index), -+ yaffs2_ybicmp, NULL); -+ -+ cond_resched(); -+ -+ yaffs_trace(YAFFS_TRACE_SCAN, "...done"); -+ -+ /* Now scan the blocks looking at the data. */ -+ start_iter = 0; -+ end_iter = n_to_scan - 1; -+ yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "%d blocks to scan", n_to_scan); -+ -+ /* For each block.... backwards */ -+ for (block_iter = end_iter; -+ !alloc_failed && block_iter >= start_iter; -+ block_iter--) { -+ /* Cooperative multitasking! This loop can run for so -+ long that watchdog timers expire. */ -+ cond_resched(); -+ -+ /* get the block to scan in the correct order */ -+ blk = block_index[block_iter].block; -+ bi = yaffs_get_block_info(dev, blk); -+ -+ summary_available = yaffs_summary_read(dev, dev->sum_tags, blk); -+ -+ /* For each chunk in each block that needs scanning.... */ -+ found_chunks = 0; -+ if (summary_available) -+ c = dev->chunks_per_summary - 1; -+ else -+ c = dev->param.chunks_per_block - 1; -+ -+ for (/* c is already initialised */; -+ !alloc_failed && c >= 0 && -+ (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN || -+ bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING); -+ c--) { -+ /* Scan backwards... -+ * Read the tags and decide what to do -+ */ -+ if (yaffs2_scan_chunk(dev, bi, blk, c, -+ &found_chunks, chunk_data, -+ &hard_list, summary_available) == -+ YAFFS_FAIL) -+ alloc_failed = 1; -+ } -+ -+ if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN) { -+ /* If we got this far while scanning, then the block -+ * is fully allocated. */ -+ bi->block_state = YAFFS_BLOCK_STATE_FULL; -+ } -+ -+ /* Now let's see if it was dirty */ -+ if (bi->pages_in_use == 0 && -+ !bi->has_shrink_hdr && -+ bi->block_state == YAFFS_BLOCK_STATE_FULL) { -+ yaffs_block_became_dirty(dev, blk); -+ } -+ } -+ -+ yaffs_skip_rest_of_block(dev); -+ -+ if (alt_block_index) -+ vfree(block_index); -+ else -+ kfree(block_index); -+ -+ /* Ok, we've done all the scanning. -+ * Fix up the hard link chains. -+ * We have scanned all the objects, now it's time to add these -+ * hardlinks. -+ */ -+ yaffs_link_fixup(dev, &hard_list); -+ -+ yaffs_release_temp_buffer(dev, chunk_data); -+ -+ if (alloc_failed) -+ return YAFFS_FAIL; -+ -+ yaffs_trace(YAFFS_TRACE_SCAN, "yaffs2_scan_backwards ends"); -+ -+ return YAFFS_OK; -+} ---- linux-4.9.37/fs/yaffs2/yaffs_yaffs2.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yaffs_yaffs2.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,39 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YAFFS_YAFFS2_H__ -+#define __YAFFS_YAFFS2_H__ -+ -+#include "yaffs_guts.h" -+ -+void yaffs_calc_oldest_dirty_seq(struct yaffs_dev *dev); -+void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev); -+void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev, -+ struct yaffs_block_info *bi); -+void yaffs2_update_oldest_dirty_seq(struct yaffs_dev *dev, unsigned block_no, -+ struct yaffs_block_info *bi); -+int yaffs_block_ok_for_gc(struct yaffs_dev *dev, struct yaffs_block_info *bi); -+u32 yaffs2_find_refresh_block(struct yaffs_dev *dev); -+int yaffs2_checkpt_required(struct yaffs_dev *dev); -+int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev); -+ -+void yaffs2_checkpt_invalidate(struct yaffs_dev *dev); -+int yaffs2_checkpt_save(struct yaffs_dev *dev); -+int yaffs2_checkpt_restore(struct yaffs_dev *dev); -+ -+int yaffs2_handle_hole(struct yaffs_obj *obj, loff_t new_size); -+int yaffs2_scan_backwards(struct yaffs_dev *dev); -+ -+#endif ---- linux-4.9.37/fs/yaffs2/yportenv.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/fs/yaffs2/yportenv.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,85 @@ -+/* -+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system. -+ * -+ * Copyright (C) 2002-2011 Aleph One Ltd. -+ * for Toby Churchill Ltd and Brightstar Engineering -+ * -+ * Created by Charles Manning -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License version 2.1 as -+ * published by the Free Software Foundation. -+ * -+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. -+ */ -+ -+#ifndef __YPORTENV_H__ -+#define __YPORTENV_H__ -+ -+/* -+ * Define the MTD version in terms of Linux Kernel versions -+ * This allows yaffs to be used independantly of the kernel -+ * as well as with it. -+ */ -+ -+#define MTD_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) -+ -+#ifdef YAFFS_OUT_OF_TREE -+#include "moduleconfig.h" -+#endif -+ -+#include -+#define MTD_VERSION_CODE LINUX_VERSION_CODE -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* These type wrappings are used to support Unicode names in WinCE. */ -+#define YCHAR char -+#define YUCHAR unsigned char -+#define _Y(x) x -+ -+#define YAFFS_LOSTNFOUND_NAME "lost+found" -+#define YAFFS_LOSTNFOUND_PREFIX "obj" -+ -+ -+#define YAFFS_ROOT_MODE 0755 -+#define YAFFS_LOSTNFOUND_MODE 0700 -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) -+#define Y_CURRENT_TIME CURRENT_TIME.tv_sec -+#define Y_TIME_CONVERT(x) (x).tv_sec -+#else -+#define Y_CURRENT_TIME CURRENT_TIME -+#define Y_TIME_CONVERT(x) (x) -+#endif -+ -+#define compile_time_assertion(assertion) \ -+ ({ int x = __builtin_choose_expr(assertion, 0, (void)0); (void) x; }) -+ -+ -+#define yaffs_printf(msk, fmt, ...) \ -+ printk(KERN_DEBUG "yaffs: " fmt "\n", ##__VA_ARGS__) -+ -+#define yaffs_trace(msk, fmt, ...) do { \ -+ if (yaffs_trace_mask & (msk)) \ -+ printk(KERN_DEBUG "yaffs: " fmt "\n", ##__VA_ARGS__); \ -+} while (0) -+ -+ -+#endif ---- linux-4.9.37/include/dt-bindings/clock/gk7202v300-clock.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/dt-bindings/clock/gk7202v300-clock.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,76 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __DTS_GK7202V300_CLOCK_H -+#define __DTS_GK7202V300_CLOCK_H -+ -+/* clk in GK7202V300 CRG */ -+/* fixed rate clocks */ -+#define GK7202V300_FIXED_100K 1 -+#define GK7202V300_FIXED_400K 2 -+#define GK7202V300_FIXED_3M 3 -+#define GK7202V300_FIXED_6M 4 -+#define GK7202V300_FIXED_12M 5 -+#define GK7202V300_FIXED_24M 6 -+#define GK7202V300_FIXED_25M 7 -+#define GK7202V300_FIXED_50M 8 -+#define GK7202V300_FIXED_83P3M 9 -+#define GK7202V300_FIXED_90M 10 -+#define GK7202V300_FIXED_100M 11 -+#define GK7202V300_FIXED_112M 12 -+#define GK7202V300_FIXED_125M 13 -+#define GK7202V300_FIXED_148P5M 14 -+#define GK7202V300_FIXED_150M 15 -+#define GK7202V300_FIXED_200M 16 -+#define GK7202V300_FIXED_250M 17 -+#define GK7202V300_FIXED_300M 18 -+#define GK7202V300_FIXED_324M 19 -+#define GK7202V300_FIXED_342M 20 -+#define GK7202V300_FIXED_375M 21 -+#define GK7202V300_FIXED_400M 22 -+#define GK7202V300_FIXED_448M 23 -+#define GK7202V300_FIXED_500M 24 -+#define GK7202V300_FIXED_540M 25 -+#define GK7202V300_FIXED_600M 26 -+#define GK7202V300_FIXED_750M 27 -+#define GK7202V300_FIXED_1000M 28 -+#define GK7202V300_FIXED_1500M 29 -+ -+/* mux clocks */ -+#define GK7202V300_SYSAXI_CLK 30 -+#define GK7202V300_SYSAPB_CLK 31 -+#define GK7202V300_FMC_MUX 32 -+#define GK7202V300_UART_MUX 33 -+#define GK7202V300_MMC0_MUX 34 -+#define GK7202V300_MMC1_MUX 35 -+#define GK7202V300_MMC2_MUX 36 -+#define GK7202V300_ETH_MUX 37 -+#define GK7202V300_USB2_MUX 80 -+/* gate clocks */ -+#define GK7202V300_UART0_CLK 40 -+#define GK7202V300_UART1_CLK 41 -+#define GK7202V300_UART2_CLK 42 -+#define GK7202V300_FMC_CLK 43 -+#define GK7202V300_ETH0_CLK 44 -+#define GK7202V300_EDMAC_AXICLK 45 -+#define GK7202V300_EDMAC_CLK 46 -+#define GK7202V300_SPI0_CLK 48 -+#define GK7202V300_SPI1_CLK 49 -+#define GK7202V300_MMC0_CLK 50 -+#define GK7202V300_MMC1_CLK 51 -+#define GK7202V300_MMC2_CLK 52 -+#define GK7202V300_I2C0_CLK 53 -+#define GK7202V300_I2C1_CLK 54 -+#define GK7202V300_I2C2_CLK 55 -+#define GK7202V300_USB2_BUS_CLK 81 -+#define GK7202V300_USB2_REF_CLK 82 -+#define GK7202V300_USB2_UTMI_CLK 83 -+#define GK7202V300_USB2_PHY_APB_CLK 84 -+#define GK7202V300_USB2_PHY_PLL_CLK 85 -+#define GK7202V300_USB2_PHY_XO_CLK 86 -+ -+#define GK7202V300_NR_CLKS 256 -+#define GK7202V300_NR_RSTS 256 -+ -+#endif /* __DTS_GK7202V300_CLOCK_H */ ---- linux-4.9.37/include/dt-bindings/clock/gk7205v200-clock.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/dt-bindings/clock/gk7205v200-clock.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,76 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __DTS_GK7205V200_CLOCK_H -+#define __DTS_GK7205V200_CLOCK_H -+ -+/* clk in GK7205V200 CRG */ -+/* fixed rate clocks */ -+#define GK7205V200_FIXED_100K 1 -+#define GK7205V200_FIXED_400K 2 -+#define GK7205V200_FIXED_3M 3 -+#define GK7205V200_FIXED_6M 4 -+#define GK7205V200_FIXED_12M 5 -+#define GK7205V200_FIXED_24M 6 -+#define GK7205V200_FIXED_25M 7 -+#define GK7205V200_FIXED_50M 8 -+#define GK7205V200_FIXED_83P3M 9 -+#define GK7205V200_FIXED_90M 10 -+#define GK7205V200_FIXED_100M 11 -+#define GK7205V200_FIXED_112M 12 -+#define GK7205V200_FIXED_125M 13 -+#define GK7205V200_FIXED_148P5M 14 -+#define GK7205V200_FIXED_150M 15 -+#define GK7205V200_FIXED_200M 16 -+#define GK7205V200_FIXED_250M 17 -+#define GK7205V200_FIXED_300M 18 -+#define GK7205V200_FIXED_324M 19 -+#define GK7205V200_FIXED_342M 20 -+#define GK7205V200_FIXED_375M 21 -+#define GK7205V200_FIXED_400M 22 -+#define GK7205V200_FIXED_448M 23 -+#define GK7205V200_FIXED_500M 24 -+#define GK7205V200_FIXED_540M 25 -+#define GK7205V200_FIXED_600M 26 -+#define GK7205V200_FIXED_750M 27 -+#define GK7205V200_FIXED_1000M 28 -+#define GK7205V200_FIXED_1500M 29 -+ -+/* mux clocks */ -+#define GK7205V200_SYSAXI_CLK 30 -+#define GK7205V200_SYSAPB_CLK 31 -+#define GK7205V200_FMC_MUX 32 -+#define GK7205V200_UART_MUX 33 -+#define GK7205V200_MMC0_MUX 34 -+#define GK7205V200_MMC1_MUX 35 -+#define GK7205V200_MMC2_MUX 36 -+#define GK7205V200_ETH_MUX 37 -+#define GK7205V200_USB2_MUX 80 -+/* gate clocks */ -+#define GK7205V200_UART0_CLK 40 -+#define GK7205V200_UART1_CLK 41 -+#define GK7205V200_UART2_CLK 42 -+#define GK7205V200_FMC_CLK 43 -+#define GK7205V200_ETH0_CLK 44 -+#define GK7205V200_EDMAC_AXICLK 45 -+#define GK7205V200_EDMAC_CLK 46 -+#define GK7205V200_SPI0_CLK 48 -+#define GK7205V200_SPI1_CLK 49 -+#define GK7205V200_MMC0_CLK 50 -+#define GK7205V200_MMC1_CLK 51 -+#define GK7205V200_MMC2_CLK 52 -+#define GK7205V200_I2C0_CLK 53 -+#define GK7205V200_I2C1_CLK 54 -+#define GK7205V200_I2C2_CLK 55 -+#define GK7205V200_USB2_BUS_CLK 81 -+#define GK7205V200_USB2_REF_CLK 82 -+#define GK7205V200_USB2_UTMI_CLK 83 -+#define GK7205V200_USB2_PHY_APB_CLK 84 -+#define GK7205V200_USB2_PHY_PLL_CLK 85 -+#define GK7205V200_USB2_PHY_XO_CLK 86 -+ -+#define GK7205V200_NR_CLKS 256 -+#define GK7205V200_NR_RSTS 256 -+ -+#endif /* __DTS_GK7205V200_CLOCK_H */ ---- linux-4.9.37/include/dt-bindings/clock/gk7205v300-clock.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/dt-bindings/clock/gk7205v300-clock.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,76 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __DTS_GK7205V300_CLOCK_H -+#define __DTS_GK7205V300_CLOCK_H -+ -+/* clk in GK7205V300 CRG */ -+/* fixed rate clocks */ -+#define GK7205V300_FIXED_100K 1 -+#define GK7205V300_FIXED_400K 2 -+#define GK7205V300_FIXED_3M 3 -+#define GK7205V300_FIXED_6M 4 -+#define GK7205V300_FIXED_12M 5 -+#define GK7205V300_FIXED_24M 6 -+#define GK7205V300_FIXED_25M 7 -+#define GK7205V300_FIXED_50M 8 -+#define GK7205V300_FIXED_83P3M 9 -+#define GK7205V300_FIXED_90M 10 -+#define GK7205V300_FIXED_100M 11 -+#define GK7205V300_FIXED_112M 12 -+#define GK7205V300_FIXED_125M 13 -+#define GK7205V300_FIXED_148P5M 14 -+#define GK7205V300_FIXED_150M 15 -+#define GK7205V300_FIXED_200M 16 -+#define GK7205V300_FIXED_250M 17 -+#define GK7205V300_FIXED_300M 18 -+#define GK7205V300_FIXED_324M 19 -+#define GK7205V300_FIXED_342M 20 -+#define GK7205V300_FIXED_375M 21 -+#define GK7205V300_FIXED_400M 22 -+#define GK7205V300_FIXED_448M 23 -+#define GK7205V300_FIXED_500M 24 -+#define GK7205V300_FIXED_540M 25 -+#define GK7205V300_FIXED_600M 26 -+#define GK7205V300_FIXED_750M 27 -+#define GK7205V300_FIXED_1000M 28 -+#define GK7205V300_FIXED_1500M 29 -+ -+/* mux clocks */ -+#define GK7205V300_SYSAXI_CLK 30 -+#define GK7205V300_SYSAPB_CLK 31 -+#define GK7205V300_FMC_MUX 32 -+#define GK7205V300_UART_MUX 33 -+#define GK7205V300_MMC0_MUX 34 -+#define GK7205V300_MMC1_MUX 35 -+#define GK7205V300_MMC2_MUX 36 -+#define GK7205V300_ETH_MUX 37 -+#define GK7205V300_USB2_MUX 80 -+/* gate clocks */ -+#define GK7205V300_UART0_CLK 40 -+#define GK7205V300_UART1_CLK 41 -+#define GK7205V300_UART2_CLK 42 -+#define GK7205V300_FMC_CLK 43 -+#define GK7205V300_ETH0_CLK 44 -+#define GK7205V300_EDMAC_AXICLK 45 -+#define GK7205V300_EDMAC_CLK 46 -+#define GK7205V300_SPI0_CLK 48 -+#define GK7205V300_SPI1_CLK 49 -+#define GK7205V300_MMC0_CLK 50 -+#define GK7205V300_MMC1_CLK 51 -+#define GK7205V300_MMC2_CLK 52 -+#define GK7205V300_I2C0_CLK 53 -+#define GK7205V300_I2C1_CLK 54 -+#define GK7205V300_I2C2_CLK 55 -+#define GK7205V300_USB2_BUS_CLK 81 -+#define GK7205V300_USB2_REF_CLK 82 -+#define GK7205V300_USB2_UTMI_CLK 83 -+#define GK7205V300_USB2_PHY_APB_CLK 84 -+#define GK7205V300_USB2_PHY_PLL_CLK 85 -+#define GK7205V300_USB2_PHY_XO_CLK 86 -+ -+#define GK7205V300_NR_CLKS 256 -+#define GK7205V300_NR_RSTS 256 -+ -+#endif /* __DTS_GK7205V300_CLOCK_H */ ---- linux-4.9.37/include/dt-bindings/clock/gk7605v100-clock.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/dt-bindings/clock/gk7605v100-clock.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,76 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __DTS_GK7605V100_CLOCK_H -+#define __DTS_GK7605V100_CLOCK_H -+ -+/* clk in GK7605V100 CRG */ -+/* fixed rate clocks */ -+#define GK7605V100_FIXED_100K 1 -+#define GK7605V100_FIXED_400K 2 -+#define GK7605V100_FIXED_3M 3 -+#define GK7605V100_FIXED_6M 4 -+#define GK7605V100_FIXED_12M 5 -+#define GK7605V100_FIXED_24M 6 -+#define GK7605V100_FIXED_25M 7 -+#define GK7605V100_FIXED_50M 8 -+#define GK7605V100_FIXED_83P3M 9 -+#define GK7605V100_FIXED_90M 10 -+#define GK7605V100_FIXED_100M 11 -+#define GK7605V100_FIXED_112M 12 -+#define GK7605V100_FIXED_125M 13 -+#define GK7605V100_FIXED_148P5M 14 -+#define GK7605V100_FIXED_150M 15 -+#define GK7605V100_FIXED_200M 16 -+#define GK7605V100_FIXED_250M 17 -+#define GK7605V100_FIXED_300M 18 -+#define GK7605V100_FIXED_324M 19 -+#define GK7605V100_FIXED_342M 20 -+#define GK7605V100_FIXED_375M 21 -+#define GK7605V100_FIXED_400M 22 -+#define GK7605V100_FIXED_448M 23 -+#define GK7605V100_FIXED_500M 24 -+#define GK7605V100_FIXED_540M 25 -+#define GK7605V100_FIXED_600M 26 -+#define GK7605V100_FIXED_750M 27 -+#define GK7605V100_FIXED_1000M 28 -+#define GK7605V100_FIXED_1500M 29 -+ -+/* mux clocks */ -+#define GK7605V100_SYSAXI_CLK 30 -+#define GK7605V100_SYSAPB_CLK 31 -+#define GK7605V100_FMC_MUX 32 -+#define GK7605V100_UART_MUX 33 -+#define GK7605V100_MMC0_MUX 34 -+#define GK7605V100_MMC1_MUX 35 -+#define GK7605V100_MMC2_MUX 36 -+#define GK7605V100_ETH_MUX 37 -+#define GK7605V100_USB2_MUX 80 -+/* gate clocks */ -+#define GK7605V100_UART0_CLK 40 -+#define GK7605V100_UART1_CLK 41 -+#define GK7605V100_UART2_CLK 42 -+#define GK7605V100_FMC_CLK 43 -+#define GK7605V100_ETH0_CLK 44 -+#define GK7605V100_EDMAC_AXICLK 45 -+#define GK7605V100_EDMAC_CLK 46 -+#define GK7605V100_SPI0_CLK 48 -+#define GK7605V100_SPI1_CLK 49 -+#define GK7605V100_MMC0_CLK 50 -+#define GK7605V100_MMC1_CLK 51 -+#define GK7605V100_MMC2_CLK 52 -+#define GK7605V100_I2C0_CLK 53 -+#define GK7605V100_I2C1_CLK 54 -+#define GK7605V100_I2C2_CLK 55 -+#define GK7605V100_USB2_BUS_CLK 81 -+#define GK7605V100_USB2_REF_CLK 82 -+#define GK7605V100_USB2_UTMI_CLK 83 -+#define GK7605V100_USB2_PHY_APB_CLK 84 -+#define GK7605V100_USB2_PHY_PLL_CLK 85 -+#define GK7605V100_USB2_PHY_XO_CLK 86 -+ -+#define GK7605V100_NR_CLKS 256 -+#define GK7605V100_NR_RSTS 256 -+ -+#endif /* __DTS_GK7605V100_CLOCK_H */ ---- linux-4.9.37/include/kvm/arm_psci.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/kvm/arm_psci.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (C) 2012 - ARM Ltd -+ * Author: Marc Zyngier -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef __KVM_ARM_PSCI_H__ -+#define __KVM_ARM_PSCI_H__ -+ -+#include -+ -+#define KVM_ARM_PSCI_0_1 PSCI_VERSION(0, 1) -+#define KVM_ARM_PSCI_0_2 PSCI_VERSION(0, 2) -+ -+int kvm_psci_version(struct kvm_vcpu *vcpu); -+int kvm_psci_call(struct kvm_vcpu *vcpu); -+ -+#endif /* __KVM_ARM_PSCI_H__ */ ---- linux-4.9.37/include/linux/blkdev.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/blkdev.h 2021-06-07 13:01:34.000000000 +0300 -@@ -1174,7 +1174,11 @@ - enum blk_default_limits { - BLK_MAX_SEGMENTS = 128, - BLK_SAFE_MAX_SECTORS = 255, -+#ifndef CONFIG_GOKE_MC - BLK_DEF_MAX_SECTORS = 2560, -+#else -+ BLK_DEF_MAX_SECTORS = 8192, -+#endif - BLK_MAX_SEGMENT_SIZE = 65536, - BLK_SEG_BOUNDARY_MASK = 0xFFFFFFFFUL, - }; ---- linux-4.9.37/include/linux/cpuidle.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/cpuidle.h 2021-06-07 13:01:34.000000000 +0300 -@@ -62,6 +62,7 @@ - }; - - /* Idle State Flags */ -+#define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ - #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */ - #define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */ - ---- linux-4.9.37/include/linux/dma-mapping.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/dma-mapping.h 2021-06-07 13:01:34.000000000 +0300 -@@ -705,6 +705,8 @@ - /* - * Managed DMA API - */ -+void bsp_dmac_map_area(const void *kaddr, size_t size, -+ enum dma_data_direction dir); - extern void *dmam_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp); - extern void dmam_free_coherent(struct device *dev, size_t size, void *vaddr, ---- linux-4.9.37/include/linux/fb.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/fb.h 2021-06-07 13:01:34.000000000 +0300 -@@ -237,7 +237,14 @@ - void (*deferred_io)(struct fb_info *info, struct list_head *pagelist); - }; - #endif -+#ifdef CONFIG_ARCH_GOKE -+#define FBIOGET_DMABUF _IOR('F', 0x21, struct fb_dmabuf_export) - -+struct fb_dmabuf_export { -+ __u32 fd; -+ __u32 flags; -+}; -+#endif - /* - * Frame buffer operations - * -@@ -320,6 +327,12 @@ - /* called at KDB enter and leave time to prepare the console */ - int (*fb_debug_enter)(struct fb_info *info); - int (*fb_debug_leave)(struct fb_info *info); -+#ifdef CONFIG_ARCH_GOKE -+#ifdef CONFIG_DMA_SHARED_BUFFER -+ /* Export the frame buffer as a dmabuf object */ -+ struct dma_buf *(*fb_dmabuf_export)(struct fb_info *info); -+#endif -+#endif - }; - - #ifdef CONFIG_FB_TILEBLITTING ---- linux-4.9.37/include/linux/fence.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/fence.h 2021-06-07 13:01:34.000000000 +0300 -@@ -108,6 +108,7 @@ - * @get_driver_name: returns the driver name. - * @get_timeline_name: return the name of the context this fence belongs to. - * @enable_signaling: enable software signaling of fence. -+ * @disable_signaling: disable software signaling of fence (optional). - * @signaled: [optional] peek whether the fence is signaled, can be null. - * @wait: custom wait implementation, or fence_default_wait. - * @release: [optional] called on destruction of fence, can be null -@@ -167,6 +168,7 @@ - const char * (*get_driver_name)(struct fence *fence); - const char * (*get_timeline_name)(struct fence *fence); - bool (*enable_signaling)(struct fence *fence); -+ void (*disable_signaling)(struct fence *fence); - bool (*signaled)(struct fence *fence); - signed long (*wait)(struct fence *fence, bool intr, signed long timeout); - void (*release)(struct fence *fence); -@@ -183,6 +185,16 @@ - void fence_free(struct fence *fence); - - /** -+ * fence_put - decreases refcount of the fence -+ * @fence: [in] fence to reduce refcount of -+ */ -+static inline void fence_put(struct fence *fence) -+{ -+ if (fence) -+ kref_put(&fence->refcount, fence_release); -+} -+ -+/** - * fence_get - increases refcount of the fence - * @fence: [in] fence to increase refcount of - * -@@ -210,13 +222,49 @@ - } - - /** -- * fence_put - decreases refcount of the fence -- * @fence: [in] fence to reduce refcount of -+ * fence_get_rcu_safe - acquire a reference to an RCU tracked fence -+ * @fence: [in] pointer to fence to increase refcount of -+ * -+ * Function returns NULL if no refcount could be obtained, or the fence. -+ * This function handles acquiring a reference to a fence that may be -+ * reallocated within the RCU grace period (such as with SLAB_DESTROY_BY_RCU), -+ * so long as the caller is using RCU on the pointer to the fence. -+ * -+ * An alternative mechanism is to employ a seqlock to protect a bunch of -+ * fences, such as used by struct reservation_object. When using a seqlock, -+ * the seqlock must be taken before and checked after a reference to the -+ * fence is acquired (as shown here). -+ * -+ * The caller is required to hold the RCU read lock. - */ --static inline void fence_put(struct fence *fence) -+static inline struct fence *fence_get_rcu_safe(struct fence * __rcu *fencep) - { -- if (fence) -- kref_put(&fence->refcount, fence_release); -+ do { -+ struct fence *fence; -+ -+ fence = rcu_dereference(*fencep); -+ if (!fence || !fence_get_rcu(fence)) -+ return NULL; -+ -+ /* The atomic_inc_not_zero() inside fence_get_rcu() -+ * provides a full memory barrier upon success (such as now). -+ * This is paired with the write barrier from assigning -+ * to the __rcu protected fence pointer so that if that -+ * pointer still matches the current fence, we know we -+ * have successfully acquire a reference to it. If it no -+ * longer matches, we are holding a reference to some other -+ * reallocated pointer. This is possible if the allocator -+ * is using a freelist like SLAB_DESTROY_BY_RCU where the -+ * fence remains valid for the RCU grace period, but it -+ * may be reallocated. When using such allocators, we are -+ * responsible for ensuring the reference we get is to -+ * the right fence, as below. -+ */ -+ if (fence == rcu_access_pointer(*fencep)) -+ return rcu_pointer_handoff(fence); -+ -+ fence_put(fence); -+ } while (1); - } - - int fence_signal(struct fence *fence); ---- linux-4.9.37/include/linux/fs.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/fs.h 2021-06-07 13:01:34.000000000 +0300 -@@ -941,9 +941,9 @@ - /* Page cache limit. The filesystems should put that into their s_maxbytes - limits, otherwise bad things can happen in VM. */ - #if BITS_PER_LONG==32 --#define MAX_LFS_FILESIZE (((loff_t)PAGE_SIZE << (BITS_PER_LONG-1))-1) -+#define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT) - #elif BITS_PER_LONG==64 --#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL) -+#define MAX_LFS_FILESIZE ((loff_t)LLONG_MAX) - #endif - - #define FL_POSIX 1 ---- linux-4.9.37/include/linux/goke_cma.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/goke_cma.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,39 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+#ifndef __GOKE_CMA_H__ -+#define __GOKE_CMA_H__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define NAME_LEN_MAX 64 -+#define ZONE_MAX 64 -+ -+struct cma_zone { -+ struct device pdev; -+ char name[NAME_LEN_MAX]; -+ gfp_t gfp; -+ phys_addr_t phys_start; -+ phys_addr_t nbytes; -+ u32 alloc_type; -+ u32 block_align; -+}; -+ -+#ifdef CONFIG_CMA -+int is_cma_address(phys_addr_t phys, unsigned long size); -+phys_addr_t goke_get_zones_start(void); -+struct cma_zone *goke_get_cma_zone(const char *name); -+struct device *goke_get_cma_device(const char *name); -+int __init goke_declare_heap_memory(void); -+#endif /* CONFIG_CMA */ -+ -+#endif ---- linux-4.9.37/include/linux/i2c.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/i2c.h 2021-06-07 13:01:34.000000000 +0300 -@@ -68,6 +68,20 @@ - */ - extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num); -+ -+#ifdef CONFIG_ARCH_GOKE -+ -+extern int gk_i2c_master_send(const struct i2c_client *client, const char *buf, -+ int count); -+ -+extern int gk_i2c_master_recv(const struct i2c_client *client, char *buf, -+ int count); -+ -+extern int gk_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, -+ int num); -+ -+#endif -+ - /* Unlocked flavor */ - extern int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num); -@@ -553,6 +567,9 @@ - const struct i2c_lock_operations *lock_ops; - struct rt_mutex bus_lock; - struct rt_mutex mux_lock; -+#ifdef CONFIG_ARCH_GOKE -+ spinlock_t spinlock; -+#endif - - int timeout; /* in jiffies */ - int retries; ---- linux-4.9.37/include/linux/lzma/LzFind.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/lzma/LzFind.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,115 @@ -+/* LzFind.h -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_FIND_H -+#define __LZ_FIND_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef UInt32 CLzRef; -+ -+typedef struct _CMatchFinder -+{ -+ Byte *buffer; -+ UInt32 pos; -+ UInt32 posLimit; -+ UInt32 streamPos; -+ UInt32 lenLimit; -+ -+ UInt32 cyclicBufferPos; -+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ -+ -+ UInt32 matchMaxLen; -+ CLzRef *hash; -+ CLzRef *son; -+ UInt32 hashMask; -+ UInt32 cutValue; -+ -+ Byte *bufferBase; -+ ISeqInStream *stream; -+ int streamEndWasReached; -+ -+ UInt32 blockSize; -+ UInt32 keepSizeBefore; -+ UInt32 keepSizeAfter; -+ -+ UInt32 numHashBytes; -+ int directInput; -+ size_t directInputRem; -+ int btMode; -+ int bigHash; -+ UInt32 historySize; -+ UInt32 fixedHashSize; -+ UInt32 hashSizeSum; -+ UInt32 numSons; -+ SRes result; -+ UInt32 crc[256]; -+} CMatchFinder; -+ -+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) -+ -+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) -+ -+int MatchFinder_NeedMove(CMatchFinder *p); -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -+void MatchFinder_MoveBlock(CMatchFinder *p); -+void MatchFinder_ReadIfRequired(CMatchFinder *p); -+ -+void MatchFinder_Construct(CMatchFinder *p); -+ -+/* Conditions: -+ historySize <= 3 GB -+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -+*/ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc); -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -+ UInt32 *distances, UInt32 maxLen); -+ -+/* -+Conditions: -+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. -+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -+*/ -+ -+typedef void (*Mf_Init_Func)(void *object); -+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); -+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -+typedef void (*Mf_Skip_Func)(void *object, UInt32); -+ -+typedef struct _IMatchFinder -+{ -+ Mf_Init_Func Init; -+ Mf_GetIndexByte_Func GetIndexByte; -+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; -+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; -+ Mf_GetMatches_Func GetMatches; -+ Mf_Skip_Func Skip; -+} IMatchFinder; -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -+ -+void MatchFinder_Init(CMatchFinder *p); -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- linux-4.9.37/include/linux/lzma/LzHash.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/lzma/LzHash.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,54 @@ -+/* LzHash.h -- HASH functions for LZ algorithms -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_HASH_H -+#define __LZ_HASH_H -+ -+#define kHash2Size (1 << 10) -+#define kHash3Size (1 << 16) -+#define kHash4Size (1 << 20) -+ -+#define kFix3HashSize (kHash2Size) -+#define kFix4HashSize (kHash2Size + kHash3Size) -+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) -+ -+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); -+ -+#define HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } -+ -+#define HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } -+ -+#define HASH5_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ -+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ -+ hash4Value &= (kHash4Size - 1); } -+ -+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; -+ -+ -+#define MT_HASH2_CALC \ -+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); -+ -+#define MT_HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -+ -+#define MT_HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } -+ -+#endif ---- linux-4.9.37/include/linux/lzma/LzmaDec.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/lzma/LzmaDec.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,231 @@ -+/* LzmaDec.h -- LZMA Decoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_DEC_H -+#define __LZMA_DEC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* #define _LZMA_PROB32 */ -+/* _LZMA_PROB32 can increase the speed on some CPUs, -+ but memory usage for CLzmaDec::probs will be doubled in that case */ -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+ -+/* ---------- LZMA Properties ---------- */ -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaProps -+{ -+ unsigned lc, lp, pb; -+ UInt32 dicSize; -+} CLzmaProps; -+ -+/* LzmaProps_Decode - decodes properties -+Returns: -+ SZ_OK -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -+ -+ -+/* ---------- LZMA Decoder state ---------- */ -+ -+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. -+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ -+ -+#define LZMA_REQUIRED_INPUT_MAX 20 -+ -+typedef struct -+{ -+ CLzmaProps prop; -+ CLzmaProb *probs; -+ Byte *dic; -+ const Byte *buf; -+ UInt32 range, code; -+ SizeT dicPos; -+ SizeT dicBufSize; -+ UInt32 processedPos; -+ UInt32 checkDicSize; -+ unsigned state; -+ UInt32 reps[4]; -+ unsigned remainLen; -+ int needFlush; -+ int needInitState; -+ UInt32 numProbs; -+ unsigned tempBufSize; -+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -+} CLzmaDec; -+ -+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -+ -+void LzmaDec_Init(CLzmaDec *p); -+ -+/* There are two types of LZMA streams: -+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. -+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -+ -+typedef enum -+{ -+ LZMA_FINISH_ANY, /* finish at any point */ -+ LZMA_FINISH_END /* block must be finished at the end */ -+} ELzmaFinishMode; -+ -+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! -+ -+ You must use LZMA_FINISH_END, when you know that current output buffer -+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. -+ -+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, -+ and output value of destLen will be less than output buffer size limit. -+ You can check status result also. -+ -+ You can use multiple checks to test data integrity after full decompression: -+ 1) Check Result and "status" variable. -+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. -+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. -+ You must use correct finish mode in that case. */ -+ -+typedef enum -+{ -+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ -+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ -+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ -+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -+} ELzmaStatus; -+ -+/* ELzmaStatus is used only as output value for function call */ -+ -+ -+/* ---------- Interfaces ---------- */ -+ -+/* There are 3 levels of interfaces: -+ 1) Dictionary Interface -+ 2) Buffer Interface -+ 3) One Call Interface -+ You can select any of these interfaces, but don't mix functions from different -+ groups for same object. */ -+ -+ -+/* There are two variants to allocate state for Dictionary Interface: -+ 1) LzmaDec_Allocate / LzmaDec_Free -+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -+ You can use variant 2, if you set dictionary buffer manually. -+ For Buffer Interface you must always use variant 1. -+ -+LzmaDec_Allocate* can return: -+ SZ_OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -+ -+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -+ -+/* ---------- Dictionary Interface ---------- */ -+ -+/* You can use it, if you want to eliminate the overhead for data copying from -+ dictionary to some other external buffer. -+ You must work with CLzmaDec variables directly in this interface. -+ -+ STEPS: -+ LzmaDec_Constr() -+ LzmaDec_Allocate() -+ for (each new stream) -+ { -+ LzmaDec_Init() -+ while (it needs more decompression) -+ { -+ LzmaDec_DecodeToDic() -+ use data from CLzmaDec::dic and update CLzmaDec::dicPos -+ } -+ } -+ LzmaDec_Free() -+*/ -+ -+/* LzmaDec_DecodeToDic -+ -+ The decoding to internal dictionary buffer (CLzmaDec::dic). -+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (dicLimit). -+ LZMA_FINISH_ANY - Decode just dicLimit bytes. -+ LZMA_FINISH_END - Stream must be finished after dicLimit. -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_NEEDS_MORE_INPUT -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+*/ -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- Buffer Interface ---------- */ -+ -+/* It's zlib-like interface. -+ See LzmaDec_DecodeToDic description for information about STEPS and return results, -+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -+ to work with CLzmaDec variables manually. -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+*/ -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaDecode -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -+*/ -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- linux-4.9.37/include/linux/lzma/LzmaEnc.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/lzma/LzmaEnc.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,80 @@ -+/* LzmaEnc.h -- LZMA Encoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_ENC_H -+#define __LZMA_ENC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaEncProps -+{ -+ int level; /* 0 <= level <= 9 */ -+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version -+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version -+ default = (1 << 24) */ -+ int lc; /* 0 <= lc <= 8, default = 3 */ -+ int lp; /* 0 <= lp <= 4, default = 0 */ -+ int pb; /* 0 <= pb <= 4, default = 2 */ -+ int algo; /* 0 - fast, 1 - normal, default = 1 */ -+ int fb; /* 5 <= fb <= 273, default = 32 */ -+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ -+ int numHashBytes; /* 2, 3 or 4, default = 4 */ -+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ -+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ -+ int numThreads; /* 1 or 2, default = 2 */ -+} CLzmaEncProps; -+ -+void LzmaEncProps_Init(CLzmaEncProps *p); -+void LzmaEncProps_Normalize(CLzmaEncProps *p); -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -+ -+ -+/* ---------- CLzmaEncHandle Interface ---------- */ -+ -+/* LzmaEnc_* functions can return the following exit codes: -+Returns: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater in props -+ SZ_ERROR_WRITE - Write callback error. -+ SZ_ERROR_PROGRESS - some break from progress callback -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+typedef void * CLzmaEncHandle; -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaEncode -+Return code: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater -+ SZ_ERROR_OUTPUT_EOF - output buffer overflow -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- linux-4.9.37/include/linux/lzma/Types.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/lzma/Types.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,226 @@ -+/* Types.h -- Basic types -+2009-11-23 : Igor Pavlov : Public domain */ -+ -+#ifndef __7Z_TYPES_H -+#define __7Z_TYPES_H -+ -+#include -+ -+#ifdef _WIN32 -+#include -+#endif -+ -+#ifndef EXTERN_C_BEGIN -+#ifdef __cplusplus -+#define EXTERN_C_BEGIN extern "C" { -+#define EXTERN_C_END } -+#else -+#define EXTERN_C_BEGIN -+#define EXTERN_C_END -+#endif -+#endif -+ -+EXTERN_C_BEGIN -+ -+#define SZ_OK 0 -+ -+#define SZ_ERROR_DATA 1 -+#define SZ_ERROR_MEM 2 -+#define SZ_ERROR_CRC 3 -+#define SZ_ERROR_UNSUPPORTED 4 -+#define SZ_ERROR_PARAM 5 -+#define SZ_ERROR_INPUT_EOF 6 -+#define SZ_ERROR_OUTPUT_EOF 7 -+#define SZ_ERROR_READ 8 -+#define SZ_ERROR_WRITE 9 -+#define SZ_ERROR_PROGRESS 10 -+#define SZ_ERROR_FAIL 11 -+#define SZ_ERROR_THREAD 12 -+ -+#define SZ_ERROR_ARCHIVE 16 -+#define SZ_ERROR_NO_ARCHIVE 17 -+ -+typedef int SRes; -+ -+#ifdef _WIN32 -+typedef DWORD WRes; -+#else -+typedef int WRes; -+#endif -+ -+#ifndef RINOK -+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -+#endif -+ -+typedef unsigned char Byte; -+typedef short Int16; -+typedef unsigned short UInt16; -+ -+#ifdef _LZMA_UINT32_IS_ULONG -+typedef long Int32; -+typedef unsigned long UInt32; -+#else -+typedef int Int32; -+typedef unsigned int UInt32; -+#endif -+ -+#ifdef _SZ_NO_INT_64 -+ -+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. -+ NOTES: Some code will work incorrectly in that case! */ -+ -+typedef long Int64; -+typedef unsigned long UInt64; -+ -+#else -+ -+#if defined(_MSC_VER) || defined(__BORLANDC__) -+typedef __int64 Int64; -+typedef unsigned __int64 UInt64; -+#else -+typedef long long int Int64; -+typedef unsigned long long int UInt64; -+#endif -+ -+#endif -+ -+#ifdef _LZMA_NO_SYSTEM_SIZE_T -+typedef UInt32 SizeT; -+#else -+typedef size_t SizeT; -+#endif -+ -+typedef int Bool; -+#define True 1 -+#define False 0 -+ -+ -+#ifdef _WIN32 -+#define MY_STD_CALL __stdcall -+#else -+#define MY_STD_CALL -+#endif -+ -+#ifdef _MSC_VER -+ -+#if _MSC_VER >= 1300 -+#define MY_NO_INLINE __declspec(noinline) -+#else -+#define MY_NO_INLINE -+#endif -+ -+#define MY_CDECL __cdecl -+#define MY_FAST_CALL __fastcall -+ -+#else -+ -+#define MY_CDECL -+#define MY_FAST_CALL -+ -+#endif -+ -+ -+/* The following interfaces use first parameter as pointer to structure */ -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) < input(*size)) is allowed */ -+} ISeqInStream; -+ -+/* it can return SZ_ERROR_INPUT_EOF */ -+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); -+ -+typedef struct -+{ -+ size_t (*Write)(void *p, const void *buf, size_t size); -+ /* Returns: result - the number of actually written bytes. -+ (result < size) means error */ -+} ISeqOutStream; -+ -+typedef enum -+{ -+ SZ_SEEK_SET = 0, -+ SZ_SEEK_CUR = 1, -+ SZ_SEEK_END = 2 -+} ESzSeek; -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ISeekInStream; -+ -+typedef struct -+{ -+ SRes (*Look)(void *p, void **buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) > input(*size)) is not allowed -+ (output(*size) < input(*size)) is allowed */ -+ SRes (*Skip)(void *p, size_t offset); -+ /* offset must be <= output(*size) of Look */ -+ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* reads directly (without buffer). It's same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ILookInStream; -+ -+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); -+ -+/* reads via ILookInStream::Read */ -+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); -+ -+#define LookToRead_BUF_SIZE (1 << 14) -+ -+typedef struct -+{ -+ ILookInStream s; -+ ISeekInStream *realStream; -+ size_t pos; -+ size_t size; -+ Byte buf[LookToRead_BUF_SIZE]; -+} CLookToRead; -+ -+void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -+void LookToRead_Init(CLookToRead *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToLook; -+ -+void SecToLook_CreateVTable(CSecToLook *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToRead; -+ -+void SecToRead_CreateVTable(CSecToRead *p); -+ -+typedef struct -+{ -+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); -+ /* Returns: result. (result != SZ_OK) means break. -+ Value (UInt64)(Int64)-1 for size means unknown value. */ -+} ICompressProgress; -+ -+typedef struct -+{ -+ void *(*Alloc)(void *p, size_t size); -+ void (*Free)(void *p, void *address); /* address can be 0 */ -+} ISzAlloc; -+ -+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -+#define IAlloc_Free(p, a) (p)->Free((p), a) -+ -+EXTERN_C_END -+ -+#endif ---- linux-4.9.37/include/linux/lzma.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/lzma.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,62 @@ -+#ifndef __LZMA_H__ -+#define __LZMA_H__ -+ -+#ifdef __KERNEL__ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #define LZMA_MALLOC vmalloc -+ #define LZMA_FREE vfree -+ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) -+ #define INIT __init -+ #define STATIC static -+#else -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #ifndef PAGE_SIZE -+ extern int page_size; -+ #define PAGE_SIZE page_size -+ #endif -+ #define LZMA_MALLOC malloc -+ #define LZMA_FREE free -+ #define PRINT_ERROR(msg) fprintf(stderr, msg) -+ #define INIT -+ #define STATIC -+#endif -+ -+#include "lzma/LzmaDec.h" -+#include "lzma/LzmaEnc.h" -+ -+#define LZMA_BEST_LEVEL (9) -+#define LZMA_BEST_LC (0) -+#define LZMA_BEST_LP (0) -+#define LZMA_BEST_PB (0) -+#define LZMA_BEST_FB (273) -+ -+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) -+ -+static void *p_lzma_malloc(void *p, size_t size) -+{ -+ if (size == 0) -+ return NULL; -+ -+ return LZMA_MALLOC(size); -+} -+ -+static void p_lzma_free(void *p, void *address) -+{ -+ if (address != NULL) -+ LZMA_FREE(address); -+} -+ -+static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free}; -+ -+#endif ---- linux-4.9.37/include/linux/mfd/goke_fmc.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/mfd/goke_fmc.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,515 @@ -+/* -+ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. -+ */ -+ -+#ifndef __BSP_FMC_H -+#define __BSP_FMC_H -+ -+#include -+#include -+#include -+#include -+ -+/*****************************************************************************/ -+#define _512B (512) -+#define _1K (1024) -+#define _2K (2048) -+#define _4K (4096) -+#define _8K (8192) -+#define _16K (16384) -+#define _32K (32768) -+#define _64K (0x10000UL) -+#define _128K (0x20000UL) -+#define _256K (0x40000UL) -+#define _512K (0x80000UL) -+#define _1M (0x100000UL) -+#define _2M (0x200000UL) -+#define _4M (0x400000UL) -+#define _8M (0x800000UL) -+#define _16M (0x1000000UL) -+#define _32M (0x2000000UL) -+#define _64M (0x4000000UL) -+#define _128M (0x8000000UL) -+#define _256M (0x10000000UL) -+#define _512M (0x20000000UL) -+#define _1G (0x40000000ULL) -+#define _2G (0x80000000ULL) -+#define _4G (0x100000000ULL) -+#define _8G (0x200000000ULL) -+#define _16G (0x400000000ULL) -+#define _64G (0x1000000000ULL) -+ -+/*****************************************************************************/ -+/* FMC REG MAP */ -+/*****************************************************************************/ -+#define FMC_CFG 0x00 -+#define FMC_CFG_SPI_NAND_SEL(_type) (((_size) & 0x3) << 11) -+#define SPI_NOR_ADDR_MODE BIT(10) -+#define FMC_CFG_OP_MODE_MASK BIT_MASK(0) -+#define FMC_CFG_OP_MODE_BOOT 0 -+#define FMC_CFG_OP_MODE_NORMAL 1 -+#define SPI_NOR_ADDR_MODE_3BYTES (0x0 << 10) -+#define SPI_NOR_ADDR_MODE_4BYTES (0x1 << 10) -+ -+#define FMC_CFG_BLOCK_SIZE(_size) (((_size) & 0x3) << 8) -+#define FMC_CFG_ECC_TYPE(_type) (((_type) & 0x7) << 5) -+#define FMC_CFG_PAGE_SIZE(_size) (((_size) & 0x3) << 3) -+#define FMC_CFG_FLASH_SEL(_type) (((_type) & 0x3) << 1) -+#define FMC_CFG_OP_MODE(_mode) ((_mode) & 0x1) -+ -+#define SPI_NAND_MFR_OTHER 0x0 -+#define SPI_NAND_MFR_WINBOND 0x1 -+#define SPI_NAND_MFR_ESMT 0x2 -+#define SPI_NAND_MFR_MICRON 0x3 -+ -+#define SPI_NAND_SEL_SHIFT 11 -+#define SPI_NAND_SEL_MASK (0x3 << SPI_NAND_SEL_SHIFT) -+ -+#define SPI_NOR_ADDR_MODE_3_BYTES 0x0 -+#define SPI_NOR_ADDR_MODE_4_BYTES 0x1 -+ -+#define SPI_NOR_ADDR_MODE_SHIFT 10 -+#define SPI_NOR_ADDR_MODE_MASK (0x1 << SPI_NOR_ADDR_MODE_SHIFT) -+ -+#define BLOCK_SIZE_64_PAGE 0x0 -+#define BLOCK_SIZE_128_PAGE 0x1 -+#define BLOCK_SIZE_256_PAGE 0x2 -+#define BLOCK_SIZE_512_PAGE 0x3 -+ -+#define BLOCK_SIZE_MASK (0x3 << 8) -+ -+#define ECC_TYPE_0BIT 0x0 -+#define ECC_TYPE_8BIT 0x1 -+#define ECC_TYPE_16BIT 0x2 -+#define ECC_TYPE_24BIT 0x3 -+#define ECC_TYPE_28BIT 0x4 -+#define ECC_TYPE_40BIT 0x5 -+#define ECC_TYPE_64BIT 0x6 -+ -+#define ECC_TYPE_SHIFT 5 -+#define ECC_TYPE_MASK (0x7 << ECC_TYPE_SHIFT) -+ -+#define PAGE_SIZE_2KB 0x0 -+#define PAGE_SIZE_4KB 0x1 -+#define PAGE_SIZE_8KB 0x2 -+#define PAGE_SIZE_16KB 0x3 -+ -+#define PAGE_SIZE_SHIFT 3 -+#define PAGE_SIZE_MASK (0x3 << PAGE_SIZE_SHIFT) -+ -+#define FLASH_TYPE_SPI_NOR 0x0 -+#define FLASH_TYPE_SPI_NAND 0x1 -+#define FLASH_TYPE_NAND 0x2 -+#define FLASH_TYPE_UNKNOWN 0x3 -+ -+#define FLASH_TYPE_SEL_MASK (0x3 << 1) -+#define GET_SPI_FLASH_TYPE(_reg) (((_reg) >> 1) & 0x3) -+ -+/*****************************************************************************/ -+#define FMC_GLOBAL_CFG 0x04 -+#define FMC_GLOBAL_CFG_WP_ENABLE BIT(6) -+#define FMC_GLOBAL_CFG_RANDOMIZER_EN (1 << 2) -+#define FLASH_TYPE_SEL_MASK (0x3 << 1) -+#define FMC_CFG_FLASH_SEL(_type) (((_type) & 0x3) << 1) -+ -+#define FMC_GLOBAL_CFG_DTR_MODE BIT(11) -+/*****************************************************************************/ -+#define FMC_SPI_TIMING_CFG 0x08 -+#define TIMING_CFG_TCSH(nr) (((nr) & 0xf) << 8) -+#define TIMING_CFG_TCSS(nr) (((nr) & 0xf) << 4) -+#define TIMING_CFG_TSHSL(nr) ((nr) & 0xf) -+ -+#define CS_HOLD_TIME 0x6 -+#define CS_SETUP_TIME 0x6 -+#define CS_DESELECT_TIME 0xf -+ -+/*****************************************************************************/ -+#define FMC_PND_PWIDTH_CFG 0x0c -+#define PWIDTH_CFG_RW_HCNT(_n) (((_n) & 0xf) << 8) -+#define PWIDTH_CFG_R_LCNT(_n) (((_n) & 0xf) << 4) -+#define PWIDTH_CFG_W_LCNT(_n) ((_n) & 0xf) -+ -+#define RW_H_WIDTH (0xa) -+#define R_L_WIDTH (0xa) -+#define W_L_WIDTH (0xa) -+ -+/*****************************************************************************/ -+#define FMC_INT 0x18 -+#define FMC_INT_AHB_OP BIT(7) -+#define FMC_INT_WR_LOCK BIT(6) -+#define FMC_INT_DMA_ERR BIT(5) -+#define FMC_INT_ERR_ALARM BIT(4) -+#define FMC_INT_ERR_INVALID BIT(3) -+#define FMC_INT_ERR_INVALID_MASK (0x8) -+#define FMC_INT_ERR_VALID BIT(2) -+#define FMC_INT_ERR_VALID_MASK (0x4) -+#define FMC_INT_OP_FAIL BIT(1) -+#define FMC_INT_OP_DONE BIT(0) -+ -+/*****************************************************************************/ -+#define FMC_INT_EN 0x1c -+#define FMC_INT_EN_AHB_OP BIT(7) -+#define FMC_INT_EN_WR_LOCK BIT(6) -+#define FMC_INT_EN_DMA_ERR BIT(5) -+#define FMC_INT_EN_ERR_ALARM BIT(4) -+#define FMC_INT_EN_ERR_INVALID BIT(3) -+#define FMC_INT_EN_ERR_VALID BIT(2) -+#define FMC_INT_EN_OP_FAIL BIT(1) -+#define FMC_INT_EN_OP_DONE BIT(0) -+ -+/*****************************************************************************/ -+#define FMC_INT_CLR 0x20 -+#define FMC_INT_CLR_AHB_OP BIT(7) -+#define FMC_INT_CLR_WR_LOCK BIT(6) -+#define FMC_INT_CLR_DMA_ERR BIT(5) -+#define FMC_INT_CLR_ERR_ALARM BIT(4) -+#define FMC_INT_CLR_ERR_INVALID BIT(3) -+#define FMC_INT_CLR_ERR_VALID BIT(2) -+#define FMC_INT_CLR_OP_FAIL BIT(1) -+#define FMC_INT_CLR_OP_DONE BIT(0) -+ -+#define FMC_INT_CLR_ALL 0xff -+ -+/*****************************************************************************/ -+#define FMC_CMD 0x24 -+#define FMC_CMD_CMD2(_cmd) (((_cmd) & 0xff) << 8) -+#define FMC_CMD_CMD1(_cmd) ((_cmd) & 0xff) -+ -+/*****************************************************************************/ -+#define FMC_ADDRH 0x28 -+#define FMC_ADDRH_SET(_addr) ((_addr) & 0xff) -+ -+/*****************************************************************************/ -+#define FMC_ADDRL 0x2c -+#define FMC_ADDRL_BLOCK_MASK(_page) ((_page) & 0xffffffc0) -+#define FMC_ADDRL_BLOCK_H_MASK(_page) (((_page) & 0xffff) << 16) -+#define FMC_ADDRL_BLOCK_L_MASK(_page) ((_page) & 0xffc0) -+ -+#define READ_ID_ADDR 0x00 -+#define PROTECT_ADDR 0xa0 -+#define FEATURE_ADDR 0xb0 -+#define STATUS_ADDR 0xc0 -+/*****************************************************************************/ -+#define FMC_OP_CFG 0x30 -+#define OP_CFG_FM_CS(_cs) ((_cs) << 11) -+#define OP_CFG_FORCE_CS_EN(_en) ((_en) << 10) -+#define OP_CFG_MEM_IF_TYPE(_type) (((_type) & 0x7) << 7) -+#define OP_CFG_ADDR_NUM(_addr) (((_addr) & 0x7) << 4) -+#define OP_CFG_DUMMY_NUM(_dummy) ((_dummy) & 0xf) -+#define OP_CFG_OEN_EN (0x1 << 13) -+ -+#define IF_TYPE_SHIFT 7 -+#define IF_TYPE_MASK (0x7 << IF_TYPE_SHIFT) -+ -+#define READ_ID_ADDR_NUM 1 -+#define FEATURES_OP_ADDR_NUM 1 -+#define STD_OP_ADDR_NUM 3 -+ -+/*****************************************************************************/ -+#define FMC_SPI_OP_ADDR 0x34 -+ -+/*****************************************************************************/ -+#define FMC_DATA_NUM 0x38 -+#define FMC_DATA_NUM_CNT(_n) ((_n) & 0x3fff) -+ -+#define SPI_NOR_SR_LEN 1 /* Status Register length */ -+#define SPI_NOR_CR_LEN 1 /* Config Register length */ -+#define FEATURES_DATA_LEN 1 -+#define READ_OOB_BB_LEN 1 -+ -+#define PROTECT_BRWD_MASK BIT(7) -+#define PROTECT_BP3_MASK BIT(6) -+#define PROTECT_BP2_MASK BIT(5) -+#define PROTECT_BP1_MASK BIT(4) -+#define PROTECT_BP0_MASK BIT(3) -+ -+#define ANY_BP_ENABLE(_val) ((PROTECT_BP3_MASK & _val) \ -+ || (PROTECT_BP2_MASK & _val) \ -+ || (PROTECT_BP1_MASK & _val) \ -+ || (PROTECT_BP0_MASK & _val)) -+ -+#define ALL_BP_MASK (PROTECT_BP3_MASK \ -+ | PROTECT_BP2_MASK \ -+ | PROTECT_BP1_MASK \ -+ | PROTECT_BP0_MASK) -+ -+#define FEATURE_ECC_ENABLE (1 << 4) -+#define FEATURE_QE_ENABLE (1 << 0) -+ -+/*****************************************************************************/ -+#define FMC_OP 0x3c -+#define FMC_OP_DUMMY_EN BIT(8) -+#define FMC_OP_CMD1_EN BIT(7) -+#define FMC_OP_ADDR_EN BIT(6) -+#define FMC_OP_WRITE_DATA_EN BIT(5) -+#define FMC_OP_CMD2_EN BIT(4) -+#define FMC_OP_WAIT_READY_EN BIT(3) -+#define FMC_OP_READ_DATA_EN BIT(2) -+#define FMC_OP_READ_STATUS_EN BIT(1) -+#define FMC_OP_REG_OP_START BIT(0) -+ -+/*****************************************************************************/ -+#define FMC_DMA_LEN 0x40 -+#define FMC_DMA_LEN_SET(_len) ((_len) & 0x0fffffff) -+ -+/*****************************************************************************/ -+#define FMC_DMA_AHB_CTRL 0x48 -+#define FMC_DMA_AHB_CTRL_DMA_PP_EN BIT(3) -+#define FMC_DMA_AHB_CTRL_BURST16_EN BIT(2) -+#define FMC_DMA_AHB_CTRL_BURST8_EN BIT(1) -+#define FMC_DMA_AHB_CTRL_BURST4_EN BIT(0) -+ -+#define ALL_BURST_ENABLE (FMC_DMA_AHB_CTRL_BURST16_EN \ -+ | FMC_DMA_AHB_CTRL_BURST8_EN \ -+ | FMC_DMA_AHB_CTRL_BURST4_EN) -+ -+#define FMC_DMA_ADDR_OFFSET 4096 -+ -+/*****************************************************************************/ -+#define FMC_DMA_SADDR_D0 0x4c -+ -+/*****************************************************************************/ -+#define FMC_DMA_SADDR_D1 0x50 -+ -+/*****************************************************************************/ -+#define FMC_DMA_SADDR_D2 0x54 -+ -+/*****************************************************************************/ -+#define FMC_DMA_SADDR_D3 0x58 -+ -+/*****************************************************************************/ -+#define FMC_DMA_SADDR_OOB 0x5c -+ -+#ifdef CONFIG_64BIT -+/*****************************************************************************/ -+#define FMC_DMA_SADDRH_D0 0x200 -+#define FMC_DMA_SADDRH_SHIFT 0x3LL -+#define FMC_DMA_SADDRH_MASK (FMC_DMA_SADDRH_SHIFT << 32) -+ -+/*****************************************************************************/ -+#define FMC_DMA_SADDRH_OOB 0x210 -+#endif -+ -+/*****************************************************************************/ -+#define FMC_DMA_BLK_SADDR 0x60 -+#define FMC_DMA_BLK_SADDR_SET(_addr) ((_addr) & 0xffffff) -+ -+/*****************************************************************************/ -+#define FMC_DMA_BLK_LEN 0x64 -+#define FMC_DMA_BLK_LEN_SET(_len) ((_len) & 0xffff) -+ -+/*****************************************************************************/ -+#define FMC_OP_CTRL 0x68 -+#define OP_CTRL_RD_OPCODE(code) (((code) & 0xff) << 16) -+#define OP_CTRL_WR_OPCODE(code) (((code) & 0xff) << 8) -+#define OP_CTRL_RD_OP_SEL(_op) (((_op) & 0x3) << 4) -+#define OP_CTRL_DMA_OP(_type) ((_type) << 2) -+#define OP_CTRL_RW_OP(op) ((op) << 1) -+#define OP_CTRL_DMA_OP_READY BIT(0) -+ -+#define RD_OP_READ_ALL_PAGE 0x0 -+#define RD_OP_READ_OOB 0x1 -+#define RD_OP_BLOCK_READ 0x2 -+ -+#define RD_OP_SHIFT 4 -+#define RD_OP_MASK (0x3 << RD_OP_SHIFT) -+ -+#define OP_TYPE_DMA 0x0 -+#define OP_TYPE_REG 0x1 -+ -+#define FMC_OP_READ 0x0 -+#define FMC_OP_WRITE 0x1 -+#define RW_OP_READ 0x0 -+#define RW_OP_WRITE 0x1 -+ -+/*****************************************************************************/ -+#define FMC_OP_PARA 0x70 -+#define FMC_OP_PARA_RD_OOB_ONLY BIT(1) -+ -+/*****************************************************************************/ -+#define FMC_BOOT_SET 0x74 -+#define FMC_BOOT_SET_DEVICE_ECC_EN BIT(3) -+#define FMC_BOOT_SET_BOOT_QUAD_EN BIT(1) -+ -+/*****************************************************************************/ -+#define FMC_STATUS 0xac -+ -+/*****************************************************************************/ -+#ifndef FMC_VERSION -+#define FMC_VERSION 0xbc -+#endif -+ -+/* fmc IP version */ -+#ifndef FMC_VER_100 -+#define FMC_VER_100 (0x100) -+#endif -+ -+/*****************************************************************************/ -+/* DMA address align with 32 bytes. */ -+#define FMC_DMA_ALIGN 32 -+ -+#define FMC_CHIP_DELAY 25 -+/*****************************************************************************/ -+#define FMC_ECC_ERR_NUM0_BUF0 0xc0 -+#define GET_ECC_ERR_NUM(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) -+ -+#define DISABLE 0 -+#define ENABLE 1 -+ -+/*****************************************************************************/ -+#define FMC_REG_ADDRESS_LEN 0x200 -+ -+/*****************************************************************************/ -+#define FMC_MAX_READY_WAIT_JIFFIES (HZ) -+ -+#define MAX_SPI_NOR_ID_LEN 8 -+#define MAX_NAND_ID_LEN 8 -+#define MAX_SPI_NAND_ID_LEN 3 -+ -+#define GET_OP 0 -+#define SET_OP 1 -+ -+#define STATUS_ECC_MASK (0x3 << 4) -+#define STATUS_P_FAIL_MASK (1 << 3) -+#define STATUS_E_FAIL_MASK (1 << 2) -+#define STATUS_WEL_MASK (1 << 1) -+#define STATUS_OIP_MASK (1 << 0) -+ -+/*****************************************************************************/ -+#define FMC_VERSION 0xbc -+ -+/* fmc IP version */ -+#define FMC_VER_100 (0x100) -+ -+#define CONFIG_SPI_NAND_MAX_CHIP_NUM (1) -+ -+#define CONFIG_FMC100_MAX_NAND_CHIP (1) -+ -+/*****************************************************************************/ -+#define GET_PAGE_INDEX(host) \ -+ ((host->addr_value[0] >> 16) | (host->addr_value[1] << 16)) -+/*****************************************************************************/ -+#define FMC_MAX_CHIP_NUM 2 -+ -+extern unsigned char fmc_cs_user[]; -+ -+/*****************************************************************************/ -+#define fmc_readl(_host, _reg) \ -+ (readl((char *)_host->regbase + (_reg))) -+ -+#define fmc_readb( _addr) \ -+ (readb((void __iomem *)(_addr))) -+ -+#define fmc_readw( _addr) \ -+ (readw((void __iomem *)(_addr))) -+ -+#define fmc_writel(_host, _reg, _value) \ -+ (writel((u_int)(_value), ((char *)_host->regbase + (_reg)))) -+ -+#define fmc_writeb(_val, _addr) \ -+ (writeb((u_int)(_val), ((char *)_addr))) -+ -+/*****************************************************************************/ -+#define FMC_WAIT_TIMEOUT 0x2000000 -+ -+#define FMC_CMD_WAIT_CPU_FINISH(_host) \ -+ do { \ -+ unsigned regval, timeout = FMC_WAIT_TIMEOUT * 2; \ -+ do { \ -+ regval = fmc_readl((_host), FMC_OP); \ -+ --timeout; \ -+ } while ((regval & FMC_OP_REG_OP_START) && timeout); \ -+ if (!timeout) \ -+ pr_info("Error: Wait cmd cpu finish timeout!\n"); \ -+ } while (0) -+ -+/*****************************************************************************/ -+#define FMC_DMA_WAIT_INT_FINISH(_host) \ -+ do { \ -+ unsigned regval, timeout = FMC_WAIT_TIMEOUT; \ -+ do { \ -+ regval = fmc_readl((_host), FMC_INT); \ -+ --timeout; \ -+ } while ((!(regval & FMC_INT_OP_DONE) && timeout)); \ -+ if (!timeout) \ -+ pr_info("Error: Wait dma int finish timeout!\n"); \ -+ } while (0) -+ -+/*****************************************************************************/ -+#define FMC_DMA_WAIT_CPU_FINISH(_host) \ -+ do { \ -+ unsigned regval, timeout = FMC_WAIT_TIMEOUT; \ -+ do { \ -+ regval = fmc_readl((_host), FMC_OP_CTRL); \ -+ --timeout; \ -+ } while ((regval & OP_CTRL_DMA_OP_READY) && timeout); \ -+ if (!timeout) \ -+ pr_info("Error: Wait dma cpu finish timeout!\n"); \ -+ } while (0) -+ -+/*****************************************************************************/ -+#define BT_DBG 0 /* Boot init debug print */ -+#define ER_DBG 0 /* Erase debug print */ -+#define WR_DBG 0 /* Write debug print */ -+#define RD_DBG 0 /* Read debug print */ -+#define QE_DBG 0 /* Quad Enable debug print */ -+#define OP_DBG 0 /* OP command debug print */ -+#define DMA_DB 0 /* DMA read or write debug print */ -+#define AC_DBG 0 /* 3-4byte Address Cycle */ -+#define SR_DBG 0 /* Status Register debug print */ -+#define CR_DBG 0 /* Config Register debug print */ -+#define FT_DBG 0 /* Features debug print */ -+#define WE_DBG 0 /* Write Enable debug print */ -+#define BP_DBG 0 /* Block Protection debug print */ -+#define EC_DBG 0 /* enable/disable ecc0 and randomizer */ -+#define PM_DBG 0 /* power management debug */ -+ -+#define FMC_PR(_type, _fmt, arg...) \ -+ do { \ -+ if (_type) \ -+ DB_MSG(_fmt, ##arg) \ -+ } while (0) -+ -+#define DB_MSG(_fmt, arg...) \ -+ pr_info("%s(%d): " _fmt, __func__, __LINE__, ##arg); -+ -+#define DB_BUG(fmt, args...) \ -+ do { \ -+ pr_info("%s(%d): BUG: " fmt, __FILE__, __LINE__, ##args); \ -+ while (1) \ -+ ; \ -+ } while (0) -+ -+/*****************************************************************************/ -+enum fmc_iftype { -+ IF_TYPE_STD, -+ IF_TYPE_DUAL, -+ IF_TYPE_DIO, -+ IF_TYPE_QUAD, -+ IF_TYPE_QIO, -+}; -+ -+struct bsp_fmc { -+ void __iomem *regbase; -+ void __iomem *iobase; -+ struct clk *clk; -+ struct mutex lock; -+ void *buffer; -+ dma_addr_t dma_buffer; -+ unsigned int dma_len; -+}; -+ -+struct fmc_cmd_op { -+ unsigned char cs; -+ unsigned char cmd; -+ unsigned char l_cmd; -+ unsigned char addr_h; -+ unsigned int addr_l; -+ unsigned int data_no; -+ unsigned short option; -+ unsigned short op_cfg; -+}; -+ -+extern struct mutex fmc_switch_mutex; -+ -+#endif /*__BSP_FMC_H*/ ---- linux-4.9.37/include/linux/mmc/card.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/mmc/card.h 2021-06-07 13:01:34.000000000 +0300 -@@ -14,6 +14,8 @@ - #include - #include - -+#define MMC_CARD_CMDQ_BLK_SIZE 512 -+ - struct mmc_cid { - unsigned int manfid; - char prod_name[8]; -@@ -84,6 +86,7 @@ - unsigned int hpi_cmd; /* cmd used as HPI */ - bool bkops; /* background support bit */ - bool man_bkops_en; /* manual bkops enable bit */ -+ bool auto_bkops_en; /* auto bkops enable bit */ - unsigned int data_sector_size; /* 512 bytes or 4KB */ - unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ - unsigned int boot_ro_lock; /* ro lock support */ -@@ -119,6 +122,8 @@ - u8 raw_pwr_cl_ddr_200_360; /* 253 */ - u8 raw_bkops_status; /* 246 */ - u8 raw_sectors[4]; /* 212 - 4 bytes */ -+ u8 cmdq_depth; /* 307 */ -+ u8 cmdq_support; /* 308 */ - - unsigned int feature_support; - #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ -@@ -264,6 +269,8 @@ - #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ - #define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ - #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ -+#define MMC_STATE_CMDQ (1<<7) /* card is in cmd queue mode */ -+ - unsigned int quirks; /* card quirks */ - #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ - #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ -@@ -281,7 +288,8 @@ - #define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */ - #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ - #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ -- -+/* Make sure CMDQ is empty before queuing DCMD */ -+#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD (1 << 14) - - unsigned int erase_size; /* erase size in sectors */ - unsigned int erase_shift; /* if erase unit is power 2 */ -@@ -316,6 +324,8 @@ - struct dentry *debugfs_root; - struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ - unsigned int nr_parts; -+ unsigned int part_curr; -+ bool cmdq_init; - }; - - /* -@@ -453,6 +463,7 @@ - #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) - #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) - #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) -+#define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ) - - #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) - #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) -@@ -463,6 +474,8 @@ - #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) - #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) - #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) -+#define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ) -+#define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ) - - /* - * Quirk add/remove for MMC products. -@@ -538,6 +551,16 @@ - return c->quirks & MMC_QUIRK_BROKEN_HPI; - } - -+static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) -+{ -+ return c->ext_csd.man_bkops_en; -+} -+ -+static inline bool mmc_card_configured_auto_bkops(const struct mmc_card *c) -+{ -+ return c->ext_csd.auto_bkops_en; -+} -+ - #define mmc_card_name(c) ((c)->cid.prod_name) - #define mmc_card_id(c) (dev_name(&(c)->dev)) - ---- linux-4.9.37/include/linux/mmc/core.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/mmc/core.h 2021-06-07 13:01:34.000000000 +0300 -@@ -142,10 +142,26 @@ - - /* Allow other commands during this ongoing data transfer or busy wait */ - bool cap_cmd_during_tfr; -+ struct mmc_cmdq_req *cmdq_req; -+ struct request *req; - }; - - struct mmc_card; - struct mmc_async_req; -+struct mmc_cmdq_req; -+ -+extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks); -+extern int mmc_cmdq_halt(struct mmc_host *host, bool enable); -+extern int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host); -+extern void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err); -+extern int mmc_cmdq_start_req(struct mmc_host *host, -+ struct mmc_cmdq_req *cmdq_req); -+extern int mmc_cmdq_prepare_flush(struct mmc_command *cmd); -+extern int mmc_cmdq_wait_for_dcmd(struct mmc_host *host, -+ struct mmc_cmdq_req *cmdq_req); -+extern int mmc_cmdq_erase(struct mmc_cmdq_req *cmdq_req, -+ struct mmc_card *card, unsigned int from, unsigned int nr, -+ unsigned int arg); - - extern int mmc_stop_bkops(struct mmc_card *); - extern int mmc_read_bkops_status(struct mmc_card *); -@@ -161,6 +177,9 @@ - extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, - struct mmc_command *, int); - extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); -+extern int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, -+ u8 value, unsigned int timeout_ms, -+ bool use_busy_signal, bool ignore_timeout); - extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); - extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); - extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); -@@ -190,6 +209,7 @@ - extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, - bool is_rel_write); - extern int mmc_hw_reset(struct mmc_host *host); -+extern int mmc_cmdq_hw_reset(struct mmc_host *host); - extern int mmc_can_reset(struct mmc_card *card); - - extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); ---- linux-4.9.37/include/linux/mmc/host.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/mmc/host.h 2021-06-07 13:01:34.000000000 +0300 -@@ -82,6 +82,17 @@ - bool enhanced_strobe; /* hs400es selection */ - }; - -+struct mmc_cmdq_host_ops { -+ int (*init)(struct mmc_host *host); -+ int (*enable)(struct mmc_host *host); -+ void (*disable)(struct mmc_host *host, bool soft); -+ int (*request)(struct mmc_host *host, struct mmc_request *mrq); -+ void (*post_req)(struct mmc_host *host, int tag, int err); -+ int (*halt)(struct mmc_host *host, bool halt); -+ void (*reset)(struct mmc_host *host, bool soft); -+ void (*dumpstate)(struct mmc_host *host); -+}; -+ - struct mmc_host_ops { - /* - * It is optional for the host to implement pre_req and post_req in -@@ -161,11 +172,37 @@ - */ - int (*multi_io_quirk)(struct mmc_card *card, - unsigned int direction, int blk_size); -+ void (*notify_halt)(struct mmc_host *mmc, bool halt); -+ int (*card_info_save)(struct mmc_host *host); - }; - - struct mmc_card; - struct device; - -+struct mmc_cmdq_req { -+ unsigned int cmd_flags; -+ u32 blk_addr; -+ /* active mmc request */ -+ struct mmc_request mrq; -+ struct mmc_data data; -+ struct mmc_command cmd; -+#define DCMD (1 << 0) -+#define QBR (1 << 1) -+#define DIR (1 << 2) -+#define PRIO (1 << 3) -+#define REL_WR (1 << 4) -+#define DAT_TAG (1 << 5) -+#define FORCED_PRG (1 << 6) -+ unsigned int cmdq_req_flags; -+ -+ unsigned int resp_idx; -+ unsigned int resp_arg; -+ unsigned int dev_pend_tasks; -+ bool resp_err; -+ int tag; /* used for command queuing */ -+ u8 ctx_id; -+}; -+ - struct mmc_async_req { - /* active mmc request */ - struct mmc_request *mrq; -@@ -192,6 +229,33 @@ - void *handler_priv; - }; - -+ -+/** -+ * mmc_cmdq_context_info - describes the contexts of cmdq -+ * @active_reqs requests being processed -+ * @data_active_reqs data requests being processed -+ * @curr_state state of cmdq engine -+ * @cmdq_ctx_lock acquire this before accessing this structure -+ * @queue_empty_wq workqueue for waiting for all -+ * the outstanding requests to be completed -+ * @wait waiting for all conditions described in -+ * mmc_cmdq_ready_wait to be satisified before -+ * issuing the new request to LLD. -+ */ -+struct mmc_cmdq_context_info { -+ unsigned long active_reqs; /* in-flight requests */ -+ unsigned long data_active_reqs; /* in-flight data requests */ -+ unsigned long curr_state; -+#define CMDQ_STATE_ERR 0 -+#define CMDQ_STATE_DCMD_ACTIVE 1 -+#define CMDQ_STATE_HALT 2 -+#define CMDQ_STATE_CQ_DISABLE 3 -+#define CMDQ_STATE_REQ_TIMED_OUT 4 -+ wait_queue_head_t queue_empty_wq; -+ wait_queue_head_t wait; -+ int active_small_sector_read_reqs; -+}; -+ - /** - * mmc_context_info - synchronization details for mmc context - * @is_done_rcv wake up reason was done request -@@ -221,10 +285,17 @@ - struct device class_dev; - int index; - const struct mmc_host_ops *ops; -+ const struct mmc_cmdq_host_ops *cmdq_ops; - struct mmc_pwrseq *pwrseq; - unsigned int f_min; - unsigned int f_max; - unsigned int f_init; -+ unsigned int type; -+#define MMC_HOST_TYPE_MMC 0 /* MMC card */ -+#define MMC_HOST_TYPE_SD 1 /* SD card */ -+#define MMC_HOST_TYPE_SDIO 2 /* SDIO card */ -+#define MMC_HOST_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ -+ - u32 ocr_avail; - u32 ocr_avail_sdio; /* SDIO-specific OCR */ - u32 ocr_avail_sd; /* SD-specific OCR */ -@@ -312,6 +383,7 @@ - #define MMC_CAP2_HS400_ES (1 << 20) /* Host supports enhanced strobe */ - #define MMC_CAP2_NO_SD (1 << 21) /* Do not send SD commands during initialization */ - #define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ -+#define MMC_CAP2_CMD_QUEUE (1 << 23) /* support eMMC command queue */ - - mmc_pm_flag_t pm_caps; /* supported pm features */ - -@@ -359,6 +431,11 @@ - - struct delayed_work detect; - int detect_change; /* card detect flag */ -+ u32 card_status; -+#define MMC_CARD_UNINIT 0 -+#define MMC_CARD_INIT 1 -+#define MMC_CARD_INIT_FAIL 2 -+ - struct mmc_slot slot; - - const struct mmc_bus_ops *bus_ops; /* current bus driver */ -@@ -397,6 +474,20 @@ - int dsr_req; /* DSR value is valid */ - u32 dsr; /* optional driver stage (DSR) value */ - -+ struct mmc_cmdq_context_info cmdq_ctx; -+ int num_cq_slots; -+ int dcmd_cq_slot; -+ u32 cmdq_thist_enabled; -+ /* -+ * several cmdq supporting host controllers are extensions -+ * of legacy controllers. This variable can be used to store -+ * a reference to the cmdq extension of the existing host -+ * controller. -+ */ -+ void *cmdq_private; -+ struct mmc_request *err_mrq; -+ struct timeval start; -+ struct timeval end; - unsigned long private[0] ____cacheline_aligned; - }; - -@@ -411,6 +502,11 @@ - return (void *)host->private; - } - -+static inline void *mmc_cmdq_private(struct mmc_host *host) -+{ -+ return host->cmdq_private; -+} -+ - #define mmc_host_is_spi(host) ((host)->caps & MMC_CAP_SPI) - - #define mmc_dev(x) ((x)->parent) -@@ -500,6 +596,36 @@ - return host->caps2 & MMC_CAP2_PACKED_WR; - } - -+static inline void mmc_host_set_halt(struct mmc_host *host) -+{ -+ set_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); -+} -+ -+static inline void mmc_host_clr_halt(struct mmc_host *host) -+{ -+ clear_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); -+} -+ -+static inline int mmc_host_halt(struct mmc_host *host) -+{ -+ return test_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); -+} -+ -+static inline void mmc_host_set_cq_disable(struct mmc_host *host) -+{ -+ set_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); -+} -+ -+static inline void mmc_host_clr_cq_disable(struct mmc_host *host) -+{ -+ clear_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); -+} -+ -+static inline int mmc_host_cq_disable(struct mmc_host *host) -+{ -+ return test_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); -+} -+ - static inline int mmc_card_hs(struct mmc_card *card) - { - return card->host->ios.timing == MMC_TIMING_SD_HS || ---- linux-4.9.37/include/linux/mmc/mmc.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/mmc/mmc.h 2021-06-07 13:01:34.000000000 +0300 -@@ -84,6 +84,11 @@ - #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ - #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ - -+/* class 11 */ -+#define MMC_CMDQ_TASK_MGMT 48 /* ac [31:0] task ID R1b */ -+#define DISCARD_QUEUE 0x1 -+#define DISCARD_TASK 0x2 -+ - static inline bool mmc_op_multi(u32 opcode) - { - return opcode == MMC_WRITE_MULTIPLE_BLOCK || -@@ -272,6 +277,7 @@ - * EXT_CSD fields - */ - -+#define EXT_CSD_CMDQ 15 /* R/W */ - #define EXT_CSD_FLUSH_CACHE 32 /* W */ - #define EXT_CSD_CACHE_CTRL 33 /* R/W */ - #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ -@@ -331,6 +337,9 @@ - #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ - #define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */ - #define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */ -+#define EXT_CSD_CMDQ_DEPTH 307 /* RO */ -+#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */ -+ - #define EXT_CSD_SUPPORTED_MODE 493 /* RO */ - #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ - #define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ -@@ -436,6 +445,7 @@ - * BKOPS modes - */ - #define EXT_CSD_MANUAL_BKOPS_MASK 0x01 -+#define EXT_CSD_AUTO_BKOPS_MASK 0x02 - - /* - * MMC_SWITCH access modes ---- linux-4.9.37/include/linux/mm_types.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/mm_types.h 2021-06-07 13:01:34.000000000 +0300 -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include ---- linux-4.9.37/include/linux/mtd/nand.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/mtd/nand.h 2021-06-07 13:01:34.000000000 +0300 -@@ -80,6 +80,7 @@ - #define NAND_CMD_READOOB 0x50 - #define NAND_CMD_ERASE1 0x60 - #define NAND_CMD_STATUS 0x70 -+#define NAND_CMD_STATUS_MULTI 0x71 - #define NAND_CMD_SEQIN 0x80 - #define NAND_CMD_RNDIN 0x85 - #define NAND_CMD_READID 0x90 -@@ -87,6 +88,7 @@ - #define NAND_CMD_PARAM 0xec - #define NAND_CMD_GET_FEATURES 0xee - #define NAND_CMD_SET_FEATURES 0xef -+#define NAND_CMD_SYNC_RESET 0xfc - #define NAND_CMD_RESET 0xff - - #define NAND_CMD_LOCK 0x2a -@@ -925,9 +927,18 @@ - #define NAND_MFR_AMD 0x01 - #define NAND_MFR_MACRONIX 0xc2 - #define NAND_MFR_EON 0x92 -+#define NAND_MFR_WINBOND 0xef -+#define NAND_MFR_ATO 0x9b -+#define NAND_MFR_MXIC 0xc2 -+#define NAND_MFR_ALL_FLASH 0xc1 -+#define NAND_MFR_PARAGON 0xa1 - #define NAND_MFR_SANDISK 0x45 - #define NAND_MFR_INTEL 0x89 - #define NAND_MFR_ATO 0x9b -+#define NAND_MFR_GD_ESMT 0xc8 -+#define NAND_MFR_HEYANGTEK 0xc9 -+#define NAND_MFR_DOSILICON 0xe5 -+#define NAND_MFR_FIDELIX 0xf8 - - /* The maximum expected count of bytes in the NAND ID sequence */ - #define NAND_MAX_ID_LEN 8 ---- linux-4.9.37/include/linux/mtd/spi-nor.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/mtd/spi-nor.h 2021-06-07 13:01:34.000000000 +0300 -@@ -12,7 +12,6 @@ - - #include - #include --#include - - /* - * Manufacturer IDs -@@ -21,13 +20,53 @@ - * Sometimes these are the same as CFI IDs, but sometimes they aren't. - */ - #define SNOR_MFR_ATMEL CFI_MFR_ATMEL --#define SNOR_MFR_GIGADEVICE 0xc8 - #define SNOR_MFR_INTEL CFI_MFR_INTEL - #define SNOR_MFR_MICRON CFI_MFR_ST /* ST Micro <--> Micron */ - #define SNOR_MFR_MACRONIX CFI_MFR_MACRONIX - #define SNOR_MFR_SPANSION CFI_MFR_AMD - #define SNOR_MFR_SST CFI_MFR_SST --#define SNOR_MFR_WINBOND 0xef /* Also used by some Spansion */ -+#define SNOR_MFR_EON CFI_MFR_EON -+#define SNOR_MFR_WINBOND 0xef -+#define SNOR_MFR_ESMT 0x8c -+#define SNOR_MFR_GD 0xc8 -+#define SNOR_MFR_XTX 0x0b -+#define SNOR_MFR_PUYA 0x85 -+#define SNOR_MFR_ISSI 0x9d -+ -+/* Flash set the RESET# from */ -+#define SPI_NOR_SR_RST_MASK BIT(7) -+#define SPI_NOR_GET_RST(val) (((val) & SPI_NOR_SR_RST_MASK) >> 7) -+#define SPI_NOR_SET_RST(val) ((val) | SPI_NOR_SR_RST_MASK) -+ -+/* Flash block protect */ -+#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT -+#define _2M (0x200000UL) -+#define _4M (0x400000UL) -+#define _8M (0x800000UL) -+#define _16M (0x1000000UL) -+#define _32M (0x2000000UL) -+ -+#define BP_NUM_3 3 -+#define BP_NUM_4 4 -+ -+#define DEBUG_SPI_NOR_BP 0 -+ -+#define SPI_NOR_SR_SRWD_SHIFT 7 -+#define SPI_NOR_SR_SRWD_MASK (1 << SPI_NOR_SR_SRWD_SHIFT) -+ -+#define SPI_NOR_SR_BP0_SHIFT 2 -+#define SPI_NOR_SR_BP_WIDTH_4 0xf -+#define SPI_NOR_SR_BP_MASK_4 (SPI_NOR_SR_BP_WIDTH_4 << SPI_NOR_SR_BP0_SHIFT) -+ -+#define SPI_NOR_SR_BP_WIDTH_3 0x7 -+#define SPI_NOR_SR_BP_MASK_3 (SPI_NOR_SR_BP_WIDTH_3 << SPI_NOR_SR_BP0_SHIFT) -+ -+#define SPI_NOR_SR_TB_SHIFT 3 -+#define SPI_NOR_SR_TB_MASK (1 << SPI_NOR_SR_TB_SHIFT) -+ -+#define LOCK_LEVEL_MAX(bp_num) (((0x01) << bp_num) - 1) -+ -+#endif /* CONFIG_SPI_BLOCK_PROTECT */ - - /* - * Note on opcode nomenclature: some opcodes have a format like -@@ -40,27 +79,42 @@ - /* Flash opcodes. */ - #define SPINOR_OP_WREN 0x06 /* Write enable */ - #define SPINOR_OP_RDSR 0x05 /* Read status register */ -+#define SPINOR_OP_RDSR2 0x35 /* Read Status Register-2 */ -+#define SPINOR_OP_RDSR3 0x15 /* Read Status Register-3 */ - #define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ -+#define SPINOR_OP_WRSR2 0x31 /* Write Status Register-2 1 byte*/ -+#define SPINOR_OP_WRSR3 0x11 /* Write Status Register-3 1 byte*/ - #define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ - #define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ --#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */ --#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */ -+#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */ -+#define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */ -+#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */ -+#define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */ - #define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ -+#define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */ -+#define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */ - #define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */ - #define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ - #define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */ - #define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */ - #define SPINOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */ - #define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */ -+#define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ - #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ - #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ - - /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ --#define SPINOR_OP_READ4 0x13 /* Read data bytes (low frequency) */ --#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */ --#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */ --#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */ -+#define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ -+#define SPINOR_OP_READ_FAST_4B 0x0c /* Read data bytes (high frequency) */ -+#define SPINOR_OP_READ_1_1_2_4B 0x3c /* Read data bytes (Dual Output SPI) */ -+#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */ -+#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */ -+#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */ - #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ -+#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */ -+#define SPINOR_OP_PP_1_4_4_4B 0x3e /* Quad page program */ -+#define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */ -+#define SPINOR_OP_BE_32K_4B 0x5c /* Erase 32KiB block */ - #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ - - /* Used for SST flashes only. */ -@@ -73,12 +127,20 @@ - #define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ - - /* Used for Spansion flashes only. */ -+#define SPINOR_OP_BRRD 0x16 /* Bank register write */ - #define SPINOR_OP_BRWR 0x17 /* Bank register write */ - -+/* Used for GigaDevice flashes only. */ -+#define SPINOR_OP_WRCR 0x31 /* Config register write */ -+ - /* Used for Micron flashes only. */ - #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ - #define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */ - -+/* Software reset code */ -+#define SPINOR_ENABLE_RESET 0x66 /* Enable reset */ -+#define SPINOR_OP_RESET 0x99 /* Reset */ -+ - /* Status Register bits. */ - #define SR_WIP BIT(0) /* Write in progress */ - #define SR_WEL BIT(1) /* Write enable latch */ -@@ -90,8 +152,9 @@ - #define SR_SRWD BIT(7) /* SR write protect */ - - #define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ -- -+#define CR_DUMMY_CYCLE (0x03 << 6) /* Macronix dummy cycle bits */ - /* Enhanced Volatile Configuration Register bits */ -+#define EVCR_DUAL_EN_MICRON BIT(6) /* Micron Dual I/O */ - #define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ - - /* Flag Status Register bits */ -@@ -99,12 +162,109 @@ - - /* Configuration Register bits. */ - #define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */ -+#define QUAD_EN_ISSI BIT(6) -+/* Status Register bits. */ -+#define SR_QUAD_EN_XTX BIT(1) -+ -+/* Supported modes */ -+enum spi_nor_mode_index { -+ /* Sorted by ascending priority order */ -+ SNOR_MIDX_SLOW = 0, -+ SNOR_MIDX_1_1_1, -+ SNOR_MIDX_1_1_2, -+ SNOR_MIDX_1_2_2, -+ SNOR_MIDX_1_1_4, -+ SNOR_MIDX_1_4_4, -+ -+ SNOR_MIDX_MAX -+}; -+ -+#define SNOR_MODE_SLOW BIT(SNOR_MIDX_SLOW) -+#define SNOR_MODE_1_1_1 BIT(SNOR_MIDX_1_1_1) -+#define SNOR_MODE_1_1_2 BIT(SNOR_MIDX_1_1_2) -+#define SNOR_MODE_1_2_2 BIT(SNOR_MIDX_1_2_2) -+#define SNOR_MODE_1_1_4 BIT(SNOR_MIDX_1_1_4) -+#define SNOR_MODE_1_4_4 BIT(SNOR_MIDX_1_4_4) -+ -+struct spi_nor_modes { -+ u32 rd_modes; /* supported SPI modes for (Fast) Read */ -+ u32 wr_modes; /* supported SPI modes for Page Program */ -+}; -+ -+struct spi_nor_read_op { -+ u8 num_mode_clocks; -+ u8 num_wait_states; -+ u8 opcode; -+}; - --enum read_mode { -- SPI_NOR_NORMAL = 0, -- SPI_NOR_FAST, -- SPI_NOR_DUAL, -- SPI_NOR_QUAD, -+#define SNOR_OP_READ(_num_mode_clocks, _num_wait_states, _opcode) \ -+ { \ -+ .num_mode_clocks = _num_mode_clocks, \ -+ .num_wait_states = _num_wait_states, \ -+ .opcode = _opcode, \ -+ } -+ -+struct spi_nor_erase_type { -+ u8 size; /* specifies 'N' so erase size = 2^N */ -+ u8 opcode; -+}; -+ -+#define SNOR_OP_ERASE(_size, _opcode) { .size = _size, .opcode = _opcode } -+#define SNOR_OP_ERASE_64K(_opcode) SNOR_OP_ERASE(0x10, _opcode) -+#define SNOR_OP_ERASE_32K(_opcode) SNOR_OP_ERASE(0x0f, _opcode) -+#define SNOR_OP_ERASE_4K(_opcode) SNOR_OP_ERASE(0x0c, _opcode) -+ -+struct spi_nor; -+ -+#define SNOR_MAX_ERASE_TYPES 4 -+ -+struct spi_nor_basic_flash_parameter { -+ /* Fast Read settings */ -+ u32 rd_modes; -+ struct spi_nor_read_op reads[SNOR_MIDX_MAX]; -+ -+ /* Page Program settings */ -+ u32 wr_modes; -+ u8 page_programs[SNOR_MIDX_MAX]; -+ -+ /* Sector Erase settings */ -+ struct spi_nor_erase_type erase_types[SNOR_MAX_ERASE_TYPES]; -+ -+ int (*enable_quad_io)(struct spi_nor *nor); -+}; -+ -+#define SNOR_PROTO_CODE_OFF 8 -+#define SNOR_PROTO_CODE_MASK GENMASK(11, 8) -+#define SNOR_PROTO_CODE_TO_PROTO(code) \ -+ (((code) << SNOR_PROTO_CODE_OFF) & SNOR_PROTO_CODE_MASK) -+#define SNOR_PROTO_CODE_FROM_PROTO(proto) \ -+ ((((u32)(proto)) & SNOR_PROTO_CODE_MASK) >> SNOR_PROTO_CODE_OFF) -+ -+#define SNOR_PROTO_ADDR_OFF 4 -+#define SNOR_PROTO_ADDR_MASK GENMASK(7, 4) -+#define SNOR_PROTO_ADDR_TO_PROTO(addr) \ -+ (((addr) << SNOR_PROTO_ADDR_OFF) & SNOR_PROTO_ADDR_MASK) -+#define SNOR_PROTO_ADDR_FROM_PROTO(proto) \ -+ ((((u32)(proto)) & SNOR_PROTO_ADDR_MASK) >> SNOR_PROTO_ADDR_OFF) -+ -+#define SNOR_PROTO_DATA_OFF 0 -+#define SNOR_PROTO_DATA_MASK GENMASK(3, 0) -+#define SNOR_PROTO_DATA_TO_PROTO(data) \ -+ (((data) << SNOR_PROTO_DATA_OFF) & SNOR_PROTO_DATA_MASK) -+#define SNOR_PROTO_DATA_FROM_PROTO(proto) \ -+ ((((u32)(proto)) & SNOR_PROTO_DATA_MASK) >> SNOR_PROTO_DATA_OFF) -+ -+#define SNOR_PROTO(code, addr, data) \ -+ (SNOR_PROTO_CODE_TO_PROTO(code) | \ -+ SNOR_PROTO_ADDR_TO_PROTO(addr) | \ -+ SNOR_PROTO_DATA_TO_PROTO(data)) -+ -+enum spi_nor_protocol { -+ SNOR_PROTO_1_1_1 = SNOR_PROTO(1, 1, 1), /* SPI */ -+ SNOR_PROTO_1_1_2 = SNOR_PROTO(1, 1, 2), /* Dual Output */ -+ SNOR_PROTO_1_2_2 = SNOR_PROTO(1, 2, 2), /* Dual IO */ -+ SNOR_PROTO_1_1_4 = SNOR_PROTO(1, 1, 4), /* Quad Output */ -+ SNOR_PROTO_1_4_4 = SNOR_PROTO(1, 4, 4), /* Quad IO */ - }; - - #define SPI_NOR_MAX_CMD_SIZE 8 -@@ -121,20 +281,26 @@ - SNOR_F_HAS_SR_TB = BIT(1), - }; - -+struct mtd_info; -+ - /** - * struct spi_nor - Structure for defining a the SPI NOR layer - * @mtd: point to a mtd_info structure - * @lock: the lock for the read/write/erase/lock/unlock operations - * @dev: point to a spi device, or a spi nor controller device. -+ * @flash_node: point to a device node describing this flash instance. - * @page_size: the page size of the SPI NOR - * @addr_width: number of address bytes - * @erase_opcode: the opcode for erasing a sector - * @read_opcode: the read opcode - * @read_dummy: the dummy needed by the read operation - * @program_opcode: the program opcode -- * @flash_read: the mode of the read - * @sst_write_second: used by the SST write operation - * @flags: flag options for the current SPI-NOR (SNOR_F_*) -+ * @erase_proto: the SPI protocol used by erase operations -+ * @read_proto: the SPI protocol used by read operations -+ * @write_proto: the SPI protocol used by write operations -+ * @reg_proto the SPI protocol used by read_reg/write_reg operations - * @cmd_buf: used by the write_reg - * @prepare: [OPTIONAL] do some preparations for the - * read/write/erase/lock/unlock operations -@@ -157,13 +323,16 @@ - struct mtd_info mtd; - struct mutex lock; - struct device *dev; -+ struct device_node *flash_node; - u32 page_size; - u8 addr_width; - u8 erase_opcode; - u8 read_opcode; - u8 read_dummy; - u8 program_opcode; -- enum read_mode flash_read; -+ enum spi_nor_protocol erase_proto; -+ enum spi_nor_protocol read_proto; -+ enum spi_nor_protocol write_proto; - bool sst_write_second; - u32 flags; - u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; -@@ -183,6 +352,12 @@ - int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); - -+#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT -+ unsigned int end_addr; -+ unsigned int lock_level_max; -+ unsigned char level; -+#endif -+ u32 clkrate; - void *priv; - }; - -@@ -201,7 +376,7 @@ - * spi_nor_scan() - scan the SPI NOR - * @nor: the spi_nor structure - * @name: the chip type name -- * @mode: the read mode supported by the driver -+ * @modes: the SPI modes supported by the controller driver - * - * The drivers can use this fuction to scan the SPI NOR. - * In the scanning, it will try to get all the necessary information to -@@ -211,6 +386,12 @@ - * - * Return: 0 for success, others for failure. - */ --int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode); -+int spi_nor_scan(struct spi_nor *nor, const char *name, -+ struct spi_nor_modes *modes); -+void spi_nor_driver_shutdown(struct spi_nor *nor); -+#ifdef CONFIG_PM -+int spi_nor_suspend(struct spi_nor *nor, pm_message_t state); -+int spi_nor_resume(struct spi_nor *nor); -+#endif - - #endif ---- linux-4.9.37/include/linux/nospec.h 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/include/linux/nospec.h 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,72 @@ -+// SPDX-License-Identifier: GPL-2.0 -+// Copyright(c) 2018 Linus Torvalds. All rights reserved. -+// Copyright(c) 2018 Alexei Starovoitov. All rights reserved. -+// Copyright(c) 2018 Intel Corporation. All rights reserved. -+ -+#ifndef _LINUX_NOSPEC_H -+#define _LINUX_NOSPEC_H -+ -+/** -+ * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise -+ * @index: array element index -+ * @size: number of elements in array -+ * -+ * When @index is out of bounds (@index >= @size), the sign bit will be -+ * set. Extend the sign bit to all bits and invert, giving a result of -+ * zero for an out of bounds index, or ~0 if within bounds [0, @size). -+ */ -+#ifndef array_index_mask_nospec -+static inline unsigned long array_index_mask_nospec(unsigned long index, -+ unsigned long size) -+{ -+ /* -+ * Warn developers about inappropriate array_index_nospec() usage. -+ * -+ * Even if the CPU speculates past the WARN_ONCE branch, the -+ * sign bit of @index is taken into account when generating the -+ * mask. -+ * -+ * This warning is compiled out when the compiler can infer that -+ * @index and @size are less than LONG_MAX. -+ */ -+ if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX, -+ "array_index_nospec() limited to range of [0, LONG_MAX]\n")) -+ return 0; -+ -+ /* -+ * Always calculate and emit the mask even if the compiler -+ * thinks the mask is not needed. The compiler does not take -+ * into account the value of @index under speculation. -+ */ -+ OPTIMIZER_HIDE_VAR(index); -+ return ~(long)(index | (size - 1UL - index)) >> (BITS_PER_LONG - 1); -+} -+#endif -+ -+/* -+ * array_index_nospec - sanitize an array index after a bounds check -+ * -+ * For a code sequence like: -+ * -+ * if (index < size) { -+ * index = array_index_nospec(index, size); -+ * val = array[index]; -+ * } -+ * -+ * ...if the CPU speculates past the bounds check then -+ * array_index_nospec() will clamp the index within the range of [0, -+ * size). -+ */ -+#define array_index_nospec(index, size) \ -+ ({ \ -+ typeof(index) _i = (index); \ -+ typeof(size) _s = (size); \ -+ unsigned long _mask = array_index_mask_nospec(_i, _s); \ -+ \ -+ BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ -+ BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ -+ \ -+ _i &= _mask; \ -+ _i; \ -+ }) -+#endif /* _LINUX_NOSPEC_H */ ---- linux-4.9.37/include/linux/phy.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/phy.h 2021-06-07 13:01:34.000000000 +0300 -@@ -829,6 +829,10 @@ - int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, - int (*run)(struct phy_device *)); - -+int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask); -+int phy_unregister_fixup_for_id(const char *bus_id); -+int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask); -+ - int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable); - int phy_get_eee_err(struct phy_device *phydev); - int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data); ---- linux-4.9.37/include/linux/psci.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/psci.h 2021-06-07 13:01:34.000000000 +0300 -@@ -25,7 +25,14 @@ - int psci_cpu_init_idle(unsigned int cpu); - int psci_cpu_suspend_enter(unsigned long index); - -+enum psci_conduit { -+ PSCI_CONDUIT_NONE, -+ PSCI_CONDUIT_SMC, -+ PSCI_CONDUIT_HVC, -+}; -+ - struct psci_operations { -+ u32 (*get_version)(void); - int (*cpu_suspend)(u32 state, unsigned long entry_point); - int (*cpu_off)(u32 state); - int (*cpu_on)(unsigned long cpuid, unsigned long entry_point); -@@ -33,6 +40,7 @@ - int (*affinity_info)(unsigned long target_affinity, - unsigned long lowest_affinity_level); - int (*migrate_info_type)(void); -+ enum psci_conduit conduit; - }; - - extern struct psci_operations psci_ops; ---- linux-4.9.37/include/linux/sched.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/sched.h 2021-06-07 13:01:34.000000000 +0300 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -38,7 +39,6 @@ - #include - #include - #include --#include - #include - #include - #include ---- linux-4.9.37/include/linux/spi/spi.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/spi/spi.h 2021-06-07 13:01:34.000000000 +0300 -@@ -233,6 +233,8 @@ - * @remove: Unbinds this driver from the spi device - * @shutdown: Standard shutdown callback used during system state - * transitions such as powerdown/halt and kexec -+ * @suspend: Standard suspend callback used during system state transitions -+ * @resume: Standard resume callback used during system state transitions - * @driver: SPI device drivers should initialize the name and owner - * field of this structure. - * -@@ -253,6 +255,8 @@ - int (*probe)(struct spi_device *spi); - int (*remove)(struct spi_device *spi); - void (*shutdown)(struct spi_device *spi); -+ int (*suspend)(struct spi_device *spi, pm_message_t mesg); -+ int (*resume)(struct spi_device *spi); - struct device_driver driver; - }; - -@@ -442,6 +446,7 @@ - #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ - #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ - #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ -+ bool slave; - - /* - * on some hardware transfer / message size may be constrained ---- linux-4.9.37/include/linux/tcp.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/tcp.h 2021-06-07 13:01:34.000000000 +0300 -@@ -432,4 +432,7 @@ - tp->saved_syn = NULL; - } - -+int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount, -+ int shiftlen); -+ - #endif /* _LINUX_TCP_H */ ---- linux-4.9.37/include/linux/usb/usbnet.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/linux/usb/usbnet.h 2021-06-07 13:01:34.000000000 +0300 -@@ -204,6 +204,7 @@ - }; - - extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *); -+extern int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf); - extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *); - extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *); - extern void usbnet_cdc_status(struct usbnet *, struct urb *); ---- linux-4.9.37/include/net/netns/ipv4.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/net/netns/ipv4.h 2021-06-07 13:01:34.000000000 +0300 -@@ -94,6 +94,7 @@ - #endif - int sysctl_tcp_mtu_probing; - int sysctl_tcp_base_mss; -+ int sysctl_tcp_min_snd_mss; - int sysctl_tcp_probe_threshold; - u32 sysctl_tcp_probe_interval; - ---- linux-4.9.37/include/net/tcp.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/net/tcp.h 2021-06-07 13:01:34.000000000 +0300 -@@ -53,6 +53,8 @@ - - #define MAX_TCP_HEADER (128 + MAX_HEADER) - #define MAX_TCP_OPTION_SPACE 40 -+#define TCP_MIN_SND_MSS 48 -+#define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE) - - /* - * Never offer a window over 32767 without using window scaling. Some ---- linux-4.9.37/include/uapi/linux/i2c-dev.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/i2c-dev.h 2021-06-07 13:01:34.000000000 +0300 -@@ -50,6 +50,9 @@ - - #define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ - #define I2C_SMBUS 0x0720 /* SMBus transfer */ -+#define I2C_16BIT_REG 0x0709 /* 16BIT REG WIDTH */ -+#define I2C_16BIT_DATA 0x070a /* 16BIT DATA WIDTH */ -+#define I2C_DMA 0x070b /* DMA mode */ - - - /* This is the structure as used in the I2C_SMBUS ioctl call */ ---- linux-4.9.37/include/uapi/linux/i2c.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/i2c.h 2021-06-07 13:01:34.000000000 +0300 -@@ -71,12 +71,19 @@ - #define I2C_M_RD 0x0001 /* read data, from slave to master */ - /* I2C_M_RD is guaranteed to be 0x0001! */ - #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ -+#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ -+#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ -+#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ - #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ - #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ - #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ - #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ - #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */ - #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */ -+#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ -+#define I2C_M_16BIT_REG 0x0002 /* indicate reg bit-width is 16bit */ -+#define I2C_M_16BIT_DATA 0x0008 /* indicate data bit-width is 16bit */ -+#define I2C_M_DMA 0x0004 /* indicate use dma mode */ - __u16 len; /* msg length */ - __u8 *buf; /* pointer to msg data */ - }; ---- linux-4.9.37/include/uapi/linux/jffs2.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/jffs2.h 2021-06-07 13:01:34.000000000 +0300 -@@ -46,6 +46,7 @@ - #define JFFS2_COMPR_DYNRUBIN 0x05 - #define JFFS2_COMPR_ZLIB 0x06 - #define JFFS2_COMPR_LZO 0x07 -+#define JFFS2_COMPR_LZMA 0x08 - /* Compatibility flags. */ - #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ - #define JFFS2_NODE_ACCURATE 0x2000 ---- linux-4.9.37/include/uapi/linux/msdos_fs.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/msdos_fs.h 2021-06-07 13:01:34.000000000 +0300 -@@ -95,7 +95,23 @@ - unsigned short d_reclen; - char d_name[256]; /* We must not include limits.h! */ - }; -+#ifdef CONFIG_GOKE_MC -+struct fat_direntall { -+ unsigned long d_ino; -+ unsigned long d_off; -+ unsigned char d_type; -+ u64 d_size; -+ char d_createtime[8]; -+ unsigned short d_reclen; -+ char d_name[1]; -+}; - -+struct fat_direntall_buf { -+ int d_count; -+ int d_usecount; -+ struct fat_direntall direntall; -+}; -+#endif - /* - * ioctl commands - */ -@@ -106,7 +122,9 @@ - #define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32) - /*Android kernel has used 0x12, so we use 0x13*/ - #define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32) -- -+#ifdef CONFIG_GOKE_MC -+#define VFAT_IOCTL_READDIR_ALL _IOR('r', 0x14, struct fat_direntall_buf) -+#endif - struct fat_boot_sector { - __u8 ignored[3]; /* Boot strap short or near jump */ - __u8 system_id[8]; /* Name - can be used to special case ---- linux-4.9.37/include/uapi/linux/psci.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/psci.h 2021-06-07 13:01:34.000000000 +0300 -@@ -87,6 +87,9 @@ - (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) - #define PSCI_VERSION_MINOR(ver) \ - ((ver) & PSCI_VERSION_MINOR_MASK) -+#define PSCI_VERSION(maj, min) \ -+ ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ -+ ((min) & PSCI_VERSION_MINOR_MASK)) - - /* PSCI features decoding (>=1.0) */ - #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1 ---- linux-4.9.37/include/uapi/linux/snmp.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/snmp.h 2021-06-07 13:01:34.000000000 +0300 -@@ -281,6 +281,7 @@ - LINUX_MIB_TCPKEEPALIVE, /* TCPKeepAlive */ - LINUX_MIB_TCPMTUPFAIL, /* TCPMTUPFail */ - LINUX_MIB_TCPMTUPSUCCESS, /* TCPMTUPSuccess */ -+ LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */ - __LINUX_MIB_MAX - }; - ---- linux-4.9.37/include/uapi/linux/usb/ch9.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/usb/ch9.h 2021-06-07 13:01:34.000000000 +0300 -@@ -423,6 +423,14 @@ - #define USB_ENDPOINT_XFER_INT 3 - #define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 - -+#define USB_EP_MAXP_MULT_SHIFT 11 -+#define USB_EP_MAXP_MULT_MASK (3 << USB_EP_MAXP_MULT_SHIFT) -+#define USB_EP_MAXP_MULT(m) \ -+ (((m) & USB_EP_MAXP_MULT_MASK) >> USB_EP_MAXP_MULT_SHIFT) -+ -+ -+#define USB_ENDPOINT_MAXP_MASK 0x07ff -+ - /* The USB 3.0 spec redefines bits 5:4 of bmAttributes as interrupt ep type. */ - #define USB_ENDPOINT_INTRTYPE 0x30 - #define USB_ENDPOINT_INTR_PERIODIC (0 << 4) -@@ -623,11 +631,25 @@ - * usb_endpoint_maxp - get endpoint's max packet size - * @epd: endpoint to be checked - * -- * Returns @epd's max packet -+ * Returns @epd's max packet bits [10:0] - */ - static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd) - { -- return __le16_to_cpu(epd->wMaxPacketSize); -+ return __le16_to_cpu(epd->wMaxPacketSize) & USB_ENDPOINT_MAXP_MASK; -+} -+ -+/** -+ * usb_endpoint_maxp_mult - get endpoint's transactional opportunities -+ * @epd: endpoint to be checked -+ * -+ * Return @epd's wMaxPacketSize[12:11] + 1 -+ */ -+static inline int -+usb_endpoint_maxp_mult(const struct usb_endpoint_descriptor *epd) -+{ -+ int maxp = __le16_to_cpu(epd->wMaxPacketSize); -+ -+ return USB_EP_MAXP_MULT(maxp) + 1; - } - - static inline int usb_endpoint_interrupt_type( ---- linux-4.9.37/include/uapi/linux/usb/video.h 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/include/uapi/linux/usb/video.h 2021-06-07 13:01:34.000000000 +0300 -@@ -303,7 +303,7 @@ - __u8 iProcessing; - } __attribute__((__packed__)); - --#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n)) -+#define UVC_DT_PROCESSING_UNIT_SIZE(n) (10+(n)) - - /* 3.7.2.6. Extension Unit Descriptor */ - struct uvc_extension_unit_descriptor { -@@ -340,6 +340,8 @@ - __u8 iExtension; \ - } __attribute__ ((packed)) - -+DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(1,2); -+ - /* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */ - struct uvc_control_endpoint_descriptor { - __u8 bLength; -@@ -565,5 +567,64 @@ - __u32 dwFrameInterval[n]; \ - } __attribute__ ((packed)) - -+ -+/* 3.1.1 Frame Based Payload Video Format Descriptor */ -+struct uvc_frame_based_format_desc { -+ __u8 bLength; -+ __u8 bDescriptorType; -+ __u8 bDescriptorSubType; -+ __u8 bFormatIndex; -+ __u8 bNumFrameDescriptors; -+ __u8 guidFormat[16]; -+ __u8 bBitsPerPixel; -+ __u8 bDefaultFrameIndex; -+ __u8 bAspectRatioX; -+ __u8 bAspectRatioY; -+ __u8 bmInterfaceFlags; -+ __u8 bCopyProtect; -+ __u8 bVariableSize; -+} __attribute__((__packed__)); -+ -+#define UVC_DT_FRAME_BASED_FORMAT_SIZE 28 -+ -+/* 3.1.2 Frame Based Payload Frame Descriptor */ -+struct uvc_frame_based_frame_desc { -+ __u8 bLength; -+ __u8 bDescriptorType; -+ __u8 bDescriptorSubType; -+ __u8 bFrameIndex; -+ __u8 bmCapabilities; -+ __u16 wWidth; -+ __u16 wHeight; -+ __u32 dwMinBitRate; -+ __u32 dwMaxBitRate; -+ __u32 dwDefaultFrameInterval; -+ __u8 bFrameIntervalType; -+ __u32 dwBytesPerLine; -+ __u32 dwFrameInterval[]; -+} __attribute__((__packed__)); -+ -+#define UVC_DT_FRAME_BASED_FRAME_SIZE(n) (26+4*(n)) -+ -+#define UVC_FRAME_BASED(n) \ -+ uvc_frame_based_desc##n -+ -+#define DECLARE_UVC_FRAME_BASED(n) \ -+struct UVC_FRAME_BASED(n) { \ -+ __u8 bLength; \ -+ __u8 bDescriptorType; \ -+ __u8 bDescriptorSubType; \ -+ __u8 bFrameIndex; \ -+ __u8 bmCapabilities; \ -+ __u16 wWidth; \ -+ __u16 wHeight; \ -+ __u32 dwMinBitRate; \ -+ __u32 dwMaxBitRate; \ -+ __u32 dwDefaultFrameInterval; \ -+ __u8 bFrameIntervalType; \ -+ __u32 dwBytesPerLine; \ -+ __u32 dwFrameInterval[n]; \ -+} __attribute__ ((packed)) -+ - #endif /* __LINUX_USB_VIDEO_H */ - ---- linux-4.9.37/kernel/sched/cputime.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/kernel/sched/cputime.c 2021-06-07 13:01:34.000000000 +0300 -@@ -75,6 +75,9 @@ - u64 *cpustat = kcpustat_this_cpu->cpustat; - cputime_t irq_cputime; - -+ if (nsecs_to_cputime64(irqtime) <= cpustat[idx]) -+ return 0; -+ - irq_cputime = nsecs_to_cputime64(irqtime) - cpustat[idx]; - irq_cputime = min(irq_cputime, maxtime); - cpustat[idx] += irq_cputime; ---- linux-4.9.37/lib/Kconfig 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/lib/Kconfig 2021-06-07 13:01:34.000000000 +0300 -@@ -241,6 +241,12 @@ - - source "lib/xz/Kconfig" - -+config LZMA_COMPRESS -+ tristate -+ -+config LZMA_DECOMPRESS -+ tristate -+ - # - # These all provide a common interface (hence the apparent duplication with - # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) -@@ -278,7 +284,7 @@ - # - config REED_SOLOMON - tristate -- -+ - config REED_SOLOMON_ENC8 - bool - ---- linux-4.9.37/lib/lzma/LzFind.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/lib/lzma/LzFind.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,711 @@ -+/* LzFind.c -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#include -+ -+#include "LzFind.h" -+#include "LzHash.h" -+ -+#define kEmptyHashValue 0 -+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -+#define kNormalizeMask (~(kNormalizeStepMin - 1)) -+#define kMaxHistorySize ((UInt32)3 << 30) -+ -+#define kStartMaxLen 3 -+ -+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ if (!p->directInput) { -+ alloc->Free(alloc, p->bufferBase); -+ p->bufferBase = 0; -+ } -+} -+ -+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -+ -+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -+{ -+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -+ if (p->directInput) { -+ p->blockSize = blockSize; -+ return 1; -+ } -+ if (p->bufferBase == 0 || p->blockSize != blockSize) { -+ LzInWindow_Free(p, alloc); -+ p->blockSize = blockSize; -+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); -+ } -+ return (p->bufferBase != 0); -+} -+ -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) -+{ -+ return p->buffer; -+} -+ -+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) -+{ -+ return p->buffer[index]; -+} -+ -+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) -+{ -+ return p->streamPos - p->pos; -+} -+ -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+{ -+ p->posLimit -= subValue; -+ p->pos -= subValue; -+ p->streamPos -= subValue; -+} -+ -+static void MatchFinder_ReadBlock(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached || p->result != SZ_OK) -+ return; -+ if (p->directInput) { -+ UInt32 curSize = 0xFFFFFFFF - p->streamPos; -+ if (curSize > p->directInputRem) -+ curSize = (UInt32)p->directInputRem; -+ p->directInputRem -= curSize; -+ p->streamPos += curSize; -+ if (p->directInputRem == 0) -+ p->streamEndWasReached = 1; -+ return; -+ } -+ for (;;) { -+ Byte *dest = p->buffer + (p->streamPos - p->pos); -+ size_t size = (p->bufferBase + p->blockSize - dest); -+ if (size == 0) -+ return; -+ p->result = p->stream->Read(p->stream, dest, &size); -+ if (p->result != SZ_OK) -+ return; -+ if (size == 0) { -+ p->streamEndWasReached = 1; -+ return; -+ } -+ p->streamPos += (UInt32)size; -+ if (p->streamPos - p->pos > p->keepSizeAfter) -+ return; -+ } -+} -+ -+void MatchFinder_MoveBlock(CMatchFinder *p) -+{ -+ memmove(p->bufferBase, p->buffer - p->keepSizeBefore, -+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); -+ p->buffer = p->bufferBase + p->keepSizeBefore; -+} -+ -+int MatchFinder_NeedMove(CMatchFinder *p) -+{ -+ if (p->directInput) -+ return 0; -+ /* if (p->streamEndWasReached) return 0; */ -+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -+} -+ -+void MatchFinder_ReadIfRequired(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached) -+ return; -+ if (p->keepSizeAfter >= p->streamPos - p->pos) -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -+{ -+ if (MatchFinder_NeedMove(p)) -+ MatchFinder_MoveBlock(p); -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -+{ -+ p->cutValue = 32; -+ p->btMode = 1; -+ p->numHashBytes = 4; -+ p->bigHash = 0; -+} -+ -+#define kCrcPoly 0xEDB88320 -+ -+void MatchFinder_Construct(CMatchFinder *p) -+{ -+ UInt32 i; -+ p->bufferBase = 0; -+ p->directInput = 0; -+ p->hash = 0; -+ MatchFinder_SetDefaultSettings(p); -+ -+ for (i = 0; i < 256; i++) { -+ UInt32 r = i; -+ int j; -+ for (j = 0; j < 8; j++) -+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); -+ p->crc[i] = r; -+ } -+} -+ -+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->hash); -+ p->hash = 0; -+} -+ -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ LzInWindow_Free(p, alloc); -+} -+ -+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -+{ -+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); -+ if (sizeInBytes / sizeof(CLzRef) != num) -+ return 0; -+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -+} -+ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc) -+{ -+ UInt32 sizeReserv; -+ if (historySize > kMaxHistorySize) { -+ MatchFinder_Free(p, alloc); -+ return 0; -+ } -+ sizeReserv = historySize >> 1; -+ if (historySize > ((UInt32)2 << 30)) -+ sizeReserv = historySize >> 2; -+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); -+ -+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; -+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; -+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ -+ if (LzInWindow_Create(p, sizeReserv, alloc)) { -+ UInt32 newCyclicBufferSize = historySize + 1; -+ UInt32 hs; -+ p->matchMaxLen = matchMaxLen; -+ { -+ p->fixedHashSize = 0; -+ if (p->numHashBytes == 2) { -+ hs = (1 << 16) - 1; -+ } else { -+ hs = historySize - 1; -+ hs |= (hs >> 1); -+ hs |= (hs >> 2); -+ hs |= (hs >> 4); -+ hs |= (hs >> 8); -+ hs >>= 1; -+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ -+ if (hs > (1 << 24)) { -+ if (p->numHashBytes == 3) -+ hs = (1 << 24) - 1; -+ else -+ hs >>= 1; -+ } -+ } -+ p->hashMask = hs; -+ hs++; -+ if (p->numHashBytes > 2) -+ p->fixedHashSize += kHash2Size; -+ if (p->numHashBytes > 3) -+ p->fixedHashSize += kHash3Size; -+ if (p->numHashBytes > 4) -+ p->fixedHashSize += kHash4Size; -+ hs += p->fixedHashSize; -+ } -+ -+ { -+ UInt32 prevSize = p->hashSizeSum + p->numSons; -+ UInt32 newSize; -+ p->historySize = historySize; -+ p->hashSizeSum = hs; -+ p->cyclicBufferSize = newCyclicBufferSize; -+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); -+ newSize = p->hashSizeSum + p->numSons; -+ if (p->hash != 0 && prevSize == newSize) -+ return 1; -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ p->hash = AllocRefs(newSize, alloc); -+ if (p->hash != 0) { -+ p->son = p->hash + p->hashSizeSum; -+ return 1; -+ } -+ } -+ } -+ MatchFinder_Free(p, alloc); -+ return 0; -+} -+ -+static void MatchFinder_SetLimits(CMatchFinder *p) -+{ -+ UInt32 limit = kMaxValForNormalize - p->pos; -+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; -+ if (limit2 < limit) -+ limit = limit2; -+ limit2 = p->streamPos - p->pos; -+ if (limit2 <= p->keepSizeAfter) { -+ if (limit2 > 0) -+ limit2 = 1; -+ } else -+ limit2 -= p->keepSizeAfter; -+ if (limit2 < limit) -+ limit = limit2; -+ { -+ UInt32 lenLimit = p->streamPos - p->pos; -+ if (lenLimit > p->matchMaxLen) -+ lenLimit = p->matchMaxLen; -+ p->lenLimit = lenLimit; -+ } -+ p->posLimit = p->pos + limit; -+} -+ -+void MatchFinder_Init(CMatchFinder *p) -+{ -+ UInt32 i; -+ for (i = 0; i < p->hashSizeSum; i++) -+ p->hash[i] = kEmptyHashValue; -+ p->cyclicBufferPos = 0; -+ p->buffer = p->bufferBase; -+ p->pos = p->streamPos = p->cyclicBufferSize; -+ p->result = SZ_OK; -+ p->streamEndWasReached = 0; -+ MatchFinder_ReadBlock(p); -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -+{ -+ return (p->pos - p->historySize - 1) & kNormalizeMask; -+} -+ -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+{ -+ UInt32 i; -+ for (i = 0; i < numItems; i++) { -+ UInt32 value = items[i]; -+ if (value <= subValue) -+ value = kEmptyHashValue; -+ else -+ value -= subValue; -+ items[i] = value; -+ } -+} -+ -+static void MatchFinder_Normalize(CMatchFinder *p) -+{ -+ UInt32 subValue = MatchFinder_GetSubValue(p); -+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); -+ MatchFinder_ReduceOffsets(p, subValue); -+} -+ -+static void MatchFinder_CheckLimits(CMatchFinder *p) -+{ -+ if (p->pos == kMaxValForNormalize) -+ MatchFinder_Normalize(p); -+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) -+ MatchFinder_CheckAndMoveAndRead(p); -+ if (p->cyclicBufferPos == p->cyclicBufferSize) -+ p->cyclicBufferPos = 0; -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ son[_cyclicBufferPos] = curMatch; -+ for (;;) { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ return distances; -+ { -+ const Byte *pb = cur - delta; -+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -+ if (pb[maxLen] == cur[maxLen] && *pb == *cur) { -+ UInt32 len = 0; -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ return distances; -+ } -+ } -+ } -+ } -+} -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return distances; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) { -+ if (++len != lenLimit && pb[len] == cur[len]) -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return distances; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } else { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) { -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ { -+ if (len == lenLimit) { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } else { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+#define MOVE_POS \ -+ ++p->cyclicBufferPos; \ -+ p->buffer++; \ -+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); -+ -+#define MOVE_POS_RET MOVE_POS return offset; -+ -+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } -+ -+#define GET_MATCHES_HEADER2(minLen, ret_op) \ -+ UInt32 lenLimit; UInt32 hashValue = 0; const Byte *cur; UInt32 curMatch; \ -+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -+ cur = p->buffer; -+ -+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) -+ -+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -+ -+#define GET_MATCHES_FOOTER(offset, maxLen) \ -+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ -+ distances + offset, maxLen) - distances); MOVE_POS_RET; -+ -+#define SKIP_FOOTER \ -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -+ -+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 1) -+} -+ -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 2) -+} -+ -+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value = 0, delta2, maxLen, offset; -+ GET_MATCHES_HEADER(3) -+ -+ HASH3_CALC; -+ -+ delta2 = p->pos - p->hash[hash2Value]; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ -+ -+ maxLen = 2; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[0] = maxLen; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ if (maxLen == lenLimit) { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value = 0, hash3Value = 0, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value = 0, hash3Value = 0, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) { -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances + offset, maxLen) - (distances)); -+ MOVE_POS_RET -+} -+ -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances, 2) - (distances)); -+ MOVE_POS_RET -+} -+ -+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do { -+ SKIP_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } while (--num != 0); -+} -+ -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } while (--num != 0); -+} -+ -+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do { -+ UInt32 hash2Value = 0; -+ SKIP_HEADER(3) -+ HASH3_CALC; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } while (--num != 0); -+} -+ -+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do { -+ UInt32 hash2Value = 0, hash3Value = 0; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = p->pos; -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } while (--num != 0); -+} -+ -+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do { -+ UInt32 hash2Value = 0, hash3Value = 0; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } while (--num != 0); -+} -+ -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } while (--num != 0); -+} -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -+{ -+ vTable->Init = (Mf_Init_Func)MatchFinder_Init; -+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; -+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; -+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -+ if (!p->btMode) { -+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -+ } else if (p->numHashBytes == 2) { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -+ } else if (p->numHashBytes == 3) { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -+ } else { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -+ } -+} ---- linux-4.9.37/lib/lzma/LzmaDec.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/lib/lzma/LzmaDec.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,999 @@ -+/* LzmaDec.c -- LZMA Decoder -+2009-09-20 : Igor Pavlov : Public domain */ -+ -+#include "LzmaDec.h" -+ -+#include -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+ -+#define RC_INIT_SIZE 5 -+ -+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ -+ { UPDATE_0(p); i = (i + i); A0; } else \ -+ { UPDATE_1(p); i = (i + i) + 1; A1; } -+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) -+ -+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -+#define TREE_DECODE(probs, limit, i) \ -+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -+ -+/* #define _LZMA_SIZE_OPT */ -+ -+#ifdef _LZMA_SIZE_OPT -+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -+#else -+#define TREE_6_DECODE(probs, i) \ -+ { i = 1; \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ i -= 0x40; } -+#endif -+ -+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0_CHECK range = bound; -+#define UPDATE_1_CHECK range -= bound; code -= bound; -+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ -+ { UPDATE_0_CHECK; i = (i + i); A0; } else \ -+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -+#define TREE_DECODE_CHECK(probs, limit, i) \ -+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } -+ -+ -+#define kNumPosBitsMax 4 -+#define kNumPosStatesMax (1 << kNumPosBitsMax) -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define LenChoice 0 -+#define LenChoice2 (LenChoice + 1) -+#define LenLow (LenChoice2 + 1) -+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -+ -+ -+#define kNumStates 12 -+#define kNumLitStates 7 -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#define kNumPosSlotBits 6 -+#define kNumLenToPosStates 4 -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+ -+#define kMatchMinLen 2 -+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define IsMatch 0 -+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -+#define IsRepG0 (IsRep + kNumStates) -+#define IsRepG1 (IsRepG0 + kNumStates) -+#define IsRepG2 (IsRepG1 + kNumStates) -+#define IsRep0Long (IsRepG2 + kNumStates) -+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -+#define LenCoder (Align + kAlignTableSize) -+#define RepLenCoder (LenCoder + kNumLenProbs) -+#define Literal (RepLenCoder + kNumLenProbs) -+ -+#define LZMA_BASE_SIZE 1846 -+#define LZMA_LIT_SIZE 768 -+ -+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) -+ -+#if Literal != LZMA_BASE_SIZE -+StopCompilingDueBUG -+#endif -+ -+#define LZMA_DIC_MIN (1 << 12) -+ -+/* First LZMA-symbol is always decoded. -+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -+Out: -+ Result: -+ SZ_OK - OK -+ SZ_ERROR_DATA - Error -+ p->remainLen: -+ < kMatchSpecLenStart : normal remain -+ = kMatchSpecLenStart : finished -+ = kMatchSpecLenStart + 1 : Flush marker -+ = kMatchSpecLenStart + 2 : State Init Marker -+*/ -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ CLzmaProb *probs = p->probs; -+ -+ unsigned state = p->state; -+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; -+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; -+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; -+ unsigned lc = p->prop.lc; -+ -+ Byte *dic = p->dic; -+ SizeT dicBufSize = p->dicBufSize; -+ SizeT dicPos = p->dicPos; -+ -+ UInt32 processedPos = p->processedPos; -+ UInt32 checkDicSize = p->checkDicSize; -+ unsigned len = 0; -+ -+ const Byte *buf = p->buf; -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ -+ do -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = processedPos & pbMask; -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ unsigned symbol; -+ UPDATE_0(prob); -+ prob = probs + Literal; -+ if (checkDicSize != 0 || processedPos != 0) -+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + -+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ state -= (state < 4) ? state : 3; -+ symbol = 1; -+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ state -= (state < 10) ? 3 : 6; -+ symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ dic[dicPos++] = (Byte)symbol; -+ processedPos++; -+ continue; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRep + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ state += kNumStates; -+ prob = probs + LenCoder; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ if (checkDicSize == 0 && processedPos == 0) -+ return SZ_ERROR_DATA; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ processedPos++; -+ state = state < kNumLitStates ? 9 : 11; -+ continue; -+ } -+ UPDATE_1(prob); -+ } -+ else -+ { -+ UInt32 distance; -+ UPDATE_1(prob); -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep1; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep2; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ distance = rep3; -+ rep3 = rep2; -+ } -+ rep2 = rep1; -+ } -+ rep1 = rep0; -+ rep0 = distance; -+ } -+ state = state < kNumLitStates ? 8 : 11; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = (1 << kLenNumLowBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenChoice2; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = (1 << kLenNumMidBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = (1 << kLenNumHighBits); -+ } -+ } -+ TREE_DECODE(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state >= kNumStates) -+ { -+ UInt32 distance; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); -+ TREE_6_DECODE(prob, distance); -+ if (distance >= kStartPosModelIndex) -+ { -+ unsigned posSlot = (unsigned)distance; -+ int numDirectBits = (int)(((distance >> 1) - 1)); -+ distance = (2 | (distance & 1)); -+ if (posSlot < kEndPosModelIndex) -+ { -+ distance <<= numDirectBits; -+ prob = probs + SpecPos + distance - posSlot - 1; -+ { -+ UInt32 mask = 1; -+ unsigned i = 1; -+ do -+ { -+ GET_BIT2(prob + i, i, ; , distance |= mask); -+ mask <<= 1; -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE -+ range >>= 1; -+ -+ { -+ UInt32 t; -+ code -= range; -+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ -+ distance = (distance << 1) + (t + 1); -+ code += range & t; -+ } -+ /* -+ distance <<= 1; -+ if (code >= range) -+ { -+ code -= range; -+ distance |= 1; -+ } -+ */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ distance <<= kNumAlignBits; -+ { -+ unsigned i = 1; -+ GET_BIT2(prob + i, i, ; , distance |= 1); -+ GET_BIT2(prob + i, i, ; , distance |= 2); -+ GET_BIT2(prob + i, i, ; , distance |= 4); -+ GET_BIT2(prob + i, i, ; , distance |= 8); -+ } -+ if (distance == (UInt32)0xFFFFFFFF) -+ { -+ len += kMatchSpecLenStart; -+ state -= kNumStates; -+ break; -+ } -+ } -+ } -+ rep3 = rep2; -+ rep2 = rep1; -+ rep1 = rep0; -+ rep0 = distance + 1; -+ if (checkDicSize == 0) -+ { -+ if (distance >= processedPos) -+ return SZ_ERROR_DATA; -+ } -+ else if (distance >= checkDicSize) -+ return SZ_ERROR_DATA; -+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; -+ } -+ -+ len += kMatchMinLen; -+ -+ if (limit == dicPos) -+ return SZ_ERROR_DATA; -+ { -+ SizeT rem = limit - dicPos; -+ unsigned curLen = ((rem < len) ? (unsigned)rem : len); -+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); -+ -+ processedPos += curLen; -+ -+ len -= curLen; -+ if (pos + curLen <= dicBufSize) -+ { -+ Byte *dest = dic + dicPos; -+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; -+ const Byte *lim = dest + curLen; -+ dicPos += curLen; -+ do -+ *(dest) = (Byte)*(dest + src); -+ while (++dest != lim); -+ } -+ else -+ { -+ do -+ { -+ dic[dicPos++] = dic[pos]; -+ if (++pos == dicBufSize) -+ pos = 0; -+ } -+ while (--curLen != 0); -+ } -+ } -+ } -+ } -+ while (dicPos < limit && buf < bufLimit); -+ NORMALIZE; -+ p->buf = buf; -+ p->range = range; -+ p->code = code; -+ p->remainLen = len; -+ p->dicPos = dicPos; -+ p->processedPos = processedPos; -+ p->reps[0] = rep0; -+ p->reps[1] = rep1; -+ p->reps[2] = rep2; -+ p->reps[3] = rep3; -+ p->state = state; -+ -+ return SZ_OK; -+} -+ -+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -+{ -+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) -+ { -+ Byte *dic = p->dic; -+ SizeT dicPos = p->dicPos; -+ SizeT dicBufSize = p->dicBufSize; -+ unsigned len = p->remainLen; -+ UInt32 rep0 = p->reps[0]; -+ if (limit - dicPos < len) -+ len = (unsigned)(limit - dicPos); -+ -+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) -+ p->checkDicSize = p->prop.dicSize; -+ -+ p->processedPos += len; -+ p->remainLen -= len; -+ while (len-- != 0) -+ { -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ } -+ p->dicPos = dicPos; -+ } -+} -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ do -+ { -+ SizeT limit2 = limit; -+ if (p->checkDicSize == 0) -+ { -+ UInt32 rem = p->prop.dicSize - p->processedPos; -+ if (limit - p->dicPos > rem) -+ limit2 = p->dicPos + rem; -+ } -+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); -+ if (p->processedPos >= p->prop.dicSize) -+ p->checkDicSize = p->prop.dicSize; -+ LzmaDec_WriteRem(p, limit); -+ } -+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); -+ -+ if (p->remainLen > kMatchSpecLenStart) -+ { -+ p->remainLen = kMatchSpecLenStart; -+ } -+ return 0; -+} -+ -+typedef enum -+{ -+ DUMMY_ERROR, /* unexpected end of input stream */ -+ DUMMY_LIT, -+ DUMMY_MATCH, -+ DUMMY_REP -+} ELzmaDummy; -+ -+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -+{ -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ const Byte *bufLimit = buf + inSize; -+ CLzmaProb *probs = p->probs; -+ unsigned state = p->state; -+ ELzmaDummy res; -+ -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK -+ -+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ -+ -+ prob = probs + Literal; -+ if (p->checkDicSize != 0 || p->processedPos != 0) -+ prob += (LZMA_LIT_SIZE * -+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + -+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ unsigned symbol = 1; -+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + -+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ unsigned symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ res = DUMMY_LIT; -+ } -+ else -+ { -+ unsigned len; -+ UPDATE_1_CHECK; -+ -+ prob = probs + IsRep + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ state = 0; -+ prob = probs + LenCoder; -+ res = DUMMY_MATCH; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ res = DUMMY_REP; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ NORMALIZE_CHECK; -+ return DUMMY_REP; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ } -+ state = kNumStates; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = 1 << kLenNumLowBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenChoice2; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = 1 << kLenNumMidBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = 1 << kLenNumHighBits; -+ } -+ } -+ TREE_DECODE_CHECK(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state < 4) -+ { -+ unsigned posSlot; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -+ kNumPosSlotBits); -+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); -+ if (posSlot >= kStartPosModelIndex) -+ { -+ int numDirectBits = ((posSlot >> 1) - 1); -+ -+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ -+ -+ if (posSlot < kEndPosModelIndex) -+ { -+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE_CHECK -+ range >>= 1; -+ code -= range & (((code - range) >> 31) - 1); -+ /* if (code >= range) code -= range; */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ numDirectBits = kNumAlignBits; -+ } -+ { -+ unsigned i = 1; -+ do -+ { -+ GET_BIT_CHECK(prob + i, i); -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ } -+ } -+ } -+ NORMALIZE_CHECK; -+ return res; -+} -+ -+ -+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -+{ -+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); -+ p->range = 0xFFFFFFFF; -+ p->needFlush = 0; -+} -+ -+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+{ -+ p->needFlush = 1; -+ p->remainLen = 0; -+ p->tempBufSize = 0; -+ -+ if (initDic) -+ { -+ p->processedPos = 0; -+ p->checkDicSize = 0; -+ p->needInitState = 1; -+ } -+ if (initState) -+ p->needInitState = 1; -+} -+ -+void LzmaDec_Init(CLzmaDec *p) -+{ -+ p->dicPos = 0; -+ LzmaDec_InitDicAndState(p, True, True); -+} -+ -+static void LzmaDec_InitStateReal(CLzmaDec *p) -+{ -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); -+ UInt32 i; -+ CLzmaProb *probs = p->probs; -+ for (i = 0; i < numProbs; i++) -+ probs[i] = kBitModelTotal >> 1; -+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; -+ p->state = 0; -+ p->needInitState = 0; -+} -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+ ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT inSize = *srcLen; -+ (*srcLen) = 0; -+ LzmaDec_WriteRem(p, dicLimit); -+ -+ *status = LZMA_STATUS_NOT_SPECIFIED; -+ -+ while (p->remainLen != kMatchSpecLenStart) -+ { -+ int checkEndMarkNow; -+ -+ if (p->needFlush != 0) -+ { -+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) -+ p->tempBuf[p->tempBufSize++] = *src++; -+ if (p->tempBufSize < RC_INIT_SIZE) -+ { -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (p->tempBuf[0] != 0) -+ return SZ_ERROR_DATA; -+ -+ LzmaDec_InitRc(p, p->tempBuf); -+ p->tempBufSize = 0; -+ } -+ -+ checkEndMarkNow = 0; -+ if (p->dicPos >= dicLimit) -+ { -+ if (p->remainLen == 0 && p->code == 0) -+ { -+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; -+ return SZ_OK; -+ } -+ if (finishMode == LZMA_FINISH_ANY) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_OK; -+ } -+ if (p->remainLen != 0) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ checkEndMarkNow = 1; -+ } -+ -+ if (p->needInitState) -+ LzmaDec_InitStateReal(p); -+ -+ if (p->tempBufSize == 0) -+ { -+ SizeT processed; -+ const Byte *bufLimit = NULL; -+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, src, inSize); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ memcpy(p->tempBuf, src, inSize); -+ p->tempBufSize = (unsigned)inSize; -+ (*srcLen) += inSize; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ bufLimit = src; -+ } -+ else -+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; -+ p->buf = src; -+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) -+ return SZ_ERROR_DATA; -+ processed = (SizeT)(p->buf - src); -+ (*srcLen) += processed; -+ src += processed; -+ inSize -= processed; -+ } -+ else -+ { -+ unsigned rem = p->tempBufSize, lookAhead = 0; -+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) -+ p->tempBuf[rem++] = src[lookAhead++]; -+ p->tempBufSize = rem; -+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ (*srcLen) += lookAhead; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ } -+ p->buf = p->tempBuf; -+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) -+ return SZ_ERROR_DATA; -+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); -+ (*srcLen) += lookAhead; -+ src += lookAhead; -+ inSize -= lookAhead; -+ p->tempBufSize = 0; -+ } -+ } -+ if (p->code == 0) -+ *status = LZMA_STATUS_FINISHED_WITH_MARK; -+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -+} -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT outSize = *destLen; -+ SizeT inSize = *srcLen; -+ *srcLen = *destLen = 0; -+ for (;;) -+ { -+ SizeT inSizeCur = inSize, outSizeCur, dicPos; -+ ELzmaFinishMode curFinishMode; -+ SRes res; -+ if (p->dicPos == p->dicBufSize) -+ p->dicPos = 0; -+ dicPos = p->dicPos; -+ if (outSize > p->dicBufSize - dicPos) -+ { -+ outSizeCur = p->dicBufSize; -+ curFinishMode = LZMA_FINISH_ANY; -+ } -+ else -+ { -+ outSizeCur = dicPos + outSize; -+ curFinishMode = finishMode; -+ } -+ -+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -+ src += inSizeCur; -+ inSize -= inSizeCur; -+ *srcLen += inSizeCur; -+ outSizeCur = p->dicPos - dicPos; -+ memcpy(dest, p->dic + dicPos, outSizeCur); -+ dest += outSizeCur; -+ outSize -= outSizeCur; -+ *destLen += outSizeCur; -+ if (res != 0) -+ return res; -+ if (outSizeCur == 0 || outSize == 0) -+ return SZ_OK; -+ } -+} -+ -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->probs); -+ p->probs = 0; -+} -+ -+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->dic); -+ p->dic = 0; -+} -+ -+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ LzmaDec_FreeProbs(p, alloc); -+ LzmaDec_FreeDict(p, alloc); -+} -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+{ -+ UInt32 dicSize; -+ Byte d; -+ -+ if (size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_UNSUPPORTED; -+ else -+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); -+ -+ if (dicSize < LZMA_DIC_MIN) -+ dicSize = LZMA_DIC_MIN; -+ p->dicSize = dicSize; -+ -+ d = data[0]; -+ if (d >= (9 * 5 * 5)) -+ return SZ_ERROR_UNSUPPORTED; -+ -+ p->lc = d % 9; -+ d /= 9; -+ p->pb = d / 5; -+ p->lp = d % 5; -+ -+ return SZ_OK; -+} -+ -+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -+{ -+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); -+ if (p->probs == 0 || numProbs != p->numProbs) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); -+ p->numProbs = numProbs; -+ if (p->probs == 0) -+ return SZ_ERROR_MEM; -+ } -+ return SZ_OK; -+} -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ SizeT dicBufSize; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ dicBufSize = propNew.dicSize; -+ if (p->dic == 0 || dicBufSize != p->dicBufSize) -+ { -+ LzmaDec_FreeDict(p, alloc); -+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -+ if (p->dic == 0) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ } -+ p->dicBufSize = dicBufSize; -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc) -+{ -+ CLzmaDec p; -+ SRes res; -+ SizeT inSize = *srcLen; -+ SizeT outSize = *destLen; -+ *srcLen = *destLen = 0; -+ if (inSize < RC_INIT_SIZE) -+ return SZ_ERROR_INPUT_EOF; -+ -+ LzmaDec_Construct(&p); -+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); -+ if (res != 0) -+ return res; -+ p.dic = dest; -+ p.dicBufSize = outSize; -+ -+ LzmaDec_Init(&p); -+ -+ *srcLen = inSize; -+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); -+ -+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) -+ res = SZ_ERROR_INPUT_EOF; -+ -+ (*destLen) = p.dicPos; -+ LzmaDec_FreeProbs(&p, alloc); -+ return res; -+} ---- linux-4.9.37/lib/lzma/LzmaEnc.c 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/lib/lzma/LzmaEnc.c 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,2271 @@ -+/* LzmaEnc.c -- LZMA Encoder -+2009-11-24 : Igor Pavlov : Public domain */ -+ -+#include -+ -+/* #define SHOW_STAT */ -+/* #define SHOW_STAT2 */ -+ -+#if defined(SHOW_STAT) || defined(SHOW_STAT2) -+#include -+#endif -+ -+#include "LzmaEnc.h" -+ -+/* disable MT */ -+#define _7ZIP_ST -+ -+#include "LzFind.h" -+#ifndef _7ZIP_ST -+#include "LzFindMt.h" -+#endif -+ -+#ifdef SHOW_STAT -+static int ttt = 0; -+#endif -+ -+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) -+ -+#define kBlockSize (9 << 10) -+#define kUnpackBlockSize (1 << 18) -+#define kMatchArraySize (1 << 21) -+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) -+ -+#define kNumMaxDirectBits (31) -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+#define kProbInitValue (kBitModelTotal >> 1) -+ -+#define kNumMoveReducingBits 4 -+#define kNumBitPriceShiftBits 4 -+#define kBitPrice (1 << kNumBitPriceShiftBits) -+ -+void LzmaEncProps_Init(CLzmaEncProps *p) -+{ -+ p->level = 5; -+ p->dictSize = p->mc = 0; -+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; -+ p->writeEndMark = 0; -+} -+ -+void LzmaEncProps_Normalize(CLzmaEncProps *p) -+{ -+ int level = p->level; -+ if (level < 0) level = 5; -+ p->level = level; -+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); -+ if (p->lc < 0) p->lc = 3; -+ if (p->lp < 0) p->lp = 0; -+ if (p->pb < 0) p->pb = 2; -+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); -+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); -+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); -+ if (p->numHashBytes < 0) p->numHashBytes = 4; -+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); -+ if (p->numThreads < 0) -+ p->numThreads = -+ #ifndef _7ZIP_ST -+ ((p->btMode && p->algo) ? 2 : 1); -+ #else -+ 1; -+ #endif -+} -+ -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+{ -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ return props.dictSize; -+} -+ -+/* #define LZMA_LOG_BSR */ -+/* Define it for Intel's CPU */ -+ -+ -+#ifdef LZMA_LOG_BSR -+ -+#define kDicLogSizeMaxCompress 30 -+ -+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } -+ -+UInt32 GetPosSlot1(UInt32 pos) -+{ -+ UInt32 res; -+ BSR2_RET(pos, res); -+ return res; -+} -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } -+ -+#else -+ -+#define kNumLogBits (9 + (int)sizeof(size_t) / 2) -+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -+ -+void LzmaEnc_FastPosInit(Byte *g_FastPos) -+{ -+ int c = 2, slotFast; -+ g_FastPos[0] = 0; -+ g_FastPos[1] = 1; -+ -+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) -+ { -+ UInt32 k = (1 << ((slotFast >> 1) - 1)); -+ UInt32 j; -+ for (j = 0; j < k; j++, c++) -+ g_FastPos[c] = (Byte)slotFast; -+ } -+} -+ -+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ -+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ -+ res = p->g_FastPos[pos >> i] + (i * 2); } -+/* -+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ -+ p->g_FastPos[pos >> 6] + 12 : \ -+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -+*/ -+ -+#define GetPosSlot1(pos) p->g_FastPos[pos] -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } -+ -+#endif -+ -+ -+#define LZMA_NUM_REPS 4 -+ -+typedef unsigned CState; -+ -+typedef struct -+{ -+ UInt32 price; -+ -+ CState state; -+ int prev1IsChar; -+ int prev2; -+ -+ UInt32 posPrev2; -+ UInt32 backPrev2; -+ -+ UInt32 posPrev; -+ UInt32 backPrev; -+ UInt32 backs[LZMA_NUM_REPS]; -+} COptimal; -+ -+#define kNumOpts (1 << 12) -+ -+#define kNumLenToPosStates 4 -+#define kNumPosSlotBits 6 -+#define kDicLogSizeMin 0 -+#define kDicLogSizeMax 32 -+#define kDistTableSizeMax (kDicLogSizeMax * 2) -+ -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+#define kAlignMask (kAlignTableSize - 1) -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) -+ -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+#define LZMA_PB_MAX 4 -+#define LZMA_LC_MAX 8 -+#define LZMA_LP_MAX 4 -+ -+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) -+ -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define LZMA_MATCH_LEN_MIN 2 -+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) -+ -+#define kNumStates 12 -+ -+typedef struct -+{ -+ CLzmaProb choice; -+ CLzmaProb choice2; -+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; -+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; -+ CLzmaProb high[kLenNumHighSymbols]; -+} CLenEnc; -+ -+typedef struct -+{ -+ CLenEnc p; -+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; -+ UInt32 tableSize; -+ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -+} CLenPriceEnc; -+ -+typedef struct -+{ -+ UInt32 range; -+ Byte cache; -+ UInt64 low; -+ UInt64 cacheSize; -+ Byte *buf; -+ Byte *bufLim; -+ Byte *bufBase; -+ ISeqOutStream *outStream; -+ UInt64 processed; -+ SRes res; -+} CRangeEnc; -+ -+typedef struct -+{ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+} CSaveState; -+ -+typedef struct -+{ -+ IMatchFinder matchFinder; -+ void *matchFinderObj; -+ -+ #ifndef _7ZIP_ST -+ Bool mtMode; -+ CMatchFinderMt matchFinderMt; -+ #endif -+ -+ CMatchFinder matchFinderBase; -+ -+ #ifndef _7ZIP_ST -+ Byte pad[128]; -+ #endif -+ -+ UInt32 optimumEndIndex; -+ UInt32 optimumCurrentIndex; -+ -+ UInt32 longestMatchLength; -+ UInt32 numPairs; -+ UInt32 numAvail; -+ COptimal opt[kNumOpts]; -+ -+ #ifndef LZMA_LOG_BSR -+ Byte g_FastPos[1 << kNumLogBits]; -+ #endif -+ -+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; -+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; -+ UInt32 numFastBytes; -+ UInt32 additionalOffset; -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+ -+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; -+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; -+ UInt32 alignPrices[kAlignTableSize]; -+ UInt32 alignPriceCount; -+ -+ UInt32 distTableSize; -+ -+ unsigned lc, lp, pb; -+ unsigned lpMask, pbMask; -+ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ unsigned lclp; -+ -+ Bool fastMode; -+ -+ CRangeEnc rc; -+ -+ Bool writeEndMark; -+ UInt64 nowPos64; -+ UInt32 matchPriceCount; -+ Bool finished; -+ Bool multiThread; -+ -+ SRes result; -+ UInt32 dictSize; -+ UInt32 matchFinderCycles; -+ -+ int needInit; -+ -+ CSaveState saveState; -+} CLzmaEnc; -+ -+void LzmaEnc_SaveState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CSaveState *dest = &p->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); -+} -+ -+void LzmaEnc_RestoreState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *dest = (CLzmaEnc *)pp; -+ const CSaveState *p = &dest->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); -+} -+ -+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ -+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || -+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) -+ return SZ_ERROR_PARAM; -+ p->dictSize = props.dictSize; -+ p->matchFinderCycles = props.mc; -+ { -+ unsigned fb = props.fb; -+ if (fb < 5) -+ fb = 5; -+ if (fb > LZMA_MATCH_LEN_MAX) -+ fb = LZMA_MATCH_LEN_MAX; -+ p->numFastBytes = fb; -+ } -+ p->lc = props.lc; -+ p->lp = props.lp; -+ p->pb = props.pb; -+ p->fastMode = (props.algo == 0); -+ p->matchFinderBase.btMode = props.btMode; -+ { -+ UInt32 numHashBytes = 4; -+ if (props.btMode) -+ { -+ if (props.numHashBytes < 2) -+ numHashBytes = 2; -+ else if (props.numHashBytes < 4) -+ numHashBytes = props.numHashBytes; -+ } -+ p->matchFinderBase.numHashBytes = numHashBytes; -+ } -+ -+ p->matchFinderBase.cutValue = props.mc; -+ -+ p->writeEndMark = props.writeEndMark; -+ -+ #ifndef _7ZIP_ST -+ /* -+ if (newMultiThread != _multiThread) -+ { -+ ReleaseMatchFinder(); -+ _multiThread = newMultiThread; -+ } -+ */ -+ p->multiThread = (props.numThreads > 1); -+ #endif -+ -+ return SZ_OK; -+} -+ -+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; -+ -+#define IsCharState(s) ((s) < 7) -+ -+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) -+ -+#define kInfinityPrice (1 << 30) -+ -+static void RangeEnc_Construct(CRangeEnc *p) -+{ -+ p->outStream = 0; -+ p->bufBase = 0; -+} -+ -+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) -+ -+#define RC_BUF_SIZE (1 << 16) -+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ if (p->bufBase == 0) -+ { -+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); -+ if (p->bufBase == 0) -+ return 0; -+ p->bufLim = p->bufBase + RC_BUF_SIZE; -+ } -+ return 1; -+} -+ -+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->bufBase); -+ p->bufBase = 0; -+} -+ -+static void RangeEnc_Init(CRangeEnc *p) -+{ -+ /* Stream.Init(); */ -+ p->low = 0; -+ p->range = 0xFFFFFFFF; -+ p->cacheSize = 1; -+ p->cache = 0; -+ -+ p->buf = p->bufBase; -+ -+ p->processed = 0; -+ p->res = SZ_OK; -+} -+ -+static void RangeEnc_FlushStream(CRangeEnc *p) -+{ -+ size_t num; -+ if (p->res != SZ_OK) -+ return; -+ num = p->buf - p->bufBase; -+ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) -+ p->res = SZ_ERROR_WRITE; -+ p->processed += num; -+ p->buf = p->bufBase; -+} -+ -+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -+{ -+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) -+ { -+ Byte temp = p->cache; -+ do -+ { -+ Byte *buf = p->buf; -+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); -+ p->buf = buf; -+ if (buf == p->bufLim) -+ RangeEnc_FlushStream(p); -+ temp = 0xFF; -+ } -+ while (--p->cacheSize != 0); -+ p->cache = (Byte)((UInt32)p->low >> 24); -+ } -+ p->cacheSize++; -+ p->low = (UInt32)p->low << 8; -+} -+ -+static void RangeEnc_FlushData(CRangeEnc *p) -+{ -+ int i; -+ for (i = 0; i < 5; i++) -+ RangeEnc_ShiftLow(p); -+} -+ -+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) -+{ -+ do -+ { -+ p->range >>= 1; -+ p->low += p->range & (0 - ((value >> --numBits) & 1)); -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+ } -+ while (numBits != 0); -+} -+ -+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -+{ -+ UInt32 ttt = *prob; -+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; -+ if (symbol == 0) -+ { -+ p->range = newBound; -+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; -+ } -+ else -+ { -+ p->low += newBound; -+ p->range -= newBound; -+ ttt -= ttt >> kNumMoveBits; -+ } -+ *prob = (CLzmaProb)ttt; -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+} -+ -+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -+{ -+ symbol |= 0x100; -+ do -+ { -+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+} -+ -+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -+{ -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+} -+ -+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+{ -+ UInt32 i; -+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -+ { -+ const int kCyclesBits = kNumBitPriceShiftBits; -+ UInt32 w = i; -+ UInt32 bitCount = 0; -+ int j; -+ for (j = 0; j < kCyclesBits; j++) -+ { -+ w = w * w; -+ bitCount <<= 1; -+ while (w >= ((UInt32)1 << 16)) -+ { -+ w >>= 1; -+ bitCount++; -+ } -+ } -+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); -+ } -+} -+ -+ -+#define GET_PRICE(prob, symbol) \ -+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICEa(prob, symbol) \ -+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= 0x100; -+ do -+ { -+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+ -+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0;) -+ { -+ UInt32 bit; -+ i--; -+ bit = (symbol >> i) & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ } -+} -+ -+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = 0; i < numBitLevels; i++) -+ { -+ UInt32 bit = symbol & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ symbol >>= 1; -+ } -+} -+ -+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= (1 << numBitLevels); -+ while (symbol != 1) -+ { -+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); -+ symbol >>= 1; -+ } -+ return price; -+} -+ -+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0; i--) -+ { -+ UInt32 bit = symbol & 1; -+ symbol >>= 1; -+ price += GET_PRICEa(probs[m], bit); -+ m = (m << 1) | bit; -+ } -+ return price; -+} -+ -+ -+static void LenEnc_Init(CLenEnc *p) -+{ -+ unsigned i; -+ p->choice = p->choice2 = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) -+ p->low[i] = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) -+ p->mid[i] = kProbInitValue; -+ for (i = 0; i < kLenNumHighSymbols; i++) -+ p->high[i] = kProbInitValue; -+} -+ -+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -+{ -+ if (symbol < kLenNumLowSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 0); -+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 1); -+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 0); -+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 1); -+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); -+ } -+ } -+} -+ -+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) -+{ -+ UInt32 a0 = GET_PRICE_0a(p->choice); -+ UInt32 a1 = GET_PRICE_1a(p->choice); -+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); -+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); -+ UInt32 i = 0; -+ for (i = 0; i < kLenNumLowSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); -+ } -+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); -+ } -+ for (; i < numSymbols; i++) -+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -+} -+ -+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -+{ -+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); -+ p->counters[posState] = p->tableSize; -+} -+ -+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) -+{ -+ UInt32 posState; -+ for (posState = 0; posState < numPosStates; posState++) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -+{ -+ LenEnc_Encode(&p->p, rc, symbol, posState); -+ if (updatePrice) -+ if (--p->counters[posState] == 0) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+ -+ -+ -+static void MovePos(CLzmaEnc *p, UInt32 num) -+{ -+ #ifdef SHOW_STAT -+ ttt += num; -+ printf("\n MovePos %d", num); -+ #endif -+ if (num != 0) -+ { -+ p->additionalOffset += num; -+ p->matchFinder.Skip(p->matchFinderObj, num); -+ } -+} -+ -+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -+{ -+ UInt32 lenRes = 0, numPairs; -+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); -+ #ifdef SHOW_STAT -+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); -+ ttt++; -+ { -+ UInt32 i; -+ for (i = 0; i < numPairs; i += 2) -+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); -+ } -+ #endif -+ if (numPairs > 0) -+ { -+ lenRes = p->matches[numPairs - 2]; -+ if (lenRes == p->numFastBytes) -+ { -+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ UInt32 distance = p->matches[numPairs - 1] + 1; -+ UInt32 numAvail = p->numAvail; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ { -+ const Byte *pby2 = pby - distance; -+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); -+ } -+ } -+ } -+ p->additionalOffset++; -+ *numDistancePairsRes = numPairs; -+ return lenRes; -+} -+ -+ -+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -+#define IsShortRep(p) ((p)->backPrev == 0) -+ -+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -+{ -+ return -+ GET_PRICE_0(p->isRepG0[state]) + -+ GET_PRICE_0(p->isRep0Long[state][posState]); -+} -+ -+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -+{ -+ UInt32 price; -+ if (repIndex == 0) -+ { -+ price = GET_PRICE_0(p->isRepG0[state]); -+ price += GET_PRICE_1(p->isRep0Long[state][posState]); -+ } -+ else -+ { -+ price = GET_PRICE_1(p->isRepG0[state]); -+ if (repIndex == 1) -+ price += GET_PRICE_0(p->isRepG1[state]); -+ else -+ { -+ price += GET_PRICE_1(p->isRepG1[state]); -+ price += GET_PRICE(p->isRepG2[state], repIndex - 2); -+ } -+ } -+ return price; -+} -+ -+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -+{ -+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + -+ GetPureRepPrice(p, repIndex, state, posState); -+} -+ -+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -+{ -+ UInt32 posMem = p->opt[cur].posPrev; -+ UInt32 backMem = p->opt[cur].backPrev; -+ p->optimumEndIndex = cur; -+ do -+ { -+ if (p->opt[cur].prev1IsChar) -+ { -+ MakeAsChar(&p->opt[posMem]) -+ p->opt[posMem].posPrev = posMem - 1; -+ if (p->opt[cur].prev2) -+ { -+ p->opt[posMem - 1].prev1IsChar = False; -+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; -+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; -+ } -+ } -+ { -+ UInt32 posPrev = posMem; -+ UInt32 backCur = backMem; -+ -+ backMem = p->opt[posPrev].backPrev; -+ posMem = p->opt[posPrev].posPrev; -+ -+ p->opt[posPrev].backPrev = backCur; -+ p->opt[posPrev].posPrev = cur; -+ cur = posPrev; -+ } -+ } -+ while (cur != 0); -+ *backRes = p->opt[0].backPrev; -+ p->optimumCurrentIndex = p->opt[0].posPrev; -+ return p->optimumCurrentIndex; -+} -+ -+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -+ -+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; -+ UInt32 matchPrice, repMatchPrice, normalMatchPrice; -+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; -+ UInt32 *matches = NULL; -+ const Byte *data = NULL; -+ Byte curByte, matchByte; -+ if (p->optimumEndIndex != p->optimumCurrentIndex) -+ { -+ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; -+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; -+ *backRes = opt->backPrev; -+ p->optimumCurrentIndex = opt->posPrev; -+ return lenRes; -+ } -+ p->optimumCurrentIndex = p->optimumEndIndex = 0; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ if (numAvail < 2) -+ { -+ *backRes = (UInt32)(-1); -+ return 1; -+ } -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ repMaxIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 lenTest; -+ const Byte *data2 = NULL; -+ reps[i] = p->reps[i]; -+ data2 = data - (reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ { -+ repLens[i] = 0; -+ continue; -+ } -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ repLens[i] = lenTest; -+ if (lenTest > repLens[repMaxIndex]) -+ repMaxIndex = i; -+ } -+ if (repLens[repMaxIndex] >= p->numFastBytes) -+ { -+ UInt32 lenRes; -+ *backRes = repMaxIndex; -+ lenRes = repLens[repMaxIndex]; -+ MovePos(p, lenRes - 1); -+ return lenRes; -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) -+ { -+ *backRes = (UInt32)-1; -+ return 1; -+ } -+ -+ p->opt[0].state = (CState)p->state; -+ -+ posState = (position & p->pbMask); -+ -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + -+ (!IsCharState(p->state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ MakeAsChar(&p->opt[1]); -+ -+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); -+ -+ if (matchByte == curByte) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); -+ if (shortRepPrice < p->opt[1].price) -+ { -+ p->opt[1].price = shortRepPrice; -+ MakeAsShortRep(&p->opt[1]); -+ } -+ } -+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); -+ -+ if (lenEnd < 2) -+ { -+ *backRes = p->opt[1].backPrev; -+ return 1; -+ } -+ -+ p->opt[1].posPrev = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ p->opt[0].backs[i] = reps[i]; -+ -+ len = lenEnd; -+ do -+ p->opt[len--].price = kInfinityPrice; -+ while (len >= 2); -+ -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 repLen = repLens[i]; -+ UInt32 price; -+ if (repLen < 2) -+ continue; -+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; -+ COptimal *opt = &p->opt[repLen]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = i; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--repLen >= 2); -+ } -+ -+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); -+ -+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); -+ if (len <= mainLen) -+ { -+ UInt32 offs = 0; -+ while (len > matches[offs]) -+ offs += 2; -+ for (; ; len++) -+ { -+ COptimal *opt = NULL; -+ UInt32 distance = matches[offs + 1]; -+ -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(len); -+ if (distance < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; -+ else -+ { -+ UInt32 slot; -+ GetPosSlot2(distance, slot); -+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; -+ } -+ opt = &p->opt[len]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = distance + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ if (len == matches[offs]) -+ { -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ } -+ } -+ } -+ -+ cur = 0; -+ -+ #ifdef SHOW_STAT2 -+ if (position >= 0) -+ { -+ unsigned i; -+ printf("\n pos = %4X", position); -+ for (i = cur; i <= lenEnd; i++) -+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); -+ } -+ #endif -+ -+ for (;;) -+ { -+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; -+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; -+ Bool nextIsChar; -+ Byte curByte, matchByte; -+ const Byte *data = NULL; -+ COptimal *curOpt = NULL; -+ COptimal *nextOpt = NULL; -+ -+ cur++; -+ if (cur == lenEnd) -+ return Backward(p, backRes, cur); -+ -+ newLen = ReadMatchDistances(p, &numPairs); -+ if (newLen >= p->numFastBytes) -+ { -+ p->numPairs = numPairs; -+ p->longestMatchLength = newLen; -+ return Backward(p, backRes, cur); -+ } -+ position++; -+ curOpt = &p->opt[cur]; -+ posPrev = curOpt->posPrev; -+ if (curOpt->prev1IsChar) -+ { -+ posPrev--; -+ if (curOpt->prev2) -+ { -+ state = p->opt[curOpt->posPrev2].state; -+ if (curOpt->backPrev2 < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ state = kLiteralNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ if (posPrev == cur - 1) -+ { -+ if (IsShortRep(curOpt)) -+ state = kShortRepNextStates[state]; -+ else -+ state = kLiteralNextStates[state]; -+ } -+ else -+ { -+ UInt32 pos; -+ const COptimal *prevOpt = NULL; -+ if (curOpt->prev1IsChar && curOpt->prev2) -+ { -+ posPrev = curOpt->posPrev2; -+ pos = curOpt->backPrev2; -+ state = kRepNextStates[state]; -+ } -+ else -+ { -+ pos = curOpt->backPrev; -+ if (pos < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ prevOpt = &p->opt[posPrev]; -+ if (pos < LZMA_NUM_REPS) -+ { -+ UInt32 i; -+ reps[0] = prevOpt->backs[pos]; -+ for (i = 1; i <= pos; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ for (; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i]; -+ } -+ else -+ { -+ UInt32 i; -+ reps[0] = (pos - LZMA_NUM_REPS); -+ for (i = 1; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ } -+ } -+ curOpt->state = (CState)state; -+ -+ curOpt->backs[0] = reps[0]; -+ curOpt->backs[1] = reps[1]; -+ curOpt->backs[2] = reps[2]; -+ curOpt->backs[3] = reps[3]; -+ -+ curPrice = curOpt->price; -+ nextIsChar = False; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ posState = (position & p->pbMask); -+ -+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ curAnd1Price += -+ (!IsCharState(state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ nextOpt = &p->opt[cur + 1]; -+ -+ if (curAnd1Price < nextOpt->price) -+ { -+ nextOpt->price = curAnd1Price; -+ nextOpt->posPrev = cur; -+ MakeAsChar(nextOpt); -+ nextIsChar = True; -+ } -+ -+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); -+ -+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); -+ if (shortRepPrice <= nextOpt->price) -+ { -+ nextOpt->price = shortRepPrice; -+ nextOpt->posPrev = cur; -+ MakeAsShortRep(nextOpt); -+ nextIsChar = True; -+ } -+ } -+ numAvailFull = p->numAvail; -+ { -+ UInt32 temp = kNumOpts - 1 - cur; -+ if (temp < numAvailFull) -+ numAvailFull = temp; -+ } -+ -+ if (numAvailFull < 2) -+ continue; -+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); -+ -+ if (!nextIsChar && matchByte != curByte) /* speed optimization */ -+ { -+ /* try Literal + rep0 */ -+ UInt32 temp; -+ UInt32 lenTest2; -+ const Byte *data2 = data - (reps[0] + 1); -+ UInt32 limit = p->numFastBytes + 1; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ -+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); -+ lenTest2 = temp - 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kLiteralNextStates[state]; -+ UInt32 posStateNext = (position + 1) & p->pbMask; -+ UInt32 nextRepMatchPrice = curAnd1Price + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = False; -+ } -+ } -+ } -+ } -+ -+ startLen = 2; /* speed optimization */ -+ { -+ UInt32 repIndex; -+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) -+ { -+ UInt32 lenTest; -+ UInt32 lenTestTemp; -+ UInt32 price; -+ const Byte *data2 = data - (reps[repIndex] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ while (lenEnd < cur + lenTest) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ lenTestTemp = lenTest; -+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; -+ COptimal *opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = repIndex; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--lenTest >= 2); -+ lenTest = lenTestTemp; -+ -+ if (repIndex == 0) -+ startLen = lenTest + 1; -+ -+ /* if (_maxMode) */ -+ { -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kRepNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = -+ price + p->repLenEnc.prices[posState][lenTest - 2] + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (position + lenTest + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = repIndex; -+ } -+ } -+ } -+ } -+ } -+ } -+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ -+ if (newLen > numAvail) -+ { -+ newLen = numAvail; -+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); -+ matches[numPairs] = newLen; -+ numPairs += 2; -+ } -+ if (newLen >= startLen) -+ { -+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); -+ UInt32 offs, curBack, posSlot; -+ UInt32 lenTest; -+ while (lenEnd < cur + newLen) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ -+ offs = 0; -+ while (startLen > matches[offs]) -+ offs += 2; -+ curBack = matches[offs + 1]; -+ GetPosSlot2(curBack, posSlot); -+ for (lenTest = /*2*/ startLen; ; lenTest++) -+ { -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(lenTest); -+ COptimal *opt = NULL; -+ if (curBack < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; -+ else -+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; -+ -+ opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = curBack + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ -+ if (/*_maxMode && */lenTest == matches[offs]) -+ { -+ /* Try Match + Literal + Rep0 */ -+ const Byte *data2 = data - (curBack + 1); -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kMatchNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = curAndLenPrice + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (posStateNext + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = curBack + LZMA_NUM_REPS; -+ } -+ } -+ } -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ curBack = matches[offs + 1]; -+ if (curBack >= kNumFullDistances) -+ GetPosSlot2(curBack, posSlot); -+ } -+ } -+ } -+ } -+} -+ -+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) -+ -+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; -+ const Byte *data = NULL; -+ const UInt32 *matches = NULL; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ *backRes = (UInt32)-1; -+ if (numAvail < 2) -+ return 1; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ -+ repLen = repIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (len = 2; len < numAvail && data[len] == data2[len]; len++); -+ if (len >= p->numFastBytes) -+ { -+ *backRes = i; -+ MovePos(p, len - 1); -+ return len; -+ } -+ if (len > repLen) -+ { -+ repIndex = i; -+ repLen = len; -+ } -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ -+ mainDist = 0; /* for GCC */ -+ if (mainLen >= 2) -+ { -+ mainDist = matches[numPairs - 1]; -+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) -+ { -+ if (!ChangePair(matches[numPairs - 3], mainDist)) -+ break; -+ numPairs -= 2; -+ mainLen = matches[numPairs - 2]; -+ mainDist = matches[numPairs - 1]; -+ } -+ if (mainLen == 2 && mainDist >= 0x80) -+ mainLen = 1; -+ } -+ -+ if (repLen >= 2 && ( -+ (repLen + 1 >= mainLen) || -+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || -+ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) -+ { -+ *backRes = repIndex; -+ MovePos(p, repLen - 1); -+ return repLen; -+ } -+ -+ if (mainLen < 2 || numAvail <= 2) -+ return 1; -+ -+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); -+ if (p->longestMatchLength >= 2) -+ { -+ UInt32 newDistance = matches[p->numPairs - 1]; -+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || -+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || -+ (p->longestMatchLength > mainLen + 1) || -+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) -+ return 1; -+ } -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len, limit; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ limit = mainLen - 1; -+ for (len = 2; len < limit && data[len] == data2[len]; len++); -+ if (len >= limit) -+ return 1; -+ } -+ *backRes = mainDist + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 2); -+ return mainLen; -+} -+ -+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -+{ -+ UInt32 len; -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ len = LZMA_MATCH_LEN_MIN; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); -+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -+} -+ -+static SRes CheckErrors(CLzmaEnc *p) -+{ -+ if (p->result != SZ_OK) -+ return p->result; -+ if (p->rc.res != SZ_OK) -+ p->result = SZ_ERROR_WRITE; -+ if (p->matchFinderBase.result != SZ_OK) -+ p->result = SZ_ERROR_READ; -+ if (p->result != SZ_OK) -+ p->finished = True; -+ return p->result; -+} -+ -+static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -+{ -+ /* ReleaseMFStream(); */ -+ p->finished = True; -+ if (p->writeEndMark) -+ WriteEndMarker(p, nowPos & p->pbMask); -+ RangeEnc_FlushData(&p->rc); -+ RangeEnc_FlushStream(&p->rc); -+ return CheckErrors(p); -+} -+ -+static void FillAlignPrices(CLzmaEnc *p) -+{ -+ UInt32 i; -+ for (i = 0; i < kAlignTableSize; i++) -+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); -+ p->alignPriceCount = 0; -+} -+ -+static void FillDistancesPrices(CLzmaEnc *p) -+{ -+ UInt32 tempPrices[kNumFullDistances]; -+ UInt32 i, lenToPosState; -+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) -+ { -+ UInt32 posSlot = GetPosSlot1(i); -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); -+ } -+ -+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) -+ { -+ UInt32 posSlot; -+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; -+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; -+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); -+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); -+ -+ { -+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; -+ UInt32 i; -+ for (i = 0; i < kStartPosModelIndex; i++) -+ distancesPrices[i] = posSlotPrices[i]; -+ for (; i < kNumFullDistances; i++) -+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; -+ } -+ } -+ p->matchPriceCount = 0; -+} -+ -+void LzmaEnc_Construct(CLzmaEnc *p) -+{ -+ RangeEnc_Construct(&p->rc); -+ MatchFinder_Construct(&p->matchFinderBase); -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Construct(&p->matchFinderMt); -+ p->matchFinderMt.MatchFinder = &p->matchFinderBase; -+ #endif -+ -+ { -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ LzmaEnc_SetProps(p, &props); -+ } -+ -+ #ifndef LZMA_LOG_BSR -+ LzmaEnc_FastPosInit(p->g_FastPos); -+ #endif -+ -+ LzmaEnc_InitPriceTables(p->ProbPrices); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -+{ -+ void *p; -+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); -+ if (p != 0) -+ LzmaEnc_Construct((CLzmaEnc *)p); -+ return p; -+} -+ -+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->litProbs); -+ alloc->Free(alloc, p->saveState.litProbs); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -+ #endif -+ MatchFinder_Free(&p->matchFinderBase, allocBig); -+ LzmaEnc_FreeLits(p, alloc); -+ RangeEnc_Free(&p->rc, alloc); -+} -+ -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); -+ alloc->Free(alloc, p); -+} -+ -+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -+{ -+ UInt32 nowPos32, startPos32; -+ if (p->needInit) -+ { -+ p->matchFinder.Init(p->matchFinderObj); -+ p->needInit = 0; -+ } -+ -+ if (p->finished) -+ return p->result; -+ RINOK(CheckErrors(p)); -+ -+ nowPos32 = (UInt32)p->nowPos64; -+ startPos32 = nowPos32; -+ -+ if (p->nowPos64 == 0) -+ { -+ UInt32 numPairs; -+ Byte curByte; -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ return Flush(p, nowPos32); -+ ReadMatchDistances(p, &numPairs); -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); -+ p->state = kLiteralNextStates[p->state]; -+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); -+ LitEnc_Encode(&p->rc, p->litProbs, curByte); -+ p->additionalOffset--; -+ nowPos32++; -+ } -+ -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) -+ for (;;) -+ { -+ UInt32 pos, len, posState; -+ -+ if (p->fastMode) -+ len = GetOptimumFast(p, &pos); -+ else -+ len = GetOptimum(p, nowPos32, &pos); -+ -+ #ifdef SHOW_STAT2 -+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); -+ #endif -+ -+ posState = nowPos32 & p->pbMask; -+ if (len == 1 && pos == (UInt32)-1) -+ { -+ Byte curByte; -+ CLzmaProb *probs = NULL; -+ const Byte *data = NULL; -+ -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+ curByte = *data; -+ probs = LIT_PROBS(nowPos32, *(data - 1)); -+ if (IsCharState(p->state)) -+ LitEnc_Encode(&p->rc, probs, curByte); -+ else -+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); -+ p->state = kLiteralNextStates[p->state]; -+ } -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ if (pos < LZMA_NUM_REPS) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); -+ if (pos == 0) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); -+ } -+ else -+ { -+ UInt32 distance = p->reps[pos]; -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); -+ if (pos == 1) -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); -+ if (pos == 3) -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ } -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = distance; -+ } -+ if (len == 1) -+ p->state = kShortRepNextStates[p->state]; -+ else -+ { -+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ p->state = kRepNextStates[p->state]; -+ } -+ } -+ else -+ { -+ UInt32 posSlot; -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ pos -= LZMA_NUM_REPS; -+ GetPosSlot(pos, posSlot); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); -+ -+ if (posSlot >= kStartPosModelIndex) -+ { -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ UInt32 posReduced = pos - base; -+ -+ if (posSlot < kEndPosModelIndex) -+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); -+ else -+ { -+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); -+ p->alignPriceCount++; -+ } -+ } -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = pos; -+ p->matchPriceCount++; -+ } -+ } -+ p->additionalOffset -= len; -+ nowPos32 += len; -+ if (p->additionalOffset == 0) -+ { -+ UInt32 processed; -+ if (!p->fastMode) -+ { -+ if (p->matchPriceCount >= (1 << 7)) -+ FillDistancesPrices(p); -+ if (p->alignPriceCount >= kAlignTableSize) -+ FillAlignPrices(p); -+ } -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ break; -+ processed = nowPos32 - startPos32; -+ if (useLimits) -+ { -+ if (processed + kNumOpts + 300 >= maxUnpackSize || -+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) -+ break; -+ } -+ else if (processed >= (1 << 15)) -+ { -+ p->nowPos64 += nowPos32 - startPos32; -+ return CheckErrors(p); -+ } -+ } -+ } -+ p->nowPos64 += nowPos32 - startPos32; -+ return Flush(p, nowPos32); -+} -+ -+#define kBigHashDicLimit ((UInt32)1 << 24) -+ -+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 beforeSize = kNumOpts; -+ Bool btMode; -+ if (!RangeEnc_Alloc(&p->rc, alloc)) -+ return SZ_ERROR_MEM; -+ btMode = (p->matchFinderBase.btMode != 0); -+ #ifndef _7ZIP_ST -+ p->mtMode = (p->multiThread && !p->fastMode && btMode); -+ #endif -+ -+ { -+ unsigned lclp = p->lc + p->lp; -+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ if (p->litProbs == 0 || p->saveState.litProbs == 0) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ p->lclp = lclp; -+ } -+ } -+ -+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); -+ -+ if (beforeSize + p->dictSize < keepWindowSize) -+ beforeSize = keepWindowSize - p->dictSize; -+ -+ #ifndef _7ZIP_ST -+ if (p->mtMode) -+ { -+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); -+ p->matchFinderObj = &p->matchFinderMt; -+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); -+ } -+ else -+ #endif -+ { -+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) -+ return SZ_ERROR_MEM; -+ p->matchFinderObj = &p->matchFinderBase; -+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); -+ } -+ return SZ_OK; -+} -+ -+void LzmaEnc_Init(CLzmaEnc *p) -+{ -+ UInt32 i; -+ p->state = 0; -+ for (i = 0 ; i < LZMA_NUM_REPS; i++) -+ p->reps[i] = 0; -+ -+ RangeEnc_Init(&p->rc); -+ -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ UInt32 j; -+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) -+ { -+ p->isMatch[i][j] = kProbInitValue; -+ p->isRep0Long[i][j] = kProbInitValue; -+ } -+ p->isRep[i] = kProbInitValue; -+ p->isRepG0[i] = kProbInitValue; -+ p->isRepG1[i] = kProbInitValue; -+ p->isRepG2[i] = kProbInitValue; -+ } -+ -+ { -+ UInt32 num = 0x300 << (p->lp + p->lc); -+ for (i = 0; i < num; i++) -+ p->litProbs[i] = kProbInitValue; -+ } -+ -+ { -+ for (i = 0; i < kNumLenToPosStates; i++) -+ { -+ CLzmaProb *probs = p->posSlotEncoder[i]; -+ UInt32 j; -+ for (j = 0; j < (1 << kNumPosSlotBits); j++) -+ probs[j] = kProbInitValue; -+ } -+ } -+ { -+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) -+ p->posEncoders[i] = kProbInitValue; -+ } -+ -+ LenEnc_Init(&p->lenEnc.p); -+ LenEnc_Init(&p->repLenEnc.p); -+ -+ for (i = 0; i < (1 << kNumAlignBits); i++) -+ p->posAlignEncoder[i] = kProbInitValue; -+ -+ p->optimumEndIndex = 0; -+ p->optimumCurrentIndex = 0; -+ p->additionalOffset = 0; -+ -+ p->pbMask = (1 << p->pb) - 1; -+ p->lpMask = (1 << p->lp) - 1; -+} -+ -+void LzmaEnc_InitPrices(CLzmaEnc *p) -+{ -+ if (!p->fastMode) -+ { -+ FillDistancesPrices(p); -+ FillAlignPrices(p); -+ } -+ -+ p->lenEnc.tableSize = -+ p->repLenEnc.tableSize = -+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; -+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); -+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -+} -+ -+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 i; -+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) -+ if (p->dictSize <= ((UInt32)1 << i)) -+ break; -+ p->distTableSize = i * 2; -+ -+ p->finished = False; -+ p->result = SZ_OK; -+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ p->nowPos64 = 0; -+ return SZ_OK; -+} -+ -+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ p->rc.outStream = outStream; -+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -+} -+ -+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -+ ISeqInStream *inStream, UInt32 keepWindowSize, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -+{ -+ p->matchFinderBase.directInput = 1; -+ p->matchFinderBase.bufferBase = (Byte *)src; -+ p->matchFinderBase.directInputRem = srcLen; -+} -+ -+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ p->needInit = 1; -+ -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+void LzmaEnc_Finish(CLzmaEncHandle pp) -+{ -+ #ifndef _7ZIP_ST -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ if (p->mtMode) -+ MatchFinderMt_ReleaseStream(&p->matchFinderMt); -+ #else -+ (void)pp; -+ #endif -+} -+ -+typedef struct -+{ -+ ISeqOutStream funcTable; -+ Byte *data; -+ SizeT rem; -+ Bool overflow; -+} CSeqOutStreamBuf; -+ -+static size_t MyWrite(void *pp, const void *data, size_t size) -+{ -+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; -+ if (p->rem < size) -+ { -+ size = p->rem; -+ p->overflow = True; -+ } -+ memcpy(p->data, data, size); -+ p->rem -= size; -+ p->data += size; -+ return size; -+} -+ -+ -+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+} -+ -+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+} -+ -+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ UInt64 nowPos64; -+ SRes res; -+ CSeqOutStreamBuf outStream; -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = False; -+ p->finished = False; -+ p->result = SZ_OK; -+ -+ if (reInit) -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ nowPos64 = p->nowPos64; -+ RangeEnc_Init(&p->rc); -+ p->rc.outStream = &outStream.funcTable; -+ -+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -+ -+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ -+ return res; -+} -+ -+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -+{ -+ SRes res = SZ_OK; -+ -+ #ifndef _7ZIP_ST -+ Byte allocaDummy[0x300]; -+ int i = 0; -+ for (i = 0; i < 16; i++) -+ allocaDummy[i] = (Byte)i; -+ #endif -+ -+ for (;;) -+ { -+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); -+ if (res != SZ_OK || p->finished != 0) -+ break; -+ if (progress != 0) -+ { -+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); -+ if (res != SZ_OK) -+ { -+ res = SZ_ERROR_PROGRESS; -+ break; -+ } -+ } -+ } -+ LzmaEnc_Finish(p); -+ return res; -+} -+ -+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -+ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -+} -+ -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ int i; -+ UInt32 dictSize = p->dictSize; -+ if (*size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_PARAM; -+ *size = LZMA_PROPS_SIZE; -+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); -+ -+ for (i = 11; i <= 30; i++) -+ { -+ if (dictSize <= ((UInt32)2 << i)) -+ { -+ dictSize = (2 << i); -+ break; -+ } -+ if (dictSize <= ((UInt32)3 << i)) -+ { -+ dictSize = (3 << i); -+ break; -+ } -+ } -+ -+ for (i = 0; i < 4; i++) -+ props[1 + i] = (Byte)(dictSize >> (8 * i)); -+ return SZ_OK; -+} -+ -+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ SRes res; -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ -+ CSeqOutStreamBuf outStream; -+ -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = writeEndMark; -+ -+ p->rc.outStream = &outStream.funcTable; -+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); -+ if (res == SZ_OK) -+ res = LzmaEnc_Encode2(p, progress); -+ -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ return res; -+} -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -+ SRes res; -+ if (p == 0) -+ return SZ_ERROR_MEM; -+ -+ res = LzmaEnc_SetProps(p, props); -+ if (res == SZ_OK) -+ { -+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -+ if (res == SZ_OK) -+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -+ writeEndMark, progress, alloc, allocBig); -+ } -+ -+ LzmaEnc_Destroy(p, alloc, allocBig); -+ return res; -+} ---- linux-4.9.37/lib/lzma/Makefile 1970-01-01 03:00:00.000000000 +0300 -+++ linux-4.9.y/lib/lzma/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -0,0 +1,7 @@ -+lzma_compress-objs := LzFind.o LzmaEnc.o -+lzma_decompress-objs := LzmaDec.o -+ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o -+ -+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h ---- linux-4.9.37/lib/Makefile 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/lib/Makefile 2021-06-07 13:01:34.000000000 +0300 -@@ -1,6 +1,15 @@ - # - # Makefile for some libs needed in the kernel. - # -+ifdef CONFIG_JFFS2_ZLIB -+ CONFIG_ZLIB_INFLATE:=y -+ CONFIG_ZLIB_DEFLATE:=y -+endif -+ -+ifdef CONFIG_JFFS2_LZMA -+ CONFIG_LZMA_DECOMPRESS:=y -+ CONFIG_LZMA_COMPRESS:=y -+endif - - ifdef CONFIG_FUNCTION_TRACER - ORIG_CFLAGS := $(KBUILD_CFLAGS) -@@ -108,6 +117,8 @@ - obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ - obj-$(CONFIG_XZ_DEC) += xz/ - obj-$(CONFIG_RAID6_PQ) += raid6/ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma/ -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ - - lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o - lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o ---- linux-4.9.37/mm/init-mm.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/mm/init-mm.c 2021-06-07 13:01:34.000000000 +0300 -@@ -25,3 +25,5 @@ - .user_ns = &init_user_ns, - INIT_MM_CONTEXT(init_mm) - }; -+ -+EXPORT_SYMBOL(init_mm); ---- linux-4.9.37/mm/page_alloc.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/mm/page_alloc.c 2021-06-07 13:01:34.000000000 +0300 -@@ -7335,7 +7335,7 @@ - - /* Make sure the range is really isolated. */ - if (test_pages_isolated(outer_start, end, false)) { -- pr_info("%s: [%lx, %lx) PFNs busy\n", -+ pr_warn_once("%s: [%lx, %lx) PFNs busy\n", - __func__, outer_start, end); - ret = -EBUSY; - goto done; ---- linux-4.9.37/net/core/net_namespace.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/core/net_namespace.c 2021-06-07 13:01:34.000000000 +0300 -@@ -263,7 +263,7 @@ - spin_lock_irqsave(&net->nsid_lock, flags); - peer = idr_find(&net->netns_ids, id); - if (peer) -- get_net(peer); -+ peer = maybe_get_net(peer); - spin_unlock_irqrestore(&net->nsid_lock, flags); - rcu_read_unlock(); - ---- linux-4.9.37/net/ipv4/cipso_ipv4.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/cipso_ipv4.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1271,7 +1271,8 @@ - return ret_val; - } - -- secattr->flags |= NETLBL_SECATTR_MLS_CAT; -+ if (secattr->attr.mls.cat) -+ secattr->flags |= NETLBL_SECATTR_MLS_CAT; - } - - return 0; -@@ -1452,7 +1453,8 @@ - return ret_val; - } - -- secattr->flags |= NETLBL_SECATTR_MLS_CAT; -+ if (secattr->attr.mls.cat) -+ secattr->flags |= NETLBL_SECATTR_MLS_CAT; - } - - return 0; ---- linux-4.9.37/net/ipv4/ip_output.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/ip_output.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1260,7 +1260,7 @@ - if (skb->ip_summed != CHECKSUM_PARTIAL) - return -EOPNOTSUPP; - -- skb_shinfo(skb)->gso_size = mtu - fragheaderlen; -+ skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; - skb_shinfo(skb)->gso_type = SKB_GSO_UDP; - } - cork->length += size; ---- linux-4.9.37/net/ipv4/proc.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/proc.c 2021-06-07 13:01:34.000000000 +0300 -@@ -305,6 +305,7 @@ - SNMP_MIB_ITEM("TCPKeepAlive", LINUX_MIB_TCPKEEPALIVE), - SNMP_MIB_ITEM("TCPMTUPFail", LINUX_MIB_TCPMTUPFAIL), - SNMP_MIB_ITEM("TCPMTUPSuccess", LINUX_MIB_TCPMTUPSUCCESS), -+ SNMP_MIB_ITEM("TCPWqueueTooBig", LINUX_MIB_TCPWQUEUETOOBIG), - SNMP_MIB_SENTINEL - }; - ---- linux-4.9.37/net/ipv4/sysctl_net_ipv4.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/sysctl_net_ipv4.c 2021-06-07 13:01:34.000000000 +0300 -@@ -35,6 +35,8 @@ - static int ip_local_port_range_max[] = { 65535, 65535 }; - static int tcp_adv_win_scale_min = -31; - static int tcp_adv_win_scale_max = 31; -+static int tcp_min_snd_mss_min = TCP_MIN_SND_MSS; -+static int tcp_min_snd_mss_max = 65535; - static int ip_ttl_min = 1; - static int ip_ttl_max = 255; - static int tcp_syn_retries_min = 1; -@@ -827,6 +829,15 @@ - .proc_handler = proc_dointvec, - }, - { -+ .procname = "tcp_min_snd_mss", -+ .data = &init_net.ipv4.sysctl_tcp_min_snd_mss, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = proc_dointvec_minmax, -+ .extra1 = &tcp_min_snd_mss_min, -+ .extra2 = &tcp_min_snd_mss_max, -+ }, -+ { - .procname = "tcp_probe_threshold", - .data = &init_net.ipv4.sysctl_tcp_probe_threshold, - .maxlen = sizeof(int), ---- linux-4.9.37/net/ipv4/tcp.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/tcp.c 2021-06-07 13:01:34.000000000 +0300 -@@ -3289,6 +3289,7 @@ - unsigned long limit; - unsigned int i; - -+ BUILD_BUG_ON(TCP_MIN_SND_MSS <= MAX_TCP_OPTION_SPACE); - BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > - FIELD_SIZEOF(struct sk_buff, cb)); - ---- linux-4.9.37/net/ipv4/tcp_input.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/tcp_input.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1312,7 +1312,7 @@ - TCP_SKB_CB(skb)->seq += shifted; - - tcp_skb_pcount_add(prev, pcount); -- BUG_ON(tcp_skb_pcount(skb) < pcount); -+ WARN_ON_ONCE(tcp_skb_pcount(skb) < pcount); - tcp_skb_pcount_add(skb, -pcount); - - /* When we're adding to gso_segs == 1, gso_size will be zero, -@@ -1379,6 +1379,21 @@ - return !skb_headlen(skb) && skb_is_nonlinear(skb); - } - -+int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, -+ int pcount, int shiftlen) -+{ -+ /* TCP min gso_size is 8 bytes (TCP_MIN_GSO_SIZE) -+ * Since TCP_SKB_CB(skb)->tcp_gso_segs is 16 bits, we need -+ * to make sure not storing more than 65535 * 8 bytes per skb, -+ * even if current MSS is bigger. -+ */ -+ if (unlikely(to->len + shiftlen >= 65535 * TCP_MIN_GSO_SIZE)) -+ return 0; -+ if (unlikely(tcp_skb_pcount(to) + pcount > 65535)) -+ return 0; -+ return skb_shift(to, from, shiftlen); -+} -+ - /* Try collapsing SACK blocks spanning across multiple skbs to a single - * skb. - */ -@@ -1390,6 +1405,7 @@ - struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *prev; - int mss; -+ int next_pcount; - int pcount = 0; - int len; - int in_sack; -@@ -1487,7 +1503,7 @@ - if (!after(TCP_SKB_CB(skb)->seq + len, tp->snd_una)) - goto fallback; - -- if (!skb_shift(prev, skb, len)) -+ if (!tcp_skb_shift(prev, skb, pcount, len)) - goto fallback; - if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss, dup_sack)) - goto out; -@@ -1506,11 +1522,11 @@ - goto out; - - len = skb->len; -- if (skb_shift(prev, skb, len)) { -- pcount += tcp_skb_pcount(skb); -- tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss, 0); -+ next_pcount = tcp_skb_pcount(skb); -+ if (tcp_skb_shift(prev, skb, next_pcount, len)) { -+ pcount += next_pcount; -+ tcp_shifted_skb(sk, skb, state, next_pcount, len, mss, 0); - } -- - out: - state->fack_count += pcount; - return prev; -@@ -4949,6 +4965,7 @@ - * 2) not add too big latencies if thousands of packets sit there. - * (But if application shrinks SO_RCVBUF, we could still end up - * freeing whole queue here) -+ * 3) Drop at least 12.5 % of sk_rcvbuf to avoid malicious attacks. - * - * Return true if queue has shrunk. - */ -@@ -4956,20 +4973,26 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - struct rb_node *node, *prev; -+ int goal; - - if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) - return false; - - NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED); -+ goal = sk->sk_rcvbuf >> 3; - node = &tp->ooo_last_skb->rbnode; - do { - prev = rb_prev(node); - rb_erase(node, &tp->out_of_order_queue); -+ goal -= rb_entry_safe(node, struct sk_buff, rbnode)->truesize; - tcp_drop(sk, rb_entry(node, struct sk_buff, rbnode)); -- sk_mem_reclaim(sk); -- if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && -- !tcp_under_memory_pressure(sk)) -- break; -+ if (!prev || goal <= 0) { -+ sk_mem_reclaim(sk); -+ if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && -+ !tcp_under_memory_pressure(sk)) -+ break; -+ goal = sk->sk_rcvbuf >> 3; -+ } - node = prev; - } while (node); - tp->ooo_last_skb = rb_entry(prev, struct sk_buff, rbnode); ---- linux-4.9.37/net/ipv4/tcp_ipv4.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/tcp_ipv4.c 2021-06-07 13:01:34.000000000 +0300 -@@ -2440,6 +2440,7 @@ - net->ipv4.sysctl_tcp_ecn_fallback = 1; - - net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; -+ net->ipv4.sysctl_tcp_min_snd_mss = TCP_MIN_SND_MSS; - net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; - net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; - ---- linux-4.9.37/net/ipv4/tcp_output.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/tcp_output.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1170,6 +1170,11 @@ - if (nsize < 0) - nsize = 0; - -+ if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) { -+ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); -+ return -ENOMEM; -+ } -+ - if (skb_unclone(skb, gfp)) - return -ENOMEM; - -@@ -1340,8 +1345,7 @@ - mss_now -= icsk->icsk_ext_hdr_len; - - /* Then reserve room for full set of TCP options and 8 bytes of data */ -- if (mss_now < 48) -- mss_now = 48; -+ mss_now = max(mss_now, sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss); - return mss_now; - } - ---- linux-4.9.37/net/ipv4/tcp_timer.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv4/tcp_timer.c 2021-06-07 13:01:34.000000000 +0300 -@@ -125,6 +125,7 @@ - mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1; - mss = min(net->ipv4.sysctl_tcp_base_mss, mss); - mss = max(mss, 68 - tp->tcp_header_len); -+ mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss); - icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss); - tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); - } ---- linux-4.9.37/net/ipv6/calipso.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv6/calipso.c 2021-06-07 13:01:34.000000000 +0300 -@@ -1062,7 +1062,8 @@ - goto getattr_return; - } - -- secattr->flags |= NETLBL_SECATTR_MLS_CAT; -+ if (secattr->attr.mls.cat) -+ secattr->flags |= NETLBL_SECATTR_MLS_CAT; - } - - secattr->type = NETLBL_NLTYPE_CALIPSO; ---- linux-4.9.37/net/ipv6/output_core.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/ipv6/output_core.c 2021-06-07 13:01:34.000000000 +0300 -@@ -78,7 +78,7 @@ - - int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) - { -- u16 offset = sizeof(struct ipv6hdr); -+ unsigned int offset = sizeof(struct ipv6hdr); - unsigned int packet_len = skb_tail_pointer(skb) - - skb_network_header(skb); - int found_rhdr = 0; -@@ -86,6 +86,7 @@ - - while (offset <= packet_len) { - struct ipv6_opt_hdr *exthdr; -+ unsigned int len; - - switch (**nexthdr) { - -@@ -111,7 +112,10 @@ - - exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + - offset); -- offset += ipv6_optlen(exthdr); -+ len = ipv6_optlen(exthdr); -+ if (len + offset >= IPV6_MAXPLEN) -+ return -EINVAL; -+ offset += len; - *nexthdr = &exthdr->nexthdr; - } - ---- linux-4.9.37/net/netlabel/netlabel_kapi.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/net/netlabel/netlabel_kapi.c 2021-06-07 13:01:34.000000000 +0300 -@@ -748,6 +748,12 @@ - if ((off & (BITS_PER_LONG - 1)) != 0) - return -EINVAL; - -+ /* a null catmap is equivalent to an empty one */ -+ if (!catmap) { -+ *offset = (u32)-1; -+ return 0; -+ } -+ - if (off < catmap->startbit) { - off = catmap->startbit; - *offset = off; ---- linux-4.9.37/scripts/Makefile.clean 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/scripts/Makefile.clean 2021-06-07 13:01:34.000000000 +0300 -@@ -11,7 +11,7 @@ - - # The filename Kbuild has precedence over Makefile - kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) --include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) -+-include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) - - # Figure out what we need to build from the various variables - # ========================================================================== ---- linux-4.9.37/scripts/setlocalversion 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/scripts/setlocalversion 2021-06-07 13:01:34.000000000 +0300 -@@ -153,6 +153,7 @@ - res="$res$(collect_files "$srctree"/localversion*)" - fi - -+LOCALVERSION= - # CONFIG_LOCALVERSION and LOCALVERSION (if set) - res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}" - ---- linux-4.9.37/sound/usb/mixer.c 2017-07-12 16:42:41.000000000 +0300 -+++ linux-4.9.y/sound/usb/mixer.c 2021-06-07 13:01:34.000000000 +0300 -@@ -318,12 +318,15 @@ - - while (timeout-- > 0) { - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); -- if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, -- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, -- validx, idx, buf, val_len) >= val_len) { -+ err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, -+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, -+ validx, idx, buf, val_len); -+ if (err >= val_len) { - *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); - err = 0; - goto out; -+ } else if (err == -ETIMEDOUT) { -+ goto out; - } - } - usb_audio_dbg(chip, -@@ -483,12 +486,15 @@ - - while (timeout-- > 0) { - idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); -- if (snd_usb_ctl_msg(chip->dev, -- usb_sndctrlpipe(chip->dev, 0), request, -- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, -- validx, idx, buf, val_len) >= 0) { -+ err = snd_usb_ctl_msg(chip->dev, -+ usb_sndctrlpipe(chip->dev, 0), request, -+ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, -+ validx, idx, buf, val_len); -+ if (err >= 0) { - err = 0; - goto out; -+ } else if (err == -ETIMEDOUT) { -+ goto out; - } - } - usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7202v300-clock.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7202v300-clock.h.patch new file mode 100644 index 00000000..f355c868 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7202v300-clock.h.patch @@ -0,0 +1,79 @@ +--- linux-4.9.37/include/dt-bindings/clock/gk7202v300-clock.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/dt-bindings/clock/gk7202v300-clock.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,76 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __DTS_GK7202V300_CLOCK_H ++#define __DTS_GK7202V300_CLOCK_H ++ ++/* clk in GK7202V300 CRG */ ++/* fixed rate clocks */ ++#define GK7202V300_FIXED_100K 1 ++#define GK7202V300_FIXED_400K 2 ++#define GK7202V300_FIXED_3M 3 ++#define GK7202V300_FIXED_6M 4 ++#define GK7202V300_FIXED_12M 5 ++#define GK7202V300_FIXED_24M 6 ++#define GK7202V300_FIXED_25M 7 ++#define GK7202V300_FIXED_50M 8 ++#define GK7202V300_FIXED_83P3M 9 ++#define GK7202V300_FIXED_90M 10 ++#define GK7202V300_FIXED_100M 11 ++#define GK7202V300_FIXED_112M 12 ++#define GK7202V300_FIXED_125M 13 ++#define GK7202V300_FIXED_148P5M 14 ++#define GK7202V300_FIXED_150M 15 ++#define GK7202V300_FIXED_200M 16 ++#define GK7202V300_FIXED_250M 17 ++#define GK7202V300_FIXED_300M 18 ++#define GK7202V300_FIXED_324M 19 ++#define GK7202V300_FIXED_342M 20 ++#define GK7202V300_FIXED_375M 21 ++#define GK7202V300_FIXED_400M 22 ++#define GK7202V300_FIXED_448M 23 ++#define GK7202V300_FIXED_500M 24 ++#define GK7202V300_FIXED_540M 25 ++#define GK7202V300_FIXED_600M 26 ++#define GK7202V300_FIXED_750M 27 ++#define GK7202V300_FIXED_1000M 28 ++#define GK7202V300_FIXED_1500M 29 ++ ++/* mux clocks */ ++#define GK7202V300_SYSAXI_CLK 30 ++#define GK7202V300_SYSAPB_CLK 31 ++#define GK7202V300_FMC_MUX 32 ++#define GK7202V300_UART_MUX 33 ++#define GK7202V300_MMC0_MUX 34 ++#define GK7202V300_MMC1_MUX 35 ++#define GK7202V300_MMC2_MUX 36 ++#define GK7202V300_ETH_MUX 37 ++#define GK7202V300_USB2_MUX 80 ++/* gate clocks */ ++#define GK7202V300_UART0_CLK 40 ++#define GK7202V300_UART1_CLK 41 ++#define GK7202V300_UART2_CLK 42 ++#define GK7202V300_FMC_CLK 43 ++#define GK7202V300_ETH0_CLK 44 ++#define GK7202V300_EDMAC_AXICLK 45 ++#define GK7202V300_EDMAC_CLK 46 ++#define GK7202V300_SPI0_CLK 48 ++#define GK7202V300_SPI1_CLK 49 ++#define GK7202V300_MMC0_CLK 50 ++#define GK7202V300_MMC1_CLK 51 ++#define GK7202V300_MMC2_CLK 52 ++#define GK7202V300_I2C0_CLK 53 ++#define GK7202V300_I2C1_CLK 54 ++#define GK7202V300_I2C2_CLK 55 ++#define GK7202V300_USB2_BUS_CLK 81 ++#define GK7202V300_USB2_REF_CLK 82 ++#define GK7202V300_USB2_UTMI_CLK 83 ++#define GK7202V300_USB2_PHY_APB_CLK 84 ++#define GK7202V300_USB2_PHY_PLL_CLK 85 ++#define GK7202V300_USB2_PHY_XO_CLK 86 ++ ++#define GK7202V300_NR_CLKS 256 ++#define GK7202V300_NR_RSTS 256 ++ ++#endif /* __DTS_GK7202V300_CLOCK_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7205v200-clock.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7205v200-clock.h.patch new file mode 100644 index 00000000..6f90403e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7205v200-clock.h.patch @@ -0,0 +1,79 @@ +--- linux-4.9.37/include/dt-bindings/clock/gk7205v200-clock.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/dt-bindings/clock/gk7205v200-clock.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,76 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __DTS_GK7205V200_CLOCK_H ++#define __DTS_GK7205V200_CLOCK_H ++ ++/* clk in GK7205V200 CRG */ ++/* fixed rate clocks */ ++#define GK7205V200_FIXED_100K 1 ++#define GK7205V200_FIXED_400K 2 ++#define GK7205V200_FIXED_3M 3 ++#define GK7205V200_FIXED_6M 4 ++#define GK7205V200_FIXED_12M 5 ++#define GK7205V200_FIXED_24M 6 ++#define GK7205V200_FIXED_25M 7 ++#define GK7205V200_FIXED_50M 8 ++#define GK7205V200_FIXED_83P3M 9 ++#define GK7205V200_FIXED_90M 10 ++#define GK7205V200_FIXED_100M 11 ++#define GK7205V200_FIXED_112M 12 ++#define GK7205V200_FIXED_125M 13 ++#define GK7205V200_FIXED_148P5M 14 ++#define GK7205V200_FIXED_150M 15 ++#define GK7205V200_FIXED_200M 16 ++#define GK7205V200_FIXED_250M 17 ++#define GK7205V200_FIXED_300M 18 ++#define GK7205V200_FIXED_324M 19 ++#define GK7205V200_FIXED_342M 20 ++#define GK7205V200_FIXED_375M 21 ++#define GK7205V200_FIXED_400M 22 ++#define GK7205V200_FIXED_448M 23 ++#define GK7205V200_FIXED_500M 24 ++#define GK7205V200_FIXED_540M 25 ++#define GK7205V200_FIXED_600M 26 ++#define GK7205V200_FIXED_750M 27 ++#define GK7205V200_FIXED_1000M 28 ++#define GK7205V200_FIXED_1500M 29 ++ ++/* mux clocks */ ++#define GK7205V200_SYSAXI_CLK 30 ++#define GK7205V200_SYSAPB_CLK 31 ++#define GK7205V200_FMC_MUX 32 ++#define GK7205V200_UART_MUX 33 ++#define GK7205V200_MMC0_MUX 34 ++#define GK7205V200_MMC1_MUX 35 ++#define GK7205V200_MMC2_MUX 36 ++#define GK7205V200_ETH_MUX 37 ++#define GK7205V200_USB2_MUX 80 ++/* gate clocks */ ++#define GK7205V200_UART0_CLK 40 ++#define GK7205V200_UART1_CLK 41 ++#define GK7205V200_UART2_CLK 42 ++#define GK7205V200_FMC_CLK 43 ++#define GK7205V200_ETH0_CLK 44 ++#define GK7205V200_EDMAC_AXICLK 45 ++#define GK7205V200_EDMAC_CLK 46 ++#define GK7205V200_SPI0_CLK 48 ++#define GK7205V200_SPI1_CLK 49 ++#define GK7205V200_MMC0_CLK 50 ++#define GK7205V200_MMC1_CLK 51 ++#define GK7205V200_MMC2_CLK 52 ++#define GK7205V200_I2C0_CLK 53 ++#define GK7205V200_I2C1_CLK 54 ++#define GK7205V200_I2C2_CLK 55 ++#define GK7205V200_USB2_BUS_CLK 81 ++#define GK7205V200_USB2_REF_CLK 82 ++#define GK7205V200_USB2_UTMI_CLK 83 ++#define GK7205V200_USB2_PHY_APB_CLK 84 ++#define GK7205V200_USB2_PHY_PLL_CLK 85 ++#define GK7205V200_USB2_PHY_XO_CLK 86 ++ ++#define GK7205V200_NR_CLKS 256 ++#define GK7205V200_NR_RSTS 256 ++ ++#endif /* __DTS_GK7205V200_CLOCK_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7205v300-clock.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7205v300-clock.h.patch new file mode 100644 index 00000000..e069a4d9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7205v300-clock.h.patch @@ -0,0 +1,79 @@ +--- linux-4.9.37/include/dt-bindings/clock/gk7205v300-clock.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/dt-bindings/clock/gk7205v300-clock.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,76 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __DTS_GK7205V300_CLOCK_H ++#define __DTS_GK7205V300_CLOCK_H ++ ++/* clk in GK7205V300 CRG */ ++/* fixed rate clocks */ ++#define GK7205V300_FIXED_100K 1 ++#define GK7205V300_FIXED_400K 2 ++#define GK7205V300_FIXED_3M 3 ++#define GK7205V300_FIXED_6M 4 ++#define GK7205V300_FIXED_12M 5 ++#define GK7205V300_FIXED_24M 6 ++#define GK7205V300_FIXED_25M 7 ++#define GK7205V300_FIXED_50M 8 ++#define GK7205V300_FIXED_83P3M 9 ++#define GK7205V300_FIXED_90M 10 ++#define GK7205V300_FIXED_100M 11 ++#define GK7205V300_FIXED_112M 12 ++#define GK7205V300_FIXED_125M 13 ++#define GK7205V300_FIXED_148P5M 14 ++#define GK7205V300_FIXED_150M 15 ++#define GK7205V300_FIXED_200M 16 ++#define GK7205V300_FIXED_250M 17 ++#define GK7205V300_FIXED_300M 18 ++#define GK7205V300_FIXED_324M 19 ++#define GK7205V300_FIXED_342M 20 ++#define GK7205V300_FIXED_375M 21 ++#define GK7205V300_FIXED_400M 22 ++#define GK7205V300_FIXED_448M 23 ++#define GK7205V300_FIXED_500M 24 ++#define GK7205V300_FIXED_540M 25 ++#define GK7205V300_FIXED_600M 26 ++#define GK7205V300_FIXED_750M 27 ++#define GK7205V300_FIXED_1000M 28 ++#define GK7205V300_FIXED_1500M 29 ++ ++/* mux clocks */ ++#define GK7205V300_SYSAXI_CLK 30 ++#define GK7205V300_SYSAPB_CLK 31 ++#define GK7205V300_FMC_MUX 32 ++#define GK7205V300_UART_MUX 33 ++#define GK7205V300_MMC0_MUX 34 ++#define GK7205V300_MMC1_MUX 35 ++#define GK7205V300_MMC2_MUX 36 ++#define GK7205V300_ETH_MUX 37 ++#define GK7205V300_USB2_MUX 80 ++/* gate clocks */ ++#define GK7205V300_UART0_CLK 40 ++#define GK7205V300_UART1_CLK 41 ++#define GK7205V300_UART2_CLK 42 ++#define GK7205V300_FMC_CLK 43 ++#define GK7205V300_ETH0_CLK 44 ++#define GK7205V300_EDMAC_AXICLK 45 ++#define GK7205V300_EDMAC_CLK 46 ++#define GK7205V300_SPI0_CLK 48 ++#define GK7205V300_SPI1_CLK 49 ++#define GK7205V300_MMC0_CLK 50 ++#define GK7205V300_MMC1_CLK 51 ++#define GK7205V300_MMC2_CLK 52 ++#define GK7205V300_I2C0_CLK 53 ++#define GK7205V300_I2C1_CLK 54 ++#define GK7205V300_I2C2_CLK 55 ++#define GK7205V300_USB2_BUS_CLK 81 ++#define GK7205V300_USB2_REF_CLK 82 ++#define GK7205V300_USB2_UTMI_CLK 83 ++#define GK7205V300_USB2_PHY_APB_CLK 84 ++#define GK7205V300_USB2_PHY_PLL_CLK 85 ++#define GK7205V300_USB2_PHY_XO_CLK 86 ++ ++#define GK7205V300_NR_CLKS 256 ++#define GK7205V300_NR_RSTS 256 ++ ++#endif /* __DTS_GK7205V300_CLOCK_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7605v100-clock.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7605v100-clock.h.patch new file mode 100644 index 00000000..4432ad96 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-dt-bindings-clock-gk7605v100-clock.h.patch @@ -0,0 +1,79 @@ +--- linux-4.9.37/include/dt-bindings/clock/gk7605v100-clock.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/dt-bindings/clock/gk7605v100-clock.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,76 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __DTS_GK7605V100_CLOCK_H ++#define __DTS_GK7605V100_CLOCK_H ++ ++/* clk in GK7605V100 CRG */ ++/* fixed rate clocks */ ++#define GK7605V100_FIXED_100K 1 ++#define GK7605V100_FIXED_400K 2 ++#define GK7605V100_FIXED_3M 3 ++#define GK7605V100_FIXED_6M 4 ++#define GK7605V100_FIXED_12M 5 ++#define GK7605V100_FIXED_24M 6 ++#define GK7605V100_FIXED_25M 7 ++#define GK7605V100_FIXED_50M 8 ++#define GK7605V100_FIXED_83P3M 9 ++#define GK7605V100_FIXED_90M 10 ++#define GK7605V100_FIXED_100M 11 ++#define GK7605V100_FIXED_112M 12 ++#define GK7605V100_FIXED_125M 13 ++#define GK7605V100_FIXED_148P5M 14 ++#define GK7605V100_FIXED_150M 15 ++#define GK7605V100_FIXED_200M 16 ++#define GK7605V100_FIXED_250M 17 ++#define GK7605V100_FIXED_300M 18 ++#define GK7605V100_FIXED_324M 19 ++#define GK7605V100_FIXED_342M 20 ++#define GK7605V100_FIXED_375M 21 ++#define GK7605V100_FIXED_400M 22 ++#define GK7605V100_FIXED_448M 23 ++#define GK7605V100_FIXED_500M 24 ++#define GK7605V100_FIXED_540M 25 ++#define GK7605V100_FIXED_600M 26 ++#define GK7605V100_FIXED_750M 27 ++#define GK7605V100_FIXED_1000M 28 ++#define GK7605V100_FIXED_1500M 29 ++ ++/* mux clocks */ ++#define GK7605V100_SYSAXI_CLK 30 ++#define GK7605V100_SYSAPB_CLK 31 ++#define GK7605V100_FMC_MUX 32 ++#define GK7605V100_UART_MUX 33 ++#define GK7605V100_MMC0_MUX 34 ++#define GK7605V100_MMC1_MUX 35 ++#define GK7605V100_MMC2_MUX 36 ++#define GK7605V100_ETH_MUX 37 ++#define GK7605V100_USB2_MUX 80 ++/* gate clocks */ ++#define GK7605V100_UART0_CLK 40 ++#define GK7605V100_UART1_CLK 41 ++#define GK7605V100_UART2_CLK 42 ++#define GK7605V100_FMC_CLK 43 ++#define GK7605V100_ETH0_CLK 44 ++#define GK7605V100_EDMAC_AXICLK 45 ++#define GK7605V100_EDMAC_CLK 46 ++#define GK7605V100_SPI0_CLK 48 ++#define GK7605V100_SPI1_CLK 49 ++#define GK7605V100_MMC0_CLK 50 ++#define GK7605V100_MMC1_CLK 51 ++#define GK7605V100_MMC2_CLK 52 ++#define GK7605V100_I2C0_CLK 53 ++#define GK7605V100_I2C1_CLK 54 ++#define GK7605V100_I2C2_CLK 55 ++#define GK7605V100_USB2_BUS_CLK 81 ++#define GK7605V100_USB2_REF_CLK 82 ++#define GK7605V100_USB2_UTMI_CLK 83 ++#define GK7605V100_USB2_PHY_APB_CLK 84 ++#define GK7605V100_USB2_PHY_PLL_CLK 85 ++#define GK7605V100_USB2_PHY_XO_CLK 86 ++ ++#define GK7605V100_NR_CLKS 256 ++#define GK7605V100_NR_RSTS 256 ++ ++#endif /* __DTS_GK7605V100_CLOCK_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-kvm-arm_psci.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-kvm-arm_psci.h.patch new file mode 100644 index 00000000..e47ba7f2 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-kvm-arm_psci.h.patch @@ -0,0 +1,32 @@ +--- linux-4.9.37/include/kvm/arm_psci.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/kvm/arm_psci.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (C) 2012 - ARM Ltd ++ * Author: Marc Zyngier ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#ifndef __KVM_ARM_PSCI_H__ ++#define __KVM_ARM_PSCI_H__ ++ ++#include ++ ++#define KVM_ARM_PSCI_0_1 PSCI_VERSION(0, 1) ++#define KVM_ARM_PSCI_0_2 PSCI_VERSION(0, 2) ++ ++int kvm_psci_version(struct kvm_vcpu *vcpu); ++int kvm_psci_call(struct kvm_vcpu *vcpu); ++ ++#endif /* __KVM_ARM_PSCI_H__ */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-blkdev.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-blkdev.h.patch new file mode 100644 index 00000000..085241e9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-blkdev.h.patch @@ -0,0 +1,14 @@ +--- linux-4.9.37/include/linux/blkdev.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/blkdev.h 2021-06-07 13:01:34.000000000 +0300 +@@ -1174,7 +1174,11 @@ + enum blk_default_limits { + BLK_MAX_SEGMENTS = 128, + BLK_SAFE_MAX_SECTORS = 255, ++#ifndef CONFIG_GOKE_MC + BLK_DEF_MAX_SECTORS = 2560, ++#else ++ BLK_DEF_MAX_SECTORS = 8192, ++#endif + BLK_MAX_SEGMENT_SIZE = 65536, + BLK_SEG_BOUNDARY_MASK = 0xFFFFFFFFUL, + }; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-cpuidle.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-cpuidle.h.patch new file mode 100644 index 00000000..0c68621e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-cpuidle.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/include/linux/cpuidle.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/cpuidle.h 2021-06-07 13:01:34.000000000 +0300 +@@ -62,6 +62,7 @@ + }; + + /* Idle State Flags */ ++#define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ + #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */ + #define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */ + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-dma-mapping.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-dma-mapping.h.patch new file mode 100644 index 00000000..97b9b13e --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-dma-mapping.h.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/include/linux/dma-mapping.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/dma-mapping.h 2021-06-07 13:01:34.000000000 +0300 +@@ -705,6 +705,8 @@ + /* + * Managed DMA API + */ ++void bsp_dmac_map_area(const void *kaddr, size_t size, ++ enum dma_data_direction dir); + extern void *dmam_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); + extern void dmam_free_coherent(struct device *dev, size_t size, void *vaddr, diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fb.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fb.h.patch new file mode 100644 index 00000000..0cffa033 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fb.h.patch @@ -0,0 +1,30 @@ +--- linux-4.9.37/include/linux/fb.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/fb.h 2021-06-07 13:01:34.000000000 +0300 +@@ -237,7 +237,14 @@ + void (*deferred_io)(struct fb_info *info, struct list_head *pagelist); + }; + #endif ++#ifdef CONFIG_ARCH_GOKE ++#define FBIOGET_DMABUF _IOR('F', 0x21, struct fb_dmabuf_export) + ++struct fb_dmabuf_export { ++ __u32 fd; ++ __u32 flags; ++}; ++#endif + /* + * Frame buffer operations + * +@@ -320,6 +327,12 @@ + /* called at KDB enter and leave time to prepare the console */ + int (*fb_debug_enter)(struct fb_info *info); + int (*fb_debug_leave)(struct fb_info *info); ++#ifdef CONFIG_ARCH_GOKE ++#ifdef CONFIG_DMA_SHARED_BUFFER ++ /* Export the frame buffer as a dmabuf object */ ++ struct dma_buf *(*fb_dmabuf_export)(struct fb_info *info); ++#endif ++#endif + }; + + #ifdef CONFIG_FB_TILEBLITTING diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fence.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fence.h.patch new file mode 100644 index 00000000..bc4827fa --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fence.h.patch @@ -0,0 +1,90 @@ +--- linux-4.9.37/include/linux/fence.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/fence.h 2021-06-07 13:01:34.000000000 +0300 +@@ -108,6 +108,7 @@ + * @get_driver_name: returns the driver name. + * @get_timeline_name: return the name of the context this fence belongs to. + * @enable_signaling: enable software signaling of fence. ++ * @disable_signaling: disable software signaling of fence (optional). + * @signaled: [optional] peek whether the fence is signaled, can be null. + * @wait: custom wait implementation, or fence_default_wait. + * @release: [optional] called on destruction of fence, can be null +@@ -167,6 +168,7 @@ + const char * (*get_driver_name)(struct fence *fence); + const char * (*get_timeline_name)(struct fence *fence); + bool (*enable_signaling)(struct fence *fence); ++ void (*disable_signaling)(struct fence *fence); + bool (*signaled)(struct fence *fence); + signed long (*wait)(struct fence *fence, bool intr, signed long timeout); + void (*release)(struct fence *fence); +@@ -183,6 +185,16 @@ + void fence_free(struct fence *fence); + + /** ++ * fence_put - decreases refcount of the fence ++ * @fence: [in] fence to reduce refcount of ++ */ ++static inline void fence_put(struct fence *fence) ++{ ++ if (fence) ++ kref_put(&fence->refcount, fence_release); ++} ++ ++/** + * fence_get - increases refcount of the fence + * @fence: [in] fence to increase refcount of + * +@@ -210,13 +222,49 @@ + } + + /** +- * fence_put - decreases refcount of the fence +- * @fence: [in] fence to reduce refcount of ++ * fence_get_rcu_safe - acquire a reference to an RCU tracked fence ++ * @fence: [in] pointer to fence to increase refcount of ++ * ++ * Function returns NULL if no refcount could be obtained, or the fence. ++ * This function handles acquiring a reference to a fence that may be ++ * reallocated within the RCU grace period (such as with SLAB_DESTROY_BY_RCU), ++ * so long as the caller is using RCU on the pointer to the fence. ++ * ++ * An alternative mechanism is to employ a seqlock to protect a bunch of ++ * fences, such as used by struct reservation_object. When using a seqlock, ++ * the seqlock must be taken before and checked after a reference to the ++ * fence is acquired (as shown here). ++ * ++ * The caller is required to hold the RCU read lock. + */ +-static inline void fence_put(struct fence *fence) ++static inline struct fence *fence_get_rcu_safe(struct fence * __rcu *fencep) + { +- if (fence) +- kref_put(&fence->refcount, fence_release); ++ do { ++ struct fence *fence; ++ ++ fence = rcu_dereference(*fencep); ++ if (!fence || !fence_get_rcu(fence)) ++ return NULL; ++ ++ /* The atomic_inc_not_zero() inside fence_get_rcu() ++ * provides a full memory barrier upon success (such as now). ++ * This is paired with the write barrier from assigning ++ * to the __rcu protected fence pointer so that if that ++ * pointer still matches the current fence, we know we ++ * have successfully acquire a reference to it. If it no ++ * longer matches, we are holding a reference to some other ++ * reallocated pointer. This is possible if the allocator ++ * is using a freelist like SLAB_DESTROY_BY_RCU where the ++ * fence remains valid for the RCU grace period, but it ++ * may be reallocated. When using such allocators, we are ++ * responsible for ensuring the reference we get is to ++ * the right fence, as below. ++ */ ++ if (fence == rcu_access_pointer(*fencep)) ++ return rcu_pointer_handoff(fence); ++ ++ fence_put(fence); ++ } while (1); + } + + int fence_signal(struct fence *fence); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fs.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fs.h.patch new file mode 100644 index 00000000..130f9c28 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-fs.h.patch @@ -0,0 +1,14 @@ +--- linux-4.9.37/include/linux/fs.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/fs.h 2021-06-07 13:01:34.000000000 +0300 +@@ -941,9 +941,9 @@ + /* Page cache limit. The filesystems should put that into their s_maxbytes + limits, otherwise bad things can happen in VM. */ + #if BITS_PER_LONG==32 +-#define MAX_LFS_FILESIZE (((loff_t)PAGE_SIZE << (BITS_PER_LONG-1))-1) ++#define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT) + #elif BITS_PER_LONG==64 +-#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL) ++#define MAX_LFS_FILESIZE ((loff_t)LLONG_MAX) + #endif + + #define FL_POSIX 1 diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-goke_cma.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-goke_cma.h.patch new file mode 100644 index 00000000..d9edb203 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-goke_cma.h.patch @@ -0,0 +1,42 @@ +--- linux-4.9.37/include/linux/goke_cma.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/goke_cma.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++#ifndef __GOKE_CMA_H__ ++#define __GOKE_CMA_H__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define NAME_LEN_MAX 64 ++#define ZONE_MAX 64 ++ ++struct cma_zone { ++ struct device pdev; ++ char name[NAME_LEN_MAX]; ++ gfp_t gfp; ++ phys_addr_t phys_start; ++ phys_addr_t nbytes; ++ u32 alloc_type; ++ u32 block_align; ++}; ++ ++#ifdef CONFIG_CMA ++int is_cma_address(phys_addr_t phys, unsigned long size); ++phys_addr_t goke_get_zones_start(void); ++struct cma_zone *goke_get_cma_zone(const char *name); ++struct device *goke_get_cma_device(const char *name); ++int __init goke_declare_heap_memory(void); ++#endif /* CONFIG_CMA */ ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-i2c.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-i2c.h.patch new file mode 100644 index 00000000..4999b0d3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-i2c.h.patch @@ -0,0 +1,33 @@ +--- linux-4.9.37/include/linux/i2c.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/i2c.h 2021-06-07 13:01:34.000000000 +0300 +@@ -68,6 +68,20 @@ + */ + extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num); ++ ++#ifdef CONFIG_ARCH_GOKE ++ ++extern int gk_i2c_master_send(const struct i2c_client *client, const char *buf, ++ int count); ++ ++extern int gk_i2c_master_recv(const struct i2c_client *client, char *buf, ++ int count); ++ ++extern int gk_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ++ int num); ++ ++#endif ++ + /* Unlocked flavor */ + extern int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num); +@@ -553,6 +567,9 @@ + const struct i2c_lock_operations *lock_ops; + struct rt_mutex bus_lock; + struct rt_mutex mux_lock; ++#ifdef CONFIG_ARCH_GOKE ++ spinlock_t spinlock; ++#endif + + int timeout; /* in jiffies */ + int retries; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzFind.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzFind.h.patch new file mode 100644 index 00000000..22db3ed7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzFind.h.patch @@ -0,0 +1,118 @@ +--- linux-4.9.37/include/linux/lzma/LzFind.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/lzma/LzFind.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,115 @@ ++/* LzFind.h -- Match finder for LZ algorithms ++2009-04-22 : Igor Pavlov : Public domain */ ++ ++#ifndef __LZ_FIND_H ++#define __LZ_FIND_H ++ ++#include "Types.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++typedef UInt32 CLzRef; ++ ++typedef struct _CMatchFinder ++{ ++ Byte *buffer; ++ UInt32 pos; ++ UInt32 posLimit; ++ UInt32 streamPos; ++ UInt32 lenLimit; ++ ++ UInt32 cyclicBufferPos; ++ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ ++ ++ UInt32 matchMaxLen; ++ CLzRef *hash; ++ CLzRef *son; ++ UInt32 hashMask; ++ UInt32 cutValue; ++ ++ Byte *bufferBase; ++ ISeqInStream *stream; ++ int streamEndWasReached; ++ ++ UInt32 blockSize; ++ UInt32 keepSizeBefore; ++ UInt32 keepSizeAfter; ++ ++ UInt32 numHashBytes; ++ int directInput; ++ size_t directInputRem; ++ int btMode; ++ int bigHash; ++ UInt32 historySize; ++ UInt32 fixedHashSize; ++ UInt32 hashSizeSum; ++ UInt32 numSons; ++ SRes result; ++ UInt32 crc[256]; ++} CMatchFinder; ++ ++#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) ++#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) ++ ++#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) ++ ++int MatchFinder_NeedMove(CMatchFinder *p); ++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); ++void MatchFinder_MoveBlock(CMatchFinder *p); ++void MatchFinder_ReadIfRequired(CMatchFinder *p); ++ ++void MatchFinder_Construct(CMatchFinder *p); ++ ++/* Conditions: ++ historySize <= 3 GB ++ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB ++*/ ++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, ++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ++ ISzAlloc *alloc); ++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); ++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); ++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); ++ ++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, ++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, ++ UInt32 *distances, UInt32 maxLen); ++ ++/* ++Conditions: ++ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. ++ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function ++*/ ++ ++typedef void (*Mf_Init_Func)(void *object); ++typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); ++typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); ++typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); ++typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); ++typedef void (*Mf_Skip_Func)(void *object, UInt32); ++ ++typedef struct _IMatchFinder ++{ ++ Mf_Init_Func Init; ++ Mf_GetIndexByte_Func GetIndexByte; ++ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; ++ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; ++ Mf_GetMatches_Func GetMatches; ++ Mf_Skip_Func Skip; ++} IMatchFinder; ++ ++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); ++ ++void MatchFinder_Init(CMatchFinder *p); ++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); ++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); ++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); ++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzHash.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzHash.h.patch new file mode 100644 index 00000000..4161ed67 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzHash.h.patch @@ -0,0 +1,57 @@ +--- linux-4.9.37/include/linux/lzma/LzHash.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/lzma/LzHash.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,54 @@ ++/* LzHash.h -- HASH functions for LZ algorithms ++2009-02-07 : Igor Pavlov : Public domain */ ++ ++#ifndef __LZ_HASH_H ++#define __LZ_HASH_H ++ ++#define kHash2Size (1 << 10) ++#define kHash3Size (1 << 16) ++#define kHash4Size (1 << 20) ++ ++#define kFix3HashSize (kHash2Size) ++#define kFix4HashSize (kHash2Size + kHash3Size) ++#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) ++ ++#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); ++ ++#define HASH3_CALC { \ ++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ ++ hash2Value = temp & (kHash2Size - 1); \ ++ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } ++ ++#define HASH4_CALC { \ ++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ ++ hash2Value = temp & (kHash2Size - 1); \ ++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ ++ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } ++ ++#define HASH5_CALC { \ ++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ ++ hash2Value = temp & (kHash2Size - 1); \ ++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ ++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ ++ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ ++ hash4Value &= (kHash4Size - 1); } ++ ++/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ ++#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; ++ ++ ++#define MT_HASH2_CALC \ ++ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); ++ ++#define MT_HASH3_CALC { \ ++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ ++ hash2Value = temp & (kHash2Size - 1); \ ++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } ++ ++#define MT_HASH4_CALC { \ ++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ ++ hash2Value = temp & (kHash2Size - 1); \ ++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ ++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzmaDec.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzmaDec.h.patch new file mode 100644 index 00000000..6b0b5d3a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzmaDec.h.patch @@ -0,0 +1,234 @@ +--- linux-4.9.37/include/linux/lzma/LzmaDec.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/lzma/LzmaDec.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,231 @@ ++/* LzmaDec.h -- LZMA Decoder ++2009-02-07 : Igor Pavlov : Public domain */ ++ ++#ifndef __LZMA_DEC_H ++#define __LZMA_DEC_H ++ ++#include "Types.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* #define _LZMA_PROB32 */ ++/* _LZMA_PROB32 can increase the speed on some CPUs, ++ but memory usage for CLzmaDec::probs will be doubled in that case */ ++ ++#ifdef _LZMA_PROB32 ++#define CLzmaProb UInt32 ++#else ++#define CLzmaProb UInt16 ++#endif ++ ++ ++/* ---------- LZMA Properties ---------- */ ++ ++#define LZMA_PROPS_SIZE 5 ++ ++typedef struct _CLzmaProps ++{ ++ unsigned lc, lp, pb; ++ UInt32 dicSize; ++} CLzmaProps; ++ ++/* LzmaProps_Decode - decodes properties ++Returns: ++ SZ_OK ++ SZ_ERROR_UNSUPPORTED - Unsupported properties ++*/ ++ ++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); ++ ++ ++/* ---------- LZMA Decoder state ---------- */ ++ ++/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. ++ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ ++ ++#define LZMA_REQUIRED_INPUT_MAX 20 ++ ++typedef struct ++{ ++ CLzmaProps prop; ++ CLzmaProb *probs; ++ Byte *dic; ++ const Byte *buf; ++ UInt32 range, code; ++ SizeT dicPos; ++ SizeT dicBufSize; ++ UInt32 processedPos; ++ UInt32 checkDicSize; ++ unsigned state; ++ UInt32 reps[4]; ++ unsigned remainLen; ++ int needFlush; ++ int needInitState; ++ UInt32 numProbs; ++ unsigned tempBufSize; ++ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; ++} CLzmaDec; ++ ++#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } ++ ++void LzmaDec_Init(CLzmaDec *p); ++ ++/* There are two types of LZMA streams: ++ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. ++ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ ++ ++typedef enum ++{ ++ LZMA_FINISH_ANY, /* finish at any point */ ++ LZMA_FINISH_END /* block must be finished at the end */ ++} ELzmaFinishMode; ++ ++/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! ++ ++ You must use LZMA_FINISH_END, when you know that current output buffer ++ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. ++ ++ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, ++ and output value of destLen will be less than output buffer size limit. ++ You can check status result also. ++ ++ You can use multiple checks to test data integrity after full decompression: ++ 1) Check Result and "status" variable. ++ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. ++ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. ++ You must use correct finish mode in that case. */ ++ ++typedef enum ++{ ++ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ ++ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ ++ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ ++ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ ++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ ++} ELzmaStatus; ++ ++/* ELzmaStatus is used only as output value for function call */ ++ ++ ++/* ---------- Interfaces ---------- */ ++ ++/* There are 3 levels of interfaces: ++ 1) Dictionary Interface ++ 2) Buffer Interface ++ 3) One Call Interface ++ You can select any of these interfaces, but don't mix functions from different ++ groups for same object. */ ++ ++ ++/* There are two variants to allocate state for Dictionary Interface: ++ 1) LzmaDec_Allocate / LzmaDec_Free ++ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs ++ You can use variant 2, if you set dictionary buffer manually. ++ For Buffer Interface you must always use variant 1. ++ ++LzmaDec_Allocate* can return: ++ SZ_OK ++ SZ_ERROR_MEM - Memory allocation error ++ SZ_ERROR_UNSUPPORTED - Unsupported properties ++*/ ++ ++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); ++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); ++ ++SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); ++void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); ++ ++/* ---------- Dictionary Interface ---------- */ ++ ++/* You can use it, if you want to eliminate the overhead for data copying from ++ dictionary to some other external buffer. ++ You must work with CLzmaDec variables directly in this interface. ++ ++ STEPS: ++ LzmaDec_Constr() ++ LzmaDec_Allocate() ++ for (each new stream) ++ { ++ LzmaDec_Init() ++ while (it needs more decompression) ++ { ++ LzmaDec_DecodeToDic() ++ use data from CLzmaDec::dic and update CLzmaDec::dicPos ++ } ++ } ++ LzmaDec_Free() ++*/ ++ ++/* LzmaDec_DecodeToDic ++ ++ The decoding to internal dictionary buffer (CLzmaDec::dic). ++ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! ++ ++finishMode: ++ It has meaning only if the decoding reaches output limit (dicLimit). ++ LZMA_FINISH_ANY - Decode just dicLimit bytes. ++ LZMA_FINISH_END - Stream must be finished after dicLimit. ++ ++Returns: ++ SZ_OK ++ status: ++ LZMA_STATUS_FINISHED_WITH_MARK ++ LZMA_STATUS_NOT_FINISHED ++ LZMA_STATUS_NEEDS_MORE_INPUT ++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ++ SZ_ERROR_DATA - Data error ++*/ ++ ++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, ++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); ++ ++ ++/* ---------- Buffer Interface ---------- */ ++ ++/* It's zlib-like interface. ++ See LzmaDec_DecodeToDic description for information about STEPS and return results, ++ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need ++ to work with CLzmaDec variables manually. ++ ++finishMode: ++ It has meaning only if the decoding reaches output limit (*destLen). ++ LZMA_FINISH_ANY - Decode just destLen bytes. ++ LZMA_FINISH_END - Stream must be finished after (*destLen). ++*/ ++ ++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, ++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); ++ ++ ++/* ---------- One Call Interface ---------- */ ++ ++/* LzmaDecode ++ ++finishMode: ++ It has meaning only if the decoding reaches output limit (*destLen). ++ LZMA_FINISH_ANY - Decode just destLen bytes. ++ LZMA_FINISH_END - Stream must be finished after (*destLen). ++ ++Returns: ++ SZ_OK ++ status: ++ LZMA_STATUS_FINISHED_WITH_MARK ++ LZMA_STATUS_NOT_FINISHED ++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ++ SZ_ERROR_DATA - Data error ++ SZ_ERROR_MEM - Memory allocation error ++ SZ_ERROR_UNSUPPORTED - Unsupported properties ++ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). ++*/ ++ ++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, ++ ELzmaStatus *status, ISzAlloc *alloc); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzmaEnc.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzmaEnc.h.patch new file mode 100644 index 00000000..ba01ddf3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-LzmaEnc.h.patch @@ -0,0 +1,83 @@ +--- linux-4.9.37/include/linux/lzma/LzmaEnc.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/lzma/LzmaEnc.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,80 @@ ++/* LzmaEnc.h -- LZMA Encoder ++2009-02-07 : Igor Pavlov : Public domain */ ++ ++#ifndef __LZMA_ENC_H ++#define __LZMA_ENC_H ++ ++#include "Types.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#define LZMA_PROPS_SIZE 5 ++ ++typedef struct _CLzmaEncProps ++{ ++ int level; /* 0 <= level <= 9 */ ++ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version ++ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version ++ default = (1 << 24) */ ++ int lc; /* 0 <= lc <= 8, default = 3 */ ++ int lp; /* 0 <= lp <= 4, default = 0 */ ++ int pb; /* 0 <= pb <= 4, default = 2 */ ++ int algo; /* 0 - fast, 1 - normal, default = 1 */ ++ int fb; /* 5 <= fb <= 273, default = 32 */ ++ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ ++ int numHashBytes; /* 2, 3 or 4, default = 4 */ ++ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ ++ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ ++ int numThreads; /* 1 or 2, default = 2 */ ++} CLzmaEncProps; ++ ++void LzmaEncProps_Init(CLzmaEncProps *p); ++void LzmaEncProps_Normalize(CLzmaEncProps *p); ++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); ++ ++ ++/* ---------- CLzmaEncHandle Interface ---------- */ ++ ++/* LzmaEnc_* functions can return the following exit codes: ++Returns: ++ SZ_OK - OK ++ SZ_ERROR_MEM - Memory allocation error ++ SZ_ERROR_PARAM - Incorrect paramater in props ++ SZ_ERROR_WRITE - Write callback error. ++ SZ_ERROR_PROGRESS - some break from progress callback ++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) ++*/ ++ ++typedef void * CLzmaEncHandle; ++ ++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); ++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); ++SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); ++SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); ++SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, ++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ++SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ++ ++/* ---------- One Call Interface ---------- */ ++ ++/* LzmaEncode ++Return code: ++ SZ_OK - OK ++ SZ_ERROR_MEM - Memory allocation error ++ SZ_ERROR_PARAM - Incorrect paramater ++ SZ_ERROR_OUTPUT_EOF - output buffer overflow ++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) ++*/ ++ ++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, ++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-Types.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-Types.h.patch new file mode 100644 index 00000000..22019a2c --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma-Types.h.patch @@ -0,0 +1,229 @@ +--- linux-4.9.37/include/linux/lzma/Types.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/lzma/Types.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,226 @@ ++/* Types.h -- Basic types ++2009-11-23 : Igor Pavlov : Public domain */ ++ ++#ifndef __7Z_TYPES_H ++#define __7Z_TYPES_H ++ ++#include ++ ++#ifdef _WIN32 ++#include ++#endif ++ ++#ifndef EXTERN_C_BEGIN ++#ifdef __cplusplus ++#define EXTERN_C_BEGIN extern "C" { ++#define EXTERN_C_END } ++#else ++#define EXTERN_C_BEGIN ++#define EXTERN_C_END ++#endif ++#endif ++ ++EXTERN_C_BEGIN ++ ++#define SZ_OK 0 ++ ++#define SZ_ERROR_DATA 1 ++#define SZ_ERROR_MEM 2 ++#define SZ_ERROR_CRC 3 ++#define SZ_ERROR_UNSUPPORTED 4 ++#define SZ_ERROR_PARAM 5 ++#define SZ_ERROR_INPUT_EOF 6 ++#define SZ_ERROR_OUTPUT_EOF 7 ++#define SZ_ERROR_READ 8 ++#define SZ_ERROR_WRITE 9 ++#define SZ_ERROR_PROGRESS 10 ++#define SZ_ERROR_FAIL 11 ++#define SZ_ERROR_THREAD 12 ++ ++#define SZ_ERROR_ARCHIVE 16 ++#define SZ_ERROR_NO_ARCHIVE 17 ++ ++typedef int SRes; ++ ++#ifdef _WIN32 ++typedef DWORD WRes; ++#else ++typedef int WRes; ++#endif ++ ++#ifndef RINOK ++#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } ++#endif ++ ++typedef unsigned char Byte; ++typedef short Int16; ++typedef unsigned short UInt16; ++ ++#ifdef _LZMA_UINT32_IS_ULONG ++typedef long Int32; ++typedef unsigned long UInt32; ++#else ++typedef int Int32; ++typedef unsigned int UInt32; ++#endif ++ ++#ifdef _SZ_NO_INT_64 ++ ++/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. ++ NOTES: Some code will work incorrectly in that case! */ ++ ++typedef long Int64; ++typedef unsigned long UInt64; ++ ++#else ++ ++#if defined(_MSC_VER) || defined(__BORLANDC__) ++typedef __int64 Int64; ++typedef unsigned __int64 UInt64; ++#else ++typedef long long int Int64; ++typedef unsigned long long int UInt64; ++#endif ++ ++#endif ++ ++#ifdef _LZMA_NO_SYSTEM_SIZE_T ++typedef UInt32 SizeT; ++#else ++typedef size_t SizeT; ++#endif ++ ++typedef int Bool; ++#define True 1 ++#define False 0 ++ ++ ++#ifdef _WIN32 ++#define MY_STD_CALL __stdcall ++#else ++#define MY_STD_CALL ++#endif ++ ++#ifdef _MSC_VER ++ ++#if _MSC_VER >= 1300 ++#define MY_NO_INLINE __declspec(noinline) ++#else ++#define MY_NO_INLINE ++#endif ++ ++#define MY_CDECL __cdecl ++#define MY_FAST_CALL __fastcall ++ ++#else ++ ++#define MY_CDECL ++#define MY_FAST_CALL ++ ++#endif ++ ++ ++/* The following interfaces use first parameter as pointer to structure */ ++ ++typedef struct ++{ ++ SRes (*Read)(void *p, void *buf, size_t *size); ++ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. ++ (output(*size) < input(*size)) is allowed */ ++} ISeqInStream; ++ ++/* it can return SZ_ERROR_INPUT_EOF */ ++SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); ++SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); ++SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); ++ ++typedef struct ++{ ++ size_t (*Write)(void *p, const void *buf, size_t size); ++ /* Returns: result - the number of actually written bytes. ++ (result < size) means error */ ++} ISeqOutStream; ++ ++typedef enum ++{ ++ SZ_SEEK_SET = 0, ++ SZ_SEEK_CUR = 1, ++ SZ_SEEK_END = 2 ++} ESzSeek; ++ ++typedef struct ++{ ++ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ ++ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); ++} ISeekInStream; ++ ++typedef struct ++{ ++ SRes (*Look)(void *p, void **buf, size_t *size); ++ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. ++ (output(*size) > input(*size)) is not allowed ++ (output(*size) < input(*size)) is allowed */ ++ SRes (*Skip)(void *p, size_t offset); ++ /* offset must be <= output(*size) of Look */ ++ ++ SRes (*Read)(void *p, void *buf, size_t *size); ++ /* reads directly (without buffer). It's same as ISeqInStream::Read */ ++ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); ++} ILookInStream; ++ ++SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); ++SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); ++ ++/* reads via ILookInStream::Read */ ++SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); ++SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); ++ ++#define LookToRead_BUF_SIZE (1 << 14) ++ ++typedef struct ++{ ++ ILookInStream s; ++ ISeekInStream *realStream; ++ size_t pos; ++ size_t size; ++ Byte buf[LookToRead_BUF_SIZE]; ++} CLookToRead; ++ ++void LookToRead_CreateVTable(CLookToRead *p, int lookahead); ++void LookToRead_Init(CLookToRead *p); ++ ++typedef struct ++{ ++ ISeqInStream s; ++ ILookInStream *realStream; ++} CSecToLook; ++ ++void SecToLook_CreateVTable(CSecToLook *p); ++ ++typedef struct ++{ ++ ISeqInStream s; ++ ILookInStream *realStream; ++} CSecToRead; ++ ++void SecToRead_CreateVTable(CSecToRead *p); ++ ++typedef struct ++{ ++ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); ++ /* Returns: result. (result != SZ_OK) means break. ++ Value (UInt64)(Int64)-1 for size means unknown value. */ ++} ICompressProgress; ++ ++typedef struct ++{ ++ void *(*Alloc)(void *p, size_t size); ++ void (*Free)(void *p, void *address); /* address can be 0 */ ++} ISzAlloc; ++ ++#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) ++#define IAlloc_Free(p, a) (p)->Free((p), a) ++ ++EXTERN_C_END ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma.h.patch new file mode 100644 index 00000000..e01720dc --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-lzma.h.patch @@ -0,0 +1,65 @@ +--- linux-4.9.37/include/linux/lzma.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/lzma.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,62 @@ ++#ifndef __LZMA_H__ ++#define __LZMA_H__ ++ ++#ifdef __KERNEL__ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #define LZMA_MALLOC vmalloc ++ #define LZMA_FREE vfree ++ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) ++ #define INIT __init ++ #define STATIC static ++#else ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #ifndef PAGE_SIZE ++ extern int page_size; ++ #define PAGE_SIZE page_size ++ #endif ++ #define LZMA_MALLOC malloc ++ #define LZMA_FREE free ++ #define PRINT_ERROR(msg) fprintf(stderr, msg) ++ #define INIT ++ #define STATIC ++#endif ++ ++#include "lzma/LzmaDec.h" ++#include "lzma/LzmaEnc.h" ++ ++#define LZMA_BEST_LEVEL (9) ++#define LZMA_BEST_LC (0) ++#define LZMA_BEST_LP (0) ++#define LZMA_BEST_PB (0) ++#define LZMA_BEST_FB (273) ++ ++#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) ++ ++static void *p_lzma_malloc(void *p, size_t size) ++{ ++ if (size == 0) ++ return NULL; ++ ++ return LZMA_MALLOC(size); ++} ++ ++static void p_lzma_free(void *p, void *address) ++{ ++ if (address != NULL) ++ LZMA_FREE(address); ++} ++ ++static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free}; ++ ++#endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mfd-goke_fmc.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mfd-goke_fmc.h.patch new file mode 100644 index 00000000..447961c7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mfd-goke_fmc.h.patch @@ -0,0 +1,518 @@ +--- linux-4.9.37/include/linux/mfd/goke_fmc.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/mfd/goke_fmc.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,515 @@ ++/* ++ * Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved. ++ */ ++ ++#ifndef __BSP_FMC_H ++#define __BSP_FMC_H ++ ++#include ++#include ++#include ++#include ++ ++/*****************************************************************************/ ++#define _512B (512) ++#define _1K (1024) ++#define _2K (2048) ++#define _4K (4096) ++#define _8K (8192) ++#define _16K (16384) ++#define _32K (32768) ++#define _64K (0x10000UL) ++#define _128K (0x20000UL) ++#define _256K (0x40000UL) ++#define _512K (0x80000UL) ++#define _1M (0x100000UL) ++#define _2M (0x200000UL) ++#define _4M (0x400000UL) ++#define _8M (0x800000UL) ++#define _16M (0x1000000UL) ++#define _32M (0x2000000UL) ++#define _64M (0x4000000UL) ++#define _128M (0x8000000UL) ++#define _256M (0x10000000UL) ++#define _512M (0x20000000UL) ++#define _1G (0x40000000ULL) ++#define _2G (0x80000000ULL) ++#define _4G (0x100000000ULL) ++#define _8G (0x200000000ULL) ++#define _16G (0x400000000ULL) ++#define _64G (0x1000000000ULL) ++ ++/*****************************************************************************/ ++/* FMC REG MAP */ ++/*****************************************************************************/ ++#define FMC_CFG 0x00 ++#define FMC_CFG_SPI_NAND_SEL(_type) (((_size) & 0x3) << 11) ++#define SPI_NOR_ADDR_MODE BIT(10) ++#define FMC_CFG_OP_MODE_MASK BIT_MASK(0) ++#define FMC_CFG_OP_MODE_BOOT 0 ++#define FMC_CFG_OP_MODE_NORMAL 1 ++#define SPI_NOR_ADDR_MODE_3BYTES (0x0 << 10) ++#define SPI_NOR_ADDR_MODE_4BYTES (0x1 << 10) ++ ++#define FMC_CFG_BLOCK_SIZE(_size) (((_size) & 0x3) << 8) ++#define FMC_CFG_ECC_TYPE(_type) (((_type) & 0x7) << 5) ++#define FMC_CFG_PAGE_SIZE(_size) (((_size) & 0x3) << 3) ++#define FMC_CFG_FLASH_SEL(_type) (((_type) & 0x3) << 1) ++#define FMC_CFG_OP_MODE(_mode) ((_mode) & 0x1) ++ ++#define SPI_NAND_MFR_OTHER 0x0 ++#define SPI_NAND_MFR_WINBOND 0x1 ++#define SPI_NAND_MFR_ESMT 0x2 ++#define SPI_NAND_MFR_MICRON 0x3 ++ ++#define SPI_NAND_SEL_SHIFT 11 ++#define SPI_NAND_SEL_MASK (0x3 << SPI_NAND_SEL_SHIFT) ++ ++#define SPI_NOR_ADDR_MODE_3_BYTES 0x0 ++#define SPI_NOR_ADDR_MODE_4_BYTES 0x1 ++ ++#define SPI_NOR_ADDR_MODE_SHIFT 10 ++#define SPI_NOR_ADDR_MODE_MASK (0x1 << SPI_NOR_ADDR_MODE_SHIFT) ++ ++#define BLOCK_SIZE_64_PAGE 0x0 ++#define BLOCK_SIZE_128_PAGE 0x1 ++#define BLOCK_SIZE_256_PAGE 0x2 ++#define BLOCK_SIZE_512_PAGE 0x3 ++ ++#define BLOCK_SIZE_MASK (0x3 << 8) ++ ++#define ECC_TYPE_0BIT 0x0 ++#define ECC_TYPE_8BIT 0x1 ++#define ECC_TYPE_16BIT 0x2 ++#define ECC_TYPE_24BIT 0x3 ++#define ECC_TYPE_28BIT 0x4 ++#define ECC_TYPE_40BIT 0x5 ++#define ECC_TYPE_64BIT 0x6 ++ ++#define ECC_TYPE_SHIFT 5 ++#define ECC_TYPE_MASK (0x7 << ECC_TYPE_SHIFT) ++ ++#define PAGE_SIZE_2KB 0x0 ++#define PAGE_SIZE_4KB 0x1 ++#define PAGE_SIZE_8KB 0x2 ++#define PAGE_SIZE_16KB 0x3 ++ ++#define PAGE_SIZE_SHIFT 3 ++#define PAGE_SIZE_MASK (0x3 << PAGE_SIZE_SHIFT) ++ ++#define FLASH_TYPE_SPI_NOR 0x0 ++#define FLASH_TYPE_SPI_NAND 0x1 ++#define FLASH_TYPE_NAND 0x2 ++#define FLASH_TYPE_UNKNOWN 0x3 ++ ++#define FLASH_TYPE_SEL_MASK (0x3 << 1) ++#define GET_SPI_FLASH_TYPE(_reg) (((_reg) >> 1) & 0x3) ++ ++/*****************************************************************************/ ++#define FMC_GLOBAL_CFG 0x04 ++#define FMC_GLOBAL_CFG_WP_ENABLE BIT(6) ++#define FMC_GLOBAL_CFG_RANDOMIZER_EN (1 << 2) ++#define FLASH_TYPE_SEL_MASK (0x3 << 1) ++#define FMC_CFG_FLASH_SEL(_type) (((_type) & 0x3) << 1) ++ ++#define FMC_GLOBAL_CFG_DTR_MODE BIT(11) ++/*****************************************************************************/ ++#define FMC_SPI_TIMING_CFG 0x08 ++#define TIMING_CFG_TCSH(nr) (((nr) & 0xf) << 8) ++#define TIMING_CFG_TCSS(nr) (((nr) & 0xf) << 4) ++#define TIMING_CFG_TSHSL(nr) ((nr) & 0xf) ++ ++#define CS_HOLD_TIME 0x6 ++#define CS_SETUP_TIME 0x6 ++#define CS_DESELECT_TIME 0xf ++ ++/*****************************************************************************/ ++#define FMC_PND_PWIDTH_CFG 0x0c ++#define PWIDTH_CFG_RW_HCNT(_n) (((_n) & 0xf) << 8) ++#define PWIDTH_CFG_R_LCNT(_n) (((_n) & 0xf) << 4) ++#define PWIDTH_CFG_W_LCNT(_n) ((_n) & 0xf) ++ ++#define RW_H_WIDTH (0xa) ++#define R_L_WIDTH (0xa) ++#define W_L_WIDTH (0xa) ++ ++/*****************************************************************************/ ++#define FMC_INT 0x18 ++#define FMC_INT_AHB_OP BIT(7) ++#define FMC_INT_WR_LOCK BIT(6) ++#define FMC_INT_DMA_ERR BIT(5) ++#define FMC_INT_ERR_ALARM BIT(4) ++#define FMC_INT_ERR_INVALID BIT(3) ++#define FMC_INT_ERR_INVALID_MASK (0x8) ++#define FMC_INT_ERR_VALID BIT(2) ++#define FMC_INT_ERR_VALID_MASK (0x4) ++#define FMC_INT_OP_FAIL BIT(1) ++#define FMC_INT_OP_DONE BIT(0) ++ ++/*****************************************************************************/ ++#define FMC_INT_EN 0x1c ++#define FMC_INT_EN_AHB_OP BIT(7) ++#define FMC_INT_EN_WR_LOCK BIT(6) ++#define FMC_INT_EN_DMA_ERR BIT(5) ++#define FMC_INT_EN_ERR_ALARM BIT(4) ++#define FMC_INT_EN_ERR_INVALID BIT(3) ++#define FMC_INT_EN_ERR_VALID BIT(2) ++#define FMC_INT_EN_OP_FAIL BIT(1) ++#define FMC_INT_EN_OP_DONE BIT(0) ++ ++/*****************************************************************************/ ++#define FMC_INT_CLR 0x20 ++#define FMC_INT_CLR_AHB_OP BIT(7) ++#define FMC_INT_CLR_WR_LOCK BIT(6) ++#define FMC_INT_CLR_DMA_ERR BIT(5) ++#define FMC_INT_CLR_ERR_ALARM BIT(4) ++#define FMC_INT_CLR_ERR_INVALID BIT(3) ++#define FMC_INT_CLR_ERR_VALID BIT(2) ++#define FMC_INT_CLR_OP_FAIL BIT(1) ++#define FMC_INT_CLR_OP_DONE BIT(0) ++ ++#define FMC_INT_CLR_ALL 0xff ++ ++/*****************************************************************************/ ++#define FMC_CMD 0x24 ++#define FMC_CMD_CMD2(_cmd) (((_cmd) & 0xff) << 8) ++#define FMC_CMD_CMD1(_cmd) ((_cmd) & 0xff) ++ ++/*****************************************************************************/ ++#define FMC_ADDRH 0x28 ++#define FMC_ADDRH_SET(_addr) ((_addr) & 0xff) ++ ++/*****************************************************************************/ ++#define FMC_ADDRL 0x2c ++#define FMC_ADDRL_BLOCK_MASK(_page) ((_page) & 0xffffffc0) ++#define FMC_ADDRL_BLOCK_H_MASK(_page) (((_page) & 0xffff) << 16) ++#define FMC_ADDRL_BLOCK_L_MASK(_page) ((_page) & 0xffc0) ++ ++#define READ_ID_ADDR 0x00 ++#define PROTECT_ADDR 0xa0 ++#define FEATURE_ADDR 0xb0 ++#define STATUS_ADDR 0xc0 ++/*****************************************************************************/ ++#define FMC_OP_CFG 0x30 ++#define OP_CFG_FM_CS(_cs) ((_cs) << 11) ++#define OP_CFG_FORCE_CS_EN(_en) ((_en) << 10) ++#define OP_CFG_MEM_IF_TYPE(_type) (((_type) & 0x7) << 7) ++#define OP_CFG_ADDR_NUM(_addr) (((_addr) & 0x7) << 4) ++#define OP_CFG_DUMMY_NUM(_dummy) ((_dummy) & 0xf) ++#define OP_CFG_OEN_EN (0x1 << 13) ++ ++#define IF_TYPE_SHIFT 7 ++#define IF_TYPE_MASK (0x7 << IF_TYPE_SHIFT) ++ ++#define READ_ID_ADDR_NUM 1 ++#define FEATURES_OP_ADDR_NUM 1 ++#define STD_OP_ADDR_NUM 3 ++ ++/*****************************************************************************/ ++#define FMC_SPI_OP_ADDR 0x34 ++ ++/*****************************************************************************/ ++#define FMC_DATA_NUM 0x38 ++#define FMC_DATA_NUM_CNT(_n) ((_n) & 0x3fff) ++ ++#define SPI_NOR_SR_LEN 1 /* Status Register length */ ++#define SPI_NOR_CR_LEN 1 /* Config Register length */ ++#define FEATURES_DATA_LEN 1 ++#define READ_OOB_BB_LEN 1 ++ ++#define PROTECT_BRWD_MASK BIT(7) ++#define PROTECT_BP3_MASK BIT(6) ++#define PROTECT_BP2_MASK BIT(5) ++#define PROTECT_BP1_MASK BIT(4) ++#define PROTECT_BP0_MASK BIT(3) ++ ++#define ANY_BP_ENABLE(_val) ((PROTECT_BP3_MASK & _val) \ ++ || (PROTECT_BP2_MASK & _val) \ ++ || (PROTECT_BP1_MASK & _val) \ ++ || (PROTECT_BP0_MASK & _val)) ++ ++#define ALL_BP_MASK (PROTECT_BP3_MASK \ ++ | PROTECT_BP2_MASK \ ++ | PROTECT_BP1_MASK \ ++ | PROTECT_BP0_MASK) ++ ++#define FEATURE_ECC_ENABLE (1 << 4) ++#define FEATURE_QE_ENABLE (1 << 0) ++ ++/*****************************************************************************/ ++#define FMC_OP 0x3c ++#define FMC_OP_DUMMY_EN BIT(8) ++#define FMC_OP_CMD1_EN BIT(7) ++#define FMC_OP_ADDR_EN BIT(6) ++#define FMC_OP_WRITE_DATA_EN BIT(5) ++#define FMC_OP_CMD2_EN BIT(4) ++#define FMC_OP_WAIT_READY_EN BIT(3) ++#define FMC_OP_READ_DATA_EN BIT(2) ++#define FMC_OP_READ_STATUS_EN BIT(1) ++#define FMC_OP_REG_OP_START BIT(0) ++ ++/*****************************************************************************/ ++#define FMC_DMA_LEN 0x40 ++#define FMC_DMA_LEN_SET(_len) ((_len) & 0x0fffffff) ++ ++/*****************************************************************************/ ++#define FMC_DMA_AHB_CTRL 0x48 ++#define FMC_DMA_AHB_CTRL_DMA_PP_EN BIT(3) ++#define FMC_DMA_AHB_CTRL_BURST16_EN BIT(2) ++#define FMC_DMA_AHB_CTRL_BURST8_EN BIT(1) ++#define FMC_DMA_AHB_CTRL_BURST4_EN BIT(0) ++ ++#define ALL_BURST_ENABLE (FMC_DMA_AHB_CTRL_BURST16_EN \ ++ | FMC_DMA_AHB_CTRL_BURST8_EN \ ++ | FMC_DMA_AHB_CTRL_BURST4_EN) ++ ++#define FMC_DMA_ADDR_OFFSET 4096 ++ ++/*****************************************************************************/ ++#define FMC_DMA_SADDR_D0 0x4c ++ ++/*****************************************************************************/ ++#define FMC_DMA_SADDR_D1 0x50 ++ ++/*****************************************************************************/ ++#define FMC_DMA_SADDR_D2 0x54 ++ ++/*****************************************************************************/ ++#define FMC_DMA_SADDR_D3 0x58 ++ ++/*****************************************************************************/ ++#define FMC_DMA_SADDR_OOB 0x5c ++ ++#ifdef CONFIG_64BIT ++/*****************************************************************************/ ++#define FMC_DMA_SADDRH_D0 0x200 ++#define FMC_DMA_SADDRH_SHIFT 0x3LL ++#define FMC_DMA_SADDRH_MASK (FMC_DMA_SADDRH_SHIFT << 32) ++ ++/*****************************************************************************/ ++#define FMC_DMA_SADDRH_OOB 0x210 ++#endif ++ ++/*****************************************************************************/ ++#define FMC_DMA_BLK_SADDR 0x60 ++#define FMC_DMA_BLK_SADDR_SET(_addr) ((_addr) & 0xffffff) ++ ++/*****************************************************************************/ ++#define FMC_DMA_BLK_LEN 0x64 ++#define FMC_DMA_BLK_LEN_SET(_len) ((_len) & 0xffff) ++ ++/*****************************************************************************/ ++#define FMC_OP_CTRL 0x68 ++#define OP_CTRL_RD_OPCODE(code) (((code) & 0xff) << 16) ++#define OP_CTRL_WR_OPCODE(code) (((code) & 0xff) << 8) ++#define OP_CTRL_RD_OP_SEL(_op) (((_op) & 0x3) << 4) ++#define OP_CTRL_DMA_OP(_type) ((_type) << 2) ++#define OP_CTRL_RW_OP(op) ((op) << 1) ++#define OP_CTRL_DMA_OP_READY BIT(0) ++ ++#define RD_OP_READ_ALL_PAGE 0x0 ++#define RD_OP_READ_OOB 0x1 ++#define RD_OP_BLOCK_READ 0x2 ++ ++#define RD_OP_SHIFT 4 ++#define RD_OP_MASK (0x3 << RD_OP_SHIFT) ++ ++#define OP_TYPE_DMA 0x0 ++#define OP_TYPE_REG 0x1 ++ ++#define FMC_OP_READ 0x0 ++#define FMC_OP_WRITE 0x1 ++#define RW_OP_READ 0x0 ++#define RW_OP_WRITE 0x1 ++ ++/*****************************************************************************/ ++#define FMC_OP_PARA 0x70 ++#define FMC_OP_PARA_RD_OOB_ONLY BIT(1) ++ ++/*****************************************************************************/ ++#define FMC_BOOT_SET 0x74 ++#define FMC_BOOT_SET_DEVICE_ECC_EN BIT(3) ++#define FMC_BOOT_SET_BOOT_QUAD_EN BIT(1) ++ ++/*****************************************************************************/ ++#define FMC_STATUS 0xac ++ ++/*****************************************************************************/ ++#ifndef FMC_VERSION ++#define FMC_VERSION 0xbc ++#endif ++ ++/* fmc IP version */ ++#ifndef FMC_VER_100 ++#define FMC_VER_100 (0x100) ++#endif ++ ++/*****************************************************************************/ ++/* DMA address align with 32 bytes. */ ++#define FMC_DMA_ALIGN 32 ++ ++#define FMC_CHIP_DELAY 25 ++/*****************************************************************************/ ++#define FMC_ECC_ERR_NUM0_BUF0 0xc0 ++#define GET_ECC_ERR_NUM(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) ++ ++#define DISABLE 0 ++#define ENABLE 1 ++ ++/*****************************************************************************/ ++#define FMC_REG_ADDRESS_LEN 0x200 ++ ++/*****************************************************************************/ ++#define FMC_MAX_READY_WAIT_JIFFIES (HZ) ++ ++#define MAX_SPI_NOR_ID_LEN 8 ++#define MAX_NAND_ID_LEN 8 ++#define MAX_SPI_NAND_ID_LEN 3 ++ ++#define GET_OP 0 ++#define SET_OP 1 ++ ++#define STATUS_ECC_MASK (0x3 << 4) ++#define STATUS_P_FAIL_MASK (1 << 3) ++#define STATUS_E_FAIL_MASK (1 << 2) ++#define STATUS_WEL_MASK (1 << 1) ++#define STATUS_OIP_MASK (1 << 0) ++ ++/*****************************************************************************/ ++#define FMC_VERSION 0xbc ++ ++/* fmc IP version */ ++#define FMC_VER_100 (0x100) ++ ++#define CONFIG_SPI_NAND_MAX_CHIP_NUM (1) ++ ++#define CONFIG_FMC100_MAX_NAND_CHIP (1) ++ ++/*****************************************************************************/ ++#define GET_PAGE_INDEX(host) \ ++ ((host->addr_value[0] >> 16) | (host->addr_value[1] << 16)) ++/*****************************************************************************/ ++#define FMC_MAX_CHIP_NUM 2 ++ ++extern unsigned char fmc_cs_user[]; ++ ++/*****************************************************************************/ ++#define fmc_readl(_host, _reg) \ ++ (readl((char *)_host->regbase + (_reg))) ++ ++#define fmc_readb( _addr) \ ++ (readb((void __iomem *)(_addr))) ++ ++#define fmc_readw( _addr) \ ++ (readw((void __iomem *)(_addr))) ++ ++#define fmc_writel(_host, _reg, _value) \ ++ (writel((u_int)(_value), ((char *)_host->regbase + (_reg)))) ++ ++#define fmc_writeb(_val, _addr) \ ++ (writeb((u_int)(_val), ((char *)_addr))) ++ ++/*****************************************************************************/ ++#define FMC_WAIT_TIMEOUT 0x2000000 ++ ++#define FMC_CMD_WAIT_CPU_FINISH(_host) \ ++ do { \ ++ unsigned regval, timeout = FMC_WAIT_TIMEOUT * 2; \ ++ do { \ ++ regval = fmc_readl((_host), FMC_OP); \ ++ --timeout; \ ++ } while ((regval & FMC_OP_REG_OP_START) && timeout); \ ++ if (!timeout) \ ++ pr_info("Error: Wait cmd cpu finish timeout!\n"); \ ++ } while (0) ++ ++/*****************************************************************************/ ++#define FMC_DMA_WAIT_INT_FINISH(_host) \ ++ do { \ ++ unsigned regval, timeout = FMC_WAIT_TIMEOUT; \ ++ do { \ ++ regval = fmc_readl((_host), FMC_INT); \ ++ --timeout; \ ++ } while ((!(regval & FMC_INT_OP_DONE) && timeout)); \ ++ if (!timeout) \ ++ pr_info("Error: Wait dma int finish timeout!\n"); \ ++ } while (0) ++ ++/*****************************************************************************/ ++#define FMC_DMA_WAIT_CPU_FINISH(_host) \ ++ do { \ ++ unsigned regval, timeout = FMC_WAIT_TIMEOUT; \ ++ do { \ ++ regval = fmc_readl((_host), FMC_OP_CTRL); \ ++ --timeout; \ ++ } while ((regval & OP_CTRL_DMA_OP_READY) && timeout); \ ++ if (!timeout) \ ++ pr_info("Error: Wait dma cpu finish timeout!\n"); \ ++ } while (0) ++ ++/*****************************************************************************/ ++#define BT_DBG 0 /* Boot init debug print */ ++#define ER_DBG 0 /* Erase debug print */ ++#define WR_DBG 0 /* Write debug print */ ++#define RD_DBG 0 /* Read debug print */ ++#define QE_DBG 0 /* Quad Enable debug print */ ++#define OP_DBG 0 /* OP command debug print */ ++#define DMA_DB 0 /* DMA read or write debug print */ ++#define AC_DBG 0 /* 3-4byte Address Cycle */ ++#define SR_DBG 0 /* Status Register debug print */ ++#define CR_DBG 0 /* Config Register debug print */ ++#define FT_DBG 0 /* Features debug print */ ++#define WE_DBG 0 /* Write Enable debug print */ ++#define BP_DBG 0 /* Block Protection debug print */ ++#define EC_DBG 0 /* enable/disable ecc0 and randomizer */ ++#define PM_DBG 0 /* power management debug */ ++ ++#define FMC_PR(_type, _fmt, arg...) \ ++ do { \ ++ if (_type) \ ++ DB_MSG(_fmt, ##arg) \ ++ } while (0) ++ ++#define DB_MSG(_fmt, arg...) \ ++ pr_info("%s(%d): " _fmt, __func__, __LINE__, ##arg); ++ ++#define DB_BUG(fmt, args...) \ ++ do { \ ++ pr_info("%s(%d): BUG: " fmt, __FILE__, __LINE__, ##args); \ ++ while (1) \ ++ ; \ ++ } while (0) ++ ++/*****************************************************************************/ ++enum fmc_iftype { ++ IF_TYPE_STD, ++ IF_TYPE_DUAL, ++ IF_TYPE_DIO, ++ IF_TYPE_QUAD, ++ IF_TYPE_QIO, ++}; ++ ++struct bsp_fmc { ++ void __iomem *regbase; ++ void __iomem *iobase; ++ struct clk *clk; ++ struct mutex lock; ++ void *buffer; ++ dma_addr_t dma_buffer; ++ unsigned int dma_len; ++}; ++ ++struct fmc_cmd_op { ++ unsigned char cs; ++ unsigned char cmd; ++ unsigned char l_cmd; ++ unsigned char addr_h; ++ unsigned int addr_l; ++ unsigned int data_no; ++ unsigned short option; ++ unsigned short op_cfg; ++}; ++ ++extern struct mutex fmc_switch_mutex; ++ ++#endif /*__BSP_FMC_H*/ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mm_types.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mm_types.h.patch new file mode 100644 index 00000000..c04986b8 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mm_types.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/include/linux/mm_types.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/mm_types.h 2021-06-07 13:01:34.000000000 +0300 +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-card.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-card.h.patch new file mode 100644 index 00000000..2610cc85 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-card.h.patch @@ -0,0 +1,90 @@ +--- linux-4.9.37/include/linux/mmc/card.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/mmc/card.h 2021-06-07 13:01:34.000000000 +0300 +@@ -14,6 +14,8 @@ + #include + #include + ++#define MMC_CARD_CMDQ_BLK_SIZE 512 ++ + struct mmc_cid { + unsigned int manfid; + char prod_name[8]; +@@ -84,6 +86,7 @@ + unsigned int hpi_cmd; /* cmd used as HPI */ + bool bkops; /* background support bit */ + bool man_bkops_en; /* manual bkops enable bit */ ++ bool auto_bkops_en; /* auto bkops enable bit */ + unsigned int data_sector_size; /* 512 bytes or 4KB */ + unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ + unsigned int boot_ro_lock; /* ro lock support */ +@@ -119,6 +122,8 @@ + u8 raw_pwr_cl_ddr_200_360; /* 253 */ + u8 raw_bkops_status; /* 246 */ + u8 raw_sectors[4]; /* 212 - 4 bytes */ ++ u8 cmdq_depth; /* 307 */ ++ u8 cmdq_support; /* 308 */ + + unsigned int feature_support; + #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ +@@ -264,6 +269,8 @@ + #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ + #define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ + #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ ++#define MMC_STATE_CMDQ (1<<7) /* card is in cmd queue mode */ ++ + unsigned int quirks; /* card quirks */ + #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ + #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ +@@ -281,7 +288,8 @@ + #define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */ + #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ + #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ +- ++/* Make sure CMDQ is empty before queuing DCMD */ ++#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD (1 << 14) + + unsigned int erase_size; /* erase size in sectors */ + unsigned int erase_shift; /* if erase unit is power 2 */ +@@ -316,6 +324,8 @@ + struct dentry *debugfs_root; + struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ + unsigned int nr_parts; ++ unsigned int part_curr; ++ bool cmdq_init; + }; + + /* +@@ -453,6 +463,7 @@ + #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) + #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) + #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) ++#define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ) + + #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) + #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) +@@ -463,6 +474,8 @@ + #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) + #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) + #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) ++#define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ) ++#define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ) + + /* + * Quirk add/remove for MMC products. +@@ -538,6 +551,16 @@ + return c->quirks & MMC_QUIRK_BROKEN_HPI; + } + ++static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) ++{ ++ return c->ext_csd.man_bkops_en; ++} ++ ++static inline bool mmc_card_configured_auto_bkops(const struct mmc_card *c) ++{ ++ return c->ext_csd.auto_bkops_en; ++} ++ + #define mmc_card_name(c) ((c)->cid.prod_name) + #define mmc_card_id(c) (dev_name(&(c)->dev)) + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-core.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-core.h.patch new file mode 100644 index 00000000..09fc6914 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-core.h.patch @@ -0,0 +1,47 @@ +--- linux-4.9.37/include/linux/mmc/core.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/mmc/core.h 2021-06-07 13:01:34.000000000 +0300 +@@ -142,10 +142,26 @@ + + /* Allow other commands during this ongoing data transfer or busy wait */ + bool cap_cmd_during_tfr; ++ struct mmc_cmdq_req *cmdq_req; ++ struct request *req; + }; + + struct mmc_card; + struct mmc_async_req; ++struct mmc_cmdq_req; ++ ++extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks); ++extern int mmc_cmdq_halt(struct mmc_host *host, bool enable); ++extern int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host); ++extern void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err); ++extern int mmc_cmdq_start_req(struct mmc_host *host, ++ struct mmc_cmdq_req *cmdq_req); ++extern int mmc_cmdq_prepare_flush(struct mmc_command *cmd); ++extern int mmc_cmdq_wait_for_dcmd(struct mmc_host *host, ++ struct mmc_cmdq_req *cmdq_req); ++extern int mmc_cmdq_erase(struct mmc_cmdq_req *cmdq_req, ++ struct mmc_card *card, unsigned int from, unsigned int nr, ++ unsigned int arg); + + extern int mmc_stop_bkops(struct mmc_card *); + extern int mmc_read_bkops_status(struct mmc_card *); +@@ -161,6 +177,9 @@ + extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, + struct mmc_command *, int); + extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); ++extern int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, ++ u8 value, unsigned int timeout_ms, ++ bool use_busy_signal, bool ignore_timeout); + extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); + extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); + extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); +@@ -190,6 +209,7 @@ + extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, + bool is_rel_write); + extern int mmc_hw_reset(struct mmc_host *host); ++extern int mmc_cmdq_hw_reset(struct mmc_host *host); + extern int mmc_can_reset(struct mmc_card *card); + + extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-host.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-host.h.patch new file mode 100644 index 00000000..1f3e2698 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-host.h.patch @@ -0,0 +1,200 @@ +--- linux-4.9.37/include/linux/mmc/host.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/mmc/host.h 2021-06-07 13:01:34.000000000 +0300 +@@ -82,6 +82,17 @@ + bool enhanced_strobe; /* hs400es selection */ + }; + ++struct mmc_cmdq_host_ops { ++ int (*init)(struct mmc_host *host); ++ int (*enable)(struct mmc_host *host); ++ void (*disable)(struct mmc_host *host, bool soft); ++ int (*request)(struct mmc_host *host, struct mmc_request *mrq); ++ void (*post_req)(struct mmc_host *host, int tag, int err); ++ int (*halt)(struct mmc_host *host, bool halt); ++ void (*reset)(struct mmc_host *host, bool soft); ++ void (*dumpstate)(struct mmc_host *host); ++}; ++ + struct mmc_host_ops { + /* + * It is optional for the host to implement pre_req and post_req in +@@ -161,11 +172,37 @@ + */ + int (*multi_io_quirk)(struct mmc_card *card, + unsigned int direction, int blk_size); ++ void (*notify_halt)(struct mmc_host *mmc, bool halt); ++ int (*card_info_save)(struct mmc_host *host); + }; + + struct mmc_card; + struct device; + ++struct mmc_cmdq_req { ++ unsigned int cmd_flags; ++ u32 blk_addr; ++ /* active mmc request */ ++ struct mmc_request mrq; ++ struct mmc_data data; ++ struct mmc_command cmd; ++#define DCMD (1 << 0) ++#define QBR (1 << 1) ++#define DIR (1 << 2) ++#define PRIO (1 << 3) ++#define REL_WR (1 << 4) ++#define DAT_TAG (1 << 5) ++#define FORCED_PRG (1 << 6) ++ unsigned int cmdq_req_flags; ++ ++ unsigned int resp_idx; ++ unsigned int resp_arg; ++ unsigned int dev_pend_tasks; ++ bool resp_err; ++ int tag; /* used for command queuing */ ++ u8 ctx_id; ++}; ++ + struct mmc_async_req { + /* active mmc request */ + struct mmc_request *mrq; +@@ -192,6 +229,33 @@ + void *handler_priv; + }; + ++ ++/** ++ * mmc_cmdq_context_info - describes the contexts of cmdq ++ * @active_reqs requests being processed ++ * @data_active_reqs data requests being processed ++ * @curr_state state of cmdq engine ++ * @cmdq_ctx_lock acquire this before accessing this structure ++ * @queue_empty_wq workqueue for waiting for all ++ * the outstanding requests to be completed ++ * @wait waiting for all conditions described in ++ * mmc_cmdq_ready_wait to be satisified before ++ * issuing the new request to LLD. ++ */ ++struct mmc_cmdq_context_info { ++ unsigned long active_reqs; /* in-flight requests */ ++ unsigned long data_active_reqs; /* in-flight data requests */ ++ unsigned long curr_state; ++#define CMDQ_STATE_ERR 0 ++#define CMDQ_STATE_DCMD_ACTIVE 1 ++#define CMDQ_STATE_HALT 2 ++#define CMDQ_STATE_CQ_DISABLE 3 ++#define CMDQ_STATE_REQ_TIMED_OUT 4 ++ wait_queue_head_t queue_empty_wq; ++ wait_queue_head_t wait; ++ int active_small_sector_read_reqs; ++}; ++ + /** + * mmc_context_info - synchronization details for mmc context + * @is_done_rcv wake up reason was done request +@@ -221,10 +285,17 @@ + struct device class_dev; + int index; + const struct mmc_host_ops *ops; ++ const struct mmc_cmdq_host_ops *cmdq_ops; + struct mmc_pwrseq *pwrseq; + unsigned int f_min; + unsigned int f_max; + unsigned int f_init; ++ unsigned int type; ++#define MMC_HOST_TYPE_MMC 0 /* MMC card */ ++#define MMC_HOST_TYPE_SD 1 /* SD card */ ++#define MMC_HOST_TYPE_SDIO 2 /* SDIO card */ ++#define MMC_HOST_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ ++ + u32 ocr_avail; + u32 ocr_avail_sdio; /* SDIO-specific OCR */ + u32 ocr_avail_sd; /* SD-specific OCR */ +@@ -312,6 +383,7 @@ + #define MMC_CAP2_HS400_ES (1 << 20) /* Host supports enhanced strobe */ + #define MMC_CAP2_NO_SD (1 << 21) /* Do not send SD commands during initialization */ + #define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ ++#define MMC_CAP2_CMD_QUEUE (1 << 23) /* support eMMC command queue */ + + mmc_pm_flag_t pm_caps; /* supported pm features */ + +@@ -359,6 +431,11 @@ + + struct delayed_work detect; + int detect_change; /* card detect flag */ ++ u32 card_status; ++#define MMC_CARD_UNINIT 0 ++#define MMC_CARD_INIT 1 ++#define MMC_CARD_INIT_FAIL 2 ++ + struct mmc_slot slot; + + const struct mmc_bus_ops *bus_ops; /* current bus driver */ +@@ -397,6 +474,20 @@ + int dsr_req; /* DSR value is valid */ + u32 dsr; /* optional driver stage (DSR) value */ + ++ struct mmc_cmdq_context_info cmdq_ctx; ++ int num_cq_slots; ++ int dcmd_cq_slot; ++ u32 cmdq_thist_enabled; ++ /* ++ * several cmdq supporting host controllers are extensions ++ * of legacy controllers. This variable can be used to store ++ * a reference to the cmdq extension of the existing host ++ * controller. ++ */ ++ void *cmdq_private; ++ struct mmc_request *err_mrq; ++ struct timeval start; ++ struct timeval end; + unsigned long private[0] ____cacheline_aligned; + }; + +@@ -411,6 +502,11 @@ + return (void *)host->private; + } + ++static inline void *mmc_cmdq_private(struct mmc_host *host) ++{ ++ return host->cmdq_private; ++} ++ + #define mmc_host_is_spi(host) ((host)->caps & MMC_CAP_SPI) + + #define mmc_dev(x) ((x)->parent) +@@ -500,6 +596,36 @@ + return host->caps2 & MMC_CAP2_PACKED_WR; + } + ++static inline void mmc_host_set_halt(struct mmc_host *host) ++{ ++ set_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); ++} ++ ++static inline void mmc_host_clr_halt(struct mmc_host *host) ++{ ++ clear_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); ++} ++ ++static inline int mmc_host_halt(struct mmc_host *host) ++{ ++ return test_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); ++} ++ ++static inline void mmc_host_set_cq_disable(struct mmc_host *host) ++{ ++ set_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); ++} ++ ++static inline void mmc_host_clr_cq_disable(struct mmc_host *host) ++{ ++ clear_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); ++} ++ ++static inline int mmc_host_cq_disable(struct mmc_host *host) ++{ ++ return test_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); ++} ++ + static inline int mmc_card_hs(struct mmc_card *card) + { + return card->host->ios.timing == MMC_TIMING_SD_HS || diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-mmc.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-mmc.h.patch new file mode 100644 index 00000000..e0ed3995 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mmc-mmc.h.patch @@ -0,0 +1,40 @@ +--- linux-4.9.37/include/linux/mmc/mmc.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/mmc/mmc.h 2021-06-07 13:01:34.000000000 +0300 +@@ -84,6 +84,11 @@ + #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ + #define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ + ++/* class 11 */ ++#define MMC_CMDQ_TASK_MGMT 48 /* ac [31:0] task ID R1b */ ++#define DISCARD_QUEUE 0x1 ++#define DISCARD_TASK 0x2 ++ + static inline bool mmc_op_multi(u32 opcode) + { + return opcode == MMC_WRITE_MULTIPLE_BLOCK || +@@ -272,6 +277,7 @@ + * EXT_CSD fields + */ + ++#define EXT_CSD_CMDQ 15 /* R/W */ + #define EXT_CSD_FLUSH_CACHE 32 /* W */ + #define EXT_CSD_CACHE_CTRL 33 /* R/W */ + #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ +@@ -331,6 +337,9 @@ + #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ + #define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */ + #define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */ ++#define EXT_CSD_CMDQ_DEPTH 307 /* RO */ ++#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */ ++ + #define EXT_CSD_SUPPORTED_MODE 493 /* RO */ + #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ + #define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ +@@ -436,6 +445,7 @@ + * BKOPS modes + */ + #define EXT_CSD_MANUAL_BKOPS_MASK 0x01 ++#define EXT_CSD_AUTO_BKOPS_MASK 0x02 + + /* + * MMC_SWITCH access modes diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mtd-nand.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mtd-nand.h.patch new file mode 100644 index 00000000..f2bf0697 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mtd-nand.h.patch @@ -0,0 +1,37 @@ +--- linux-4.9.37/include/linux/mtd/nand.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/mtd/nand.h 2021-06-07 13:01:34.000000000 +0300 +@@ -80,6 +80,7 @@ + #define NAND_CMD_READOOB 0x50 + #define NAND_CMD_ERASE1 0x60 + #define NAND_CMD_STATUS 0x70 ++#define NAND_CMD_STATUS_MULTI 0x71 + #define NAND_CMD_SEQIN 0x80 + #define NAND_CMD_RNDIN 0x85 + #define NAND_CMD_READID 0x90 +@@ -87,6 +88,7 @@ + #define NAND_CMD_PARAM 0xec + #define NAND_CMD_GET_FEATURES 0xee + #define NAND_CMD_SET_FEATURES 0xef ++#define NAND_CMD_SYNC_RESET 0xfc + #define NAND_CMD_RESET 0xff + + #define NAND_CMD_LOCK 0x2a +@@ -925,9 +927,18 @@ + #define NAND_MFR_AMD 0x01 + #define NAND_MFR_MACRONIX 0xc2 + #define NAND_MFR_EON 0x92 ++#define NAND_MFR_WINBOND 0xef ++#define NAND_MFR_ATO 0x9b ++#define NAND_MFR_MXIC 0xc2 ++#define NAND_MFR_ALL_FLASH 0xc1 ++#define NAND_MFR_PARAGON 0xa1 + #define NAND_MFR_SANDISK 0x45 + #define NAND_MFR_INTEL 0x89 + #define NAND_MFR_ATO 0x9b ++#define NAND_MFR_GD_ESMT 0xc8 ++#define NAND_MFR_HEYANGTEK 0xc9 ++#define NAND_MFR_DOSILICON 0xe5 ++#define NAND_MFR_FIDELIX 0xf8 + + /* The maximum expected count of bytes in the NAND ID sequence */ + #define NAND_MAX_ID_LEN 8 diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mtd-spi-nor.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mtd-spi-nor.h.patch new file mode 100644 index 00000000..80098d10 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-mtd-spi-nor.h.patch @@ -0,0 +1,344 @@ +--- linux-4.9.37/include/linux/mtd/spi-nor.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/mtd/spi-nor.h 2021-06-07 13:01:34.000000000 +0300 +@@ -12,7 +12,6 @@ + + #include + #include +-#include + + /* + * Manufacturer IDs +@@ -21,13 +20,53 @@ + * Sometimes these are the same as CFI IDs, but sometimes they aren't. + */ + #define SNOR_MFR_ATMEL CFI_MFR_ATMEL +-#define SNOR_MFR_GIGADEVICE 0xc8 + #define SNOR_MFR_INTEL CFI_MFR_INTEL + #define SNOR_MFR_MICRON CFI_MFR_ST /* ST Micro <--> Micron */ + #define SNOR_MFR_MACRONIX CFI_MFR_MACRONIX + #define SNOR_MFR_SPANSION CFI_MFR_AMD + #define SNOR_MFR_SST CFI_MFR_SST +-#define SNOR_MFR_WINBOND 0xef /* Also used by some Spansion */ ++#define SNOR_MFR_EON CFI_MFR_EON ++#define SNOR_MFR_WINBOND 0xef ++#define SNOR_MFR_ESMT 0x8c ++#define SNOR_MFR_GD 0xc8 ++#define SNOR_MFR_XTX 0x0b ++#define SNOR_MFR_PUYA 0x85 ++#define SNOR_MFR_ISSI 0x9d ++ ++/* Flash set the RESET# from */ ++#define SPI_NOR_SR_RST_MASK BIT(7) ++#define SPI_NOR_GET_RST(val) (((val) & SPI_NOR_SR_RST_MASK) >> 7) ++#define SPI_NOR_SET_RST(val) ((val) | SPI_NOR_SR_RST_MASK) ++ ++/* Flash block protect */ ++#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT ++#define _2M (0x200000UL) ++#define _4M (0x400000UL) ++#define _8M (0x800000UL) ++#define _16M (0x1000000UL) ++#define _32M (0x2000000UL) ++ ++#define BP_NUM_3 3 ++#define BP_NUM_4 4 ++ ++#define DEBUG_SPI_NOR_BP 0 ++ ++#define SPI_NOR_SR_SRWD_SHIFT 7 ++#define SPI_NOR_SR_SRWD_MASK (1 << SPI_NOR_SR_SRWD_SHIFT) ++ ++#define SPI_NOR_SR_BP0_SHIFT 2 ++#define SPI_NOR_SR_BP_WIDTH_4 0xf ++#define SPI_NOR_SR_BP_MASK_4 (SPI_NOR_SR_BP_WIDTH_4 << SPI_NOR_SR_BP0_SHIFT) ++ ++#define SPI_NOR_SR_BP_WIDTH_3 0x7 ++#define SPI_NOR_SR_BP_MASK_3 (SPI_NOR_SR_BP_WIDTH_3 << SPI_NOR_SR_BP0_SHIFT) ++ ++#define SPI_NOR_SR_TB_SHIFT 3 ++#define SPI_NOR_SR_TB_MASK (1 << SPI_NOR_SR_TB_SHIFT) ++ ++#define LOCK_LEVEL_MAX(bp_num) (((0x01) << bp_num) - 1) ++ ++#endif /* CONFIG_SPI_BLOCK_PROTECT */ + + /* + * Note on opcode nomenclature: some opcodes have a format like +@@ -40,27 +79,42 @@ + /* Flash opcodes. */ + #define SPINOR_OP_WREN 0x06 /* Write enable */ + #define SPINOR_OP_RDSR 0x05 /* Read status register */ ++#define SPINOR_OP_RDSR2 0x35 /* Read Status Register-2 */ ++#define SPINOR_OP_RDSR3 0x15 /* Read Status Register-3 */ + #define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ ++#define SPINOR_OP_WRSR2 0x31 /* Write Status Register-2 1 byte*/ ++#define SPINOR_OP_WRSR3 0x11 /* Write Status Register-3 1 byte*/ + #define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ + #define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ +-#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */ +-#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */ ++#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */ ++#define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */ ++#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */ ++#define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */ + #define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ ++#define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */ ++#define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */ + #define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */ + #define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ + #define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */ + #define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */ + #define SPINOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */ + #define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */ ++#define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ + #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ + #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ + + /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ +-#define SPINOR_OP_READ4 0x13 /* Read data bytes (low frequency) */ +-#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */ +-#define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */ +-#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */ ++#define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ ++#define SPINOR_OP_READ_FAST_4B 0x0c /* Read data bytes (high frequency) */ ++#define SPINOR_OP_READ_1_1_2_4B 0x3c /* Read data bytes (Dual Output SPI) */ ++#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */ ++#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */ ++#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */ + #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ ++#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */ ++#define SPINOR_OP_PP_1_4_4_4B 0x3e /* Quad page program */ ++#define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */ ++#define SPINOR_OP_BE_32K_4B 0x5c /* Erase 32KiB block */ + #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ + + /* Used for SST flashes only. */ +@@ -73,12 +127,20 @@ + #define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ + + /* Used for Spansion flashes only. */ ++#define SPINOR_OP_BRRD 0x16 /* Bank register write */ + #define SPINOR_OP_BRWR 0x17 /* Bank register write */ + ++/* Used for GigaDevice flashes only. */ ++#define SPINOR_OP_WRCR 0x31 /* Config register write */ ++ + /* Used for Micron flashes only. */ + #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ + #define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */ + ++/* Software reset code */ ++#define SPINOR_ENABLE_RESET 0x66 /* Enable reset */ ++#define SPINOR_OP_RESET 0x99 /* Reset */ ++ + /* Status Register bits. */ + #define SR_WIP BIT(0) /* Write in progress */ + #define SR_WEL BIT(1) /* Write enable latch */ +@@ -90,8 +152,9 @@ + #define SR_SRWD BIT(7) /* SR write protect */ + + #define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ +- ++#define CR_DUMMY_CYCLE (0x03 << 6) /* Macronix dummy cycle bits */ + /* Enhanced Volatile Configuration Register bits */ ++#define EVCR_DUAL_EN_MICRON BIT(6) /* Micron Dual I/O */ + #define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ + + /* Flag Status Register bits */ +@@ -99,12 +162,109 @@ + + /* Configuration Register bits. */ + #define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */ ++#define QUAD_EN_ISSI BIT(6) ++/* Status Register bits. */ ++#define SR_QUAD_EN_XTX BIT(1) ++ ++/* Supported modes */ ++enum spi_nor_mode_index { ++ /* Sorted by ascending priority order */ ++ SNOR_MIDX_SLOW = 0, ++ SNOR_MIDX_1_1_1, ++ SNOR_MIDX_1_1_2, ++ SNOR_MIDX_1_2_2, ++ SNOR_MIDX_1_1_4, ++ SNOR_MIDX_1_4_4, ++ ++ SNOR_MIDX_MAX ++}; ++ ++#define SNOR_MODE_SLOW BIT(SNOR_MIDX_SLOW) ++#define SNOR_MODE_1_1_1 BIT(SNOR_MIDX_1_1_1) ++#define SNOR_MODE_1_1_2 BIT(SNOR_MIDX_1_1_2) ++#define SNOR_MODE_1_2_2 BIT(SNOR_MIDX_1_2_2) ++#define SNOR_MODE_1_1_4 BIT(SNOR_MIDX_1_1_4) ++#define SNOR_MODE_1_4_4 BIT(SNOR_MIDX_1_4_4) ++ ++struct spi_nor_modes { ++ u32 rd_modes; /* supported SPI modes for (Fast) Read */ ++ u32 wr_modes; /* supported SPI modes for Page Program */ ++}; ++ ++struct spi_nor_read_op { ++ u8 num_mode_clocks; ++ u8 num_wait_states; ++ u8 opcode; ++}; + +-enum read_mode { +- SPI_NOR_NORMAL = 0, +- SPI_NOR_FAST, +- SPI_NOR_DUAL, +- SPI_NOR_QUAD, ++#define SNOR_OP_READ(_num_mode_clocks, _num_wait_states, _opcode) \ ++ { \ ++ .num_mode_clocks = _num_mode_clocks, \ ++ .num_wait_states = _num_wait_states, \ ++ .opcode = _opcode, \ ++ } ++ ++struct spi_nor_erase_type { ++ u8 size; /* specifies 'N' so erase size = 2^N */ ++ u8 opcode; ++}; ++ ++#define SNOR_OP_ERASE(_size, _opcode) { .size = _size, .opcode = _opcode } ++#define SNOR_OP_ERASE_64K(_opcode) SNOR_OP_ERASE(0x10, _opcode) ++#define SNOR_OP_ERASE_32K(_opcode) SNOR_OP_ERASE(0x0f, _opcode) ++#define SNOR_OP_ERASE_4K(_opcode) SNOR_OP_ERASE(0x0c, _opcode) ++ ++struct spi_nor; ++ ++#define SNOR_MAX_ERASE_TYPES 4 ++ ++struct spi_nor_basic_flash_parameter { ++ /* Fast Read settings */ ++ u32 rd_modes; ++ struct spi_nor_read_op reads[SNOR_MIDX_MAX]; ++ ++ /* Page Program settings */ ++ u32 wr_modes; ++ u8 page_programs[SNOR_MIDX_MAX]; ++ ++ /* Sector Erase settings */ ++ struct spi_nor_erase_type erase_types[SNOR_MAX_ERASE_TYPES]; ++ ++ int (*enable_quad_io)(struct spi_nor *nor); ++}; ++ ++#define SNOR_PROTO_CODE_OFF 8 ++#define SNOR_PROTO_CODE_MASK GENMASK(11, 8) ++#define SNOR_PROTO_CODE_TO_PROTO(code) \ ++ (((code) << SNOR_PROTO_CODE_OFF) & SNOR_PROTO_CODE_MASK) ++#define SNOR_PROTO_CODE_FROM_PROTO(proto) \ ++ ((((u32)(proto)) & SNOR_PROTO_CODE_MASK) >> SNOR_PROTO_CODE_OFF) ++ ++#define SNOR_PROTO_ADDR_OFF 4 ++#define SNOR_PROTO_ADDR_MASK GENMASK(7, 4) ++#define SNOR_PROTO_ADDR_TO_PROTO(addr) \ ++ (((addr) << SNOR_PROTO_ADDR_OFF) & SNOR_PROTO_ADDR_MASK) ++#define SNOR_PROTO_ADDR_FROM_PROTO(proto) \ ++ ((((u32)(proto)) & SNOR_PROTO_ADDR_MASK) >> SNOR_PROTO_ADDR_OFF) ++ ++#define SNOR_PROTO_DATA_OFF 0 ++#define SNOR_PROTO_DATA_MASK GENMASK(3, 0) ++#define SNOR_PROTO_DATA_TO_PROTO(data) \ ++ (((data) << SNOR_PROTO_DATA_OFF) & SNOR_PROTO_DATA_MASK) ++#define SNOR_PROTO_DATA_FROM_PROTO(proto) \ ++ ((((u32)(proto)) & SNOR_PROTO_DATA_MASK) >> SNOR_PROTO_DATA_OFF) ++ ++#define SNOR_PROTO(code, addr, data) \ ++ (SNOR_PROTO_CODE_TO_PROTO(code) | \ ++ SNOR_PROTO_ADDR_TO_PROTO(addr) | \ ++ SNOR_PROTO_DATA_TO_PROTO(data)) ++ ++enum spi_nor_protocol { ++ SNOR_PROTO_1_1_1 = SNOR_PROTO(1, 1, 1), /* SPI */ ++ SNOR_PROTO_1_1_2 = SNOR_PROTO(1, 1, 2), /* Dual Output */ ++ SNOR_PROTO_1_2_2 = SNOR_PROTO(1, 2, 2), /* Dual IO */ ++ SNOR_PROTO_1_1_4 = SNOR_PROTO(1, 1, 4), /* Quad Output */ ++ SNOR_PROTO_1_4_4 = SNOR_PROTO(1, 4, 4), /* Quad IO */ + }; + + #define SPI_NOR_MAX_CMD_SIZE 8 +@@ -121,20 +281,26 @@ + SNOR_F_HAS_SR_TB = BIT(1), + }; + ++struct mtd_info; ++ + /** + * struct spi_nor - Structure for defining a the SPI NOR layer + * @mtd: point to a mtd_info structure + * @lock: the lock for the read/write/erase/lock/unlock operations + * @dev: point to a spi device, or a spi nor controller device. ++ * @flash_node: point to a device node describing this flash instance. + * @page_size: the page size of the SPI NOR + * @addr_width: number of address bytes + * @erase_opcode: the opcode for erasing a sector + * @read_opcode: the read opcode + * @read_dummy: the dummy needed by the read operation + * @program_opcode: the program opcode +- * @flash_read: the mode of the read + * @sst_write_second: used by the SST write operation + * @flags: flag options for the current SPI-NOR (SNOR_F_*) ++ * @erase_proto: the SPI protocol used by erase operations ++ * @read_proto: the SPI protocol used by read operations ++ * @write_proto: the SPI protocol used by write operations ++ * @reg_proto the SPI protocol used by read_reg/write_reg operations + * @cmd_buf: used by the write_reg + * @prepare: [OPTIONAL] do some preparations for the + * read/write/erase/lock/unlock operations +@@ -157,13 +323,16 @@ + struct mtd_info mtd; + struct mutex lock; + struct device *dev; ++ struct device_node *flash_node; + u32 page_size; + u8 addr_width; + u8 erase_opcode; + u8 read_opcode; + u8 read_dummy; + u8 program_opcode; +- enum read_mode flash_read; ++ enum spi_nor_protocol erase_proto; ++ enum spi_nor_protocol read_proto; ++ enum spi_nor_protocol write_proto; + bool sst_write_second; + u32 flags; + u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; +@@ -183,6 +352,12 @@ + int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); + int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); + ++#ifdef CONFIG_GOKE_SPI_BLOCK_PROTECT ++ unsigned int end_addr; ++ unsigned int lock_level_max; ++ unsigned char level; ++#endif ++ u32 clkrate; + void *priv; + }; + +@@ -201,7 +376,7 @@ + * spi_nor_scan() - scan the SPI NOR + * @nor: the spi_nor structure + * @name: the chip type name +- * @mode: the read mode supported by the driver ++ * @modes: the SPI modes supported by the controller driver + * + * The drivers can use this fuction to scan the SPI NOR. + * In the scanning, it will try to get all the necessary information to +@@ -211,6 +386,12 @@ + * + * Return: 0 for success, others for failure. + */ +-int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode); ++int spi_nor_scan(struct spi_nor *nor, const char *name, ++ struct spi_nor_modes *modes); ++void spi_nor_driver_shutdown(struct spi_nor *nor); ++#ifdef CONFIG_PM ++int spi_nor_suspend(struct spi_nor *nor, pm_message_t state); ++int spi_nor_resume(struct spi_nor *nor); ++#endif + + #endif diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-nospec.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-nospec.h.patch new file mode 100644 index 00000000..38a35e93 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-nospec.h.patch @@ -0,0 +1,75 @@ +--- linux-4.9.37/include/linux/nospec.h 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/include/linux/nospec.h 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,72 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright(c) 2018 Linus Torvalds. All rights reserved. ++// Copyright(c) 2018 Alexei Starovoitov. All rights reserved. ++// Copyright(c) 2018 Intel Corporation. All rights reserved. ++ ++#ifndef _LINUX_NOSPEC_H ++#define _LINUX_NOSPEC_H ++ ++/** ++ * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise ++ * @index: array element index ++ * @size: number of elements in array ++ * ++ * When @index is out of bounds (@index >= @size), the sign bit will be ++ * set. Extend the sign bit to all bits and invert, giving a result of ++ * zero for an out of bounds index, or ~0 if within bounds [0, @size). ++ */ ++#ifndef array_index_mask_nospec ++static inline unsigned long array_index_mask_nospec(unsigned long index, ++ unsigned long size) ++{ ++ /* ++ * Warn developers about inappropriate array_index_nospec() usage. ++ * ++ * Even if the CPU speculates past the WARN_ONCE branch, the ++ * sign bit of @index is taken into account when generating the ++ * mask. ++ * ++ * This warning is compiled out when the compiler can infer that ++ * @index and @size are less than LONG_MAX. ++ */ ++ if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX, ++ "array_index_nospec() limited to range of [0, LONG_MAX]\n")) ++ return 0; ++ ++ /* ++ * Always calculate and emit the mask even if the compiler ++ * thinks the mask is not needed. The compiler does not take ++ * into account the value of @index under speculation. ++ */ ++ OPTIMIZER_HIDE_VAR(index); ++ return ~(long)(index | (size - 1UL - index)) >> (BITS_PER_LONG - 1); ++} ++#endif ++ ++/* ++ * array_index_nospec - sanitize an array index after a bounds check ++ * ++ * For a code sequence like: ++ * ++ * if (index < size) { ++ * index = array_index_nospec(index, size); ++ * val = array[index]; ++ * } ++ * ++ * ...if the CPU speculates past the bounds check then ++ * array_index_nospec() will clamp the index within the range of [0, ++ * size). ++ */ ++#define array_index_nospec(index, size) \ ++ ({ \ ++ typeof(index) _i = (index); \ ++ typeof(size) _s = (size); \ ++ unsigned long _mask = array_index_mask_nospec(_i, _s); \ ++ \ ++ BUILD_BUG_ON(sizeof(_i) > sizeof(long)); \ ++ BUILD_BUG_ON(sizeof(_s) > sizeof(long)); \ ++ \ ++ _i &= _mask; \ ++ _i; \ ++ }) ++#endif /* _LINUX_NOSPEC_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-phy.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-phy.h.patch new file mode 100644 index 00000000..984b9059 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-phy.h.patch @@ -0,0 +1,13 @@ +--- linux-4.9.37/include/linux/phy.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/phy.h 2021-06-07 13:01:34.000000000 +0300 +@@ -829,6 +829,10 @@ + int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, + int (*run)(struct phy_device *)); + ++int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask); ++int phy_unregister_fixup_for_id(const char *bus_id); ++int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask); ++ + int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable); + int phy_get_eee_err(struct phy_device *phydev); + int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-psci.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-psci.h.patch new file mode 100644 index 00000000..34312fa3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-psci.h.patch @@ -0,0 +1,25 @@ +--- linux-4.9.37/include/linux/psci.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/psci.h 2021-06-07 13:01:34.000000000 +0300 +@@ -25,7 +25,14 @@ + int psci_cpu_init_idle(unsigned int cpu); + int psci_cpu_suspend_enter(unsigned long index); + ++enum psci_conduit { ++ PSCI_CONDUIT_NONE, ++ PSCI_CONDUIT_SMC, ++ PSCI_CONDUIT_HVC, ++}; ++ + struct psci_operations { ++ u32 (*get_version)(void); + int (*cpu_suspend)(u32 state, unsigned long entry_point); + int (*cpu_off)(u32 state); + int (*cpu_on)(unsigned long cpuid, unsigned long entry_point); +@@ -33,6 +40,7 @@ + int (*affinity_info)(unsigned long target_affinity, + unsigned long lowest_affinity_level); + int (*migrate_info_type)(void); ++ enum psci_conduit conduit; + }; + + extern struct psci_operations psci_ops; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-sched.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-sched.h.patch new file mode 100644 index 00000000..93c53209 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-sched.h.patch @@ -0,0 +1,18 @@ +--- linux-4.9.37/include/linux/sched.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/sched.h 2021-06-07 13:01:34.000000000 +0300 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -38,7 +39,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-spi-spi.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-spi-spi.h.patch new file mode 100644 index 00000000..66c58ee3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-spi-spi.h.patch @@ -0,0 +1,28 @@ +--- linux-4.9.37/include/linux/spi/spi.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/spi/spi.h 2021-06-07 13:01:34.000000000 +0300 +@@ -233,6 +233,8 @@ + * @remove: Unbinds this driver from the spi device + * @shutdown: Standard shutdown callback used during system state + * transitions such as powerdown/halt and kexec ++ * @suspend: Standard suspend callback used during system state transitions ++ * @resume: Standard resume callback used during system state transitions + * @driver: SPI device drivers should initialize the name and owner + * field of this structure. + * +@@ -253,6 +255,8 @@ + int (*probe)(struct spi_device *spi); + int (*remove)(struct spi_device *spi); + void (*shutdown)(struct spi_device *spi); ++ int (*suspend)(struct spi_device *spi, pm_message_t mesg); ++ int (*resume)(struct spi_device *spi); + struct device_driver driver; + }; + +@@ -442,6 +446,7 @@ + #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ + #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ + #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ ++ bool slave; + + /* + * on some hardware transfer / message size may be constrained diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-tcp.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-tcp.h.patch new file mode 100644 index 00000000..f6dbce09 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-tcp.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/include/linux/tcp.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/tcp.h 2021-06-07 13:01:34.000000000 +0300 +@@ -432,4 +432,7 @@ + tp->saved_syn = NULL; + } + ++int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount, ++ int shiftlen); ++ + #endif /* _LINUX_TCP_H */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-usb-usbnet.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-usb-usbnet.h.patch new file mode 100644 index 00000000..6a151e30 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-linux-usb-usbnet.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/include/linux/usb/usbnet.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/linux/usb/usbnet.h 2021-06-07 13:01:34.000000000 +0300 +@@ -204,6 +204,7 @@ + }; + + extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *); ++extern int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf); + extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *); + extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *); + extern void usbnet_cdc_status(struct usbnet *, struct urb *); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-net-netns-ipv4.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-net-netns-ipv4.h.patch new file mode 100644 index 00000000..c389b59f --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-net-netns-ipv4.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/include/net/netns/ipv4.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/net/netns/ipv4.h 2021-06-07 13:01:34.000000000 +0300 +@@ -94,6 +94,7 @@ + #endif + int sysctl_tcp_mtu_probing; + int sysctl_tcp_base_mss; ++ int sysctl_tcp_min_snd_mss; + int sysctl_tcp_probe_threshold; + u32 sysctl_tcp_probe_interval; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-net-tcp.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-net-tcp.h.patch new file mode 100644 index 00000000..c462a5bd --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-net-tcp.h.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/include/net/tcp.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/net/tcp.h 2021-06-07 13:01:34.000000000 +0300 +@@ -53,6 +53,8 @@ + + #define MAX_TCP_HEADER (128 + MAX_HEADER) + #define MAX_TCP_OPTION_SPACE 40 ++#define TCP_MIN_SND_MSS 48 ++#define TCP_MIN_GSO_SIZE (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE) + + /* + * Never offer a window over 32767 without using window scaling. Some diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-i2c-dev.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-i2c-dev.h.patch new file mode 100644 index 00000000..e561a66d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-i2c-dev.h.patch @@ -0,0 +1,12 @@ +--- linux-4.9.37/include/uapi/linux/i2c-dev.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/i2c-dev.h 2021-06-07 13:01:34.000000000 +0300 +@@ -50,6 +50,9 @@ + + #define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ + #define I2C_SMBUS 0x0720 /* SMBus transfer */ ++#define I2C_16BIT_REG 0x0709 /* 16BIT REG WIDTH */ ++#define I2C_16BIT_DATA 0x070a /* 16BIT DATA WIDTH */ ++#define I2C_DMA 0x070b /* DMA mode */ + + + /* This is the structure as used in the I2C_SMBUS ioctl call */ diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-i2c.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-i2c.h.patch new file mode 100644 index 00000000..83fa9f60 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-i2c.h.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/include/uapi/linux/i2c.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/i2c.h 2021-06-07 13:01:34.000000000 +0300 +@@ -71,12 +71,19 @@ + #define I2C_M_RD 0x0001 /* read data, from slave to master */ + /* I2C_M_RD is guaranteed to be 0x0001! */ + #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ ++#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ ++#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ ++#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ + #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ + #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ + #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ + #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ + #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */ + #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */ ++#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ ++#define I2C_M_16BIT_REG 0x0002 /* indicate reg bit-width is 16bit */ ++#define I2C_M_16BIT_DATA 0x0008 /* indicate data bit-width is 16bit */ ++#define I2C_M_DMA 0x0004 /* indicate use dma mode */ + __u16 len; /* msg length */ + __u8 *buf; /* pointer to msg data */ + }; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-jffs2.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-jffs2.h.patch new file mode 100644 index 00000000..32fd2ee9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-jffs2.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/include/uapi/linux/jffs2.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/jffs2.h 2021-06-07 13:01:34.000000000 +0300 +@@ -46,6 +46,7 @@ + #define JFFS2_COMPR_DYNRUBIN 0x05 + #define JFFS2_COMPR_ZLIB 0x06 + #define JFFS2_COMPR_LZO 0x07 ++#define JFFS2_COMPR_LZMA 0x08 + /* Compatibility flags. */ + #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ + #define JFFS2_NODE_ACCURATE 0x2000 diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-msdos_fs.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-msdos_fs.h.patch new file mode 100644 index 00000000..b4de32d3 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-msdos_fs.h.patch @@ -0,0 +1,37 @@ +--- linux-4.9.37/include/uapi/linux/msdos_fs.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/msdos_fs.h 2021-06-07 13:01:34.000000000 +0300 +@@ -95,7 +95,23 @@ + unsigned short d_reclen; + char d_name[256]; /* We must not include limits.h! */ + }; ++#ifdef CONFIG_GOKE_MC ++struct fat_direntall { ++ unsigned long d_ino; ++ unsigned long d_off; ++ unsigned char d_type; ++ u64 d_size; ++ char d_createtime[8]; ++ unsigned short d_reclen; ++ char d_name[1]; ++}; + ++struct fat_direntall_buf { ++ int d_count; ++ int d_usecount; ++ struct fat_direntall direntall; ++}; ++#endif + /* + * ioctl commands + */ +@@ -106,7 +122,9 @@ + #define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32) + /*Android kernel has used 0x12, so we use 0x13*/ + #define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32) +- ++#ifdef CONFIG_GOKE_MC ++#define VFAT_IOCTL_READDIR_ALL _IOR('r', 0x14, struct fat_direntall_buf) ++#endif + struct fat_boot_sector { + __u8 ignored[3]; /* Boot strap short or near jump */ + __u8 system_id[8]; /* Name - can be used to special case diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-psci.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-psci.h.patch new file mode 100644 index 00000000..c344a545 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-psci.h.patch @@ -0,0 +1,12 @@ +--- linux-4.9.37/include/uapi/linux/psci.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/psci.h 2021-06-07 13:01:34.000000000 +0300 +@@ -87,6 +87,9 @@ + (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) + #define PSCI_VERSION_MINOR(ver) \ + ((ver) & PSCI_VERSION_MINOR_MASK) ++#define PSCI_VERSION(maj, min) \ ++ ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ ++ ((min) & PSCI_VERSION_MINOR_MASK)) + + /* PSCI features decoding (>=1.0) */ + #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1 diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-snmp.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-snmp.h.patch new file mode 100644 index 00000000..79ff9d3d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-snmp.h.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/include/uapi/linux/snmp.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/snmp.h 2021-06-07 13:01:34.000000000 +0300 +@@ -281,6 +281,7 @@ + LINUX_MIB_TCPKEEPALIVE, /* TCPKeepAlive */ + LINUX_MIB_TCPMTUPFAIL, /* TCPMTUPFail */ + LINUX_MIB_TCPMTUPSUCCESS, /* TCPMTUPSuccess */ ++ LINUX_MIB_TCPWQUEUETOOBIG, /* TCPWqueueTooBig */ + __LINUX_MIB_MAX + }; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-usb-ch9.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-usb-ch9.h.patch new file mode 100644 index 00000000..e1e9691d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-usb-ch9.h.patch @@ -0,0 +1,45 @@ +--- linux-4.9.37/include/uapi/linux/usb/ch9.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/usb/ch9.h 2021-06-07 13:01:34.000000000 +0300 +@@ -423,6 +423,14 @@ + #define USB_ENDPOINT_XFER_INT 3 + #define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 + ++#define USB_EP_MAXP_MULT_SHIFT 11 ++#define USB_EP_MAXP_MULT_MASK (3 << USB_EP_MAXP_MULT_SHIFT) ++#define USB_EP_MAXP_MULT(m) \ ++ (((m) & USB_EP_MAXP_MULT_MASK) >> USB_EP_MAXP_MULT_SHIFT) ++ ++ ++#define USB_ENDPOINT_MAXP_MASK 0x07ff ++ + /* The USB 3.0 spec redefines bits 5:4 of bmAttributes as interrupt ep type. */ + #define USB_ENDPOINT_INTRTYPE 0x30 + #define USB_ENDPOINT_INTR_PERIODIC (0 << 4) +@@ -623,11 +631,25 @@ + * usb_endpoint_maxp - get endpoint's max packet size + * @epd: endpoint to be checked + * +- * Returns @epd's max packet ++ * Returns @epd's max packet bits [10:0] + */ + static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd) + { +- return __le16_to_cpu(epd->wMaxPacketSize); ++ return __le16_to_cpu(epd->wMaxPacketSize) & USB_ENDPOINT_MAXP_MASK; ++} ++ ++/** ++ * usb_endpoint_maxp_mult - get endpoint's transactional opportunities ++ * @epd: endpoint to be checked ++ * ++ * Return @epd's wMaxPacketSize[12:11] + 1 ++ */ ++static inline int ++usb_endpoint_maxp_mult(const struct usb_endpoint_descriptor *epd) ++{ ++ int maxp = __le16_to_cpu(epd->wMaxPacketSize); ++ ++ return USB_EP_MAXP_MULT(maxp) + 1; + } + + static inline int usb_endpoint_interrupt_type( diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-usb-video.h.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-usb-video.h.patch new file mode 100644 index 00000000..94c548fd --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_include-uapi-linux-usb-video.h.patch @@ -0,0 +1,85 @@ +--- linux-4.9.37/include/uapi/linux/usb/video.h 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/include/uapi/linux/usb/video.h 2021-06-07 13:01:34.000000000 +0300 +@@ -303,7 +303,7 @@ + __u8 iProcessing; + } __attribute__((__packed__)); + +-#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n)) ++#define UVC_DT_PROCESSING_UNIT_SIZE(n) (10+(n)) + + /* 3.7.2.6. Extension Unit Descriptor */ + struct uvc_extension_unit_descriptor { +@@ -340,6 +340,8 @@ + __u8 iExtension; \ + } __attribute__ ((packed)) + ++DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(1,2); ++ + /* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */ + struct uvc_control_endpoint_descriptor { + __u8 bLength; +@@ -565,5 +567,64 @@ + __u32 dwFrameInterval[n]; \ + } __attribute__ ((packed)) + ++ ++/* 3.1.1 Frame Based Payload Video Format Descriptor */ ++struct uvc_frame_based_format_desc { ++ __u8 bLength; ++ __u8 bDescriptorType; ++ __u8 bDescriptorSubType; ++ __u8 bFormatIndex; ++ __u8 bNumFrameDescriptors; ++ __u8 guidFormat[16]; ++ __u8 bBitsPerPixel; ++ __u8 bDefaultFrameIndex; ++ __u8 bAspectRatioX; ++ __u8 bAspectRatioY; ++ __u8 bmInterfaceFlags; ++ __u8 bCopyProtect; ++ __u8 bVariableSize; ++} __attribute__((__packed__)); ++ ++#define UVC_DT_FRAME_BASED_FORMAT_SIZE 28 ++ ++/* 3.1.2 Frame Based Payload Frame Descriptor */ ++struct uvc_frame_based_frame_desc { ++ __u8 bLength; ++ __u8 bDescriptorType; ++ __u8 bDescriptorSubType; ++ __u8 bFrameIndex; ++ __u8 bmCapabilities; ++ __u16 wWidth; ++ __u16 wHeight; ++ __u32 dwMinBitRate; ++ __u32 dwMaxBitRate; ++ __u32 dwDefaultFrameInterval; ++ __u8 bFrameIntervalType; ++ __u32 dwBytesPerLine; ++ __u32 dwFrameInterval[]; ++} __attribute__((__packed__)); ++ ++#define UVC_DT_FRAME_BASED_FRAME_SIZE(n) (26+4*(n)) ++ ++#define UVC_FRAME_BASED(n) \ ++ uvc_frame_based_desc##n ++ ++#define DECLARE_UVC_FRAME_BASED(n) \ ++struct UVC_FRAME_BASED(n) { \ ++ __u8 bLength; \ ++ __u8 bDescriptorType; \ ++ __u8 bDescriptorSubType; \ ++ __u8 bFrameIndex; \ ++ __u8 bmCapabilities; \ ++ __u16 wWidth; \ ++ __u16 wHeight; \ ++ __u32 dwMinBitRate; \ ++ __u32 dwMaxBitRate; \ ++ __u32 dwDefaultFrameInterval; \ ++ __u8 bFrameIntervalType; \ ++ __u32 dwBytesPerLine; \ ++ __u32 dwFrameInterval[n]; \ ++} __attribute__ ((packed)) ++ + #endif /* __LINUX_USB_VIDEO_H */ + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_kernel-sched-cputime.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_kernel-sched-cputime.c.patch new file mode 100644 index 00000000..4dda249b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_kernel-sched-cputime.c.patch @@ -0,0 +1,12 @@ +--- linux-4.9.37/kernel/sched/cputime.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/kernel/sched/cputime.c 2021-06-07 13:01:34.000000000 +0300 +@@ -75,6 +75,9 @@ + u64 *cpustat = kcpustat_this_cpu->cpustat; + cputime_t irq_cputime; + ++ if (nsecs_to_cputime64(irqtime) <= cpustat[idx]) ++ return 0; ++ + irq_cputime = nsecs_to_cputime64(irqtime) - cpustat[idx]; + irq_cputime = min(irq_cputime, maxtime); + cpustat[idx] += irq_cputime; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-Kconfig.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-Kconfig.patch new file mode 100644 index 00000000..e48aea35 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-Kconfig.patch @@ -0,0 +1,24 @@ +--- linux-4.9.37/lib/Kconfig 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/lib/Kconfig 2021-06-07 13:01:34.000000000 +0300 +@@ -241,6 +241,12 @@ + + source "lib/xz/Kconfig" + ++config LZMA_COMPRESS ++ tristate ++ ++config LZMA_DECOMPRESS ++ tristate ++ + # + # These all provide a common interface (hence the apparent duplication with + # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) +@@ -278,7 +284,7 @@ + # + config REED_SOLOMON + tristate +- ++ + config REED_SOLOMON_ENC8 + bool + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-Makefile.patch new file mode 100644 index 00000000..664d772a --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-Makefile.patch @@ -0,0 +1,27 @@ +--- linux-4.9.37/lib/Makefile 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/lib/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -1,6 +1,15 @@ + # + # Makefile for some libs needed in the kernel. + # ++ifdef CONFIG_JFFS2_ZLIB ++ CONFIG_ZLIB_INFLATE:=y ++ CONFIG_ZLIB_DEFLATE:=y ++endif ++ ++ifdef CONFIG_JFFS2_LZMA ++ CONFIG_LZMA_DECOMPRESS:=y ++ CONFIG_LZMA_COMPRESS:=y ++endif + + ifdef CONFIG_FUNCTION_TRACER + ORIG_CFLAGS := $(KBUILD_CFLAGS) +@@ -108,6 +117,8 @@ + obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/ + obj-$(CONFIG_XZ_DEC) += xz/ + obj-$(CONFIG_RAID6_PQ) += raid6/ ++obj-$(CONFIG_LZMA_COMPRESS) += lzma/ ++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ + + lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o + lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzFind.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzFind.c.patch new file mode 100644 index 00000000..2b16b757 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzFind.c.patch @@ -0,0 +1,714 @@ +--- linux-4.9.37/lib/lzma/LzFind.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/lib/lzma/LzFind.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,711 @@ ++/* LzFind.c -- Match finder for LZ algorithms ++2009-04-22 : Igor Pavlov : Public domain */ ++ ++#include ++ ++#include "LzFind.h" ++#include "LzHash.h" ++ ++#define kEmptyHashValue 0 ++#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) ++#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ ++#define kNormalizeMask (~(kNormalizeStepMin - 1)) ++#define kMaxHistorySize ((UInt32)3 << 30) ++ ++#define kStartMaxLen 3 ++ ++static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) ++{ ++ if (!p->directInput) { ++ alloc->Free(alloc, p->bufferBase); ++ p->bufferBase = 0; ++ } ++} ++ ++/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ ++ ++static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) ++{ ++ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; ++ if (p->directInput) { ++ p->blockSize = blockSize; ++ return 1; ++ } ++ if (p->bufferBase == 0 || p->blockSize != blockSize) { ++ LzInWindow_Free(p, alloc); ++ p->blockSize = blockSize; ++ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); ++ } ++ return (p->bufferBase != 0); ++} ++ ++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) ++{ ++ return p->buffer; ++} ++ ++Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) ++{ ++ return p->buffer[index]; ++} ++ ++UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) ++{ ++ return p->streamPos - p->pos; ++} ++ ++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) ++{ ++ p->posLimit -= subValue; ++ p->pos -= subValue; ++ p->streamPos -= subValue; ++} ++ ++static void MatchFinder_ReadBlock(CMatchFinder *p) ++{ ++ if (p->streamEndWasReached || p->result != SZ_OK) ++ return; ++ if (p->directInput) { ++ UInt32 curSize = 0xFFFFFFFF - p->streamPos; ++ if (curSize > p->directInputRem) ++ curSize = (UInt32)p->directInputRem; ++ p->directInputRem -= curSize; ++ p->streamPos += curSize; ++ if (p->directInputRem == 0) ++ p->streamEndWasReached = 1; ++ return; ++ } ++ for (;;) { ++ Byte *dest = p->buffer + (p->streamPos - p->pos); ++ size_t size = (p->bufferBase + p->blockSize - dest); ++ if (size == 0) ++ return; ++ p->result = p->stream->Read(p->stream, dest, &size); ++ if (p->result != SZ_OK) ++ return; ++ if (size == 0) { ++ p->streamEndWasReached = 1; ++ return; ++ } ++ p->streamPos += (UInt32)size; ++ if (p->streamPos - p->pos > p->keepSizeAfter) ++ return; ++ } ++} ++ ++void MatchFinder_MoveBlock(CMatchFinder *p) ++{ ++ memmove(p->bufferBase, p->buffer - p->keepSizeBefore, ++ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); ++ p->buffer = p->bufferBase + p->keepSizeBefore; ++} ++ ++int MatchFinder_NeedMove(CMatchFinder *p) ++{ ++ if (p->directInput) ++ return 0; ++ /* if (p->streamEndWasReached) return 0; */ ++ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); ++} ++ ++void MatchFinder_ReadIfRequired(CMatchFinder *p) ++{ ++ if (p->streamEndWasReached) ++ return; ++ if (p->keepSizeAfter >= p->streamPos - p->pos) ++ MatchFinder_ReadBlock(p); ++} ++ ++static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) ++{ ++ if (MatchFinder_NeedMove(p)) ++ MatchFinder_MoveBlock(p); ++ MatchFinder_ReadBlock(p); ++} ++ ++static void MatchFinder_SetDefaultSettings(CMatchFinder *p) ++{ ++ p->cutValue = 32; ++ p->btMode = 1; ++ p->numHashBytes = 4; ++ p->bigHash = 0; ++} ++ ++#define kCrcPoly 0xEDB88320 ++ ++void MatchFinder_Construct(CMatchFinder *p) ++{ ++ UInt32 i; ++ p->bufferBase = 0; ++ p->directInput = 0; ++ p->hash = 0; ++ MatchFinder_SetDefaultSettings(p); ++ ++ for (i = 0; i < 256; i++) { ++ UInt32 r = i; ++ int j; ++ for (j = 0; j < 8; j++) ++ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); ++ p->crc[i] = r; ++ } ++} ++ ++static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) ++{ ++ alloc->Free(alloc, p->hash); ++ p->hash = 0; ++} ++ ++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) ++{ ++ MatchFinder_FreeThisClassMemory(p, alloc); ++ LzInWindow_Free(p, alloc); ++} ++ ++static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) ++{ ++ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); ++ if (sizeInBytes / sizeof(CLzRef) != num) ++ return 0; ++ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); ++} ++ ++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, ++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ++ ISzAlloc *alloc) ++{ ++ UInt32 sizeReserv; ++ if (historySize > kMaxHistorySize) { ++ MatchFinder_Free(p, alloc); ++ return 0; ++ } ++ sizeReserv = historySize >> 1; ++ if (historySize > ((UInt32)2 << 30)) ++ sizeReserv = historySize >> 2; ++ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); ++ ++ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; ++ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; ++ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ ++ if (LzInWindow_Create(p, sizeReserv, alloc)) { ++ UInt32 newCyclicBufferSize = historySize + 1; ++ UInt32 hs; ++ p->matchMaxLen = matchMaxLen; ++ { ++ p->fixedHashSize = 0; ++ if (p->numHashBytes == 2) { ++ hs = (1 << 16) - 1; ++ } else { ++ hs = historySize - 1; ++ hs |= (hs >> 1); ++ hs |= (hs >> 2); ++ hs |= (hs >> 4); ++ hs |= (hs >> 8); ++ hs >>= 1; ++ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ ++ if (hs > (1 << 24)) { ++ if (p->numHashBytes == 3) ++ hs = (1 << 24) - 1; ++ else ++ hs >>= 1; ++ } ++ } ++ p->hashMask = hs; ++ hs++; ++ if (p->numHashBytes > 2) ++ p->fixedHashSize += kHash2Size; ++ if (p->numHashBytes > 3) ++ p->fixedHashSize += kHash3Size; ++ if (p->numHashBytes > 4) ++ p->fixedHashSize += kHash4Size; ++ hs += p->fixedHashSize; ++ } ++ ++ { ++ UInt32 prevSize = p->hashSizeSum + p->numSons; ++ UInt32 newSize; ++ p->historySize = historySize; ++ p->hashSizeSum = hs; ++ p->cyclicBufferSize = newCyclicBufferSize; ++ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); ++ newSize = p->hashSizeSum + p->numSons; ++ if (p->hash != 0 && prevSize == newSize) ++ return 1; ++ MatchFinder_FreeThisClassMemory(p, alloc); ++ p->hash = AllocRefs(newSize, alloc); ++ if (p->hash != 0) { ++ p->son = p->hash + p->hashSizeSum; ++ return 1; ++ } ++ } ++ } ++ MatchFinder_Free(p, alloc); ++ return 0; ++} ++ ++static void MatchFinder_SetLimits(CMatchFinder *p) ++{ ++ UInt32 limit = kMaxValForNormalize - p->pos; ++ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; ++ if (limit2 < limit) ++ limit = limit2; ++ limit2 = p->streamPos - p->pos; ++ if (limit2 <= p->keepSizeAfter) { ++ if (limit2 > 0) ++ limit2 = 1; ++ } else ++ limit2 -= p->keepSizeAfter; ++ if (limit2 < limit) ++ limit = limit2; ++ { ++ UInt32 lenLimit = p->streamPos - p->pos; ++ if (lenLimit > p->matchMaxLen) ++ lenLimit = p->matchMaxLen; ++ p->lenLimit = lenLimit; ++ } ++ p->posLimit = p->pos + limit; ++} ++ ++void MatchFinder_Init(CMatchFinder *p) ++{ ++ UInt32 i; ++ for (i = 0; i < p->hashSizeSum; i++) ++ p->hash[i] = kEmptyHashValue; ++ p->cyclicBufferPos = 0; ++ p->buffer = p->bufferBase; ++ p->pos = p->streamPos = p->cyclicBufferSize; ++ p->result = SZ_OK; ++ p->streamEndWasReached = 0; ++ MatchFinder_ReadBlock(p); ++ MatchFinder_SetLimits(p); ++} ++ ++static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) ++{ ++ return (p->pos - p->historySize - 1) & kNormalizeMask; ++} ++ ++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) ++{ ++ UInt32 i; ++ for (i = 0; i < numItems; i++) { ++ UInt32 value = items[i]; ++ if (value <= subValue) ++ value = kEmptyHashValue; ++ else ++ value -= subValue; ++ items[i] = value; ++ } ++} ++ ++static void MatchFinder_Normalize(CMatchFinder *p) ++{ ++ UInt32 subValue = MatchFinder_GetSubValue(p); ++ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); ++ MatchFinder_ReduceOffsets(p, subValue); ++} ++ ++static void MatchFinder_CheckLimits(CMatchFinder *p) ++{ ++ if (p->pos == kMaxValForNormalize) ++ MatchFinder_Normalize(p); ++ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) ++ MatchFinder_CheckAndMoveAndRead(p); ++ if (p->cyclicBufferPos == p->cyclicBufferSize) ++ p->cyclicBufferPos = 0; ++ MatchFinder_SetLimits(p); ++} ++ ++static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, ++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, ++ UInt32 *distances, UInt32 maxLen) ++{ ++ son[_cyclicBufferPos] = curMatch; ++ for (;;) { ++ UInt32 delta = pos - curMatch; ++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) ++ return distances; ++ { ++ const Byte *pb = cur - delta; ++ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; ++ if (pb[maxLen] == cur[maxLen] && *pb == *cur) { ++ UInt32 len = 0; ++ while (++len != lenLimit) ++ if (pb[len] != cur[len]) ++ break; ++ if (maxLen < len) { ++ *distances++ = maxLen = len; ++ *distances++ = delta - 1; ++ if (len == lenLimit) ++ return distances; ++ } ++ } ++ } ++ } ++} ++ ++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, ++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, ++ UInt32 *distances, UInt32 maxLen) ++{ ++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; ++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); ++ UInt32 len0 = 0, len1 = 0; ++ for (;;) { ++ UInt32 delta = pos - curMatch; ++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) { ++ *ptr0 = *ptr1 = kEmptyHashValue; ++ return distances; ++ } ++ { ++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); ++ const Byte *pb = cur - delta; ++ UInt32 len = (len0 < len1 ? len0 : len1); ++ if (pb[len] == cur[len]) { ++ if (++len != lenLimit && pb[len] == cur[len]) ++ while (++len != lenLimit) ++ if (pb[len] != cur[len]) ++ break; ++ if (maxLen < len) { ++ *distances++ = maxLen = len; ++ *distances++ = delta - 1; ++ if (len == lenLimit) { ++ *ptr1 = pair[0]; ++ *ptr0 = pair[1]; ++ return distances; ++ } ++ } ++ } ++ if (pb[len] < cur[len]) { ++ *ptr1 = curMatch; ++ ptr1 = pair + 1; ++ curMatch = *ptr1; ++ len1 = len; ++ } else { ++ *ptr0 = curMatch; ++ ptr0 = pair; ++ curMatch = *ptr0; ++ len0 = len; ++ } ++ } ++ } ++} ++ ++static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, ++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) ++{ ++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; ++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); ++ UInt32 len0 = 0, len1 = 0; ++ for (;;) { ++ UInt32 delta = pos - curMatch; ++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) { ++ *ptr0 = *ptr1 = kEmptyHashValue; ++ return; ++ } ++ { ++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); ++ const Byte *pb = cur - delta; ++ UInt32 len = (len0 < len1 ? len0 : len1); ++ if (pb[len] == cur[len]) { ++ while (++len != lenLimit) ++ if (pb[len] != cur[len]) ++ break; ++ { ++ if (len == lenLimit) { ++ *ptr1 = pair[0]; ++ *ptr0 = pair[1]; ++ return; ++ } ++ } ++ } ++ if (pb[len] < cur[len]) { ++ *ptr1 = curMatch; ++ ptr1 = pair + 1; ++ curMatch = *ptr1; ++ len1 = len; ++ } else { ++ *ptr0 = curMatch; ++ ptr0 = pair; ++ curMatch = *ptr0; ++ len0 = len; ++ } ++ } ++ } ++} ++ ++#define MOVE_POS \ ++ ++p->cyclicBufferPos; \ ++ p->buffer++; \ ++ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); ++ ++#define MOVE_POS_RET MOVE_POS return offset; ++ ++static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } ++ ++#define GET_MATCHES_HEADER2(minLen, ret_op) \ ++ UInt32 lenLimit; UInt32 hashValue = 0; const Byte *cur; UInt32 curMatch; \ ++ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ ++ cur = p->buffer; ++ ++#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) ++#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) ++ ++#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue ++ ++#define GET_MATCHES_FOOTER(offset, maxLen) \ ++ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ ++ distances + offset, maxLen) - distances); MOVE_POS_RET; ++ ++#define SKIP_FOOTER \ ++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; ++ ++static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++{ ++ UInt32 offset; ++ GET_MATCHES_HEADER(2) ++ HASH2_CALC; ++ curMatch = p->hash[hashValue]; ++ p->hash[hashValue] = p->pos; ++ offset = 0; ++ GET_MATCHES_FOOTER(offset, 1) ++} ++ ++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++{ ++ UInt32 offset; ++ GET_MATCHES_HEADER(3) ++ HASH_ZIP_CALC; ++ curMatch = p->hash[hashValue]; ++ p->hash[hashValue] = p->pos; ++ offset = 0; ++ GET_MATCHES_FOOTER(offset, 2) ++} ++ ++static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++{ ++ UInt32 hash2Value = 0, delta2, maxLen, offset; ++ GET_MATCHES_HEADER(3) ++ ++ HASH3_CALC; ++ ++ delta2 = p->pos - p->hash[hash2Value]; ++ curMatch = p->hash[kFix3HashSize + hashValue]; ++ ++ p->hash[hash2Value] = ++ p->hash[kFix3HashSize + hashValue] = p->pos; ++ ++ ++ maxLen = 2; ++ offset = 0; ++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) { ++ for (; maxLen != lenLimit; maxLen++) ++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) ++ break; ++ distances[0] = maxLen; ++ distances[1] = delta2 - 1; ++ offset = 2; ++ if (maxLen == lenLimit) { ++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); ++ MOVE_POS_RET; ++ } ++ } ++ GET_MATCHES_FOOTER(offset, maxLen) ++} ++ ++static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++{ ++ UInt32 hash2Value = 0, hash3Value = 0, delta2, delta3, maxLen, offset; ++ GET_MATCHES_HEADER(4) ++ ++ HASH4_CALC; ++ ++ delta2 = p->pos - p->hash[ hash2Value]; ++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; ++ curMatch = p->hash[kFix4HashSize + hashValue]; ++ ++ p->hash[ hash2Value] = ++ p->hash[kFix3HashSize + hash3Value] = ++ p->hash[kFix4HashSize + hashValue] = p->pos; ++ ++ maxLen = 1; ++ offset = 0; ++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) { ++ distances[0] = maxLen = 2; ++ distances[1] = delta2 - 1; ++ offset = 2; ++ } ++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) { ++ maxLen = 3; ++ distances[offset + 1] = delta3 - 1; ++ offset += 2; ++ delta2 = delta3; ++ } ++ if (offset != 0) { ++ for (; maxLen != lenLimit; maxLen++) ++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) ++ break; ++ distances[offset - 2] = maxLen; ++ if (maxLen == lenLimit) { ++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); ++ MOVE_POS_RET; ++ } ++ } ++ if (maxLen < 3) ++ maxLen = 3; ++ GET_MATCHES_FOOTER(offset, maxLen) ++} ++ ++static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++{ ++ UInt32 hash2Value = 0, hash3Value = 0, delta2, delta3, maxLen, offset; ++ GET_MATCHES_HEADER(4) ++ ++ HASH4_CALC; ++ ++ delta2 = p->pos - p->hash[hash2Value]; ++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; ++ curMatch = p->hash[kFix4HashSize + hashValue]; ++ ++ p->hash[hash2Value] = ++ p->hash[kFix3HashSize + hash3Value] = ++ p->hash[kFix4HashSize + hashValue] = p->pos; ++ ++ maxLen = 1; ++ offset = 0; ++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) { ++ distances[0] = maxLen = 2; ++ distances[1] = delta2 - 1; ++ offset = 2; ++ } ++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) { ++ maxLen = 3; ++ distances[offset + 1] = delta3 - 1; ++ offset += 2; ++ delta2 = delta3; ++ } ++ if (offset != 0) { ++ for (; maxLen != lenLimit; maxLen++) ++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) ++ break; ++ distances[offset - 2] = maxLen; ++ if (maxLen == lenLimit) { ++ p->son[p->cyclicBufferPos] = curMatch; ++ MOVE_POS_RET; ++ } ++ } ++ if (maxLen < 3) ++ maxLen = 3; ++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), ++ distances + offset, maxLen) - (distances)); ++ MOVE_POS_RET ++} ++ ++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++{ ++ UInt32 offset; ++ GET_MATCHES_HEADER(3) ++ HASH_ZIP_CALC; ++ curMatch = p->hash[hashValue]; ++ p->hash[hashValue] = p->pos; ++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), ++ distances, 2) - (distances)); ++ MOVE_POS_RET ++} ++ ++static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++{ ++ do { ++ SKIP_HEADER(2) ++ HASH2_CALC; ++ curMatch = p->hash[hashValue]; ++ p->hash[hashValue] = p->pos; ++ SKIP_FOOTER ++ } while (--num != 0); ++} ++ ++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++{ ++ do { ++ SKIP_HEADER(3) ++ HASH_ZIP_CALC; ++ curMatch = p->hash[hashValue]; ++ p->hash[hashValue] = p->pos; ++ SKIP_FOOTER ++ } while (--num != 0); ++} ++ ++static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++{ ++ do { ++ UInt32 hash2Value = 0; ++ SKIP_HEADER(3) ++ HASH3_CALC; ++ curMatch = p->hash[kFix3HashSize + hashValue]; ++ p->hash[hash2Value] = ++ p->hash[kFix3HashSize + hashValue] = p->pos; ++ SKIP_FOOTER ++ } while (--num != 0); ++} ++ ++static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++{ ++ do { ++ UInt32 hash2Value = 0, hash3Value = 0; ++ SKIP_HEADER(4) ++ HASH4_CALC; ++ curMatch = p->hash[kFix4HashSize + hashValue]; ++ p->hash[ hash2Value] = ++ p->hash[kFix3HashSize + hash3Value] = p->pos; ++ p->hash[kFix4HashSize + hashValue] = p->pos; ++ SKIP_FOOTER ++ } while (--num != 0); ++} ++ ++static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++{ ++ do { ++ UInt32 hash2Value = 0, hash3Value = 0; ++ SKIP_HEADER(4) ++ HASH4_CALC; ++ curMatch = p->hash[kFix4HashSize + hashValue]; ++ p->hash[ hash2Value] = ++ p->hash[kFix3HashSize + hash3Value] = ++ p->hash[kFix4HashSize + hashValue] = p->pos; ++ p->son[p->cyclicBufferPos] = curMatch; ++ MOVE_POS ++ } while (--num != 0); ++} ++ ++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++{ ++ do { ++ SKIP_HEADER(3) ++ HASH_ZIP_CALC; ++ curMatch = p->hash[hashValue]; ++ p->hash[hashValue] = p->pos; ++ p->son[p->cyclicBufferPos] = curMatch; ++ MOVE_POS ++ } while (--num != 0); ++} ++ ++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) ++{ ++ vTable->Init = (Mf_Init_Func)MatchFinder_Init; ++ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; ++ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; ++ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; ++ if (!p->btMode) { ++ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; ++ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; ++ } else if (p->numHashBytes == 2) { ++ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; ++ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; ++ } else if (p->numHashBytes == 3) { ++ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; ++ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; ++ } else { ++ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; ++ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; ++ } ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzmaDec.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzmaDec.c.patch new file mode 100644 index 00000000..aba20fb2 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzmaDec.c.patch @@ -0,0 +1,1002 @@ +--- linux-4.9.37/lib/lzma/LzmaDec.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/lib/lzma/LzmaDec.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,999 @@ ++/* LzmaDec.c -- LZMA Decoder ++2009-09-20 : Igor Pavlov : Public domain */ ++ ++#include "LzmaDec.h" ++ ++#include ++ ++#define kNumTopBits 24 ++#define kTopValue ((UInt32)1 << kNumTopBits) ++ ++#define kNumBitModelTotalBits 11 ++#define kBitModelTotal (1 << kNumBitModelTotalBits) ++#define kNumMoveBits 5 ++ ++#define RC_INIT_SIZE 5 ++ ++#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } ++ ++#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) ++#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); ++#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); ++#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ ++ { UPDATE_0(p); i = (i + i); A0; } else \ ++ { UPDATE_1(p); i = (i + i) + 1; A1; } ++#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) ++ ++#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } ++#define TREE_DECODE(probs, limit, i) \ ++ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } ++ ++/* #define _LZMA_SIZE_OPT */ ++ ++#ifdef _LZMA_SIZE_OPT ++#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) ++#else ++#define TREE_6_DECODE(probs, i) \ ++ { i = 1; \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ TREE_GET_BIT(probs, i); \ ++ i -= 0x40; } ++#endif ++ ++#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } ++ ++#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) ++#define UPDATE_0_CHECK range = bound; ++#define UPDATE_1_CHECK range -= bound; code -= bound; ++#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ ++ { UPDATE_0_CHECK; i = (i + i); A0; } else \ ++ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } ++#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) ++#define TREE_DECODE_CHECK(probs, limit, i) \ ++ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } ++ ++ ++#define kNumPosBitsMax 4 ++#define kNumPosStatesMax (1 << kNumPosBitsMax) ++ ++#define kLenNumLowBits 3 ++#define kLenNumLowSymbols (1 << kLenNumLowBits) ++#define kLenNumMidBits 3 ++#define kLenNumMidSymbols (1 << kLenNumMidBits) ++#define kLenNumHighBits 8 ++#define kLenNumHighSymbols (1 << kLenNumHighBits) ++ ++#define LenChoice 0 ++#define LenChoice2 (LenChoice + 1) ++#define LenLow (LenChoice2 + 1) ++#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) ++#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) ++#define kNumLenProbs (LenHigh + kLenNumHighSymbols) ++ ++ ++#define kNumStates 12 ++#define kNumLitStates 7 ++ ++#define kStartPosModelIndex 4 ++#define kEndPosModelIndex 14 ++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) ++ ++#define kNumPosSlotBits 6 ++#define kNumLenToPosStates 4 ++ ++#define kNumAlignBits 4 ++#define kAlignTableSize (1 << kNumAlignBits) ++ ++#define kMatchMinLen 2 ++#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) ++ ++#define IsMatch 0 ++#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) ++#define IsRepG0 (IsRep + kNumStates) ++#define IsRepG1 (IsRepG0 + kNumStates) ++#define IsRepG2 (IsRepG1 + kNumStates) ++#define IsRep0Long (IsRepG2 + kNumStates) ++#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) ++#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) ++#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) ++#define LenCoder (Align + kAlignTableSize) ++#define RepLenCoder (LenCoder + kNumLenProbs) ++#define Literal (RepLenCoder + kNumLenProbs) ++ ++#define LZMA_BASE_SIZE 1846 ++#define LZMA_LIT_SIZE 768 ++ ++#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) ++ ++#if Literal != LZMA_BASE_SIZE ++StopCompilingDueBUG ++#endif ++ ++#define LZMA_DIC_MIN (1 << 12) ++ ++/* First LZMA-symbol is always decoded. ++And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization ++Out: ++ Result: ++ SZ_OK - OK ++ SZ_ERROR_DATA - Error ++ p->remainLen: ++ < kMatchSpecLenStart : normal remain ++ = kMatchSpecLenStart : finished ++ = kMatchSpecLenStart + 1 : Flush marker ++ = kMatchSpecLenStart + 2 : State Init Marker ++*/ ++ ++static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) ++{ ++ CLzmaProb *probs = p->probs; ++ ++ unsigned state = p->state; ++ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; ++ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; ++ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; ++ unsigned lc = p->prop.lc; ++ ++ Byte *dic = p->dic; ++ SizeT dicBufSize = p->dicBufSize; ++ SizeT dicPos = p->dicPos; ++ ++ UInt32 processedPos = p->processedPos; ++ UInt32 checkDicSize = p->checkDicSize; ++ unsigned len = 0; ++ ++ const Byte *buf = p->buf; ++ UInt32 range = p->range; ++ UInt32 code = p->code; ++ ++ do ++ { ++ CLzmaProb *prob; ++ UInt32 bound; ++ unsigned ttt; ++ unsigned posState = processedPos & pbMask; ++ ++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; ++ IF_BIT_0(prob) ++ { ++ unsigned symbol; ++ UPDATE_0(prob); ++ prob = probs + Literal; ++ if (checkDicSize != 0 || processedPos != 0) ++ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + ++ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); ++ ++ if (state < kNumLitStates) ++ { ++ state -= (state < 4) ? state : 3; ++ symbol = 1; ++ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); ++ } ++ else ++ { ++ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; ++ unsigned offs = 0x100; ++ state -= (state < 10) ? 3 : 6; ++ symbol = 1; ++ do ++ { ++ unsigned bit; ++ CLzmaProb *probLit; ++ matchByte <<= 1; ++ bit = (matchByte & offs); ++ probLit = prob + offs + bit + symbol; ++ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) ++ } ++ while (symbol < 0x100); ++ } ++ dic[dicPos++] = (Byte)symbol; ++ processedPos++; ++ continue; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ prob = probs + IsRep + state; ++ IF_BIT_0(prob) ++ { ++ UPDATE_0(prob); ++ state += kNumStates; ++ prob = probs + LenCoder; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ if (checkDicSize == 0 && processedPos == 0) ++ return SZ_ERROR_DATA; ++ prob = probs + IsRepG0 + state; ++ IF_BIT_0(prob) ++ { ++ UPDATE_0(prob); ++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; ++ IF_BIT_0(prob) ++ { ++ UPDATE_0(prob); ++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; ++ dicPos++; ++ processedPos++; ++ state = state < kNumLitStates ? 9 : 11; ++ continue; ++ } ++ UPDATE_1(prob); ++ } ++ else ++ { ++ UInt32 distance; ++ UPDATE_1(prob); ++ prob = probs + IsRepG1 + state; ++ IF_BIT_0(prob) ++ { ++ UPDATE_0(prob); ++ distance = rep1; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ prob = probs + IsRepG2 + state; ++ IF_BIT_0(prob) ++ { ++ UPDATE_0(prob); ++ distance = rep2; ++ } ++ else ++ { ++ UPDATE_1(prob); ++ distance = rep3; ++ rep3 = rep2; ++ } ++ rep2 = rep1; ++ } ++ rep1 = rep0; ++ rep0 = distance; ++ } ++ state = state < kNumLitStates ? 8 : 11; ++ prob = probs + RepLenCoder; ++ } ++ { ++ unsigned limit, offset; ++ CLzmaProb *probLen = prob + LenChoice; ++ IF_BIT_0(probLen) ++ { ++ UPDATE_0(probLen); ++ probLen = prob + LenLow + (posState << kLenNumLowBits); ++ offset = 0; ++ limit = (1 << kLenNumLowBits); ++ } ++ else ++ { ++ UPDATE_1(probLen); ++ probLen = prob + LenChoice2; ++ IF_BIT_0(probLen) ++ { ++ UPDATE_0(probLen); ++ probLen = prob + LenMid + (posState << kLenNumMidBits); ++ offset = kLenNumLowSymbols; ++ limit = (1 << kLenNumMidBits); ++ } ++ else ++ { ++ UPDATE_1(probLen); ++ probLen = prob + LenHigh; ++ offset = kLenNumLowSymbols + kLenNumMidSymbols; ++ limit = (1 << kLenNumHighBits); ++ } ++ } ++ TREE_DECODE(probLen, limit, len); ++ len += offset; ++ } ++ ++ if (state >= kNumStates) ++ { ++ UInt32 distance; ++ prob = probs + PosSlot + ++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); ++ TREE_6_DECODE(prob, distance); ++ if (distance >= kStartPosModelIndex) ++ { ++ unsigned posSlot = (unsigned)distance; ++ int numDirectBits = (int)(((distance >> 1) - 1)); ++ distance = (2 | (distance & 1)); ++ if (posSlot < kEndPosModelIndex) ++ { ++ distance <<= numDirectBits; ++ prob = probs + SpecPos + distance - posSlot - 1; ++ { ++ UInt32 mask = 1; ++ unsigned i = 1; ++ do ++ { ++ GET_BIT2(prob + i, i, ; , distance |= mask); ++ mask <<= 1; ++ } ++ while (--numDirectBits != 0); ++ } ++ } ++ else ++ { ++ numDirectBits -= kNumAlignBits; ++ do ++ { ++ NORMALIZE ++ range >>= 1; ++ ++ { ++ UInt32 t; ++ code -= range; ++ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ ++ distance = (distance << 1) + (t + 1); ++ code += range & t; ++ } ++ /* ++ distance <<= 1; ++ if (code >= range) ++ { ++ code -= range; ++ distance |= 1; ++ } ++ */ ++ } ++ while (--numDirectBits != 0); ++ prob = probs + Align; ++ distance <<= kNumAlignBits; ++ { ++ unsigned i = 1; ++ GET_BIT2(prob + i, i, ; , distance |= 1); ++ GET_BIT2(prob + i, i, ; , distance |= 2); ++ GET_BIT2(prob + i, i, ; , distance |= 4); ++ GET_BIT2(prob + i, i, ; , distance |= 8); ++ } ++ if (distance == (UInt32)0xFFFFFFFF) ++ { ++ len += kMatchSpecLenStart; ++ state -= kNumStates; ++ break; ++ } ++ } ++ } ++ rep3 = rep2; ++ rep2 = rep1; ++ rep1 = rep0; ++ rep0 = distance + 1; ++ if (checkDicSize == 0) ++ { ++ if (distance >= processedPos) ++ return SZ_ERROR_DATA; ++ } ++ else if (distance >= checkDicSize) ++ return SZ_ERROR_DATA; ++ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; ++ } ++ ++ len += kMatchMinLen; ++ ++ if (limit == dicPos) ++ return SZ_ERROR_DATA; ++ { ++ SizeT rem = limit - dicPos; ++ unsigned curLen = ((rem < len) ? (unsigned)rem : len); ++ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); ++ ++ processedPos += curLen; ++ ++ len -= curLen; ++ if (pos + curLen <= dicBufSize) ++ { ++ Byte *dest = dic + dicPos; ++ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; ++ const Byte *lim = dest + curLen; ++ dicPos += curLen; ++ do ++ *(dest) = (Byte)*(dest + src); ++ while (++dest != lim); ++ } ++ else ++ { ++ do ++ { ++ dic[dicPos++] = dic[pos]; ++ if (++pos == dicBufSize) ++ pos = 0; ++ } ++ while (--curLen != 0); ++ } ++ } ++ } ++ } ++ while (dicPos < limit && buf < bufLimit); ++ NORMALIZE; ++ p->buf = buf; ++ p->range = range; ++ p->code = code; ++ p->remainLen = len; ++ p->dicPos = dicPos; ++ p->processedPos = processedPos; ++ p->reps[0] = rep0; ++ p->reps[1] = rep1; ++ p->reps[2] = rep2; ++ p->reps[3] = rep3; ++ p->state = state; ++ ++ return SZ_OK; ++} ++ ++static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) ++{ ++ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) ++ { ++ Byte *dic = p->dic; ++ SizeT dicPos = p->dicPos; ++ SizeT dicBufSize = p->dicBufSize; ++ unsigned len = p->remainLen; ++ UInt32 rep0 = p->reps[0]; ++ if (limit - dicPos < len) ++ len = (unsigned)(limit - dicPos); ++ ++ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) ++ p->checkDicSize = p->prop.dicSize; ++ ++ p->processedPos += len; ++ p->remainLen -= len; ++ while (len-- != 0) ++ { ++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; ++ dicPos++; ++ } ++ p->dicPos = dicPos; ++ } ++} ++ ++static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) ++{ ++ do ++ { ++ SizeT limit2 = limit; ++ if (p->checkDicSize == 0) ++ { ++ UInt32 rem = p->prop.dicSize - p->processedPos; ++ if (limit - p->dicPos > rem) ++ limit2 = p->dicPos + rem; ++ } ++ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); ++ if (p->processedPos >= p->prop.dicSize) ++ p->checkDicSize = p->prop.dicSize; ++ LzmaDec_WriteRem(p, limit); ++ } ++ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); ++ ++ if (p->remainLen > kMatchSpecLenStart) ++ { ++ p->remainLen = kMatchSpecLenStart; ++ } ++ return 0; ++} ++ ++typedef enum ++{ ++ DUMMY_ERROR, /* unexpected end of input stream */ ++ DUMMY_LIT, ++ DUMMY_MATCH, ++ DUMMY_REP ++} ELzmaDummy; ++ ++static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) ++{ ++ UInt32 range = p->range; ++ UInt32 code = p->code; ++ const Byte *bufLimit = buf + inSize; ++ CLzmaProb *probs = p->probs; ++ unsigned state = p->state; ++ ELzmaDummy res; ++ ++ { ++ CLzmaProb *prob; ++ UInt32 bound; ++ unsigned ttt; ++ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); ++ ++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK ++ ++ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ ++ ++ prob = probs + Literal; ++ if (p->checkDicSize != 0 || p->processedPos != 0) ++ prob += (LZMA_LIT_SIZE * ++ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + ++ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); ++ ++ if (state < kNumLitStates) ++ { ++ unsigned symbol = 1; ++ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); ++ } ++ else ++ { ++ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + ++ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; ++ unsigned offs = 0x100; ++ unsigned symbol = 1; ++ do ++ { ++ unsigned bit; ++ CLzmaProb *probLit; ++ matchByte <<= 1; ++ bit = (matchByte & offs); ++ probLit = prob + offs + bit + symbol; ++ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) ++ } ++ while (symbol < 0x100); ++ } ++ res = DUMMY_LIT; ++ } ++ else ++ { ++ unsigned len; ++ UPDATE_1_CHECK; ++ ++ prob = probs + IsRep + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ state = 0; ++ prob = probs + LenCoder; ++ res = DUMMY_MATCH; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ res = DUMMY_REP; ++ prob = probs + IsRepG0 + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ NORMALIZE_CHECK; ++ return DUMMY_REP; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ } ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ prob = probs + IsRepG1 + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ prob = probs + IsRepG2 + state; ++ IF_BIT_0_CHECK(prob) ++ { ++ UPDATE_0_CHECK; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ } ++ } ++ } ++ state = kNumStates; ++ prob = probs + RepLenCoder; ++ } ++ { ++ unsigned limit, offset; ++ CLzmaProb *probLen = prob + LenChoice; ++ IF_BIT_0_CHECK(probLen) ++ { ++ UPDATE_0_CHECK; ++ probLen = prob + LenLow + (posState << kLenNumLowBits); ++ offset = 0; ++ limit = 1 << kLenNumLowBits; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ probLen = prob + LenChoice2; ++ IF_BIT_0_CHECK(probLen) ++ { ++ UPDATE_0_CHECK; ++ probLen = prob + LenMid + (posState << kLenNumMidBits); ++ offset = kLenNumLowSymbols; ++ limit = 1 << kLenNumMidBits; ++ } ++ else ++ { ++ UPDATE_1_CHECK; ++ probLen = prob + LenHigh; ++ offset = kLenNumLowSymbols + kLenNumMidSymbols; ++ limit = 1 << kLenNumHighBits; ++ } ++ } ++ TREE_DECODE_CHECK(probLen, limit, len); ++ len += offset; ++ } ++ ++ if (state < 4) ++ { ++ unsigned posSlot; ++ prob = probs + PosSlot + ++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << ++ kNumPosSlotBits); ++ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); ++ if (posSlot >= kStartPosModelIndex) ++ { ++ int numDirectBits = ((posSlot >> 1) - 1); ++ ++ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ ++ ++ if (posSlot < kEndPosModelIndex) ++ { ++ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; ++ } ++ else ++ { ++ numDirectBits -= kNumAlignBits; ++ do ++ { ++ NORMALIZE_CHECK ++ range >>= 1; ++ code -= range & (((code - range) >> 31) - 1); ++ /* if (code >= range) code -= range; */ ++ } ++ while (--numDirectBits != 0); ++ prob = probs + Align; ++ numDirectBits = kNumAlignBits; ++ } ++ { ++ unsigned i = 1; ++ do ++ { ++ GET_BIT_CHECK(prob + i, i); ++ } ++ while (--numDirectBits != 0); ++ } ++ } ++ } ++ } ++ } ++ NORMALIZE_CHECK; ++ return res; ++} ++ ++ ++static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) ++{ ++ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); ++ p->range = 0xFFFFFFFF; ++ p->needFlush = 0; ++} ++ ++void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) ++{ ++ p->needFlush = 1; ++ p->remainLen = 0; ++ p->tempBufSize = 0; ++ ++ if (initDic) ++ { ++ p->processedPos = 0; ++ p->checkDicSize = 0; ++ p->needInitState = 1; ++ } ++ if (initState) ++ p->needInitState = 1; ++} ++ ++void LzmaDec_Init(CLzmaDec *p) ++{ ++ p->dicPos = 0; ++ LzmaDec_InitDicAndState(p, True, True); ++} ++ ++static void LzmaDec_InitStateReal(CLzmaDec *p) ++{ ++ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); ++ UInt32 i; ++ CLzmaProb *probs = p->probs; ++ for (i = 0; i < numProbs; i++) ++ probs[i] = kBitModelTotal >> 1; ++ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; ++ p->state = 0; ++ p->needInitState = 0; ++} ++ ++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ++ ELzmaFinishMode finishMode, ELzmaStatus *status) ++{ ++ SizeT inSize = *srcLen; ++ (*srcLen) = 0; ++ LzmaDec_WriteRem(p, dicLimit); ++ ++ *status = LZMA_STATUS_NOT_SPECIFIED; ++ ++ while (p->remainLen != kMatchSpecLenStart) ++ { ++ int checkEndMarkNow; ++ ++ if (p->needFlush != 0) ++ { ++ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) ++ p->tempBuf[p->tempBufSize++] = *src++; ++ if (p->tempBufSize < RC_INIT_SIZE) ++ { ++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; ++ return SZ_OK; ++ } ++ if (p->tempBuf[0] != 0) ++ return SZ_ERROR_DATA; ++ ++ LzmaDec_InitRc(p, p->tempBuf); ++ p->tempBufSize = 0; ++ } ++ ++ checkEndMarkNow = 0; ++ if (p->dicPos >= dicLimit) ++ { ++ if (p->remainLen == 0 && p->code == 0) ++ { ++ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; ++ return SZ_OK; ++ } ++ if (finishMode == LZMA_FINISH_ANY) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_OK; ++ } ++ if (p->remainLen != 0) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_ERROR_DATA; ++ } ++ checkEndMarkNow = 1; ++ } ++ ++ if (p->needInitState) ++ LzmaDec_InitStateReal(p); ++ ++ if (p->tempBufSize == 0) ++ { ++ SizeT processed; ++ const Byte *bufLimit = NULL; ++ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) ++ { ++ int dummyRes = LzmaDec_TryDummy(p, src, inSize); ++ if (dummyRes == DUMMY_ERROR) ++ { ++ memcpy(p->tempBuf, src, inSize); ++ p->tempBufSize = (unsigned)inSize; ++ (*srcLen) += inSize; ++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; ++ return SZ_OK; ++ } ++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_ERROR_DATA; ++ } ++ bufLimit = src; ++ } ++ else ++ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; ++ p->buf = src; ++ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) ++ return SZ_ERROR_DATA; ++ processed = (SizeT)(p->buf - src); ++ (*srcLen) += processed; ++ src += processed; ++ inSize -= processed; ++ } ++ else ++ { ++ unsigned rem = p->tempBufSize, lookAhead = 0; ++ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) ++ p->tempBuf[rem++] = src[lookAhead++]; ++ p->tempBufSize = rem; ++ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) ++ { ++ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); ++ if (dummyRes == DUMMY_ERROR) ++ { ++ (*srcLen) += lookAhead; ++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; ++ return SZ_OK; ++ } ++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) ++ { ++ *status = LZMA_STATUS_NOT_FINISHED; ++ return SZ_ERROR_DATA; ++ } ++ } ++ p->buf = p->tempBuf; ++ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) ++ return SZ_ERROR_DATA; ++ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); ++ (*srcLen) += lookAhead; ++ src += lookAhead; ++ inSize -= lookAhead; ++ p->tempBufSize = 0; ++ } ++ } ++ if (p->code == 0) ++ *status = LZMA_STATUS_FINISHED_WITH_MARK; ++ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; ++} ++ ++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) ++{ ++ SizeT outSize = *destLen; ++ SizeT inSize = *srcLen; ++ *srcLen = *destLen = 0; ++ for (;;) ++ { ++ SizeT inSizeCur = inSize, outSizeCur, dicPos; ++ ELzmaFinishMode curFinishMode; ++ SRes res; ++ if (p->dicPos == p->dicBufSize) ++ p->dicPos = 0; ++ dicPos = p->dicPos; ++ if (outSize > p->dicBufSize - dicPos) ++ { ++ outSizeCur = p->dicBufSize; ++ curFinishMode = LZMA_FINISH_ANY; ++ } ++ else ++ { ++ outSizeCur = dicPos + outSize; ++ curFinishMode = finishMode; ++ } ++ ++ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); ++ src += inSizeCur; ++ inSize -= inSizeCur; ++ *srcLen += inSizeCur; ++ outSizeCur = p->dicPos - dicPos; ++ memcpy(dest, p->dic + dicPos, outSizeCur); ++ dest += outSizeCur; ++ outSize -= outSizeCur; ++ *destLen += outSizeCur; ++ if (res != 0) ++ return res; ++ if (outSizeCur == 0 || outSize == 0) ++ return SZ_OK; ++ } ++} ++ ++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) ++{ ++ alloc->Free(alloc, p->probs); ++ p->probs = 0; ++} ++ ++static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) ++{ ++ alloc->Free(alloc, p->dic); ++ p->dic = 0; ++} ++ ++void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) ++{ ++ LzmaDec_FreeProbs(p, alloc); ++ LzmaDec_FreeDict(p, alloc); ++} ++ ++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) ++{ ++ UInt32 dicSize; ++ Byte d; ++ ++ if (size < LZMA_PROPS_SIZE) ++ return SZ_ERROR_UNSUPPORTED; ++ else ++ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); ++ ++ if (dicSize < LZMA_DIC_MIN) ++ dicSize = LZMA_DIC_MIN; ++ p->dicSize = dicSize; ++ ++ d = data[0]; ++ if (d >= (9 * 5 * 5)) ++ return SZ_ERROR_UNSUPPORTED; ++ ++ p->lc = d % 9; ++ d /= 9; ++ p->pb = d / 5; ++ p->lp = d % 5; ++ ++ return SZ_OK; ++} ++ ++static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) ++{ ++ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); ++ if (p->probs == 0 || numProbs != p->numProbs) ++ { ++ LzmaDec_FreeProbs(p, alloc); ++ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); ++ p->numProbs = numProbs; ++ if (p->probs == 0) ++ return SZ_ERROR_MEM; ++ } ++ return SZ_OK; ++} ++ ++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) ++{ ++ CLzmaProps propNew; ++ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); ++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); ++ p->prop = propNew; ++ return SZ_OK; ++} ++ ++SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) ++{ ++ CLzmaProps propNew; ++ SizeT dicBufSize; ++ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); ++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); ++ dicBufSize = propNew.dicSize; ++ if (p->dic == 0 || dicBufSize != p->dicBufSize) ++ { ++ LzmaDec_FreeDict(p, alloc); ++ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); ++ if (p->dic == 0) ++ { ++ LzmaDec_FreeProbs(p, alloc); ++ return SZ_ERROR_MEM; ++ } ++ } ++ p->dicBufSize = dicBufSize; ++ p->prop = propNew; ++ return SZ_OK; ++} ++ ++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, ++ ELzmaStatus *status, ISzAlloc *alloc) ++{ ++ CLzmaDec p; ++ SRes res; ++ SizeT inSize = *srcLen; ++ SizeT outSize = *destLen; ++ *srcLen = *destLen = 0; ++ if (inSize < RC_INIT_SIZE) ++ return SZ_ERROR_INPUT_EOF; ++ ++ LzmaDec_Construct(&p); ++ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); ++ if (res != 0) ++ return res; ++ p.dic = dest; ++ p.dicBufSize = outSize; ++ ++ LzmaDec_Init(&p); ++ ++ *srcLen = inSize; ++ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); ++ ++ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) ++ res = SZ_ERROR_INPUT_EOF; ++ ++ (*destLen) = p.dicPos; ++ LzmaDec_FreeProbs(&p, alloc); ++ return res; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzmaEnc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzmaEnc.c.patch new file mode 100644 index 00000000..62c620c6 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-LzmaEnc.c.patch @@ -0,0 +1,2274 @@ +--- linux-4.9.37/lib/lzma/LzmaEnc.c 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/lib/lzma/LzmaEnc.c 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,2271 @@ ++/* LzmaEnc.c -- LZMA Encoder ++2009-11-24 : Igor Pavlov : Public domain */ ++ ++#include ++ ++/* #define SHOW_STAT */ ++/* #define SHOW_STAT2 */ ++ ++#if defined(SHOW_STAT) || defined(SHOW_STAT2) ++#include ++#endif ++ ++#include "LzmaEnc.h" ++ ++/* disable MT */ ++#define _7ZIP_ST ++ ++#include "LzFind.h" ++#ifndef _7ZIP_ST ++#include "LzFindMt.h" ++#endif ++ ++#ifdef SHOW_STAT ++static int ttt = 0; ++#endif ++ ++#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) ++ ++#define kBlockSize (9 << 10) ++#define kUnpackBlockSize (1 << 18) ++#define kMatchArraySize (1 << 21) ++#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) ++ ++#define kNumMaxDirectBits (31) ++ ++#define kNumTopBits 24 ++#define kTopValue ((UInt32)1 << kNumTopBits) ++ ++#define kNumBitModelTotalBits 11 ++#define kBitModelTotal (1 << kNumBitModelTotalBits) ++#define kNumMoveBits 5 ++#define kProbInitValue (kBitModelTotal >> 1) ++ ++#define kNumMoveReducingBits 4 ++#define kNumBitPriceShiftBits 4 ++#define kBitPrice (1 << kNumBitPriceShiftBits) ++ ++void LzmaEncProps_Init(CLzmaEncProps *p) ++{ ++ p->level = 5; ++ p->dictSize = p->mc = 0; ++ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; ++ p->writeEndMark = 0; ++} ++ ++void LzmaEncProps_Normalize(CLzmaEncProps *p) ++{ ++ int level = p->level; ++ if (level < 0) level = 5; ++ p->level = level; ++ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); ++ if (p->lc < 0) p->lc = 3; ++ if (p->lp < 0) p->lp = 0; ++ if (p->pb < 0) p->pb = 2; ++ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); ++ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); ++ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); ++ if (p->numHashBytes < 0) p->numHashBytes = 4; ++ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); ++ if (p->numThreads < 0) ++ p->numThreads = ++ #ifndef _7ZIP_ST ++ ((p->btMode && p->algo) ? 2 : 1); ++ #else ++ 1; ++ #endif ++} ++ ++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) ++{ ++ CLzmaEncProps props = *props2; ++ LzmaEncProps_Normalize(&props); ++ return props.dictSize; ++} ++ ++/* #define LZMA_LOG_BSR */ ++/* Define it for Intel's CPU */ ++ ++ ++#ifdef LZMA_LOG_BSR ++ ++#define kDicLogSizeMaxCompress 30 ++ ++#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } ++ ++UInt32 GetPosSlot1(UInt32 pos) ++{ ++ UInt32 res; ++ BSR2_RET(pos, res); ++ return res; ++} ++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } ++#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } ++ ++#else ++ ++#define kNumLogBits (9 + (int)sizeof(size_t) / 2) ++#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) ++ ++void LzmaEnc_FastPosInit(Byte *g_FastPos) ++{ ++ int c = 2, slotFast; ++ g_FastPos[0] = 0; ++ g_FastPos[1] = 1; ++ ++ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) ++ { ++ UInt32 k = (1 << ((slotFast >> 1) - 1)); ++ UInt32 j; ++ for (j = 0; j < k; j++, c++) ++ g_FastPos[c] = (Byte)slotFast; ++ } ++} ++ ++#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ ++ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ ++ res = p->g_FastPos[pos >> i] + (i * 2); } ++/* ++#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ ++ p->g_FastPos[pos >> 6] + 12 : \ ++ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } ++*/ ++ ++#define GetPosSlot1(pos) p->g_FastPos[pos] ++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } ++#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } ++ ++#endif ++ ++ ++#define LZMA_NUM_REPS 4 ++ ++typedef unsigned CState; ++ ++typedef struct ++{ ++ UInt32 price; ++ ++ CState state; ++ int prev1IsChar; ++ int prev2; ++ ++ UInt32 posPrev2; ++ UInt32 backPrev2; ++ ++ UInt32 posPrev; ++ UInt32 backPrev; ++ UInt32 backs[LZMA_NUM_REPS]; ++} COptimal; ++ ++#define kNumOpts (1 << 12) ++ ++#define kNumLenToPosStates 4 ++#define kNumPosSlotBits 6 ++#define kDicLogSizeMin 0 ++#define kDicLogSizeMax 32 ++#define kDistTableSizeMax (kDicLogSizeMax * 2) ++ ++ ++#define kNumAlignBits 4 ++#define kAlignTableSize (1 << kNumAlignBits) ++#define kAlignMask (kAlignTableSize - 1) ++ ++#define kStartPosModelIndex 4 ++#define kEndPosModelIndex 14 ++#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) ++ ++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) ++ ++#ifdef _LZMA_PROB32 ++#define CLzmaProb UInt32 ++#else ++#define CLzmaProb UInt16 ++#endif ++ ++#define LZMA_PB_MAX 4 ++#define LZMA_LC_MAX 8 ++#define LZMA_LP_MAX 4 ++ ++#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) ++ ++ ++#define kLenNumLowBits 3 ++#define kLenNumLowSymbols (1 << kLenNumLowBits) ++#define kLenNumMidBits 3 ++#define kLenNumMidSymbols (1 << kLenNumMidBits) ++#define kLenNumHighBits 8 ++#define kLenNumHighSymbols (1 << kLenNumHighBits) ++ ++#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) ++ ++#define LZMA_MATCH_LEN_MIN 2 ++#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) ++ ++#define kNumStates 12 ++ ++typedef struct ++{ ++ CLzmaProb choice; ++ CLzmaProb choice2; ++ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; ++ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; ++ CLzmaProb high[kLenNumHighSymbols]; ++} CLenEnc; ++ ++typedef struct ++{ ++ CLenEnc p; ++ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; ++ UInt32 tableSize; ++ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; ++} CLenPriceEnc; ++ ++typedef struct ++{ ++ UInt32 range; ++ Byte cache; ++ UInt64 low; ++ UInt64 cacheSize; ++ Byte *buf; ++ Byte *bufLim; ++ Byte *bufBase; ++ ISeqOutStream *outStream; ++ UInt64 processed; ++ SRes res; ++} CRangeEnc; ++ ++typedef struct ++{ ++ CLzmaProb *litProbs; ++ ++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; ++ CLzmaProb isRep[kNumStates]; ++ CLzmaProb isRepG0[kNumStates]; ++ CLzmaProb isRepG1[kNumStates]; ++ CLzmaProb isRepG2[kNumStates]; ++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; ++ ++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; ++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; ++ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; ++ ++ CLenPriceEnc lenEnc; ++ CLenPriceEnc repLenEnc; ++ ++ UInt32 reps[LZMA_NUM_REPS]; ++ UInt32 state; ++} CSaveState; ++ ++typedef struct ++{ ++ IMatchFinder matchFinder; ++ void *matchFinderObj; ++ ++ #ifndef _7ZIP_ST ++ Bool mtMode; ++ CMatchFinderMt matchFinderMt; ++ #endif ++ ++ CMatchFinder matchFinderBase; ++ ++ #ifndef _7ZIP_ST ++ Byte pad[128]; ++ #endif ++ ++ UInt32 optimumEndIndex; ++ UInt32 optimumCurrentIndex; ++ ++ UInt32 longestMatchLength; ++ UInt32 numPairs; ++ UInt32 numAvail; ++ COptimal opt[kNumOpts]; ++ ++ #ifndef LZMA_LOG_BSR ++ Byte g_FastPos[1 << kNumLogBits]; ++ #endif ++ ++ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; ++ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; ++ UInt32 numFastBytes; ++ UInt32 additionalOffset; ++ UInt32 reps[LZMA_NUM_REPS]; ++ UInt32 state; ++ ++ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; ++ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; ++ UInt32 alignPrices[kAlignTableSize]; ++ UInt32 alignPriceCount; ++ ++ UInt32 distTableSize; ++ ++ unsigned lc, lp, pb; ++ unsigned lpMask, pbMask; ++ ++ CLzmaProb *litProbs; ++ ++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; ++ CLzmaProb isRep[kNumStates]; ++ CLzmaProb isRepG0[kNumStates]; ++ CLzmaProb isRepG1[kNumStates]; ++ CLzmaProb isRepG2[kNumStates]; ++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; ++ ++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; ++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; ++ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; ++ ++ CLenPriceEnc lenEnc; ++ CLenPriceEnc repLenEnc; ++ ++ unsigned lclp; ++ ++ Bool fastMode; ++ ++ CRangeEnc rc; ++ ++ Bool writeEndMark; ++ UInt64 nowPos64; ++ UInt32 matchPriceCount; ++ Bool finished; ++ Bool multiThread; ++ ++ SRes result; ++ UInt32 dictSize; ++ UInt32 matchFinderCycles; ++ ++ int needInit; ++ ++ CSaveState saveState; ++} CLzmaEnc; ++ ++void LzmaEnc_SaveState(CLzmaEncHandle pp) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ CSaveState *dest = &p->saveState; ++ int i; ++ dest->lenEnc = p->lenEnc; ++ dest->repLenEnc = p->repLenEnc; ++ dest->state = p->state; ++ ++ for (i = 0; i < kNumStates; i++) ++ { ++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); ++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); ++ } ++ for (i = 0; i < kNumLenToPosStates; i++) ++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); ++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); ++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); ++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); ++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); ++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); ++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); ++ memcpy(dest->reps, p->reps, sizeof(p->reps)); ++ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); ++} ++ ++void LzmaEnc_RestoreState(CLzmaEncHandle pp) ++{ ++ CLzmaEnc *dest = (CLzmaEnc *)pp; ++ const CSaveState *p = &dest->saveState; ++ int i; ++ dest->lenEnc = p->lenEnc; ++ dest->repLenEnc = p->repLenEnc; ++ dest->state = p->state; ++ ++ for (i = 0; i < kNumStates; i++) ++ { ++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); ++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); ++ } ++ for (i = 0; i < kNumLenToPosStates; i++) ++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); ++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); ++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); ++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); ++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); ++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); ++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); ++ memcpy(dest->reps, p->reps, sizeof(p->reps)); ++ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); ++} ++ ++SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ CLzmaEncProps props = *props2; ++ LzmaEncProps_Normalize(&props); ++ ++ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || ++ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) ++ return SZ_ERROR_PARAM; ++ p->dictSize = props.dictSize; ++ p->matchFinderCycles = props.mc; ++ { ++ unsigned fb = props.fb; ++ if (fb < 5) ++ fb = 5; ++ if (fb > LZMA_MATCH_LEN_MAX) ++ fb = LZMA_MATCH_LEN_MAX; ++ p->numFastBytes = fb; ++ } ++ p->lc = props.lc; ++ p->lp = props.lp; ++ p->pb = props.pb; ++ p->fastMode = (props.algo == 0); ++ p->matchFinderBase.btMode = props.btMode; ++ { ++ UInt32 numHashBytes = 4; ++ if (props.btMode) ++ { ++ if (props.numHashBytes < 2) ++ numHashBytes = 2; ++ else if (props.numHashBytes < 4) ++ numHashBytes = props.numHashBytes; ++ } ++ p->matchFinderBase.numHashBytes = numHashBytes; ++ } ++ ++ p->matchFinderBase.cutValue = props.mc; ++ ++ p->writeEndMark = props.writeEndMark; ++ ++ #ifndef _7ZIP_ST ++ /* ++ if (newMultiThread != _multiThread) ++ { ++ ReleaseMatchFinder(); ++ _multiThread = newMultiThread; ++ } ++ */ ++ p->multiThread = (props.numThreads > 1); ++ #endif ++ ++ return SZ_OK; ++} ++ ++static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; ++static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; ++static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; ++static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; ++ ++#define IsCharState(s) ((s) < 7) ++ ++#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) ++ ++#define kInfinityPrice (1 << 30) ++ ++static void RangeEnc_Construct(CRangeEnc *p) ++{ ++ p->outStream = 0; ++ p->bufBase = 0; ++} ++ ++#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) ++ ++#define RC_BUF_SIZE (1 << 16) ++static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) ++{ ++ if (p->bufBase == 0) ++ { ++ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); ++ if (p->bufBase == 0) ++ return 0; ++ p->bufLim = p->bufBase + RC_BUF_SIZE; ++ } ++ return 1; ++} ++ ++static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) ++{ ++ alloc->Free(alloc, p->bufBase); ++ p->bufBase = 0; ++} ++ ++static void RangeEnc_Init(CRangeEnc *p) ++{ ++ /* Stream.Init(); */ ++ p->low = 0; ++ p->range = 0xFFFFFFFF; ++ p->cacheSize = 1; ++ p->cache = 0; ++ ++ p->buf = p->bufBase; ++ ++ p->processed = 0; ++ p->res = SZ_OK; ++} ++ ++static void RangeEnc_FlushStream(CRangeEnc *p) ++{ ++ size_t num; ++ if (p->res != SZ_OK) ++ return; ++ num = p->buf - p->bufBase; ++ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) ++ p->res = SZ_ERROR_WRITE; ++ p->processed += num; ++ p->buf = p->bufBase; ++} ++ ++static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) ++{ ++ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) ++ { ++ Byte temp = p->cache; ++ do ++ { ++ Byte *buf = p->buf; ++ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); ++ p->buf = buf; ++ if (buf == p->bufLim) ++ RangeEnc_FlushStream(p); ++ temp = 0xFF; ++ } ++ while (--p->cacheSize != 0); ++ p->cache = (Byte)((UInt32)p->low >> 24); ++ } ++ p->cacheSize++; ++ p->low = (UInt32)p->low << 8; ++} ++ ++static void RangeEnc_FlushData(CRangeEnc *p) ++{ ++ int i; ++ for (i = 0; i < 5; i++) ++ RangeEnc_ShiftLow(p); ++} ++ ++static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) ++{ ++ do ++ { ++ p->range >>= 1; ++ p->low += p->range & (0 - ((value >> --numBits) & 1)); ++ if (p->range < kTopValue) ++ { ++ p->range <<= 8; ++ RangeEnc_ShiftLow(p); ++ } ++ } ++ while (numBits != 0); ++} ++ ++static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) ++{ ++ UInt32 ttt = *prob; ++ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; ++ if (symbol == 0) ++ { ++ p->range = newBound; ++ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; ++ } ++ else ++ { ++ p->low += newBound; ++ p->range -= newBound; ++ ttt -= ttt >> kNumMoveBits; ++ } ++ *prob = (CLzmaProb)ttt; ++ if (p->range < kTopValue) ++ { ++ p->range <<= 8; ++ RangeEnc_ShiftLow(p); ++ } ++} ++ ++static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) ++{ ++ symbol |= 0x100; ++ do ++ { ++ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); ++ symbol <<= 1; ++ } ++ while (symbol < 0x10000); ++} ++ ++static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) ++{ ++ UInt32 offs = 0x100; ++ symbol |= 0x100; ++ do ++ { ++ matchByte <<= 1; ++ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); ++ symbol <<= 1; ++ offs &= ~(matchByte ^ symbol); ++ } ++ while (symbol < 0x10000); ++} ++ ++void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) ++{ ++ UInt32 i; ++ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) ++ { ++ const int kCyclesBits = kNumBitPriceShiftBits; ++ UInt32 w = i; ++ UInt32 bitCount = 0; ++ int j; ++ for (j = 0; j < kCyclesBits; j++) ++ { ++ w = w * w; ++ bitCount <<= 1; ++ while (w >= ((UInt32)1 << 16)) ++ { ++ w >>= 1; ++ bitCount++; ++ } ++ } ++ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); ++ } ++} ++ ++ ++#define GET_PRICE(prob, symbol) \ ++ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; ++ ++#define GET_PRICEa(prob, symbol) \ ++ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; ++ ++#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] ++#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] ++ ++#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] ++#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] ++ ++static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) ++{ ++ UInt32 price = 0; ++ symbol |= 0x100; ++ do ++ { ++ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); ++ symbol <<= 1; ++ } ++ while (symbol < 0x10000); ++ return price; ++} ++ ++static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) ++{ ++ UInt32 price = 0; ++ UInt32 offs = 0x100; ++ symbol |= 0x100; ++ do ++ { ++ matchByte <<= 1; ++ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); ++ symbol <<= 1; ++ offs &= ~(matchByte ^ symbol); ++ } ++ while (symbol < 0x10000); ++ return price; ++} ++ ++ ++static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) ++{ ++ UInt32 m = 1; ++ int i; ++ for (i = numBitLevels; i != 0;) ++ { ++ UInt32 bit; ++ i--; ++ bit = (symbol >> i) & 1; ++ RangeEnc_EncodeBit(rc, probs + m, bit); ++ m = (m << 1) | bit; ++ } ++} ++ ++static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) ++{ ++ UInt32 m = 1; ++ int i; ++ for (i = 0; i < numBitLevels; i++) ++ { ++ UInt32 bit = symbol & 1; ++ RangeEnc_EncodeBit(rc, probs + m, bit); ++ m = (m << 1) | bit; ++ symbol >>= 1; ++ } ++} ++ ++static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) ++{ ++ UInt32 price = 0; ++ symbol |= (1 << numBitLevels); ++ while (symbol != 1) ++ { ++ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); ++ symbol >>= 1; ++ } ++ return price; ++} ++ ++static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) ++{ ++ UInt32 price = 0; ++ UInt32 m = 1; ++ int i; ++ for (i = numBitLevels; i != 0; i--) ++ { ++ UInt32 bit = symbol & 1; ++ symbol >>= 1; ++ price += GET_PRICEa(probs[m], bit); ++ m = (m << 1) | bit; ++ } ++ return price; ++} ++ ++ ++static void LenEnc_Init(CLenEnc *p) ++{ ++ unsigned i; ++ p->choice = p->choice2 = kProbInitValue; ++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) ++ p->low[i] = kProbInitValue; ++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) ++ p->mid[i] = kProbInitValue; ++ for (i = 0; i < kLenNumHighSymbols; i++) ++ p->high[i] = kProbInitValue; ++} ++ ++static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) ++{ ++ if (symbol < kLenNumLowSymbols) ++ { ++ RangeEnc_EncodeBit(rc, &p->choice, 0); ++ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); ++ } ++ else ++ { ++ RangeEnc_EncodeBit(rc, &p->choice, 1); ++ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) ++ { ++ RangeEnc_EncodeBit(rc, &p->choice2, 0); ++ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); ++ } ++ else ++ { ++ RangeEnc_EncodeBit(rc, &p->choice2, 1); ++ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); ++ } ++ } ++} ++ ++static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) ++{ ++ UInt32 a0 = GET_PRICE_0a(p->choice); ++ UInt32 a1 = GET_PRICE_1a(p->choice); ++ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); ++ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); ++ UInt32 i = 0; ++ for (i = 0; i < kLenNumLowSymbols; i++) ++ { ++ if (i >= numSymbols) ++ return; ++ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); ++ } ++ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) ++ { ++ if (i >= numSymbols) ++ return; ++ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); ++ } ++ for (; i < numSymbols; i++) ++ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); ++} ++ ++static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) ++{ ++ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); ++ p->counters[posState] = p->tableSize; ++} ++ ++static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) ++{ ++ UInt32 posState; ++ for (posState = 0; posState < numPosStates; posState++) ++ LenPriceEnc_UpdateTable(p, posState, ProbPrices); ++} ++ ++static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) ++{ ++ LenEnc_Encode(&p->p, rc, symbol, posState); ++ if (updatePrice) ++ if (--p->counters[posState] == 0) ++ LenPriceEnc_UpdateTable(p, posState, ProbPrices); ++} ++ ++ ++ ++ ++static void MovePos(CLzmaEnc *p, UInt32 num) ++{ ++ #ifdef SHOW_STAT ++ ttt += num; ++ printf("\n MovePos %d", num); ++ #endif ++ if (num != 0) ++ { ++ p->additionalOffset += num; ++ p->matchFinder.Skip(p->matchFinderObj, num); ++ } ++} ++ ++static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) ++{ ++ UInt32 lenRes = 0, numPairs; ++ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); ++ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); ++ #ifdef SHOW_STAT ++ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); ++ ttt++; ++ { ++ UInt32 i; ++ for (i = 0; i < numPairs; i += 2) ++ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); ++ } ++ #endif ++ if (numPairs > 0) ++ { ++ lenRes = p->matches[numPairs - 2]; ++ if (lenRes == p->numFastBytes) ++ { ++ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; ++ UInt32 distance = p->matches[numPairs - 1] + 1; ++ UInt32 numAvail = p->numAvail; ++ if (numAvail > LZMA_MATCH_LEN_MAX) ++ numAvail = LZMA_MATCH_LEN_MAX; ++ { ++ const Byte *pby2 = pby - distance; ++ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); ++ } ++ } ++ } ++ p->additionalOffset++; ++ *numDistancePairsRes = numPairs; ++ return lenRes; ++} ++ ++ ++#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; ++#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; ++#define IsShortRep(p) ((p)->backPrev == 0) ++ ++static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) ++{ ++ return ++ GET_PRICE_0(p->isRepG0[state]) + ++ GET_PRICE_0(p->isRep0Long[state][posState]); ++} ++ ++static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) ++{ ++ UInt32 price; ++ if (repIndex == 0) ++ { ++ price = GET_PRICE_0(p->isRepG0[state]); ++ price += GET_PRICE_1(p->isRep0Long[state][posState]); ++ } ++ else ++ { ++ price = GET_PRICE_1(p->isRepG0[state]); ++ if (repIndex == 1) ++ price += GET_PRICE_0(p->isRepG1[state]); ++ else ++ { ++ price += GET_PRICE_1(p->isRepG1[state]); ++ price += GET_PRICE(p->isRepG2[state], repIndex - 2); ++ } ++ } ++ return price; ++} ++ ++static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) ++{ ++ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + ++ GetPureRepPrice(p, repIndex, state, posState); ++} ++ ++static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) ++{ ++ UInt32 posMem = p->opt[cur].posPrev; ++ UInt32 backMem = p->opt[cur].backPrev; ++ p->optimumEndIndex = cur; ++ do ++ { ++ if (p->opt[cur].prev1IsChar) ++ { ++ MakeAsChar(&p->opt[posMem]) ++ p->opt[posMem].posPrev = posMem - 1; ++ if (p->opt[cur].prev2) ++ { ++ p->opt[posMem - 1].prev1IsChar = False; ++ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; ++ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; ++ } ++ } ++ { ++ UInt32 posPrev = posMem; ++ UInt32 backCur = backMem; ++ ++ backMem = p->opt[posPrev].backPrev; ++ posMem = p->opt[posPrev].posPrev; ++ ++ p->opt[posPrev].backPrev = backCur; ++ p->opt[posPrev].posPrev = cur; ++ cur = posPrev; ++ } ++ } ++ while (cur != 0); ++ *backRes = p->opt[0].backPrev; ++ p->optimumCurrentIndex = p->opt[0].posPrev; ++ return p->optimumCurrentIndex; ++} ++ ++#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) ++ ++static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) ++{ ++ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; ++ UInt32 matchPrice, repMatchPrice, normalMatchPrice; ++ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; ++ UInt32 *matches = NULL; ++ const Byte *data = NULL; ++ Byte curByte, matchByte; ++ if (p->optimumEndIndex != p->optimumCurrentIndex) ++ { ++ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; ++ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; ++ *backRes = opt->backPrev; ++ p->optimumCurrentIndex = opt->posPrev; ++ return lenRes; ++ } ++ p->optimumCurrentIndex = p->optimumEndIndex = 0; ++ ++ if (p->additionalOffset == 0) ++ mainLen = ReadMatchDistances(p, &numPairs); ++ else ++ { ++ mainLen = p->longestMatchLength; ++ numPairs = p->numPairs; ++ } ++ ++ numAvail = p->numAvail; ++ if (numAvail < 2) ++ { ++ *backRes = (UInt32)(-1); ++ return 1; ++ } ++ if (numAvail > LZMA_MATCH_LEN_MAX) ++ numAvail = LZMA_MATCH_LEN_MAX; ++ ++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; ++ repMaxIndex = 0; ++ for (i = 0; i < LZMA_NUM_REPS; i++) ++ { ++ UInt32 lenTest; ++ const Byte *data2 = NULL; ++ reps[i] = p->reps[i]; ++ data2 = data - (reps[i] + 1); ++ if (data[0] != data2[0] || data[1] != data2[1]) ++ { ++ repLens[i] = 0; ++ continue; ++ } ++ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); ++ repLens[i] = lenTest; ++ if (lenTest > repLens[repMaxIndex]) ++ repMaxIndex = i; ++ } ++ if (repLens[repMaxIndex] >= p->numFastBytes) ++ { ++ UInt32 lenRes; ++ *backRes = repMaxIndex; ++ lenRes = repLens[repMaxIndex]; ++ MovePos(p, lenRes - 1); ++ return lenRes; ++ } ++ ++ matches = p->matches; ++ if (mainLen >= p->numFastBytes) ++ { ++ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; ++ MovePos(p, mainLen - 1); ++ return mainLen; ++ } ++ curByte = *data; ++ matchByte = *(data - (reps[0] + 1)); ++ ++ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) ++ { ++ *backRes = (UInt32)-1; ++ return 1; ++ } ++ ++ p->opt[0].state = (CState)p->state; ++ ++ posState = (position & p->pbMask); ++ ++ { ++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); ++ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + ++ (!IsCharState(p->state) ? ++ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : ++ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); ++ } ++ ++ MakeAsChar(&p->opt[1]); ++ ++ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); ++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); ++ ++ if (matchByte == curByte) ++ { ++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); ++ if (shortRepPrice < p->opt[1].price) ++ { ++ p->opt[1].price = shortRepPrice; ++ MakeAsShortRep(&p->opt[1]); ++ } ++ } ++ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); ++ ++ if (lenEnd < 2) ++ { ++ *backRes = p->opt[1].backPrev; ++ return 1; ++ } ++ ++ p->opt[1].posPrev = 0; ++ for (i = 0; i < LZMA_NUM_REPS; i++) ++ p->opt[0].backs[i] = reps[i]; ++ ++ len = lenEnd; ++ do ++ p->opt[len--].price = kInfinityPrice; ++ while (len >= 2); ++ ++ for (i = 0; i < LZMA_NUM_REPS; i++) ++ { ++ UInt32 repLen = repLens[i]; ++ UInt32 price; ++ if (repLen < 2) ++ continue; ++ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); ++ do ++ { ++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; ++ COptimal *opt = &p->opt[repLen]; ++ if (curAndLenPrice < opt->price) ++ { ++ opt->price = curAndLenPrice; ++ opt->posPrev = 0; ++ opt->backPrev = i; ++ opt->prev1IsChar = False; ++ } ++ } ++ while (--repLen >= 2); ++ } ++ ++ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); ++ ++ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); ++ if (len <= mainLen) ++ { ++ UInt32 offs = 0; ++ while (len > matches[offs]) ++ offs += 2; ++ for (; ; len++) ++ { ++ COptimal *opt = NULL; ++ UInt32 distance = matches[offs + 1]; ++ ++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; ++ UInt32 lenToPosState = GetLenToPosState(len); ++ if (distance < kNumFullDistances) ++ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; ++ else ++ { ++ UInt32 slot; ++ GetPosSlot2(distance, slot); ++ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; ++ } ++ opt = &p->opt[len]; ++ if (curAndLenPrice < opt->price) ++ { ++ opt->price = curAndLenPrice; ++ opt->posPrev = 0; ++ opt->backPrev = distance + LZMA_NUM_REPS; ++ opt->prev1IsChar = False; ++ } ++ if (len == matches[offs]) ++ { ++ offs += 2; ++ if (offs == numPairs) ++ break; ++ } ++ } ++ } ++ ++ cur = 0; ++ ++ #ifdef SHOW_STAT2 ++ if (position >= 0) ++ { ++ unsigned i; ++ printf("\n pos = %4X", position); ++ for (i = cur; i <= lenEnd; i++) ++ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); ++ } ++ #endif ++ ++ for (;;) ++ { ++ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; ++ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; ++ Bool nextIsChar; ++ Byte curByte, matchByte; ++ const Byte *data = NULL; ++ COptimal *curOpt = NULL; ++ COptimal *nextOpt = NULL; ++ ++ cur++; ++ if (cur == lenEnd) ++ return Backward(p, backRes, cur); ++ ++ newLen = ReadMatchDistances(p, &numPairs); ++ if (newLen >= p->numFastBytes) ++ { ++ p->numPairs = numPairs; ++ p->longestMatchLength = newLen; ++ return Backward(p, backRes, cur); ++ } ++ position++; ++ curOpt = &p->opt[cur]; ++ posPrev = curOpt->posPrev; ++ if (curOpt->prev1IsChar) ++ { ++ posPrev--; ++ if (curOpt->prev2) ++ { ++ state = p->opt[curOpt->posPrev2].state; ++ if (curOpt->backPrev2 < LZMA_NUM_REPS) ++ state = kRepNextStates[state]; ++ else ++ state = kMatchNextStates[state]; ++ } ++ else ++ state = p->opt[posPrev].state; ++ state = kLiteralNextStates[state]; ++ } ++ else ++ state = p->opt[posPrev].state; ++ if (posPrev == cur - 1) ++ { ++ if (IsShortRep(curOpt)) ++ state = kShortRepNextStates[state]; ++ else ++ state = kLiteralNextStates[state]; ++ } ++ else ++ { ++ UInt32 pos; ++ const COptimal *prevOpt = NULL; ++ if (curOpt->prev1IsChar && curOpt->prev2) ++ { ++ posPrev = curOpt->posPrev2; ++ pos = curOpt->backPrev2; ++ state = kRepNextStates[state]; ++ } ++ else ++ { ++ pos = curOpt->backPrev; ++ if (pos < LZMA_NUM_REPS) ++ state = kRepNextStates[state]; ++ else ++ state = kMatchNextStates[state]; ++ } ++ prevOpt = &p->opt[posPrev]; ++ if (pos < LZMA_NUM_REPS) ++ { ++ UInt32 i; ++ reps[0] = prevOpt->backs[pos]; ++ for (i = 1; i <= pos; i++) ++ reps[i] = prevOpt->backs[i - 1]; ++ for (; i < LZMA_NUM_REPS; i++) ++ reps[i] = prevOpt->backs[i]; ++ } ++ else ++ { ++ UInt32 i; ++ reps[0] = (pos - LZMA_NUM_REPS); ++ for (i = 1; i < LZMA_NUM_REPS; i++) ++ reps[i] = prevOpt->backs[i - 1]; ++ } ++ } ++ curOpt->state = (CState)state; ++ ++ curOpt->backs[0] = reps[0]; ++ curOpt->backs[1] = reps[1]; ++ curOpt->backs[2] = reps[2]; ++ curOpt->backs[3] = reps[3]; ++ ++ curPrice = curOpt->price; ++ nextIsChar = False; ++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; ++ curByte = *data; ++ matchByte = *(data - (reps[0] + 1)); ++ ++ posState = (position & p->pbMask); ++ ++ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); ++ { ++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); ++ curAnd1Price += ++ (!IsCharState(state) ? ++ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : ++ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); ++ } ++ ++ nextOpt = &p->opt[cur + 1]; ++ ++ if (curAnd1Price < nextOpt->price) ++ { ++ nextOpt->price = curAnd1Price; ++ nextOpt->posPrev = cur; ++ MakeAsChar(nextOpt); ++ nextIsChar = True; ++ } ++ ++ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); ++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); ++ ++ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) ++ { ++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); ++ if (shortRepPrice <= nextOpt->price) ++ { ++ nextOpt->price = shortRepPrice; ++ nextOpt->posPrev = cur; ++ MakeAsShortRep(nextOpt); ++ nextIsChar = True; ++ } ++ } ++ numAvailFull = p->numAvail; ++ { ++ UInt32 temp = kNumOpts - 1 - cur; ++ if (temp < numAvailFull) ++ numAvailFull = temp; ++ } ++ ++ if (numAvailFull < 2) ++ continue; ++ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); ++ ++ if (!nextIsChar && matchByte != curByte) /* speed optimization */ ++ { ++ /* try Literal + rep0 */ ++ UInt32 temp; ++ UInt32 lenTest2; ++ const Byte *data2 = data - (reps[0] + 1); ++ UInt32 limit = p->numFastBytes + 1; ++ if (limit > numAvailFull) ++ limit = numAvailFull; ++ ++ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); ++ lenTest2 = temp - 1; ++ if (lenTest2 >= 2) ++ { ++ UInt32 state2 = kLiteralNextStates[state]; ++ UInt32 posStateNext = (position + 1) & p->pbMask; ++ UInt32 nextRepMatchPrice = curAnd1Price + ++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + ++ GET_PRICE_1(p->isRep[state2]); ++ /* for (; lenTest2 >= 2; lenTest2--) */ ++ { ++ UInt32 curAndLenPrice; ++ COptimal *opt; ++ UInt32 offset = cur + 1 + lenTest2; ++ while (lenEnd < offset) ++ p->opt[++lenEnd].price = kInfinityPrice; ++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); ++ opt = &p->opt[offset]; ++ if (curAndLenPrice < opt->price) ++ { ++ opt->price = curAndLenPrice; ++ opt->posPrev = cur + 1; ++ opt->backPrev = 0; ++ opt->prev1IsChar = True; ++ opt->prev2 = False; ++ } ++ } ++ } ++ } ++ ++ startLen = 2; /* speed optimization */ ++ { ++ UInt32 repIndex; ++ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) ++ { ++ UInt32 lenTest; ++ UInt32 lenTestTemp; ++ UInt32 price; ++ const Byte *data2 = data - (reps[repIndex] + 1); ++ if (data[0] != data2[0] || data[1] != data2[1]) ++ continue; ++ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); ++ while (lenEnd < cur + lenTest) ++ p->opt[++lenEnd].price = kInfinityPrice; ++ lenTestTemp = lenTest; ++ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); ++ do ++ { ++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; ++ COptimal *opt = &p->opt[cur + lenTest]; ++ if (curAndLenPrice < opt->price) ++ { ++ opt->price = curAndLenPrice; ++ opt->posPrev = cur; ++ opt->backPrev = repIndex; ++ opt->prev1IsChar = False; ++ } ++ } ++ while (--lenTest >= 2); ++ lenTest = lenTestTemp; ++ ++ if (repIndex == 0) ++ startLen = lenTest + 1; ++ ++ /* if (_maxMode) */ ++ { ++ UInt32 lenTest2 = lenTest + 1; ++ UInt32 limit = lenTest2 + p->numFastBytes; ++ UInt32 nextRepMatchPrice; ++ if (limit > numAvailFull) ++ limit = numAvailFull; ++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); ++ lenTest2 -= lenTest + 1; ++ if (lenTest2 >= 2) ++ { ++ UInt32 state2 = kRepNextStates[state]; ++ UInt32 posStateNext = (position + lenTest) & p->pbMask; ++ UInt32 curAndLenCharPrice = ++ price + p->repLenEnc.prices[posState][lenTest - 2] + ++ GET_PRICE_0(p->isMatch[state2][posStateNext]) + ++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), ++ data[lenTest], data2[lenTest], p->ProbPrices); ++ state2 = kLiteralNextStates[state2]; ++ posStateNext = (position + lenTest + 1) & p->pbMask; ++ nextRepMatchPrice = curAndLenCharPrice + ++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + ++ GET_PRICE_1(p->isRep[state2]); ++ ++ /* for (; lenTest2 >= 2; lenTest2--) */ ++ { ++ UInt32 curAndLenPrice; ++ COptimal *opt; ++ UInt32 offset = cur + lenTest + 1 + lenTest2; ++ while (lenEnd < offset) ++ p->opt[++lenEnd].price = kInfinityPrice; ++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); ++ opt = &p->opt[offset]; ++ if (curAndLenPrice < opt->price) ++ { ++ opt->price = curAndLenPrice; ++ opt->posPrev = cur + lenTest + 1; ++ opt->backPrev = 0; ++ opt->prev1IsChar = True; ++ opt->prev2 = True; ++ opt->posPrev2 = cur; ++ opt->backPrev2 = repIndex; ++ } ++ } ++ } ++ } ++ } ++ } ++ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ ++ if (newLen > numAvail) ++ { ++ newLen = numAvail; ++ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); ++ matches[numPairs] = newLen; ++ numPairs += 2; ++ } ++ if (newLen >= startLen) ++ { ++ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); ++ UInt32 offs, curBack, posSlot; ++ UInt32 lenTest; ++ while (lenEnd < cur + newLen) ++ p->opt[++lenEnd].price = kInfinityPrice; ++ ++ offs = 0; ++ while (startLen > matches[offs]) ++ offs += 2; ++ curBack = matches[offs + 1]; ++ GetPosSlot2(curBack, posSlot); ++ for (lenTest = /*2*/ startLen; ; lenTest++) ++ { ++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; ++ UInt32 lenToPosState = GetLenToPosState(lenTest); ++ COptimal *opt = NULL; ++ if (curBack < kNumFullDistances) ++ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; ++ else ++ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; ++ ++ opt = &p->opt[cur + lenTest]; ++ if (curAndLenPrice < opt->price) ++ { ++ opt->price = curAndLenPrice; ++ opt->posPrev = cur; ++ opt->backPrev = curBack + LZMA_NUM_REPS; ++ opt->prev1IsChar = False; ++ } ++ ++ if (/*_maxMode && */lenTest == matches[offs]) ++ { ++ /* Try Match + Literal + Rep0 */ ++ const Byte *data2 = data - (curBack + 1); ++ UInt32 lenTest2 = lenTest + 1; ++ UInt32 limit = lenTest2 + p->numFastBytes; ++ UInt32 nextRepMatchPrice; ++ if (limit > numAvailFull) ++ limit = numAvailFull; ++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); ++ lenTest2 -= lenTest + 1; ++ if (lenTest2 >= 2) ++ { ++ UInt32 state2 = kMatchNextStates[state]; ++ UInt32 posStateNext = (position + lenTest) & p->pbMask; ++ UInt32 curAndLenCharPrice = curAndLenPrice + ++ GET_PRICE_0(p->isMatch[state2][posStateNext]) + ++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), ++ data[lenTest], data2[lenTest], p->ProbPrices); ++ state2 = kLiteralNextStates[state2]; ++ posStateNext = (posStateNext + 1) & p->pbMask; ++ nextRepMatchPrice = curAndLenCharPrice + ++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + ++ GET_PRICE_1(p->isRep[state2]); ++ ++ /* for (; lenTest2 >= 2; lenTest2--) */ ++ { ++ UInt32 offset = cur + lenTest + 1 + lenTest2; ++ UInt32 curAndLenPrice; ++ COptimal *opt; ++ while (lenEnd < offset) ++ p->opt[++lenEnd].price = kInfinityPrice; ++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); ++ opt = &p->opt[offset]; ++ if (curAndLenPrice < opt->price) ++ { ++ opt->price = curAndLenPrice; ++ opt->posPrev = cur + lenTest + 1; ++ opt->backPrev = 0; ++ opt->prev1IsChar = True; ++ opt->prev2 = True; ++ opt->posPrev2 = cur; ++ opt->backPrev2 = curBack + LZMA_NUM_REPS; ++ } ++ } ++ } ++ offs += 2; ++ if (offs == numPairs) ++ break; ++ curBack = matches[offs + 1]; ++ if (curBack >= kNumFullDistances) ++ GetPosSlot2(curBack, posSlot); ++ } ++ } ++ } ++ } ++} ++ ++#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) ++ ++static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) ++{ ++ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; ++ const Byte *data = NULL; ++ const UInt32 *matches = NULL; ++ ++ if (p->additionalOffset == 0) ++ mainLen = ReadMatchDistances(p, &numPairs); ++ else ++ { ++ mainLen = p->longestMatchLength; ++ numPairs = p->numPairs; ++ } ++ ++ numAvail = p->numAvail; ++ *backRes = (UInt32)-1; ++ if (numAvail < 2) ++ return 1; ++ if (numAvail > LZMA_MATCH_LEN_MAX) ++ numAvail = LZMA_MATCH_LEN_MAX; ++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; ++ ++ repLen = repIndex = 0; ++ for (i = 0; i < LZMA_NUM_REPS; i++) ++ { ++ UInt32 len; ++ const Byte *data2 = data - (p->reps[i] + 1); ++ if (data[0] != data2[0] || data[1] != data2[1]) ++ continue; ++ for (len = 2; len < numAvail && data[len] == data2[len]; len++); ++ if (len >= p->numFastBytes) ++ { ++ *backRes = i; ++ MovePos(p, len - 1); ++ return len; ++ } ++ if (len > repLen) ++ { ++ repIndex = i; ++ repLen = len; ++ } ++ } ++ ++ matches = p->matches; ++ if (mainLen >= p->numFastBytes) ++ { ++ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; ++ MovePos(p, mainLen - 1); ++ return mainLen; ++ } ++ ++ mainDist = 0; /* for GCC */ ++ if (mainLen >= 2) ++ { ++ mainDist = matches[numPairs - 1]; ++ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) ++ { ++ if (!ChangePair(matches[numPairs - 3], mainDist)) ++ break; ++ numPairs -= 2; ++ mainLen = matches[numPairs - 2]; ++ mainDist = matches[numPairs - 1]; ++ } ++ if (mainLen == 2 && mainDist >= 0x80) ++ mainLen = 1; ++ } ++ ++ if (repLen >= 2 && ( ++ (repLen + 1 >= mainLen) || ++ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || ++ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) ++ { ++ *backRes = repIndex; ++ MovePos(p, repLen - 1); ++ return repLen; ++ } ++ ++ if (mainLen < 2 || numAvail <= 2) ++ return 1; ++ ++ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); ++ if (p->longestMatchLength >= 2) ++ { ++ UInt32 newDistance = matches[p->numPairs - 1]; ++ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || ++ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || ++ (p->longestMatchLength > mainLen + 1) || ++ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) ++ return 1; ++ } ++ ++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; ++ for (i = 0; i < LZMA_NUM_REPS; i++) ++ { ++ UInt32 len, limit; ++ const Byte *data2 = data - (p->reps[i] + 1); ++ if (data[0] != data2[0] || data[1] != data2[1]) ++ continue; ++ limit = mainLen - 1; ++ for (len = 2; len < limit && data[len] == data2[len]; len++); ++ if (len >= limit) ++ return 1; ++ } ++ *backRes = mainDist + LZMA_NUM_REPS; ++ MovePos(p, mainLen - 2); ++ return mainLen; ++} ++ ++static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) ++{ ++ UInt32 len; ++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); ++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); ++ p->state = kMatchNextStates[p->state]; ++ len = LZMA_MATCH_LEN_MIN; ++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); ++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); ++ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); ++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); ++} ++ ++static SRes CheckErrors(CLzmaEnc *p) ++{ ++ if (p->result != SZ_OK) ++ return p->result; ++ if (p->rc.res != SZ_OK) ++ p->result = SZ_ERROR_WRITE; ++ if (p->matchFinderBase.result != SZ_OK) ++ p->result = SZ_ERROR_READ; ++ if (p->result != SZ_OK) ++ p->finished = True; ++ return p->result; ++} ++ ++static SRes Flush(CLzmaEnc *p, UInt32 nowPos) ++{ ++ /* ReleaseMFStream(); */ ++ p->finished = True; ++ if (p->writeEndMark) ++ WriteEndMarker(p, nowPos & p->pbMask); ++ RangeEnc_FlushData(&p->rc); ++ RangeEnc_FlushStream(&p->rc); ++ return CheckErrors(p); ++} ++ ++static void FillAlignPrices(CLzmaEnc *p) ++{ ++ UInt32 i; ++ for (i = 0; i < kAlignTableSize; i++) ++ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); ++ p->alignPriceCount = 0; ++} ++ ++static void FillDistancesPrices(CLzmaEnc *p) ++{ ++ UInt32 tempPrices[kNumFullDistances]; ++ UInt32 i, lenToPosState; ++ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) ++ { ++ UInt32 posSlot = GetPosSlot1(i); ++ UInt32 footerBits = ((posSlot >> 1) - 1); ++ UInt32 base = ((2 | (posSlot & 1)) << footerBits); ++ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); ++ } ++ ++ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) ++ { ++ UInt32 posSlot; ++ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; ++ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; ++ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) ++ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); ++ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) ++ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); ++ ++ { ++ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; ++ UInt32 i; ++ for (i = 0; i < kStartPosModelIndex; i++) ++ distancesPrices[i] = posSlotPrices[i]; ++ for (; i < kNumFullDistances; i++) ++ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; ++ } ++ } ++ p->matchPriceCount = 0; ++} ++ ++void LzmaEnc_Construct(CLzmaEnc *p) ++{ ++ RangeEnc_Construct(&p->rc); ++ MatchFinder_Construct(&p->matchFinderBase); ++ #ifndef _7ZIP_ST ++ MatchFinderMt_Construct(&p->matchFinderMt); ++ p->matchFinderMt.MatchFinder = &p->matchFinderBase; ++ #endif ++ ++ { ++ CLzmaEncProps props; ++ LzmaEncProps_Init(&props); ++ LzmaEnc_SetProps(p, &props); ++ } ++ ++ #ifndef LZMA_LOG_BSR ++ LzmaEnc_FastPosInit(p->g_FastPos); ++ #endif ++ ++ LzmaEnc_InitPriceTables(p->ProbPrices); ++ p->litProbs = 0; ++ p->saveState.litProbs = 0; ++} ++ ++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) ++{ ++ void *p; ++ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); ++ if (p != 0) ++ LzmaEnc_Construct((CLzmaEnc *)p); ++ return p; ++} ++ ++void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) ++{ ++ alloc->Free(alloc, p->litProbs); ++ alloc->Free(alloc, p->saveState.litProbs); ++ p->litProbs = 0; ++ p->saveState.litProbs = 0; ++} ++ ++void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ #ifndef _7ZIP_ST ++ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); ++ #endif ++ MatchFinder_Free(&p->matchFinderBase, allocBig); ++ LzmaEnc_FreeLits(p, alloc); ++ RangeEnc_Free(&p->rc, alloc); ++} ++ ++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); ++ alloc->Free(alloc, p); ++} ++ ++static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) ++{ ++ UInt32 nowPos32, startPos32; ++ if (p->needInit) ++ { ++ p->matchFinder.Init(p->matchFinderObj); ++ p->needInit = 0; ++ } ++ ++ if (p->finished) ++ return p->result; ++ RINOK(CheckErrors(p)); ++ ++ nowPos32 = (UInt32)p->nowPos64; ++ startPos32 = nowPos32; ++ ++ if (p->nowPos64 == 0) ++ { ++ UInt32 numPairs; ++ Byte curByte; ++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) ++ return Flush(p, nowPos32); ++ ReadMatchDistances(p, &numPairs); ++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); ++ p->state = kLiteralNextStates[p->state]; ++ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); ++ LitEnc_Encode(&p->rc, p->litProbs, curByte); ++ p->additionalOffset--; ++ nowPos32++; ++ } ++ ++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) ++ for (;;) ++ { ++ UInt32 pos, len, posState; ++ ++ if (p->fastMode) ++ len = GetOptimumFast(p, &pos); ++ else ++ len = GetOptimum(p, nowPos32, &pos); ++ ++ #ifdef SHOW_STAT2 ++ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); ++ #endif ++ ++ posState = nowPos32 & p->pbMask; ++ if (len == 1 && pos == (UInt32)-1) ++ { ++ Byte curByte; ++ CLzmaProb *probs = NULL; ++ const Byte *data = NULL; ++ ++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); ++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; ++ curByte = *data; ++ probs = LIT_PROBS(nowPos32, *(data - 1)); ++ if (IsCharState(p->state)) ++ LitEnc_Encode(&p->rc, probs, curByte); ++ else ++ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); ++ p->state = kLiteralNextStates[p->state]; ++ } ++ else ++ { ++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); ++ if (pos < LZMA_NUM_REPS) ++ { ++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); ++ if (pos == 0) ++ { ++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); ++ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); ++ } ++ else ++ { ++ UInt32 distance = p->reps[pos]; ++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); ++ if (pos == 1) ++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); ++ else ++ { ++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); ++ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); ++ if (pos == 3) ++ p->reps[3] = p->reps[2]; ++ p->reps[2] = p->reps[1]; ++ } ++ p->reps[1] = p->reps[0]; ++ p->reps[0] = distance; ++ } ++ if (len == 1) ++ p->state = kShortRepNextStates[p->state]; ++ else ++ { ++ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); ++ p->state = kRepNextStates[p->state]; ++ } ++ } ++ else ++ { ++ UInt32 posSlot; ++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); ++ p->state = kMatchNextStates[p->state]; ++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); ++ pos -= LZMA_NUM_REPS; ++ GetPosSlot(pos, posSlot); ++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); ++ ++ if (posSlot >= kStartPosModelIndex) ++ { ++ UInt32 footerBits = ((posSlot >> 1) - 1); ++ UInt32 base = ((2 | (posSlot & 1)) << footerBits); ++ UInt32 posReduced = pos - base; ++ ++ if (posSlot < kEndPosModelIndex) ++ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); ++ else ++ { ++ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); ++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); ++ p->alignPriceCount++; ++ } ++ } ++ p->reps[3] = p->reps[2]; ++ p->reps[2] = p->reps[1]; ++ p->reps[1] = p->reps[0]; ++ p->reps[0] = pos; ++ p->matchPriceCount++; ++ } ++ } ++ p->additionalOffset -= len; ++ nowPos32 += len; ++ if (p->additionalOffset == 0) ++ { ++ UInt32 processed; ++ if (!p->fastMode) ++ { ++ if (p->matchPriceCount >= (1 << 7)) ++ FillDistancesPrices(p); ++ if (p->alignPriceCount >= kAlignTableSize) ++ FillAlignPrices(p); ++ } ++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) ++ break; ++ processed = nowPos32 - startPos32; ++ if (useLimits) ++ { ++ if (processed + kNumOpts + 300 >= maxUnpackSize || ++ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) ++ break; ++ } ++ else if (processed >= (1 << 15)) ++ { ++ p->nowPos64 += nowPos32 - startPos32; ++ return CheckErrors(p); ++ } ++ } ++ } ++ p->nowPos64 += nowPos32 - startPos32; ++ return Flush(p, nowPos32); ++} ++ ++#define kBigHashDicLimit ((UInt32)1 << 24) ++ ++static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ UInt32 beforeSize = kNumOpts; ++ Bool btMode; ++ if (!RangeEnc_Alloc(&p->rc, alloc)) ++ return SZ_ERROR_MEM; ++ btMode = (p->matchFinderBase.btMode != 0); ++ #ifndef _7ZIP_ST ++ p->mtMode = (p->multiThread && !p->fastMode && btMode); ++ #endif ++ ++ { ++ unsigned lclp = p->lc + p->lp; ++ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) ++ { ++ LzmaEnc_FreeLits(p, alloc); ++ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); ++ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); ++ if (p->litProbs == 0 || p->saveState.litProbs == 0) ++ { ++ LzmaEnc_FreeLits(p, alloc); ++ return SZ_ERROR_MEM; ++ } ++ p->lclp = lclp; ++ } ++ } ++ ++ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); ++ ++ if (beforeSize + p->dictSize < keepWindowSize) ++ beforeSize = keepWindowSize - p->dictSize; ++ ++ #ifndef _7ZIP_ST ++ if (p->mtMode) ++ { ++ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); ++ p->matchFinderObj = &p->matchFinderMt; ++ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); ++ } ++ else ++ #endif ++ { ++ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) ++ return SZ_ERROR_MEM; ++ p->matchFinderObj = &p->matchFinderBase; ++ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); ++ } ++ return SZ_OK; ++} ++ ++void LzmaEnc_Init(CLzmaEnc *p) ++{ ++ UInt32 i; ++ p->state = 0; ++ for (i = 0 ; i < LZMA_NUM_REPS; i++) ++ p->reps[i] = 0; ++ ++ RangeEnc_Init(&p->rc); ++ ++ ++ for (i = 0; i < kNumStates; i++) ++ { ++ UInt32 j; ++ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) ++ { ++ p->isMatch[i][j] = kProbInitValue; ++ p->isRep0Long[i][j] = kProbInitValue; ++ } ++ p->isRep[i] = kProbInitValue; ++ p->isRepG0[i] = kProbInitValue; ++ p->isRepG1[i] = kProbInitValue; ++ p->isRepG2[i] = kProbInitValue; ++ } ++ ++ { ++ UInt32 num = 0x300 << (p->lp + p->lc); ++ for (i = 0; i < num; i++) ++ p->litProbs[i] = kProbInitValue; ++ } ++ ++ { ++ for (i = 0; i < kNumLenToPosStates; i++) ++ { ++ CLzmaProb *probs = p->posSlotEncoder[i]; ++ UInt32 j; ++ for (j = 0; j < (1 << kNumPosSlotBits); j++) ++ probs[j] = kProbInitValue; ++ } ++ } ++ { ++ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) ++ p->posEncoders[i] = kProbInitValue; ++ } ++ ++ LenEnc_Init(&p->lenEnc.p); ++ LenEnc_Init(&p->repLenEnc.p); ++ ++ for (i = 0; i < (1 << kNumAlignBits); i++) ++ p->posAlignEncoder[i] = kProbInitValue; ++ ++ p->optimumEndIndex = 0; ++ p->optimumCurrentIndex = 0; ++ p->additionalOffset = 0; ++ ++ p->pbMask = (1 << p->pb) - 1; ++ p->lpMask = (1 << p->lp) - 1; ++} ++ ++void LzmaEnc_InitPrices(CLzmaEnc *p) ++{ ++ if (!p->fastMode) ++ { ++ FillDistancesPrices(p); ++ FillAlignPrices(p); ++ } ++ ++ p->lenEnc.tableSize = ++ p->repLenEnc.tableSize = ++ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; ++ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); ++ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); ++} ++ ++static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ UInt32 i; ++ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) ++ if (p->dictSize <= ((UInt32)1 << i)) ++ break; ++ p->distTableSize = i * 2; ++ ++ p->finished = False; ++ p->result = SZ_OK; ++ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); ++ LzmaEnc_Init(p); ++ LzmaEnc_InitPrices(p); ++ p->nowPos64 = 0; ++ return SZ_OK; ++} ++ ++static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ++ ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ p->matchFinderBase.stream = inStream; ++ p->needInit = 1; ++ p->rc.outStream = outStream; ++ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); ++} ++ ++SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ++ ISeqInStream *inStream, UInt32 keepWindowSize, ++ ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ p->matchFinderBase.stream = inStream; ++ p->needInit = 1; ++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); ++} ++ ++static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) ++{ ++ p->matchFinderBase.directInput = 1; ++ p->matchFinderBase.bufferBase = (Byte *)src; ++ p->matchFinderBase.directInputRem = srcLen; ++} ++ ++SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, ++ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ LzmaEnc_SetInputBuf(p, src, srcLen); ++ p->needInit = 1; ++ ++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); ++} ++ ++void LzmaEnc_Finish(CLzmaEncHandle pp) ++{ ++ #ifndef _7ZIP_ST ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ if (p->mtMode) ++ MatchFinderMt_ReleaseStream(&p->matchFinderMt); ++ #else ++ (void)pp; ++ #endif ++} ++ ++typedef struct ++{ ++ ISeqOutStream funcTable; ++ Byte *data; ++ SizeT rem; ++ Bool overflow; ++} CSeqOutStreamBuf; ++ ++static size_t MyWrite(void *pp, const void *data, size_t size) ++{ ++ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; ++ if (p->rem < size) ++ { ++ size = p->rem; ++ p->overflow = True; ++ } ++ memcpy(p->data, data, size); ++ p->rem -= size; ++ p->data += size; ++ return size; ++} ++ ++ ++UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) ++{ ++ const CLzmaEnc *p = (CLzmaEnc *)pp; ++ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); ++} ++ ++const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) ++{ ++ const CLzmaEnc *p = (CLzmaEnc *)pp; ++ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; ++} ++ ++SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, ++ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ UInt64 nowPos64; ++ SRes res; ++ CSeqOutStreamBuf outStream; ++ ++ outStream.funcTable.Write = MyWrite; ++ outStream.data = dest; ++ outStream.rem = *destLen; ++ outStream.overflow = False; ++ ++ p->writeEndMark = False; ++ p->finished = False; ++ p->result = SZ_OK; ++ ++ if (reInit) ++ LzmaEnc_Init(p); ++ LzmaEnc_InitPrices(p); ++ nowPos64 = p->nowPos64; ++ RangeEnc_Init(&p->rc); ++ p->rc.outStream = &outStream.funcTable; ++ ++ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); ++ ++ *unpackSize = (UInt32)(p->nowPos64 - nowPos64); ++ *destLen -= outStream.rem; ++ if (outStream.overflow) ++ return SZ_ERROR_OUTPUT_EOF; ++ ++ return res; ++} ++ ++static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) ++{ ++ SRes res = SZ_OK; ++ ++ #ifndef _7ZIP_ST ++ Byte allocaDummy[0x300]; ++ int i = 0; ++ for (i = 0; i < 16; i++) ++ allocaDummy[i] = (Byte)i; ++ #endif ++ ++ for (;;) ++ { ++ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); ++ if (res != SZ_OK || p->finished != 0) ++ break; ++ if (progress != 0) ++ { ++ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); ++ if (res != SZ_OK) ++ { ++ res = SZ_ERROR_PROGRESS; ++ break; ++ } ++ } ++ } ++ LzmaEnc_Finish(p); ++ return res; ++} ++ ++SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, ++ ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); ++ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); ++} ++ ++SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ int i; ++ UInt32 dictSize = p->dictSize; ++ if (*size < LZMA_PROPS_SIZE) ++ return SZ_ERROR_PARAM; ++ *size = LZMA_PROPS_SIZE; ++ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); ++ ++ for (i = 11; i <= 30; i++) ++ { ++ if (dictSize <= ((UInt32)2 << i)) ++ { ++ dictSize = (2 << i); ++ break; ++ } ++ if (dictSize <= ((UInt32)3 << i)) ++ { ++ dictSize = (3 << i); ++ break; ++ } ++ } ++ ++ for (i = 0; i < 4; i++) ++ props[1 + i] = (Byte)(dictSize >> (8 * i)); ++ return SZ_OK; ++} ++ ++SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ SRes res; ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++ ++ CSeqOutStreamBuf outStream; ++ ++ LzmaEnc_SetInputBuf(p, src, srcLen); ++ ++ outStream.funcTable.Write = MyWrite; ++ outStream.data = dest; ++ outStream.rem = *destLen; ++ outStream.overflow = False; ++ ++ p->writeEndMark = writeEndMark; ++ ++ p->rc.outStream = &outStream.funcTable; ++ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); ++ if (res == SZ_OK) ++ res = LzmaEnc_Encode2(p, progress); ++ ++ *destLen -= outStream.rem; ++ if (outStream.overflow) ++ return SZ_ERROR_OUTPUT_EOF; ++ return res; ++} ++ ++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, ++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) ++{ ++ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); ++ SRes res; ++ if (p == 0) ++ return SZ_ERROR_MEM; ++ ++ res = LzmaEnc_SetProps(p, props); ++ if (res == SZ_OK) ++ { ++ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); ++ if (res == SZ_OK) ++ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, ++ writeEndMark, progress, alloc, allocBig); ++ } ++ ++ LzmaEnc_Destroy(p, alloc, allocBig); ++ return res; ++} diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-Makefile.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-Makefile.patch new file mode 100644 index 00000000..f0728aba --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_lib-lzma-Makefile.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/lib/lzma/Makefile 1970-01-01 03:00:00.000000000 +0300 ++++ linux-4.9.y/lib/lzma/Makefile 2021-06-07 13:01:34.000000000 +0300 +@@ -0,0 +1,7 @@ ++lzma_compress-objs := LzFind.o LzmaEnc.o ++lzma_decompress-objs := LzmaDec.o ++ ++obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o ++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o ++ ++EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_mm-init-mm.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_mm-init-mm.c.patch new file mode 100644 index 00000000..1d49f029 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_mm-init-mm.c.patch @@ -0,0 +1,8 @@ +--- linux-4.9.37/mm/init-mm.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/mm/init-mm.c 2021-06-07 13:01:34.000000000 +0300 +@@ -25,3 +25,5 @@ + .user_ns = &init_user_ns, + INIT_MM_CONTEXT(init_mm) + }; ++ ++EXPORT_SYMBOL(init_mm); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_mm-page_alloc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_mm-page_alloc.c.patch new file mode 100644 index 00000000..409b8f2b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_mm-page_alloc.c.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/mm/page_alloc.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/mm/page_alloc.c 2021-06-07 13:01:34.000000000 +0300 +@@ -7335,7 +7335,7 @@ + + /* Make sure the range is really isolated. */ + if (test_pages_isolated(outer_start, end, false)) { +- pr_info("%s: [%lx, %lx) PFNs busy\n", ++ pr_warn_once("%s: [%lx, %lx) PFNs busy\n", + __func__, outer_start, end); + ret = -EBUSY; + goto done; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-core-net_namespace.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-core-net_namespace.c.patch new file mode 100644 index 00000000..1e297da2 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-core-net_namespace.c.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/net/core/net_namespace.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/core/net_namespace.c 2021-06-07 13:01:34.000000000 +0300 +@@ -263,7 +263,7 @@ + spin_lock_irqsave(&net->nsid_lock, flags); + peer = idr_find(&net->netns_ids, id); + if (peer) +- get_net(peer); ++ peer = maybe_get_net(peer); + spin_unlock_irqrestore(&net->nsid_lock, flags); + rcu_read_unlock(); + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-cipso_ipv4.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-cipso_ipv4.c.patch new file mode 100644 index 00000000..7463306d --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-cipso_ipv4.c.patch @@ -0,0 +1,22 @@ +--- linux-4.9.37/net/ipv4/cipso_ipv4.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/cipso_ipv4.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1271,7 +1271,8 @@ + return ret_val; + } + +- secattr->flags |= NETLBL_SECATTR_MLS_CAT; ++ if (secattr->attr.mls.cat) ++ secattr->flags |= NETLBL_SECATTR_MLS_CAT; + } + + return 0; +@@ -1452,7 +1453,8 @@ + return ret_val; + } + +- secattr->flags |= NETLBL_SECATTR_MLS_CAT; ++ if (secattr->attr.mls.cat) ++ secattr->flags |= NETLBL_SECATTR_MLS_CAT; + } + + return 0; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-ip_output.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-ip_output.c.patch new file mode 100644 index 00000000..96015380 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-ip_output.c.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/net/ipv4/ip_output.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/ip_output.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1260,7 +1260,7 @@ + if (skb->ip_summed != CHECKSUM_PARTIAL) + return -EOPNOTSUPP; + +- skb_shinfo(skb)->gso_size = mtu - fragheaderlen; ++ skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen; + skb_shinfo(skb)->gso_type = SKB_GSO_UDP; + } + cork->length += size; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-proc.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-proc.c.patch new file mode 100644 index 00000000..22d46177 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-proc.c.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/net/ipv4/proc.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/proc.c 2021-06-07 13:01:34.000000000 +0300 +@@ -305,6 +305,7 @@ + SNMP_MIB_ITEM("TCPKeepAlive", LINUX_MIB_TCPKEEPALIVE), + SNMP_MIB_ITEM("TCPMTUPFail", LINUX_MIB_TCPMTUPFAIL), + SNMP_MIB_ITEM("TCPMTUPSuccess", LINUX_MIB_TCPMTUPSUCCESS), ++ SNMP_MIB_ITEM("TCPWqueueTooBig", LINUX_MIB_TCPWQUEUETOOBIG), + SNMP_MIB_SENTINEL + }; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-sysctl_net_ipv4.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-sysctl_net_ipv4.c.patch new file mode 100644 index 00000000..7960135b --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-sysctl_net_ipv4.c.patch @@ -0,0 +1,27 @@ +--- linux-4.9.37/net/ipv4/sysctl_net_ipv4.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/sysctl_net_ipv4.c 2021-06-07 13:01:34.000000000 +0300 +@@ -35,6 +35,8 @@ + static int ip_local_port_range_max[] = { 65535, 65535 }; + static int tcp_adv_win_scale_min = -31; + static int tcp_adv_win_scale_max = 31; ++static int tcp_min_snd_mss_min = TCP_MIN_SND_MSS; ++static int tcp_min_snd_mss_max = 65535; + static int ip_ttl_min = 1; + static int ip_ttl_max = 255; + static int tcp_syn_retries_min = 1; +@@ -827,6 +829,15 @@ + .proc_handler = proc_dointvec, + }, + { ++ .procname = "tcp_min_snd_mss", ++ .data = &init_net.ipv4.sysctl_tcp_min_snd_mss, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = &tcp_min_snd_mss_min, ++ .extra2 = &tcp_min_snd_mss_max, ++ }, ++ { + .procname = "tcp_probe_threshold", + .data = &init_net.ipv4.sysctl_tcp_probe_threshold, + .maxlen = sizeof(int), diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp.c.patch new file mode 100644 index 00000000..4d1ac733 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp.c.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/net/ipv4/tcp.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/tcp.c 2021-06-07 13:01:34.000000000 +0300 +@@ -3289,6 +3289,7 @@ + unsigned long limit; + unsigned int i; + ++ BUILD_BUG_ON(TCP_MIN_SND_MSS <= MAX_TCP_OPTION_SPACE); + BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > + FIELD_SIZEOF(struct sk_buff, cb)); + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_input.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_input.c.patch new file mode 100644 index 00000000..412660d7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_input.c.patch @@ -0,0 +1,105 @@ +--- linux-4.9.37/net/ipv4/tcp_input.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/tcp_input.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1312,7 +1312,7 @@ + TCP_SKB_CB(skb)->seq += shifted; + + tcp_skb_pcount_add(prev, pcount); +- BUG_ON(tcp_skb_pcount(skb) < pcount); ++ WARN_ON_ONCE(tcp_skb_pcount(skb) < pcount); + tcp_skb_pcount_add(skb, -pcount); + + /* When we're adding to gso_segs == 1, gso_size will be zero, +@@ -1379,6 +1379,21 @@ + return !skb_headlen(skb) && skb_is_nonlinear(skb); + } + ++int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, ++ int pcount, int shiftlen) ++{ ++ /* TCP min gso_size is 8 bytes (TCP_MIN_GSO_SIZE) ++ * Since TCP_SKB_CB(skb)->tcp_gso_segs is 16 bits, we need ++ * to make sure not storing more than 65535 * 8 bytes per skb, ++ * even if current MSS is bigger. ++ */ ++ if (unlikely(to->len + shiftlen >= 65535 * TCP_MIN_GSO_SIZE)) ++ return 0; ++ if (unlikely(tcp_skb_pcount(to) + pcount > 65535)) ++ return 0; ++ return skb_shift(to, from, shiftlen); ++} ++ + /* Try collapsing SACK blocks spanning across multiple skbs to a single + * skb. + */ +@@ -1390,6 +1405,7 @@ + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *prev; + int mss; ++ int next_pcount; + int pcount = 0; + int len; + int in_sack; +@@ -1487,7 +1503,7 @@ + if (!after(TCP_SKB_CB(skb)->seq + len, tp->snd_una)) + goto fallback; + +- if (!skb_shift(prev, skb, len)) ++ if (!tcp_skb_shift(prev, skb, pcount, len)) + goto fallback; + if (!tcp_shifted_skb(sk, skb, state, pcount, len, mss, dup_sack)) + goto out; +@@ -1506,11 +1522,11 @@ + goto out; + + len = skb->len; +- if (skb_shift(prev, skb, len)) { +- pcount += tcp_skb_pcount(skb); +- tcp_shifted_skb(sk, skb, state, tcp_skb_pcount(skb), len, mss, 0); ++ next_pcount = tcp_skb_pcount(skb); ++ if (tcp_skb_shift(prev, skb, next_pcount, len)) { ++ pcount += next_pcount; ++ tcp_shifted_skb(sk, skb, state, next_pcount, len, mss, 0); + } +- + out: + state->fack_count += pcount; + return prev; +@@ -4949,6 +4965,7 @@ + * 2) not add too big latencies if thousands of packets sit there. + * (But if application shrinks SO_RCVBUF, we could still end up + * freeing whole queue here) ++ * 3) Drop at least 12.5 % of sk_rcvbuf to avoid malicious attacks. + * + * Return true if queue has shrunk. + */ +@@ -4956,20 +4973,26 @@ + { + struct tcp_sock *tp = tcp_sk(sk); + struct rb_node *node, *prev; ++ int goal; + + if (RB_EMPTY_ROOT(&tp->out_of_order_queue)) + return false; + + NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED); ++ goal = sk->sk_rcvbuf >> 3; + node = &tp->ooo_last_skb->rbnode; + do { + prev = rb_prev(node); + rb_erase(node, &tp->out_of_order_queue); ++ goal -= rb_entry_safe(node, struct sk_buff, rbnode)->truesize; + tcp_drop(sk, rb_entry(node, struct sk_buff, rbnode)); +- sk_mem_reclaim(sk); +- if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && +- !tcp_under_memory_pressure(sk)) +- break; ++ if (!prev || goal <= 0) { ++ sk_mem_reclaim(sk); ++ if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && ++ !tcp_under_memory_pressure(sk)) ++ break; ++ goal = sk->sk_rcvbuf >> 3; ++ } + node = prev; + } while (node); + tp->ooo_last_skb = rb_entry(prev, struct sk_buff, rbnode); diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_ipv4.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_ipv4.c.patch new file mode 100644 index 00000000..21463afc --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_ipv4.c.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/net/ipv4/tcp_ipv4.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/tcp_ipv4.c 2021-06-07 13:01:34.000000000 +0300 +@@ -2440,6 +2440,7 @@ + net->ipv4.sysctl_tcp_ecn_fallback = 1; + + net->ipv4.sysctl_tcp_base_mss = TCP_BASE_MSS; ++ net->ipv4.sysctl_tcp_min_snd_mss = TCP_MIN_SND_MSS; + net->ipv4.sysctl_tcp_probe_threshold = TCP_PROBE_THRESHOLD; + net->ipv4.sysctl_tcp_probe_interval = TCP_PROBE_INTERVAL; + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_output.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_output.c.patch new file mode 100644 index 00000000..ac15c464 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_output.c.patch @@ -0,0 +1,24 @@ +--- linux-4.9.37/net/ipv4/tcp_output.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/tcp_output.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1170,6 +1170,11 @@ + if (nsize < 0) + nsize = 0; + ++ if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) { ++ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); ++ return -ENOMEM; ++ } ++ + if (skb_unclone(skb, gfp)) + return -ENOMEM; + +@@ -1340,8 +1345,7 @@ + mss_now -= icsk->icsk_ext_hdr_len; + + /* Then reserve room for full set of TCP options and 8 bytes of data */ +- if (mss_now < 48) +- mss_now = 48; ++ mss_now = max(mss_now, sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss); + return mss_now; + } + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_timer.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_timer.c.patch new file mode 100644 index 00000000..9d6b09f9 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv4-tcp_timer.c.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/net/ipv4/tcp_timer.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv4/tcp_timer.c 2021-06-07 13:01:34.000000000 +0300 +@@ -125,6 +125,7 @@ + mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1; + mss = min(net->ipv4.sysctl_tcp_base_mss, mss); + mss = max(mss, 68 - tp->tcp_header_len); ++ mss = max(mss, net->ipv4.sysctl_tcp_min_snd_mss); + icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss); + tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); + } diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv6-calipso.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv6-calipso.c.patch new file mode 100644 index 00000000..dcbf46b7 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv6-calipso.c.patch @@ -0,0 +1,12 @@ +--- linux-4.9.37/net/ipv6/calipso.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv6/calipso.c 2021-06-07 13:01:34.000000000 +0300 +@@ -1062,7 +1062,8 @@ + goto getattr_return; + } + +- secattr->flags |= NETLBL_SECATTR_MLS_CAT; ++ if (secattr->attr.mls.cat) ++ secattr->flags |= NETLBL_SECATTR_MLS_CAT; + } + + secattr->type = NETLBL_NLTYPE_CALIPSO; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv6-output_core.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv6-output_core.c.patch new file mode 100644 index 00000000..b624aa13 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-ipv6-output_core.c.patch @@ -0,0 +1,31 @@ +--- linux-4.9.37/net/ipv6/output_core.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/ipv6/output_core.c 2021-06-07 13:01:34.000000000 +0300 +@@ -78,7 +78,7 @@ + + int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) + { +- u16 offset = sizeof(struct ipv6hdr); ++ unsigned int offset = sizeof(struct ipv6hdr); + unsigned int packet_len = skb_tail_pointer(skb) - + skb_network_header(skb); + int found_rhdr = 0; +@@ -86,6 +86,7 @@ + + while (offset <= packet_len) { + struct ipv6_opt_hdr *exthdr; ++ unsigned int len; + + switch (**nexthdr) { + +@@ -111,7 +112,10 @@ + + exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + + offset); +- offset += ipv6_optlen(exthdr); ++ len = ipv6_optlen(exthdr); ++ if (len + offset >= IPV6_MAXPLEN) ++ return -EINVAL; ++ offset += len; + *nexthdr = &exthdr->nexthdr; + } + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-netlabel-netlabel_kapi.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-netlabel-netlabel_kapi.c.patch new file mode 100644 index 00000000..2a155402 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_net-netlabel-netlabel_kapi.c.patch @@ -0,0 +1,15 @@ +--- linux-4.9.37/net/netlabel/netlabel_kapi.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/net/netlabel/netlabel_kapi.c 2021-06-07 13:01:34.000000000 +0300 +@@ -748,6 +748,12 @@ + if ((off & (BITS_PER_LONG - 1)) != 0) + return -EINVAL; + ++ /* a null catmap is equivalent to an empty one */ ++ if (!catmap) { ++ *offset = (u32)-1; ++ return 0; ++ } ++ + if (off < catmap->startbit) { + off = catmap->startbit; + *offset = off; diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_scripts-Makefile.clean.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_scripts-Makefile.clean.patch new file mode 100644 index 00000000..79b0a586 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_scripts-Makefile.clean.patch @@ -0,0 +1,11 @@ +--- linux-4.9.37/scripts/Makefile.clean 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/scripts/Makefile.clean 2021-06-07 13:01:34.000000000 +0300 +@@ -11,7 +11,7 @@ + + # The filename Kbuild has precedence over Makefile + kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +-include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) ++-include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) + + # Figure out what we need to build from the various variables + # ========================================================================== diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_scripts-setlocalversion.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_scripts-setlocalversion.patch new file mode 100644 index 00000000..bc5dd630 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_scripts-setlocalversion.patch @@ -0,0 +1,10 @@ +--- linux-4.9.37/scripts/setlocalversion 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/scripts/setlocalversion 2021-06-07 13:01:34.000000000 +0300 +@@ -153,6 +153,7 @@ + res="$res$(collect_files "$srctree"/localversion*)" + fi + ++LOCALVERSION= + # CONFIG_LOCALVERSION and LOCALVERSION (if set) + res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}" + diff --git a/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_sound-usb-mixer.c.patch b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_sound-usb-mixer.c.patch new file mode 100644 index 00000000..13100c47 --- /dev/null +++ b/br-ext-chip-goke/board/gk7205v200/kernel/patches/00_sound-usb-mixer.c.patch @@ -0,0 +1,41 @@ +--- linux-4.9.37/sound/usb/mixer.c 2017-07-12 16:42:41.000000000 +0300 ++++ linux-4.9.y/sound/usb/mixer.c 2021-06-07 13:01:34.000000000 +0300 +@@ -318,12 +318,15 @@ + + while (timeout-- > 0) { + idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); +- if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, +- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, +- validx, idx, buf, val_len) >= val_len) { ++ err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, ++ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, ++ validx, idx, buf, val_len); ++ if (err >= val_len) { + *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); + err = 0; + goto out; ++ } else if (err == -ETIMEDOUT) { ++ goto out; + } + } + usb_audio_dbg(chip, +@@ -483,12 +486,15 @@ + + while (timeout-- > 0) { + idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); +- if (snd_usb_ctl_msg(chip->dev, +- usb_sndctrlpipe(chip->dev, 0), request, +- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, +- validx, idx, buf, val_len) >= 0) { ++ err = snd_usb_ctl_msg(chip->dev, ++ usb_sndctrlpipe(chip->dev, 0), request, ++ USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, ++ validx, idx, buf, val_len); ++ if (err >= 0) { + err = 0; + goto out; ++ } else if (err == -ETIMEDOUT) { ++ goto out; + } + } + usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",