diff -urN linux-4.9.37/arch/alpha/kernel/.gitignore linux-4.9.y/arch/alpha/kernel/.gitignore --- linux-4.9.37/arch/alpha/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/alpha/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/arc/boot/.gitignore linux-4.9.y/arch/arc/boot/.gitignore --- linux-4.9.37/arch/arc/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arc/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -*.dtb* -uImage diff -urN linux-4.9.37/arch/arc/kernel/.gitignore linux-4.9.y/arch/arc/kernel/.gitignore --- linux-4.9.37/arch/arc/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arc/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/arm/boot/compressed/.gitignore linux-4.9.y/arch/arm/boot/compressed/.gitignore --- linux-4.9.37/arch/arm/boot/compressed/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm/boot/compressed/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,17 +0,0 @@ -ashldi3.S -bswapsdi2.S -font.c -lib1funcs.S -hyp-stub.S -piggy_data -vmlinux -vmlinux.lds - -# borrowed libfdt files -fdt.c -fdt.h -fdt_ro.c -fdt_rw.c -fdt_wip.c -libfdt.h -libfdt_internal.h diff -urN linux-4.9.37/arch/arm/boot/compressed/head.S linux-4.9.y/arch/arm/boot/compressed/head.S --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7202v300-demb.dts linux-4.9.y/arch/arm/boot/dts/gk7202v300-demb.dts --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7202v300.dtsi linux-4.9.y/arch/arm/boot/dts/gk7202v300.dtsi --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7205v200-demb.dts linux-4.9.y/arch/arm/boot/dts/gk7205v200-demb.dts --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7205v200.dtsi linux-4.9.y/arch/arm/boot/dts/gk7205v200.dtsi --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7205v300-demb.dts linux-4.9.y/arch/arm/boot/dts/gk7205v300-demb.dts --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7205v300.dtsi linux-4.9.y/arch/arm/boot/dts/gk7205v300.dtsi --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7605v100-demb.dts linux-4.9.y/arch/arm/boot/dts/gk7605v100-demb.dts --- 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 -urN linux-4.9.37/arch/arm/boot/dts/gk7605v100.dtsi linux-4.9.y/arch/arm/boot/dts/gk7605v100.dtsi --- 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 -urN linux-4.9.37/arch/arm/boot/dts/Makefile linux-4.9.y/arch/arm/boot/dts/Makefile --- 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 -urN linux-4.9.37/arch/arm/boot/.gitignore linux-4.9.y/arch/arm/boot/.gitignore --- linux-4.9.37/arch/arm/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -Image -zImage -xipImage -bootpImage -uImage -*.dtb diff -urN linux-4.9.37/arch/arm/boot/Makefile linux-4.9.y/arch/arm/boot/Makefile --- 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 -urN linux-4.9.37/arch/arm/configs/gk7202v300_emmc_defconfig linux-4.9.y/arch/arm/configs/gk7202v300_emmc_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7202v300_full_defconfig linux-4.9.y/arch/arm/configs/gk7202v300_full_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7202v300_mini_defconfig linux-4.9.y/arch/arm/configs/gk7202v300_mini_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7205v200_emmc_defconfig linux-4.9.y/arch/arm/configs/gk7205v200_emmc_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7205v200_full_defconfig linux-4.9.y/arch/arm/configs/gk7205v200_full_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7205v200_mini_defconfig linux-4.9.y/arch/arm/configs/gk7205v200_mini_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7205v300_emmc_defconfig linux-4.9.y/arch/arm/configs/gk7205v300_emmc_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7205v300_full_defconfig linux-4.9.y/arch/arm/configs/gk7205v300_full_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7605v100_emmc_defconfig linux-4.9.y/arch/arm/configs/gk7605v100_emmc_defconfig --- 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 -urN linux-4.9.37/arch/arm/configs/gk7605v100_full_defconfig linux-4.9.y/arch/arm/configs/gk7605v100_full_defconfig --- 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 -urN linux-4.9.37/arch/arm/crypto/.gitignore linux-4.9.y/arch/arm/crypto/.gitignore --- linux-4.9.37/arch/arm/crypto/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm/crypto/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -aesbs-core.S -sha256-core.S -sha512-core.S diff -urN linux-4.9.37/arch/arm/Kconfig linux-4.9.y/arch/arm/Kconfig --- 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 -urN linux-4.9.37/arch/arm/Kconfig.debug linux-4.9.y/arch/arm/Kconfig.debug --- 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 -urN linux-4.9.37/arch/arm/kernel/.gitignore linux-4.9.y/arch/arm/kernel/.gitignore --- linux-4.9.37/arch/arm/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/arm/kvm/handle_exit.c linux-4.9.y/arch/arm/kvm/handle_exit.c --- 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 -urN linux-4.9.37/arch/arm/mach-goke/include/mach/io.h linux-4.9.y/arch/arm/mach-goke/include/mach/io.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 diff -urN linux-4.9.37/arch/arm/mach-goke/include/mach/platform.h linux-4.9.y/arch/arm/mach-goke/include/mach/platform.h --- 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 -urN linux-4.9.37/arch/arm/mach-goke/Kconfig linux-4.9.y/arch/arm/mach-goke/Kconfig --- 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 -urN linux-4.9.37/arch/arm/mach-goke/mach-common.h linux-4.9.y/arch/arm/mach-goke/mach-common.h --- 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 -urN linux-4.9.37/arch/arm/mach-goke/mach-gk7202v300.c linux-4.9.y/arch/arm/mach-goke/mach-gk7202v300.c --- 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 -urN linux-4.9.37/arch/arm/mach-goke/mach-gk7205v200.c linux-4.9.y/arch/arm/mach-goke/mach-gk7205v200.c --- 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 -urN linux-4.9.37/arch/arm/mach-goke/mach-gk7205v300.c linux-4.9.y/arch/arm/mach-goke/mach-gk7205v300.c --- 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 -urN linux-4.9.37/arch/arm/mach-goke/mach-gk7605v100.c linux-4.9.y/arch/arm/mach-goke/mach-gk7605v100.c --- 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 -urN linux-4.9.37/arch/arm/mach-goke/Makefile linux-4.9.y/arch/arm/mach-goke/Makefile --- 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 -urN linux-4.9.37/arch/arm/mach-goke/Makefile.boot linux-4.9.y/arch/arm/mach-goke/Makefile.boot --- 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 -urN linux-4.9.37/arch/arm/Makefile linux-4.9.y/arch/arm/Makefile --- 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 -urN linux-4.9.37/arch/arm/mm/dma-mapping.c linux-4.9.y/arch/arm/mm/dma-mapping.c --- 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 -urN linux-4.9.37/arch/arm/mm/init.c linux-4.9.y/arch/arm/mm/init.c --- 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 -urN linux-4.9.37/arch/arm/vdso/.gitignore linux-4.9.y/arch/arm/vdso/.gitignore --- linux-4.9.37/arch/arm/vdso/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm/vdso/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -vdso.lds -vdso.so.raw -vdsomunge diff -urN linux-4.9.37/arch/arm/vdso/vgettimeofday.c linux-4.9.y/arch/arm/vdso/vgettimeofday.c --- 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 -urN linux-4.9.37/arch/arm64/boot/dts/.gitignore linux-4.9.y/arch/arm64/boot/dts/.gitignore --- linux-4.9.37/arch/arm64/boot/dts/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm64/boot/dts/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -*.dtb diff -urN linux-4.9.37/arch/arm64/boot/.gitignore linux-4.9.y/arch/arm64/boot/.gitignore --- linux-4.9.37/arch/arm64/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm64/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -Image -Image.gz diff -urN linux-4.9.37/arch/arm64/kernel/.gitignore linux-4.9.y/arch/arm64/kernel/.gitignore --- linux-4.9.37/arch/arm64/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm64/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/arm64/kernel/vdso/.gitignore linux-4.9.y/arch/arm64/kernel/vdso/.gitignore --- linux-4.9.37/arch/arm64/kernel/vdso/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/arm64/kernel/vdso/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -vdso.lds -vdso-offsets.h diff -urN linux-4.9.37/arch/avr32/boot/images/.gitignore linux-4.9.y/arch/avr32/boot/images/.gitignore --- linux-4.9.37/arch/avr32/boot/images/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/avr32/boot/images/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -uImage -uImage.srec -vmlinux.cso -sfdwarf.log diff -urN linux-4.9.37/arch/avr32/kernel/.gitignore linux-4.9.y/arch/avr32/kernel/.gitignore --- linux-4.9.37/arch/avr32/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/avr32/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/blackfin/boot/.gitignore linux-4.9.y/arch/blackfin/boot/.gitignore --- linux-4.9.37/arch/blackfin/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/blackfin/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -vmImage* -vmlinux* -uImage* diff -urN linux-4.9.37/arch/blackfin/kernel/.gitignore linux-4.9.y/arch/blackfin/kernel/.gitignore --- linux-4.9.37/arch/blackfin/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/blackfin/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/cris/boot/.gitignore linux-4.9.y/arch/cris/boot/.gitignore --- linux-4.9.37/arch/cris/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/cris/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -Image -zImage diff -urN linux-4.9.37/arch/.gitignore linux-4.9.y/arch/.gitignore --- linux-4.9.37/arch/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -i386 -x86_64 diff -urN linux-4.9.37/arch/ia64/kernel/.gitignore linux-4.9.y/arch/ia64/kernel/.gitignore --- linux-4.9.37/arch/ia64/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/ia64/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -gate.lds -vmlinux.lds diff -urN linux-4.9.37/arch/m32r/kernel/.gitignore linux-4.9.y/arch/m32r/kernel/.gitignore --- linux-4.9.37/arch/m32r/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/m32r/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/m68k/kernel/.gitignore linux-4.9.y/arch/m68k/kernel/.gitignore --- linux-4.9.37/arch/m68k/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/m68k/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/metag/boot/.gitignore linux-4.9.y/arch/metag/boot/.gitignore --- linux-4.9.37/arch/metag/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/metag/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -vmlinux* -uImage* -ramdisk.* -*.dtb* diff -urN linux-4.9.37/arch/metag/kernel/.gitignore linux-4.9.y/arch/metag/kernel/.gitignore --- linux-4.9.37/arch/metag/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/metag/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/microblaze/boot/.gitignore linux-4.9.y/arch/microblaze/boot/.gitignore --- linux-4.9.37/arch/microblaze/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/microblaze/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -*.dtb -linux.bin* -simpleImage.* diff -urN linux-4.9.37/arch/microblaze/kernel/.gitignore linux-4.9.y/arch/microblaze/kernel/.gitignore --- linux-4.9.37/arch/microblaze/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/microblaze/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/mips/boot/.gitignore linux-4.9.y/arch/mips/boot/.gitignore --- linux-4.9.37/arch/mips/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/mips/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,8 +0,0 @@ -mkboot -elf2ecoff -vmlinux.* -zImage -zImage.tmp -calc_vmlinuz_load_addr -uImage -*.dtb diff -urN linux-4.9.37/arch/mips/boot/tools/.gitignore linux-4.9.y/arch/mips/boot/tools/.gitignore --- linux-4.9.37/arch/mips/boot/tools/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/mips/boot/tools/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -relocs diff -urN linux-4.9.37/arch/mips/kernel/.gitignore linux-4.9.y/arch/mips/kernel/.gitignore --- linux-4.9.37/arch/mips/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/mips/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/mips/vdso/.gitignore linux-4.9.y/arch/mips/vdso/.gitignore --- linux-4.9.37/arch/mips/vdso/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/mips/vdso/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -*.so* -vdso-*image.c -genvdso -vdso*.lds diff -urN linux-4.9.37/arch/mn10300/boot/.gitignore linux-4.9.y/arch/mn10300/boot/.gitignore --- linux-4.9.37/arch/mn10300/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/mn10300/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -zImage diff -urN linux-4.9.37/arch/parisc/kernel/.gitignore linux-4.9.y/arch/parisc/kernel/.gitignore --- linux-4.9.37/arch/parisc/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/parisc/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/powerpc/boot/.gitignore linux-4.9.y/arch/powerpc/boot/.gitignore --- linux-4.9.37/arch/powerpc/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/powerpc/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,44 +0,0 @@ -addnote -empty.c -hack-coff -inffast.c -inffast.h -inffixed.h -inflate.c -inflate.h -inftrees.c -inftrees.h -infutil.c -infutil.h -kernel-vmlinux.strip.c -kernel-vmlinux.strip.gz -mktree -uImage -cuImage.* -dtbImage.* -*.dtb -treeImage.* -zImage -zImage.initrd -zImage.bin.* -zImage.chrp -zImage.coff -zImage.epapr -zImage.holly -zImage.*lds -zImage.miboot -zImage.pmac -zImage.pseries -zconf.h -zlib.h -zutil.h -fdt.c -fdt.h -fdt_ro.c -fdt_rw.c -fdt_strerror.c -fdt_sw.c -fdt_wip.c -libfdt.h -libfdt_internal.h - diff -urN linux-4.9.37/arch/powerpc/kernel/.gitignore linux-4.9.y/arch/powerpc/kernel/.gitignore --- linux-4.9.37/arch/powerpc/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/powerpc/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/powerpc/kernel/vdso32/.gitignore linux-4.9.y/arch/powerpc/kernel/vdso32/.gitignore --- linux-4.9.37/arch/powerpc/kernel/vdso32/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/powerpc/kernel/vdso32/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -vdso32.lds -vdso32.so.dbg diff -urN linux-4.9.37/arch/powerpc/kernel/vdso64/.gitignore linux-4.9.y/arch/powerpc/kernel/vdso64/.gitignore --- linux-4.9.37/arch/powerpc/kernel/vdso64/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/powerpc/kernel/vdso64/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -vdso64.lds -vdso64.so.dbg diff -urN linux-4.9.37/arch/powerpc/platforms/cell/spufs/.gitignore linux-4.9.y/arch/powerpc/platforms/cell/spufs/.gitignore --- linux-4.9.37/arch/powerpc/platforms/cell/spufs/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/powerpc/platforms/cell/spufs/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -spu_save_dump.h -spu_restore_dump.h diff -urN linux-4.9.37/arch/s390/boot/compressed/.gitignore linux-4.9.y/arch/s390/boot/compressed/.gitignore --- linux-4.9.37/arch/s390/boot/compressed/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/s390/boot/compressed/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -sizes.h -vmlinux -vmlinux.lds diff -urN linux-4.9.37/arch/s390/boot/.gitignore linux-4.9.y/arch/s390/boot/.gitignore --- linux-4.9.37/arch/s390/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/s390/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -image -bzImage diff -urN linux-4.9.37/arch/s390/kernel/.gitignore linux-4.9.y/arch/s390/kernel/.gitignore --- linux-4.9.37/arch/s390/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/s390/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/s390/kernel/vdso32/.gitignore linux-4.9.y/arch/s390/kernel/vdso32/.gitignore --- linux-4.9.37/arch/s390/kernel/vdso32/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/s390/kernel/vdso32/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vdso32.lds diff -urN linux-4.9.37/arch/s390/kernel/vdso64/.gitignore linux-4.9.y/arch/s390/kernel/vdso64/.gitignore --- linux-4.9.37/arch/s390/kernel/vdso64/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/s390/kernel/vdso64/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vdso64.lds diff -urN linux-4.9.37/arch/s390/tools/.gitignore linux-4.9.y/arch/s390/tools/.gitignore --- linux-4.9.37/arch/s390/tools/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/s390/tools/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -gen_facilities diff -urN linux-4.9.37/arch/sh/boot/compressed/.gitignore linux-4.9.y/arch/sh/boot/compressed/.gitignore --- linux-4.9.37/arch/sh/boot/compressed/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/sh/boot/compressed/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.bin.* diff -urN linux-4.9.37/arch/sh/boot/compressed/vmlinux.scr linux-4.9.y/arch/sh/boot/compressed/vmlinux.scr --- 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 -urN linux-4.9.37/arch/sh/boot/.gitignore linux-4.9.y/arch/sh/boot/.gitignore --- linux-4.9.37/arch/sh/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/sh/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -zImage -vmlinux* -uImage* diff -urN linux-4.9.37/arch/sh/boot/romimage/vmlinux.scr linux-4.9.y/arch/sh/boot/romimage/vmlinux.scr --- 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 -urN linux-4.9.37/arch/sh/kernel/.gitignore linux-4.9.y/arch/sh/kernel/.gitignore --- linux-4.9.37/arch/sh/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/sh/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/sh/kernel/vsyscall/.gitignore linux-4.9.y/arch/sh/kernel/vsyscall/.gitignore --- linux-4.9.37/arch/sh/kernel/vsyscall/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/sh/kernel/vsyscall/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vsyscall.lds diff -urN linux-4.9.37/arch/sparc/boot/.gitignore linux-4.9.y/arch/sparc/boot/.gitignore --- linux-4.9.37/arch/sparc/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/sparc/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,8 +0,0 @@ -btfix.S -btfixupprep -image -zImage -tftpboot.img -vmlinux.aout -piggyback - diff -urN linux-4.9.37/arch/sparc/kernel/.gitignore linux-4.9.y/arch/sparc/kernel/.gitignore --- linux-4.9.37/arch/sparc/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/sparc/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/arch/um/.gitignore linux-4.9.y/arch/um/.gitignore --- linux-4.9.37/arch/um/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/um/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -kernel/config.c -kernel/config.tmp -kernel/vmlinux.lds diff -urN linux-4.9.37/arch/unicore32/.gitignore linux-4.9.y/arch/unicore32/.gitignore --- linux-4.9.37/arch/unicore32/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/unicore32/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,21 +0,0 @@ -# -# Generated include files -# -include/generated -# -# Generated ld script file -# -kernel/vmlinux.lds -# -# Generated images in boot -# -boot/Image -boot/zImage -boot/uImage -# -# Generated files in boot/compressed -# -boot/compressed/piggy.S -boot/compressed/piggy.gzip -boot/compressed/vmlinux -boot/compressed/vmlinux.lds diff -urN linux-4.9.37/arch/x86/boot/compressed/.gitignore linux-4.9.y/arch/x86/boot/compressed/.gitignore --- linux-4.9.37/arch/x86/boot/compressed/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/boot/compressed/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -relocs -vmlinux.bin.all -vmlinux.relocs -vmlinux.lds -mkpiggy -piggy.S diff -urN linux-4.9.37/arch/x86/boot/.gitignore linux-4.9.y/arch/x86/boot/.gitignore --- linux-4.9.37/arch/x86/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,9 +0,0 @@ -bootsect -bzImage -cpustr.h -mkcpustr -voffset.h -zoffset.h -setup -setup.bin -setup.elf diff -urN linux-4.9.37/arch/x86/boot/tools/.gitignore linux-4.9.y/arch/x86/boot/tools/.gitignore --- linux-4.9.37/arch/x86/boot/tools/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/boot/tools/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -build diff -urN linux-4.9.37/arch/x86/entry/vdso/.gitignore linux-4.9.y/arch/x86/entry/vdso/.gitignore --- linux-4.9.37/arch/x86/entry/vdso/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/entry/vdso/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,7 +0,0 @@ -vdso.lds -vdsox32.lds -vdso32-syscall-syms.lds -vdso32-sysenter-syms.lds -vdso32-int80-syms.lds -vdso-image-*.c -vdso2c diff -urN linux-4.9.37/arch/x86/entry/vdso/vdso32/.gitignore linux-4.9.y/arch/x86/entry/vdso/vdso32/.gitignore --- linux-4.9.37/arch/x86/entry/vdso/vdso32/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/entry/vdso/vdso32/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vdso32.lds diff -urN linux-4.9.37/arch/x86/.gitignore linux-4.9.y/arch/x86/.gitignore --- linux-4.9.37/arch/x86/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -boot/compressed/vmlinux -tools/test_get_len -tools/insn_sanity -purgatory/kexec-purgatory.c -purgatory/purgatory.ro - diff -urN linux-4.9.37/arch/x86/kernel/cpu/.gitignore linux-4.9.y/arch/x86/kernel/cpu/.gitignore --- linux-4.9.37/arch/x86/kernel/cpu/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/kernel/cpu/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -capflags.c diff -urN linux-4.9.37/arch/x86/kernel/.gitignore linux-4.9.y/arch/x86/kernel/.gitignore --- linux-4.9.37/arch/x86/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -vsyscall.lds -vsyscall_32.lds -vmlinux.lds diff -urN linux-4.9.37/arch/x86/lib/.gitignore linux-4.9.y/arch/x86/lib/.gitignore --- linux-4.9.37/arch/x86/lib/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/lib/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -inat-tables.c diff -urN linux-4.9.37/arch/x86/realmode/rm/.gitignore linux-4.9.y/arch/x86/realmode/rm/.gitignore --- linux-4.9.37/arch/x86/realmode/rm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/realmode/rm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -pasyms.h -realmode.lds -realmode.relocs diff -urN linux-4.9.37/arch/x86/tools/.gitignore linux-4.9.y/arch/x86/tools/.gitignore --- linux-4.9.37/arch/x86/tools/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/tools/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -relocs diff -urN linux-4.9.37/arch/x86/um/vdso/.gitignore linux-4.9.y/arch/x86/um/vdso/.gitignore --- linux-4.9.37/arch/x86/um/vdso/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/x86/um/vdso/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -vdso-syms.lds -vdso.lds diff -urN linux-4.9.37/arch/xtensa/boot/boot-elf/.gitignore linux-4.9.y/arch/xtensa/boot/boot-elf/.gitignore --- linux-4.9.37/arch/xtensa/boot/boot-elf/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/xtensa/boot/boot-elf/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -boot.lds diff -urN linux-4.9.37/arch/xtensa/boot/.gitignore linux-4.9.y/arch/xtensa/boot/.gitignore --- linux-4.9.37/arch/xtensa/boot/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/xtensa/boot/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -uImage -zImage.redboot -*.dtb diff -urN linux-4.9.37/arch/xtensa/boot/lib/.gitignore linux-4.9.y/arch/xtensa/boot/lib/.gitignore --- linux-4.9.37/arch/xtensa/boot/lib/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/xtensa/boot/lib/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -inffast.c -inflate.c -inftrees.c diff -urN linux-4.9.37/arch/xtensa/kernel/.gitignore linux-4.9.y/arch/xtensa/kernel/.gitignore --- linux-4.9.37/arch/xtensa/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/arch/xtensa/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vmlinux.lds diff -urN linux-4.9.37/certs/.gitignore linux-4.9.y/certs/.gitignore --- linux-4.9.37/certs/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/certs/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -# -# Generated files -# -x509_certificate_list diff -urN linux-4.9.37/crypto/asymmetric_keys/.gitignore linux-4.9.y/crypto/asymmetric_keys/.gitignore --- linux-4.9.37/crypto/asymmetric_keys/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/crypto/asymmetric_keys/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -*-asn1.[ch] diff -urN linux-4.9.37/crypto/.gitignore linux-4.9.y/crypto/.gitignore --- linux-4.9.37/crypto/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/crypto/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -*-asn1.[ch] diff -urN linux-4.9.37/Documentation/arm/SH-Mobile/.gitignore linux-4.9.y/Documentation/arm/SH-Mobile/.gitignore --- linux-4.9.37/Documentation/arm/SH-Mobile/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/Documentation/arm/SH-Mobile/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -vrl4 diff -urN linux-4.9.37/Documentation/DocBook/.gitignore linux-4.9.y/Documentation/DocBook/.gitignore --- linux-4.9.37/Documentation/DocBook/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/Documentation/DocBook/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,17 +0,0 @@ -*.xml -*.ps -*.pdf -*.html -*.9.gz -*.9 -*.aux -*.dvi -*.log -*.out -*.png -*.gif -*.svg -*.proc -*.db -media-indices.tmpl -media-entities.tmpl diff -urN linux-4.9.37/Documentation/.gitignore linux-4.9.y/Documentation/.gitignore --- linux-4.9.37/Documentation/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/Documentation/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -output -*.pyc diff -urN linux-4.9.37/Documentation/vm/.gitignore linux-4.9.y/Documentation/vm/.gitignore --- linux-4.9.37/Documentation/vm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/Documentation/vm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -page-types -slabinfo diff -urN linux-4.9.37/drivers/atm/.gitignore linux-4.9.y/drivers/atm/.gitignore --- linux-4.9.37/drivers/atm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/atm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,5 +0,0 @@ -# Ignore generated files -fore200e_mkfirm -fore200e_pca_fw.c -pca200e.bin -pca200e_ecd.bin2 diff -urN linux-4.9.37/drivers/base/dma-contiguous.c linux-4.9.y/drivers/base/dma-contiguous.c --- 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 -urN linux-4.9.37/drivers/char/random.c linux-4.9.y/drivers/char/random.c --- 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 -urN linux-4.9.37/drivers/clk/goke/clk.c linux-4.9.y/drivers/clk/goke/clk.c --- 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 -urN linux-4.9.37/drivers/clk/goke/clk-gk7202v300.c linux-4.9.y/drivers/clk/goke/clk-gk7202v300.c --- 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 -urN linux-4.9.37/drivers/clk/goke/clk-gk7205v200.c linux-4.9.y/drivers/clk/goke/clk-gk7205v200.c --- 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 -urN linux-4.9.37/drivers/clk/goke/clk-gk7205v300.c linux-4.9.y/drivers/clk/goke/clk-gk7205v300.c --- 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 -urN linux-4.9.37/drivers/clk/goke/clk-gk7605v100.c linux-4.9.y/drivers/clk/goke/clk-gk7605v100.c --- 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 -urN linux-4.9.37/drivers/clk/goke/clk.h linux-4.9.y/drivers/clk/goke/clk.h --- 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 -urN linux-4.9.37/drivers/clk/goke/Kconfig linux-4.9.y/drivers/clk/goke/Kconfig --- 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 -urN linux-4.9.37/drivers/clk/goke/Makefile linux-4.9.y/drivers/clk/goke/Makefile --- 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 -urN linux-4.9.37/drivers/clk/goke/reset.c linux-4.9.y/drivers/clk/goke/reset.c --- 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 -urN linux-4.9.37/drivers/clk/goke/reset.h linux-4.9.y/drivers/clk/goke/reset.h --- 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 -urN linux-4.9.37/drivers/clk/Kconfig linux-4.9.y/drivers/clk/Kconfig --- 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 -urN linux-4.9.37/drivers/clk/Makefile linux-4.9.y/drivers/clk/Makefile --- 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 -urN linux-4.9.37/drivers/clocksource/arm_arch_timer.c linux-4.9.y/drivers/clocksource/arm_arch_timer.c --- 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 -urN linux-4.9.37/drivers/clocksource/Kconfig linux-4.9.y/drivers/clocksource/Kconfig --- 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 -urN linux-4.9.37/drivers/clocksource/timer-sp804.c linux-4.9.y/drivers/clocksource/timer-sp804.c --- 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 -urN linux-4.9.37/drivers/crypto/qat/qat_common/.gitignore linux-4.9.y/drivers/crypto/qat/qat_common/.gitignore --- linux-4.9.37/drivers/crypto/qat/qat_common/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/crypto/qat/qat_common/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -*-asn1.[ch] diff -urN linux-4.9.37/drivers/crypto/vmx/.gitignore linux-4.9.y/drivers/crypto/vmx/.gitignore --- linux-4.9.37/drivers/crypto/vmx/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/crypto/vmx/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -aesp8-ppc.S -ghashp8-ppc.S diff -urN linux-4.9.37/drivers/dma/edmac_goke.c linux-4.9.y/drivers/dma/edmac_goke.c --- 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 -urN linux-4.9.37/drivers/dma/edmac_goke.h linux-4.9.y/drivers/dma/edmac_goke.h --- 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 -urN linux-4.9.37/drivers/dma/Kconfig linux-4.9.y/drivers/dma/Kconfig --- 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 -urN linux-4.9.37/drivers/dma/Makefile linux-4.9.y/drivers/dma/Makefile --- 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 -urN linux-4.9.37/drivers/dma-buf/fence.c linux-4.9.y/drivers/dma-buf/fence.c --- 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 -urN linux-4.9.37/drivers/dma-buf/reservation.c linux-4.9.y/drivers/dma-buf/reservation.c --- 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 -urN linux-4.9.37/drivers/dma-buf/sw_sync.c linux-4.9.y/drivers/dma-buf/sw_sync.c --- 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 -urN linux-4.9.37/drivers/dma-buf/_sw_sync.h linux-4.9.y/drivers/dma-buf/_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,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 -urN linux-4.9.37/drivers/dma-buf/sw_sync.h linux-4.9.y/drivers/dma-buf/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 */ diff -urN linux-4.9.37/drivers/dma-buf/sync.c linux-4.9.y/drivers/dma-buf/sync.c --- 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 -urN linux-4.9.37/drivers/dma-buf/sync_file.c linux-4.9.y/drivers/dma-buf/sync_file.c --- 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 -urN linux-4.9.37/drivers/dma-buf/_sync.h linux-4.9.y/drivers/dma-buf/_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,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 -urN linux-4.9.37/drivers/dma-buf/sync.h linux-4.9.y/drivers/dma-buf/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 */ diff -urN linux-4.9.37/drivers/eisa/.gitignore linux-4.9.y/drivers/eisa/.gitignore --- linux-4.9.37/drivers/eisa/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/eisa/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -devlist.h diff -urN linux-4.9.37/drivers/fence/Kconfig linux-4.9.y/drivers/fence/Kconfig --- 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 -urN linux-4.9.37/drivers/fence/Makefile linux-4.9.y/drivers/fence/Makefile --- 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 -urN linux-4.9.37/drivers/fence/sw_sync.c linux-4.9.y/drivers/fence/sw_sync.c --- 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 -urN linux-4.9.37/drivers/fence/_sw_sync.h linux-4.9.y/drivers/fence/_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,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 -urN linux-4.9.37/drivers/fence/sw_sync.h linux-4.9.y/drivers/fence/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 */ diff -urN linux-4.9.37/drivers/fence/sync.c linux-4.9.y/drivers/fence/sync.c --- 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 -urN linux-4.9.37/drivers/fence/sync_debug.c linux-4.9.y/drivers/fence/sync_debug.c --- 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 -urN linux-4.9.37/drivers/fence/_sync.h linux-4.9.y/drivers/fence/_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,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 -urN linux-4.9.37/drivers/fence/sync.h linux-4.9.y/drivers/fence/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 */ diff -urN linux-4.9.37/drivers/firmware/psci.c linux-4.9.y/drivers/firmware/psci.c --- 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 -urN linux-4.9.37/drivers/goke/cma/cma.c linux-4.9.y/drivers/goke/cma/cma.c --- 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 -urN linux-4.9.37/drivers/goke/cma/Kconfig linux-4.9.y/drivers/goke/cma/Kconfig --- 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 -urN linux-4.9.37/drivers/goke/cma/Makefile linux-4.9.y/drivers/goke/cma/Makefile --- 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 -urN linux-4.9.37/drivers/goke/Kconfig linux-4.9.y/drivers/goke/Kconfig --- 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 -urN linux-4.9.37/drivers/goke/Makefile linux-4.9.y/drivers/goke/Makefile --- 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 -urN linux-4.9.37/drivers/gpio/gpio-pl061.c linux-4.9.y/drivers/gpio/gpio-pl061.c --- 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 -urN linux-4.9.37/drivers/gpu/drm/radeon/.gitignore linux-4.9.y/drivers/gpu/drm/radeon/.gitignore --- linux-4.9.37/drivers/gpu/drm/radeon/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/gpu/drm/radeon/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -mkregtable -*_reg_safe.h - diff -urN linux-4.9.37/drivers/i2c/busses/i2c-goke.c linux-4.9.y/drivers/i2c/busses/i2c-goke.c --- 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 -urN linux-4.9.37/drivers/i2c/busses/Kconfig linux-4.9.y/drivers/i2c/busses/Kconfig --- 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 -urN linux-4.9.37/drivers/i2c/busses/Makefile linux-4.9.y/drivers/i2c/busses/Makefile --- 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 -urN linux-4.9.37/drivers/i2c/i2c-dev.c linux-4.9.y/drivers/i2c/i2c-dev.c --- 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 -urN linux-4.9.37/drivers/irqchip/irq-gic.c linux-4.9.y/drivers/irqchip/irq-gic.c --- 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 -urN linux-4.9.37/drivers/irqchip/irq-gic-v3.c linux-4.9.y/drivers/irqchip/irq-gic-v3.c --- 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 -urN linux-4.9.37/drivers/Kconfig linux-4.9.y/drivers/Kconfig --- 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 -urN linux-4.9.37/drivers/Makefile linux-4.9.y/drivers/Makefile --- 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 -urN linux-4.9.37/drivers/media/usb/uvc/uvc_video.c linux-4.9.y/drivers/media/usb/uvc/uvc_video.c --- 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 -urN linux-4.9.37/drivers/media/v4l2-core/videobuf2-v4l2.c linux-4.9.y/drivers/media/v4l2-core/videobuf2-v4l2.c --- 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 -urN linux-4.9.37/drivers/mfd/goke_fmc.c linux-4.9.y/drivers/mfd/goke_fmc.c --- 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 -urN linux-4.9.37/drivers/mfd/Kconfig linux-4.9.y/drivers/mfd/Kconfig --- 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 -urN linux-4.9.37/drivers/mfd/Makefile linux-4.9.y/drivers/mfd/Makefile --- 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 -urN linux-4.9.37/drivers/mmc/card/block.c linux-4.9.y/drivers/mmc/card/block.c --- 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 -urN linux-4.9.37/drivers/mmc/card/queue.c linux-4.9.y/drivers/mmc/card/queue.c --- 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 -urN linux-4.9.37/drivers/mmc/card/queue.h linux-4.9.y/drivers/mmc/card/queue.h --- 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 -urN linux-4.9.37/drivers/mmc/core/core.c linux-4.9.y/drivers/mmc/core/core.c --- 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 -urN linux-4.9.37/drivers/mmc/core/mmc.c linux-4.9.y/drivers/mmc/core/mmc.c --- 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 -urN linux-4.9.37/drivers/mmc/core/mmc_ops.c linux-4.9.y/drivers/mmc/core/mmc_ops.c --- 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 -urN linux-4.9.37/drivers/mmc/core/mmc_ops.h linux-4.9.y/drivers/mmc/core/mmc_ops.h --- 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 -urN linux-4.9.37/drivers/mmc/core/sd.c linux-4.9.y/drivers/mmc/core/sd.c --- 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 -urN linux-4.9.37/drivers/mmc/core/sdio.c linux-4.9.y/drivers/mmc/core/sdio.c --- 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 -urN linux-4.9.37/drivers/mmc/host/Kconfig linux-4.9.y/drivers/mmc/host/Kconfig --- 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 -urN linux-4.9.37/drivers/mmc/host/Makefile linux-4.9.y/drivers/mmc/host/Makefile --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci.c linux-4.9.y/drivers/mmc/host/sdhci.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-cmdq.c linux-4.9.y/drivers/mmc/host/sdhci-cmdq.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-cmdq.h linux-4.9.y/drivers/mmc/host/sdhci-cmdq.h --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-gk7202v300.c linux-4.9.y/drivers/mmc/host/sdhci-gk7202v300.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-gk7205v200.c linux-4.9.y/drivers/mmc/host/sdhci-gk7205v200.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-gk7205v300.c linux-4.9.y/drivers/mmc/host/sdhci-gk7205v300.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-gk7605v100.c linux-4.9.y/drivers/mmc/host/sdhci-gk7605v100.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-goke.c linux-4.9.y/drivers/mmc/host/sdhci-goke.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci.h linux-4.9.y/drivers/mmc/host/sdhci.h --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-pltfm.c linux-4.9.y/drivers/mmc/host/sdhci-pltfm.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-pltfm.h linux-4.9.y/drivers/mmc/host/sdhci-pltfm.h --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-proc.c linux-4.9.y/drivers/mmc/host/sdhci-proc.c --- 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 -urN linux-4.9.37/drivers/mmc/host/sdhci-proc.h linux-4.9.y/drivers/mmc/host/sdhci-proc.h --- 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 -urN linux-4.9.37/drivers/mtd/Makefile linux-4.9.y/drivers/mtd/Makefile --- 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 -urN linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100.c linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100.h linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100.h --- 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 -urN linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100_os.c linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100_os.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc100_spi_general.c linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc100_spi_general.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/gkfmc100/fmc_spi_nand_ids.c linux-4.9.y/drivers/mtd/nand/gkfmc100/fmc_spi_nand_ids.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/gkfmc100/Kconfig linux-4.9.y/drivers/mtd/nand/gkfmc100/Kconfig --- 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 -urN linux-4.9.37/drivers/mtd/nand/gkfmc100/Makefile linux-4.9.y/drivers/mtd/nand/gkfmc100/Makefile --- 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 -urN linux-4.9.37/drivers/mtd/nand/Kconfig linux-4.9.y/drivers/mtd/nand/Kconfig --- 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 -urN linux-4.9.37/drivers/mtd/nand/Makefile linux-4.9.y/drivers/mtd/nand/Makefile --- 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 -urN linux-4.9.37/drivers/mtd/nand/match_table.c linux-4.9.y/drivers/mtd/nand/match_table.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/match_table.h linux-4.9.y/drivers/mtd/nand/match_table.h --- 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 -urN linux-4.9.37/drivers/mtd/nand/nand_base.c linux-4.9.y/drivers/mtd/nand/nand_base.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/nand_ids.c linux-4.9.y/drivers/mtd/nand/nand_ids.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/nfc_gen.c linux-4.9.y/drivers/mtd/nand/nfc_gen.c --- 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 -urN linux-4.9.37/drivers/mtd/nand/nfc_gen.h linux-4.9.y/drivers/mtd/nand/nfc_gen.h --- 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 -urN linux-4.9.37/drivers/mtd/nand/nfc_spl_ids.c linux-4.9.y/drivers/mtd/nand/nfc_spl_ids.c --- 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 -urN linux-4.9.37/drivers/mtd/spi-nor/goke-sfc.c linux-4.9.y/drivers/mtd/spi-nor/goke-sfc.c --- 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 -urN linux-4.9.37/drivers/mtd/spi-nor/Kconfig linux-4.9.y/drivers/mtd/spi-nor/Kconfig --- 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 -urN linux-4.9.37/drivers/mtd/spi-nor/Makefile linux-4.9.y/drivers/mtd/spi-nor/Makefile --- 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 -urN linux-4.9.37/drivers/mtd/spi-nor/spi-nor.c linux-4.9.y/drivers/mtd/spi-nor/spi-nor.c --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/femac.c linux-4.9.y/drivers/net/ethernet/goke/femac/femac.c --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/femac.h linux-4.9.y/drivers/net/ethernet/goke/femac/femac.h --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/Makefile linux-4.9.y/drivers/net/ethernet/goke/femac/Makefile --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/phy_fix.c linux-4.9.y/drivers/net/ethernet/goke/femac/phy_fix.c --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/phy_fix.h linux-4.9.y/drivers/net/ethernet/goke/femac/phy_fix.h --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/phy_v1.h linux-4.9.y/drivers/net/ethernet/goke/femac/phy_v1.h --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/phy_v2.h linux-4.9.y/drivers/net/ethernet/goke/femac/phy_v2.h --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/util.c linux-4.9.y/drivers/net/ethernet/goke/femac/util.c --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/femac/util.h linux-4.9.y/drivers/net/ethernet/goke/femac/util.h --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/Kconfig linux-4.9.y/drivers/net/ethernet/goke/Kconfig --- 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 -urN linux-4.9.37/drivers/net/ethernet/goke/Makefile linux-4.9.y/drivers/net/ethernet/goke/Makefile --- 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 -urN linux-4.9.37/drivers/net/ethernet/Kconfig linux-4.9.y/drivers/net/ethernet/Kconfig --- 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 -urN linux-4.9.37/drivers/net/ethernet/Makefile linux-4.9.y/drivers/net/ethernet/Makefile --- 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 -urN linux-4.9.37/drivers/net/phy/Kconfig linux-4.9.y/drivers/net/phy/Kconfig --- 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 -urN linux-4.9.37/drivers/net/phy/Makefile linux-4.9.y/drivers/net/phy/Makefile --- 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 -urN linux-4.9.37/drivers/net/phy/mdio-goke-femac.c linux-4.9.y/drivers/net/phy/mdio-goke-femac.c --- 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 -urN linux-4.9.37/drivers/net/phy/phy_device.c linux-4.9.y/drivers/net/phy/phy_device.c --- 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 -urN linux-4.9.37/drivers/net/usb/cdc_ether.c linux-4.9.y/drivers/net/usb/cdc_ether.c --- 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 -urN linux-4.9.37/drivers/net/wan/.gitignore linux-4.9.y/drivers/net/wan/.gitignore --- linux-4.9.37/drivers/net/wan/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/net/wan/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -wanxlfw.inc diff -urN linux-4.9.37/drivers/of/unittest-data/.gitignore linux-4.9.y/drivers/of/unittest-data/.gitignore --- linux-4.9.37/drivers/of/unittest-data/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/of/unittest-data/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -testcases.dtb -testcases.dtb.S diff -urN linux-4.9.37/drivers/phy/goke/Kconfig linux-4.9.y/drivers/phy/goke/Kconfig --- 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 -urN linux-4.9.37/drivers/phy/goke/Makefile linux-4.9.y/drivers/phy/goke/Makefile --- 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 -urN linux-4.9.37/drivers/phy/goke/phy-goke-usb.h linux-4.9.y/drivers/phy/goke/phy-goke-usb.h --- 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 -urN linux-4.9.37/drivers/phy/goke/phy-goke-usbp2.c linux-4.9.y/drivers/phy/goke/phy-goke-usbp2.c --- 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 -urN linux-4.9.37/drivers/phy/Kconfig linux-4.9.y/drivers/phy/Kconfig --- 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 -urN linux-4.9.37/drivers/phy/Makefile linux-4.9.y/drivers/phy/Makefile --- 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 -urN linux-4.9.37/drivers/power/reset/goke-reboot.c linux-4.9.y/drivers/power/reset/goke-reboot.c --- 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 -urN linux-4.9.37/drivers/power/reset/Kconfig linux-4.9.y/drivers/power/reset/Kconfig --- 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 -urN linux-4.9.37/drivers/power/reset/Makefile linux-4.9.y/drivers/power/reset/Makefile --- 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 -urN linux-4.9.37/drivers/pwm/Kconfig linux-4.9.y/drivers/pwm/Kconfig --- 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 -urN linux-4.9.37/drivers/pwm/Makefile linux-4.9.y/drivers/pwm/Makefile --- 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 -urN linux-4.9.37/drivers/pwm/pwm-goke.c linux-4.9.y/drivers/pwm/pwm-goke.c --- 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 -urN linux-4.9.37/drivers/rtc/Kconfig linux-4.9.y/drivers/rtc/Kconfig --- 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 -urN linux-4.9.37/drivers/rtc/Makefile linux-4.9.y/drivers/rtc/Makefile --- 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 -urN linux-4.9.37/drivers/rtc/rtc-goke.c linux-4.9.y/drivers/rtc/rtc-goke.c --- 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 -urN linux-4.9.37/drivers/scsi/aic7xxx/.gitignore linux-4.9.y/drivers/scsi/aic7xxx/.gitignore --- linux-4.9.37/drivers/scsi/aic7xxx/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/scsi/aic7xxx/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -aic79xx_reg.h -aic79xx_reg_print.c -aic79xx_seq.h -aic7xxx_reg.h -aic7xxx_reg_print.c -aic7xxx_seq.h diff -urN linux-4.9.37/drivers/scsi/.gitignore linux-4.9.y/drivers/scsi/.gitignore --- linux-4.9.37/drivers/scsi/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/scsi/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -53c700_d.h diff -urN linux-4.9.37/drivers/scsi/scsi_lib.c linux-4.9.y/drivers/scsi/scsi_lib.c --- 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 -urN linux-4.9.37/drivers/spi/spi.c linux-4.9.y/drivers/spi/spi.c --- 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 -urN linux-4.9.37/drivers/spi/spi-pl022.c linux-4.9.y/drivers/spi/spi-pl022.c --- 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 -urN linux-4.9.37/drivers/staging/greybus/tools/.gitignore linux-4.9.y/drivers/staging/greybus/tools/.gitignore --- linux-4.9.37/drivers/staging/greybus/tools/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/staging/greybus/tools/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -loopback_test diff -urN linux-4.9.37/drivers/tty/serial/amba-pl011.c linux-4.9.y/drivers/tty/serial/amba-pl011.c --- 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 -urN linux-4.9.37/drivers/tty/vt/.gitignore linux-4.9.y/drivers/tty/vt/.gitignore --- linux-4.9.37/drivers/tty/vt/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/tty/vt/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -consolemap_deftbl.c -defkeymap.c diff -urN linux-4.9.37/drivers/tty/vt/selection.c linux-4.9.y/drivers/tty/vt/selection.c --- 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 -urN linux-4.9.37/drivers/usb/core/devices.c linux-4.9.y/drivers/usb/core/devices.c --- 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 -urN linux-4.9.37/drivers/usb/core/hub.c linux-4.9.y/drivers/usb/core/hub.c --- 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 -urN linux-4.9.37/drivers/usb/core/urb.c linux-4.9.y/drivers/usb/core/urb.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/core.c linux-4.9.y/drivers/usb/dwc3/core.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/core.h linux-4.9.y/drivers/usb/dwc3/core.h --- 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 -urN linux-4.9.37/drivers/usb/dwc3/debugfs.c linux-4.9.y/drivers/usb/dwc3/debugfs.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/debug.h linux-4.9.y/drivers/usb/dwc3/debug.h --- 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 -urN linux-4.9.37/drivers/usb/dwc3/dwc3-goke.c linux-4.9.y/drivers/usb/dwc3/dwc3-goke.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/dwc3-goke.h linux-4.9.y/drivers/usb/dwc3/dwc3-goke.h --- 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 -urN linux-4.9.37/drivers/usb/dwc3/ep0.c linux-4.9.y/drivers/usb/dwc3/ep0.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/gadget.c linux-4.9.y/drivers/usb/dwc3/gadget.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/host.c linux-4.9.y/drivers/usb/dwc3/host.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/io.h linux-4.9.y/drivers/usb/dwc3/io.h --- 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 -urN linux-4.9.37/drivers/usb/dwc3/Makefile linux-4.9.y/drivers/usb/dwc3/Makefile --- 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 -urN linux-4.9.37/drivers/usb/dwc3/proc.c linux-4.9.y/drivers/usb/dwc3/proc.c --- 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 -urN linux-4.9.37/drivers/usb/dwc3/trace.h linux-4.9.y/drivers/usb/dwc3/trace.h --- 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 -urN linux-4.9.37/drivers/usb/gadget/composite.c linux-4.9.y/drivers/usb/gadget/composite.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/configfs.c linux-4.9.y/drivers/usb/gadget/configfs.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/epautoconf.c linux-4.9.y/drivers/usb/gadget/epautoconf.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/f_hid.c linux-4.9.y/drivers/usb/gadget/function/f_hid.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/f_mass_storage.c linux-4.9.y/drivers/usb/gadget/function/f_mass_storage.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/f_uac1.c linux-4.9.y/drivers/usb/gadget/function/f_uac1.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/f_uac1_legacy.c linux-4.9.y/drivers/usb/gadget/function/f_uac1_legacy.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/f_uac2.c linux-4.9.y/drivers/usb/gadget/function/f_uac2.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/f_uvc.c linux-4.9.y/drivers/usb/gadget/function/f_uvc.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/Makefile linux-4.9.y/drivers/usb/gadget/function/Makefile --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/u_audio.c linux-4.9.y/drivers/usb/gadget/function/u_audio.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/u_audio.h linux-4.9.y/drivers/usb/gadget/function/u_audio.h --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/u_uac1.c linux-4.9.y/drivers/usb/gadget/function/u_uac1.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/u_uac1.h linux-4.9.y/drivers/usb/gadget/function/u_uac1.h --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/u_uac1_legacy.c linux-4.9.y/drivers/usb/gadget/function/u_uac1_legacy.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/u_uac1_legacy.h linux-4.9.y/drivers/usb/gadget/function/u_uac1_legacy.h --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/u_uac2.h linux-4.9.y/drivers/usb/gadget/function/u_uac2.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; diff -urN linux-4.9.37/drivers/usb/gadget/function/u_uvc.h linux-4.9.y/drivers/usb/gadget/function/u_uvc.h --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/uvc_configfs.c linux-4.9.y/drivers/usb/gadget/function/uvc_configfs.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/uvc.h linux-4.9.y/drivers/usb/gadget/function/uvc.h --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/uvc_v4l2.c linux-4.9.y/drivers/usb/gadget/function/uvc_v4l2.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/uvc_video.c linux-4.9.y/drivers/usb/gadget/function/uvc_video.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/function/uvc_video.h linux-4.9.y/drivers/usb/gadget/function/uvc_video.h --- 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 -urN linux-4.9.37/drivers/usb/gadget/Kconfig linux-4.9.y/drivers/usb/gadget/Kconfig --- 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 -urN linux-4.9.37/drivers/usb/gadget/legacy/audio.c linux-4.9.y/drivers/usb/gadget/legacy/audio.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/legacy/Kconfig linux-4.9.y/drivers/usb/gadget/legacy/Kconfig --- 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 -urN linux-4.9.37/drivers/usb/gadget/legacy/multi.c linux-4.9.y/drivers/usb/gadget/legacy/multi.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/legacy/webcam.c linux-4.9.y/drivers/usb/gadget/legacy/webcam.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/udc/core.c linux-4.9.y/drivers/usb/gadget/udc/core.c --- 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 -urN linux-4.9.37/drivers/usb/gadget/udc/trace.h linux-4.9.y/drivers/usb/gadget/udc/trace.h --- 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 -urN linux-4.9.37/drivers/usb/host/xhci.c linux-4.9.y/drivers/usb/host/xhci.c --- 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 -urN linux-4.9.37/drivers/usb/host/xhci.h linux-4.9.y/drivers/usb/host/xhci.h --- 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 -urN linux-4.9.37/drivers/usb/host/xhci-hub.c linux-4.9.y/drivers/usb/host/xhci-hub.c --- 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 -urN linux-4.9.37/drivers/usb/host/xhci-mem.c linux-4.9.y/drivers/usb/host/xhci-mem.c --- 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 -urN linux-4.9.37/drivers/usb/host/xhci-plat.c linux-4.9.y/drivers/usb/host/xhci-plat.c --- 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 -urN linux-4.9.37/drivers/usb/Makefile linux-4.9.y/drivers/usb/Makefile --- 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 -urN linux-4.9.37/drivers/video/fbdev/core/fbmem.c linux-4.9.y/drivers/video/fbdev/core/fbmem.c --- 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 -urN linux-4.9.37/drivers/video/logo/.gitignore linux-4.9.y/drivers/video/logo/.gitignore --- linux-4.9.37/drivers/video/logo/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/video/logo/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,7 +0,0 @@ -# -# Generated files -# -*_mono.c -*_vga16.c -*_clut224.c -*_gray256.c diff -urN linux-4.9.37/drivers/zorro/.gitignore linux-4.9.y/drivers/zorro/.gitignore --- linux-4.9.37/drivers/zorro/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/drivers/zorro/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -devlist.h -gen-devlist diff -urN linux-4.9.37/firmware/cis/.gitignore linux-4.9.y/firmware/cis/.gitignore --- linux-4.9.37/firmware/cis/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/firmware/cis/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -*.cis diff -urN linux-4.9.37/firmware/.gitignore linux-4.9.y/firmware/.gitignore --- linux-4.9.37/firmware/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/firmware/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -*.gen.S -*.fw -*.bin -*.csp -*.dsp -ihex2fw diff -urN linux-4.9.37/fs/buffer.c linux-4.9.y/fs/buffer.c --- 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 -urN linux-4.9.37/fs/compat_ioctl.c linux-4.9.y/fs/compat_ioctl.c --- 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 -urN linux-4.9.37/fs/dcache.c linux-4.9.y/fs/dcache.c --- 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 -urN linux-4.9.37/fs/fat/dir.c linux-4.9.y/fs/fat/dir.c --- 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 -urN linux-4.9.37/fs/fat/fatent.c linux-4.9.y/fs/fat/fatent.c --- 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 -urN linux-4.9.37/fs/fat/fat.h linux-4.9.y/fs/fat/fat.h --- 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 -urN linux-4.9.37/fs/fat/file.c linux-4.9.y/fs/fat/file.c --- 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 -urN linux-4.9.37/fs/fat/inode.c linux-4.9.y/fs/fat/inode.c --- 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 -urN linux-4.9.37/fs/fat/misc.c linux-4.9.y/fs/fat/misc.c --- 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 -urN linux-4.9.37/fs/jffs2/compr.c linux-4.9.y/fs/jffs2/compr.c --- 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 -urN linux-4.9.37/fs/jffs2/compr.h linux-4.9.y/fs/jffs2/compr.h --- 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 -urN linux-4.9.37/fs/jffs2/compr_lzma.c linux-4.9.y/fs/jffs2/compr_lzma.c --- 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 -urN linux-4.9.37/fs/jffs2/Kconfig linux-4.9.y/fs/jffs2/Kconfig --- 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 -urN linux-4.9.37/fs/jffs2/Makefile linux-4.9.y/fs/jffs2/Makefile --- 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 -urN linux-4.9.37/fs/jffs2/super.c linux-4.9.y/fs/jffs2/super.c --- 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 -urN linux-4.9.37/fs/Kconfig linux-4.9.y/fs/Kconfig --- 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 -urN linux-4.9.37/fs/Makefile linux-4.9.y/fs/Makefile --- 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 -urN linux-4.9.37/fs/xfs/xfs_buf.c linux-4.9.y/fs/xfs/xfs_buf.c --- 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 -urN linux-4.9.37/fs/xfs/xfs_icache.c linux-4.9.y/fs/xfs/xfs_icache.c --- 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 -urN linux-4.9.37/fs/yaffs2/Kconfig linux-4.9.y/fs/yaffs2/Kconfig --- 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 -urN linux-4.9.37/fs/yaffs2/Makefile linux-4.9.y/fs/yaffs2/Makefile --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_allocator.c linux-4.9.y/fs/yaffs2/yaffs_allocator.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_allocator.h linux-4.9.y/fs/yaffs2/yaffs_allocator.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_attribs.c linux-4.9.y/fs/yaffs2/yaffs_attribs.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_attribs.h linux-4.9.y/fs/yaffs2/yaffs_attribs.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_bitmap.c linux-4.9.y/fs/yaffs2/yaffs_bitmap.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_bitmap.h linux-4.9.y/fs/yaffs2/yaffs_bitmap.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_checkptrw.c linux-4.9.y/fs/yaffs2/yaffs_checkptrw.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_checkptrw.h linux-4.9.y/fs/yaffs2/yaffs_checkptrw.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_ecc.c linux-4.9.y/fs/yaffs2/yaffs_ecc.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_ecc.h linux-4.9.y/fs/yaffs2/yaffs_ecc.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_endian.c linux-4.9.y/fs/yaffs2/yaffs_endian.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_endian.h linux-4.9.y/fs/yaffs2/yaffs_endian.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_getblockinfo.h linux-4.9.y/fs/yaffs2/yaffs_getblockinfo.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_guts.c linux-4.9.y/fs/yaffs2/yaffs_guts.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_guts.h linux-4.9.y/fs/yaffs2/yaffs_guts.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_linux.h linux-4.9.y/fs/yaffs2/yaffs_linux.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_mtdif.c linux-4.9.y/fs/yaffs2/yaffs_mtdif.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_mtdif.h linux-4.9.y/fs/yaffs2/yaffs_mtdif.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_nameval.c linux-4.9.y/fs/yaffs2/yaffs_nameval.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_nameval.h linux-4.9.y/fs/yaffs2/yaffs_nameval.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_nand.c linux-4.9.y/fs/yaffs2/yaffs_nand.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_nand.h linux-4.9.y/fs/yaffs2/yaffs_nand.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_packedtags1.c linux-4.9.y/fs/yaffs2/yaffs_packedtags1.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_packedtags1.h linux-4.9.y/fs/yaffs2/yaffs_packedtags1.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_packedtags2.c linux-4.9.y/fs/yaffs2/yaffs_packedtags2.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_packedtags2.h linux-4.9.y/fs/yaffs2/yaffs_packedtags2.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_summary.c linux-4.9.y/fs/yaffs2/yaffs_summary.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_summary.h linux-4.9.y/fs/yaffs2/yaffs_summary.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_tagscompat.c linux-4.9.y/fs/yaffs2/yaffs_tagscompat.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_tagscompat.h linux-4.9.y/fs/yaffs2/yaffs_tagscompat.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_tagsmarshall.c linux-4.9.y/fs/yaffs2/yaffs_tagsmarshall.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_tagsmarshall.h linux-4.9.y/fs/yaffs2/yaffs_tagsmarshall.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_trace.h linux-4.9.y/fs/yaffs2/yaffs_trace.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_verify.c linux-4.9.y/fs/yaffs2/yaffs_verify.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_verify.h linux-4.9.y/fs/yaffs2/yaffs_verify.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_vfs.c linux-4.9.y/fs/yaffs2/yaffs_vfs.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_yaffs1.c linux-4.9.y/fs/yaffs2/yaffs_yaffs1.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_yaffs1.h linux-4.9.y/fs/yaffs2/yaffs_yaffs1.h --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_yaffs2.c linux-4.9.y/fs/yaffs2/yaffs_yaffs2.c --- 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 -urN linux-4.9.37/fs/yaffs2/yaffs_yaffs2.h linux-4.9.y/fs/yaffs2/yaffs_yaffs2.h --- 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 -urN linux-4.9.37/fs/yaffs2/yportenv.h linux-4.9.y/fs/yaffs2/yportenv.h --- 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 -urN linux-4.9.37/.get_maintainer.ignore linux-4.9.y/.get_maintainer.ignore --- linux-4.9.37/.get_maintainer.ignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/.get_maintainer.ignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -Christoph Hellwig diff -urN linux-4.9.37/.gitattributes linux-4.9.y/.gitattributes --- linux-4.9.37/.gitattributes 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/.gitattributes 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -*.c diff=cpp -*.h diff=cpp diff -urN linux-4.9.37/.gitignore linux-4.9.y/.gitignore --- linux-4.9.37/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,116 +0,0 @@ -# -# NOTE! Don't add files that are generated in specific -# subdirectories here. Add them in the ".gitignore" file -# in that subdirectory instead. -# -# NOTE! Please use 'git ls-files -i --exclude-standard' -# command after changing this file, to see if there are -# any tracked files which get ignored after the change. -# -# Normal rules -# -.* -*.o -*.o.* -*.a -*.s -*.ko -*.so -*.so.dbg -*.mod.c -*.i -*.lst -*.symtypes -*.order -*.elf -*.bin -*.tar -*.gz -*.bz2 -*.lzma -*.xz -*.lz4 -*.lzo -*.patch -*.gcno -modules.builtin -Module.symvers -*.dwo -*.su -*.c.[012]*.* - -# -# Top-level generic files -# -/tags -/TAGS -/linux -/vmlinux -/vmlinux.32 -/vmlinux-gdb.py -/vmlinuz -/System.map -/Module.markers - -# -# Debian directory (make deb-pkg) -# -/debian/ - -# -# tar directory (make tar*-pkg) -# -/tar-install/ - -# -# git files that we don't want to ignore even if they are dot-files -# -!.gitignore -!.mailmap -!.cocciconfig - -# -# Generated include files -# -include/config -include/generated -arch/*/include/generated - -# stgit generated dirs -patches-* - -# quilt's files -patches -series - -# cscope files -cscope.* -ncscope.* - -# gnu global files -GPATH -GRTAGS -GSYMS -GTAGS - -# id-utils files -ID - -*.orig -*~ -\#*# - -# -# Leavings from module signing -# -extra_certificates -signing_key.pem -signing_key.priv -signing_key.x509 -x509.genkey - -# Kconfig presets -all.config - -# Kdevelop4 -*.kdev4 diff -urN linux-4.9.37/include/dt-bindings/clock/gk7202v300-clock.h linux-4.9.y/include/dt-bindings/clock/gk7202v300-clock.h --- 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 -urN linux-4.9.37/include/dt-bindings/clock/gk7205v200-clock.h linux-4.9.y/include/dt-bindings/clock/gk7205v200-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 */ diff -urN linux-4.9.37/include/dt-bindings/clock/gk7205v300-clock.h linux-4.9.y/include/dt-bindings/clock/gk7205v300-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 */ diff -urN linux-4.9.37/include/dt-bindings/clock/gk7605v100-clock.h linux-4.9.y/include/dt-bindings/clock/gk7605v100-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 */ diff -urN linux-4.9.37/include/kvm/arm_psci.h linux-4.9.y/include/kvm/arm_psci.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__ */ diff -urN linux-4.9.37/include/linux/blkdev.h linux-4.9.y/include/linux/blkdev.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, }; diff -urN linux-4.9.37/include/linux/cpuidle.h linux-4.9.y/include/linux/cpuidle.h --- 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 -urN linux-4.9.37/include/linux/dma-mapping.h linux-4.9.y/include/linux/dma-mapping.h --- 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 -urN linux-4.9.37/include/linux/fb.h linux-4.9.y/include/linux/fb.h --- 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 -urN linux-4.9.37/include/linux/fence.h linux-4.9.y/include/linux/fence.h --- 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 -urN linux-4.9.37/include/linux/fs.h linux-4.9.y/include/linux/fs.h --- 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 -urN linux-4.9.37/include/linux/goke_cma.h linux-4.9.y/include/linux/goke_cma.h --- 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 -urN linux-4.9.37/include/linux/i2c.h linux-4.9.y/include/linux/i2c.h --- 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 -urN linux-4.9.37/include/linux/lzma/LzFind.h linux-4.9.y/include/linux/lzma/LzFind.h --- 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 -urN linux-4.9.37/include/linux/lzma/LzHash.h linux-4.9.y/include/linux/lzma/LzHash.h --- 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 -urN linux-4.9.37/include/linux/lzma/LzmaDec.h linux-4.9.y/include/linux/lzma/LzmaDec.h --- 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 -urN linux-4.9.37/include/linux/lzma/LzmaEnc.h linux-4.9.y/include/linux/lzma/LzmaEnc.h --- 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 -urN linux-4.9.37/include/linux/lzma/Types.h linux-4.9.y/include/linux/lzma/Types.h --- 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 -urN linux-4.9.37/include/linux/lzma.h linux-4.9.y/include/linux/lzma.h --- 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 -urN linux-4.9.37/include/linux/mfd/goke_fmc.h linux-4.9.y/include/linux/mfd/goke_fmc.h --- 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 -urN linux-4.9.37/include/linux/mmc/card.h linux-4.9.y/include/linux/mmc/card.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)) diff -urN linux-4.9.37/include/linux/mmc/core.h linux-4.9.y/include/linux/mmc/core.h --- 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 -urN linux-4.9.37/include/linux/mmc/host.h linux-4.9.y/include/linux/mmc/host.h --- 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 -urN linux-4.9.37/include/linux/mmc/mmc.h linux-4.9.y/include/linux/mmc/mmc.h --- 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 -urN linux-4.9.37/include/linux/mm_types.h linux-4.9.y/include/linux/mm_types.h --- 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 -urN linux-4.9.37/include/linux/mtd/nand.h linux-4.9.y/include/linux/mtd/nand.h --- 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 -urN linux-4.9.37/include/linux/mtd/spi-nor.h linux-4.9.y/include/linux/mtd/spi-nor.h --- 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 -urN linux-4.9.37/include/linux/nospec.h linux-4.9.y/include/linux/nospec.h --- 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 -urN linux-4.9.37/include/linux/phy.h linux-4.9.y/include/linux/phy.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); diff -urN linux-4.9.37/include/linux/psci.h linux-4.9.y/include/linux/psci.h --- 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 -urN linux-4.9.37/include/linux/sched.h linux-4.9.y/include/linux/sched.h --- 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 -urN linux-4.9.37/include/linux/spi/spi.h linux-4.9.y/include/linux/spi/spi.h --- 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 -urN linux-4.9.37/include/linux/tcp.h linux-4.9.y/include/linux/tcp.h --- 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 -urN linux-4.9.37/include/linux/usb/usbnet.h linux-4.9.y/include/linux/usb/usbnet.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 *); diff -urN linux-4.9.37/include/net/netns/ipv4.h linux-4.9.y/include/net/netns/ipv4.h --- 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 -urN linux-4.9.37/include/net/tcp.h linux-4.9.y/include/net/tcp.h --- 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 -urN linux-4.9.37/include/uapi/linux/i2c-dev.h linux-4.9.y/include/uapi/linux/i2c-dev.h --- 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 -urN linux-4.9.37/include/uapi/linux/i2c.h linux-4.9.y/include/uapi/linux/i2c.h --- 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 -urN linux-4.9.37/include/uapi/linux/jffs2.h linux-4.9.y/include/uapi/linux/jffs2.h --- 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 -urN linux-4.9.37/include/uapi/linux/msdos_fs.h linux-4.9.y/include/uapi/linux/msdos_fs.h --- 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 -urN linux-4.9.37/include/uapi/linux/psci.h linux-4.9.y/include/uapi/linux/psci.h --- 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 -urN linux-4.9.37/include/uapi/linux/snmp.h linux-4.9.y/include/uapi/linux/snmp.h --- 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 -urN linux-4.9.37/include/uapi/linux/usb/ch9.h linux-4.9.y/include/uapi/linux/usb/ch9.h --- 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 -urN linux-4.9.37/include/uapi/linux/usb/video.h linux-4.9.y/include/uapi/linux/usb/video.h --- 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 -urN linux-4.9.37/kernel/debug/kdb/.gitignore linux-4.9.y/kernel/debug/kdb/.gitignore --- linux-4.9.37/kernel/debug/kdb/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/kernel/debug/kdb/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -gen-kdb_cmds.c diff -urN linux-4.9.37/kernel/.gitignore linux-4.9.y/kernel/.gitignore --- linux-4.9.37/kernel/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/kernel/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,7 +0,0 @@ -# -# Generated files -# -config_data.h -config_data.gz -timeconst.h -hz.bc diff -urN linux-4.9.37/kernel/sched/cputime.c linux-4.9.y/kernel/sched/cputime.c --- 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 -urN linux-4.9.37/lib/.gitignore linux-4.9.y/lib/.gitignore --- linux-4.9.37/lib/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/lib/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -# -# Generated files -# -gen_crc32table -crc32table.h -oid_registry_data.c diff -urN linux-4.9.37/lib/Kconfig linux-4.9.y/lib/Kconfig --- 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 -urN linux-4.9.37/lib/lzma/LzFind.c linux-4.9.y/lib/lzma/LzFind.c --- 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 -urN linux-4.9.37/lib/lzma/LzmaDec.c linux-4.9.y/lib/lzma/LzmaDec.c --- 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 -urN linux-4.9.37/lib/lzma/LzmaEnc.c linux-4.9.y/lib/lzma/LzmaEnc.c --- 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 -urN linux-4.9.37/lib/lzma/Makefile linux-4.9.y/lib/lzma/Makefile --- 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 -urN linux-4.9.37/lib/Makefile linux-4.9.y/lib/Makefile --- 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 -urN linux-4.9.37/lib/raid6/.gitignore linux-4.9.y/lib/raid6/.gitignore --- linux-4.9.37/lib/raid6/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/lib/raid6/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -mktables -altivec*.c -int*.c -tables.c -neon?.c -s390vx?.c diff -urN linux-4.9.37/mm/init-mm.c linux-4.9.y/mm/init-mm.c --- 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 -urN linux-4.9.37/mm/page_alloc.c linux-4.9.y/mm/page_alloc.c --- 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 -urN linux-4.9.37/net/core/net_namespace.c linux-4.9.y/net/core/net_namespace.c --- 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 -urN linux-4.9.37/net/ipv4/cipso_ipv4.c linux-4.9.y/net/ipv4/cipso_ipv4.c --- 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 -urN linux-4.9.37/net/ipv4/ip_output.c linux-4.9.y/net/ipv4/ip_output.c --- 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 -urN linux-4.9.37/net/ipv4/proc.c linux-4.9.y/net/ipv4/proc.c --- 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 -urN linux-4.9.37/net/ipv4/sysctl_net_ipv4.c linux-4.9.y/net/ipv4/sysctl_net_ipv4.c --- 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 -urN linux-4.9.37/net/ipv4/tcp.c linux-4.9.y/net/ipv4/tcp.c --- 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 -urN linux-4.9.37/net/ipv4/tcp_input.c linux-4.9.y/net/ipv4/tcp_input.c --- 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 -urN linux-4.9.37/net/ipv4/tcp_ipv4.c linux-4.9.y/net/ipv4/tcp_ipv4.c --- 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 -urN linux-4.9.37/net/ipv4/tcp_output.c linux-4.9.y/net/ipv4/tcp_output.c --- 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 -urN linux-4.9.37/net/ipv4/tcp_timer.c linux-4.9.y/net/ipv4/tcp_timer.c --- 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 -urN linux-4.9.37/net/ipv6/calipso.c linux-4.9.y/net/ipv6/calipso.c --- 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 -urN linux-4.9.37/net/ipv6/output_core.c linux-4.9.y/net/ipv6/output_core.c --- 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 -urN linux-4.9.37/net/netlabel/netlabel_kapi.c linux-4.9.y/net/netlabel/netlabel_kapi.c --- 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 -urN linux-4.9.37/net/wireless/.gitignore linux-4.9.y/net/wireless/.gitignore --- linux-4.9.37/net/wireless/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/net/wireless/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -regdb.c diff -urN linux-4.9.37/samples/auxdisplay/.gitignore linux-4.9.y/samples/auxdisplay/.gitignore --- linux-4.9.37/samples/auxdisplay/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/auxdisplay/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -cfag12864b-example diff -urN linux-4.9.37/samples/connector/.gitignore linux-4.9.y/samples/connector/.gitignore --- linux-4.9.37/samples/connector/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/connector/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -ucon diff -urN linux-4.9.37/samples/hidraw/.gitignore linux-4.9.y/samples/hidraw/.gitignore --- linux-4.9.37/samples/hidraw/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/hidraw/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -hid-example diff -urN linux-4.9.37/samples/mei/.gitignore linux-4.9.y/samples/mei/.gitignore --- linux-4.9.37/samples/mei/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/mei/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -mei-amt-version diff -urN linux-4.9.37/samples/mic/mpssd/.gitignore linux-4.9.y/samples/mic/mpssd/.gitignore --- linux-4.9.37/samples/mic/mpssd/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/mic/mpssd/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -mpssd diff -urN linux-4.9.37/samples/seccomp/.gitignore linux-4.9.y/samples/seccomp/.gitignore --- linux-4.9.37/samples/seccomp/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/seccomp/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -bpf-direct -bpf-fancy -dropper diff -urN linux-4.9.37/samples/timers/.gitignore linux-4.9.y/samples/timers/.gitignore --- linux-4.9.37/samples/timers/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/timers/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -hpet_example diff -urN linux-4.9.37/samples/watchdog/.gitignore linux-4.9.y/samples/watchdog/.gitignore --- linux-4.9.37/samples/watchdog/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/samples/watchdog/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -watchdog-simple diff -urN linux-4.9.37/scripts/basic/.gitignore linux-4.9.y/scripts/basic/.gitignore --- linux-4.9.37/scripts/basic/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/basic/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -fixdep -bin2c diff -urN linux-4.9.37/scripts/dtc/.gitignore linux-4.9.y/scripts/dtc/.gitignore --- linux-4.9.37/scripts/dtc/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/dtc/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -dtc -dtc-lexer.lex.c -dtc-parser.tab.c -dtc-parser.tab.h diff -urN linux-4.9.37/scripts/gdb/linux/.gitignore linux-4.9.y/scripts/gdb/linux/.gitignore --- linux-4.9.37/scripts/gdb/linux/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/gdb/linux/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -*.pyc -*.pyo -constants.py diff -urN linux-4.9.37/scripts/genksyms/.gitignore linux-4.9.y/scripts/genksyms/.gitignore --- linux-4.9.37/scripts/genksyms/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/genksyms/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,5 +0,0 @@ -*.hash.c -*.lex.c -*.tab.c -*.tab.h -genksyms diff -urN linux-4.9.37/scripts/.gitignore linux-4.9.y/scripts/.gitignore --- linux-4.9.37/scripts/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,16 +0,0 @@ -# -# Generated files -# -conmakehash -kallsyms -pnmtologo -unifdef -ihex2fw -recordmcount -docproc -check-lc_ctype -sortextable -asn1_compiler -extract-cert -sign-file -insert-sys-cert diff -urN linux-4.9.37/scripts/kconfig/.gitignore linux-4.9.y/scripts/kconfig/.gitignore --- linux-4.9.37/scripts/kconfig/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/kconfig/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,22 +0,0 @@ -# -# Generated files -# -config* -*.lex.c -*.tab.c -*.tab.h -zconf.hash.c -*.moc -gconf.glade.h -*.pot -*.mo - -# -# configuration programs -# -conf -mconf -nconf -qconf -gconf -kxgettext diff -urN linux-4.9.37/scripts/kconfig/lxdialog/.gitignore linux-4.9.y/scripts/kconfig/lxdialog/.gitignore --- linux-4.9.37/scripts/kconfig/lxdialog/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/kconfig/lxdialog/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -# -# Generated files -# -lxdialog diff -urN linux-4.9.37/scripts/Makefile.clean linux-4.9.y/scripts/Makefile.clean --- 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 -urN linux-4.9.37/scripts/mod/.gitignore linux-4.9.y/scripts/mod/.gitignore --- linux-4.9.37/scripts/mod/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/mod/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -elfconfig.h -mk_elfconfig -modpost -devicetable-offsets.h diff -urN linux-4.9.37/scripts/selinux/genheaders/.gitignore linux-4.9.y/scripts/selinux/genheaders/.gitignore --- linux-4.9.37/scripts/selinux/genheaders/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/selinux/genheaders/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -genheaders diff -urN linux-4.9.37/scripts/selinux/mdp/.gitignore linux-4.9.y/scripts/selinux/mdp/.gitignore --- linux-4.9.37/scripts/selinux/mdp/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/scripts/selinux/mdp/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -# Generated file -mdp diff -urN linux-4.9.37/scripts/setlocalversion linux-4.9.y/scripts/setlocalversion --- 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 -urN linux-4.9.37/security/apparmor/.gitignore linux-4.9.y/security/apparmor/.gitignore --- linux-4.9.37/security/apparmor/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/security/apparmor/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,5 +0,0 @@ -# -# Generated include files -# -capability_names.h -rlim_names.h diff -urN linux-4.9.37/security/selinux/.gitignore linux-4.9.y/security/selinux/.gitignore --- linux-4.9.37/security/selinux/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/security/selinux/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -av_permissions.h -flask.h diff -urN linux-4.9.37/security/tomoyo/.gitignore linux-4.9.y/security/tomoyo/.gitignore --- linux-4.9.37/security/tomoyo/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/security/tomoyo/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -builtin-policy.h -policy/*.conf diff -urN linux-4.9.37/sound/oss/.gitignore linux-4.9.y/sound/oss/.gitignore --- linux-4.9.37/sound/oss/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/sound/oss/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -#Ignore generated files -pss_boot.h -trix_boot.h diff -urN linux-4.9.37/sound/usb/mixer.c linux-4.9.y/sound/usb/mixer.c --- 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 -urN linux-4.9.37/tools/accounting/.gitignore linux-4.9.y/tools/accounting/.gitignore --- linux-4.9.37/tools/accounting/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/accounting/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -getdelays diff -urN linux-4.9.37/tools/build/feature/.gitignore linux-4.9.y/tools/build/feature/.gitignore --- linux-4.9.37/tools/build/feature/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/build/feature/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -*.d -*.bin -*.output diff -urN linux-4.9.37/tools/build/.gitignore linux-4.9.y/tools/build/.gitignore --- linux-4.9.37/tools/build/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/build/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -fixdep diff -urN linux-4.9.37/tools/cgroup/.gitignore linux-4.9.y/tools/cgroup/.gitignore --- linux-4.9.37/tools/cgroup/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/cgroup/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -cgroup_event_listener diff -urN linux-4.9.37/tools/laptop/dslm/.gitignore linux-4.9.y/tools/laptop/dslm/.gitignore --- linux-4.9.37/tools/laptop/dslm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/laptop/dslm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -dslm diff -urN linux-4.9.37/tools/lguest/.gitignore linux-4.9.y/tools/lguest/.gitignore --- linux-4.9.37/tools/lguest/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/lguest/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -lguest -include diff -urN linux-4.9.37/tools/lib/bpf/.gitignore linux-4.9.y/tools/lib/bpf/.gitignore --- linux-4.9.37/tools/lib/bpf/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/lib/bpf/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -libbpf_version.h -FEATURE-DUMP.libbpf diff -urN linux-4.9.37/tools/lib/lockdep/.gitignore linux-4.9.y/tools/lib/lockdep/.gitignore --- linux-4.9.37/tools/lib/lockdep/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/lib/lockdep/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -liblockdep.so.* diff -urN linux-4.9.37/tools/lib/traceevent/.gitignore linux-4.9.y/tools/lib/traceevent/.gitignore --- linux-4.9.37/tools/lib/traceevent/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/lib/traceevent/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -TRACEEVENT-CFLAGS -libtraceevent-dynamic-list -libtraceevent.so.* diff -urN linux-4.9.37/tools/objtool/.gitignore linux-4.9.y/tools/objtool/.gitignore --- linux-4.9.37/tools/objtool/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/objtool/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -arch/x86/insn/inat-tables.c -objtool -fixdep diff -urN linux-4.9.37/tools/pcmcia/.gitignore linux-4.9.y/tools/pcmcia/.gitignore --- linux-4.9.37/tools/pcmcia/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/pcmcia/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -crc32hash diff -urN linux-4.9.37/tools/perf/.gitignore linux-4.9.y/tools/perf/.gitignore --- linux-4.9.37/tools/perf/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/perf/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,33 +0,0 @@ -PERF-CFLAGS -PERF-GUI-VARS -PERF-VERSION-FILE -FEATURE-DUMP -perf -perf-read-vdso32 -perf-read-vdsox32 -perf-help -perf-record -perf-report -perf-stat -perf-top -perf*.1 -perf*.xml -perf*.html -common-cmds.h -perf.data -perf.data.old -output.svg -perf-archive -perf-with-kcore -tags -TAGS -cscope* -config.mak -config.mak.autogen -*-bison.* -*-flex.* -*.pyc -*.pyo -.config-detected -util/intel-pt-decoder/inat-tables.c -arch/*/include/generated/ diff -urN linux-4.9.37/tools/perf/tests/.gitignore linux-4.9.y/tools/perf/tests/.gitignore --- linux-4.9.37/tools/perf/tests/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/perf/tests/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -llvm-src-base.c -llvm-src-kbuild.c -llvm-src-prologue.c -llvm-src-relocation.c diff -urN linux-4.9.37/tools/power/cpupower/.gitignore linux-4.9.y/tools/power/cpupower/.gitignore --- linux-4.9.37/tools/power/cpupower/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/power/cpupower/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,29 +0,0 @@ -.libs -libcpupower.so -libcpupower.so.0 -libcpupower.so.0.0.0 -build/ccdv -cpufreq-info -cpufreq-set -cpufreq-aperf -lib/.libs -lib/cpufreq.lo -lib/cpufreq.o -lib/proc.lo -lib/proc.o -lib/sysfs.lo -lib/sysfs.o -po/cpupowerutils.pot -po/*.gmo -utils/cpufreq-info.o -utils/cpufreq-set.o -utils/cpufreq-aperf.o -cpupower -bench/cpufreq-bench -debug/kernel/Module.symvers -debug/i386/centrino-decode -debug/i386/dump_psb -debug/i386/intel_gsic -debug/i386/powernow-k8-decode -debug/x86_64/centrino-decode -debug/x86_64/powernow-k8-decode diff -urN linux-4.9.37/tools/power/x86/turbostat/.gitignore linux-4.9.y/tools/power/x86/turbostat/.gitignore --- linux-4.9.37/tools/power/x86/turbostat/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/power/x86/turbostat/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -turbostat diff -urN linux-4.9.37/tools/spi/.gitignore linux-4.9.y/tools/spi/.gitignore --- linux-4.9.37/tools/spi/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/spi/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -spidev_fdx -spidev_test diff -urN linux-4.9.37/tools/testing/radix-tree/.gitignore linux-4.9.y/tools/testing/radix-tree/.gitignore --- linux-4.9.37/tools/testing/radix-tree/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/radix-tree/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -main -radix-tree.c diff -urN linux-4.9.37/tools/testing/selftests/breakpoints/.gitignore linux-4.9.y/tools/testing/selftests/breakpoints/.gitignore --- linux-4.9.37/tools/testing/selftests/breakpoints/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/breakpoints/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -breakpoint_test -step_after_suspend_test diff -urN linux-4.9.37/tools/testing/selftests/capabilities/.gitignore linux-4.9.y/tools/testing/selftests/capabilities/.gitignore --- linux-4.9.37/tools/testing/selftests/capabilities/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/capabilities/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -test_execve -validate_cap diff -urN linux-4.9.37/tools/testing/selftests/efivarfs/.gitignore linux-4.9.y/tools/testing/selftests/efivarfs/.gitignore --- linux-4.9.37/tools/testing/selftests/efivarfs/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/efivarfs/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -create-read -open-unlink diff -urN linux-4.9.37/tools/testing/selftests/exec/.gitignore linux-4.9.y/tools/testing/selftests/exec/.gitignore --- linux-4.9.37/tools/testing/selftests/exec/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/exec/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,9 +0,0 @@ -subdir* -script* -execveat -execveat.symlink -execveat.moved -execveat.path.ephemeral -execveat.ephemeral -execveat.denatured -xxxxxxxx* \ В конце файла нет новой строки diff -urN linux-4.9.37/tools/testing/selftests/filesystems/.gitignore linux-4.9.y/tools/testing/selftests/filesystems/.gitignore --- linux-4.9.37/tools/testing/selftests/filesystems/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/filesystems/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -dnotify_test diff -urN linux-4.9.37/tools/testing/selftests/futex/functional/.gitignore linux-4.9.y/tools/testing/selftests/futex/functional/.gitignore --- linux-4.9.37/tools/testing/selftests/futex/functional/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/futex/functional/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,7 +0,0 @@ -futex_requeue_pi -futex_requeue_pi_mismatched_ops -futex_requeue_pi_signal_restart -futex_wait_private_mapped_file -futex_wait_timeout -futex_wait_uninitialized_heap -futex_wait_wouldblock diff -urN linux-4.9.37/tools/testing/selftests/ia64/.gitignore linux-4.9.y/tools/testing/selftests/ia64/.gitignore --- linux-4.9.37/tools/testing/selftests/ia64/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/ia64/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -aliasing-test diff -urN linux-4.9.37/tools/testing/selftests/ipc/.gitignore linux-4.9.y/tools/testing/selftests/ipc/.gitignore --- linux-4.9.37/tools/testing/selftests/ipc/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/ipc/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -msgque_test diff -urN linux-4.9.37/tools/testing/selftests/kcmp/.gitignore linux-4.9.y/tools/testing/selftests/kcmp/.gitignore --- linux-4.9.37/tools/testing/selftests/kcmp/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/kcmp/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -kcmp_test -kcmp-test-file diff -urN linux-4.9.37/tools/testing/selftests/media_tests/.gitignore linux-4.9.y/tools/testing/selftests/media_tests/.gitignore --- linux-4.9.37/tools/testing/selftests/media_tests/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/media_tests/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -media_device_test -media_device_open -video_device_test diff -urN linux-4.9.37/tools/testing/selftests/membarrier/.gitignore linux-4.9.y/tools/testing/selftests/membarrier/.gitignore --- linux-4.9.37/tools/testing/selftests/membarrier/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/membarrier/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -membarrier_test diff -urN linux-4.9.37/tools/testing/selftests/memfd/.gitignore linux-4.9.y/tools/testing/selftests/memfd/.gitignore --- linux-4.9.37/tools/testing/selftests/memfd/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/memfd/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -fuse_mnt -fuse_test -memfd_test -memfd-test-file diff -urN linux-4.9.37/tools/testing/selftests/mount/.gitignore linux-4.9.y/tools/testing/selftests/mount/.gitignore --- linux-4.9.37/tools/testing/selftests/mount/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/mount/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -unprivileged-remount-test diff -urN linux-4.9.37/tools/testing/selftests/mqueue/.gitignore linux-4.9.y/tools/testing/selftests/mqueue/.gitignore --- linux-4.9.37/tools/testing/selftests/mqueue/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/mqueue/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -mq_open_tests -mq_perf_tests diff -urN linux-4.9.37/tools/testing/selftests/net/.gitignore linux-4.9.y/tools/testing/selftests/net/.gitignore --- linux-4.9.37/tools/testing/selftests/net/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/net/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -socket -psock_fanout -psock_tpacket -reuseport_bpf -reuseport_bpf_cpu -reuseport_dualstack diff -urN linux-4.9.37/tools/testing/selftests/networking/timestamping/.gitignore linux-4.9.y/tools/testing/selftests/networking/timestamping/.gitignore --- linux-4.9.37/tools/testing/selftests/networking/timestamping/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/networking/timestamping/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -timestamping -txtimestamp -hwtstamp_config diff -urN linux-4.9.37/tools/testing/selftests/powerpc/alignment/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/alignment/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/alignment/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/alignment/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,5 +0,0 @@ -copy_unaligned -copy_first_unaligned -paste_unaligned -paste_last_unaligned -copy_paste_unaligned_common diff -urN linux-4.9.37/tools/testing/selftests/powerpc/benchmarks/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/benchmarks/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/benchmarks/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/benchmarks/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -gettimeofday -context_switch -mmap_bench -futex_bench \ В конце файла нет новой строки diff -urN linux-4.9.37/tools/testing/selftests/powerpc/context_switch/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/context_switch/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/context_switch/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/context_switch/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -cp_abort diff -urN linux-4.9.37/tools/testing/selftests/powerpc/copyloops/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/copyloops/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/copyloops/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/copyloops/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -copyuser_64 -copyuser_power7 -memcpy_64 -memcpy_power7 diff -urN linux-4.9.37/tools/testing/selftests/powerpc/dscr/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/dscr/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/dscr/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/dscr/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,7 +0,0 @@ -dscr_default_test -dscr_explicit_test -dscr_inherit_exec_test -dscr_inherit_test -dscr_sysfs_test -dscr_sysfs_thread_test -dscr_user_test diff -urN linux-4.9.37/tools/testing/selftests/powerpc/math/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/math/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/math/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/math/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,7 +0,0 @@ -fpu_syscall -vmx_syscall -fpu_preempt -vmx_preempt -fpu_signal -vmx_signal -vsx_preempt diff -urN linux-4.9.37/tools/testing/selftests/powerpc/mm/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/mm/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/mm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/mm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,4 +0,0 @@ -hugetlb_vs_thp_test -subpage_prot -tempfile -prot_sao \ В конце файла нет новой строки diff -urN linux-4.9.37/tools/testing/selftests/powerpc/pmu/ebb/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/pmu/ebb/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/pmu/ebb/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/pmu/ebb/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,24 +0,0 @@ -reg_access_test -event_attributes_test -cycles_test -cycles_with_freeze_test -pmc56_overflow_test -ebb_vs_cpu_event_test -cpu_event_vs_ebb_test -cpu_event_pinned_vs_ebb_test -task_event_vs_ebb_test -task_event_pinned_vs_ebb_test -multi_ebb_procs_test -multi_counter_test -pmae_handling_test -close_clears_pmcc_test -instruction_count_test -fork_cleanup_test -ebb_on_child_test -ebb_on_willing_child_test -back_to_back_ebbs_test -lost_exception_test -no_handler_test -cycles_with_mmcr2_test -ebb_lmr -ebb_lmr_regs \ В конце файла нет новой строки diff -urN linux-4.9.37/tools/testing/selftests/powerpc/pmu/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/pmu/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/pmu/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/pmu/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -count_instructions -l3_bank_test -per_event_excludes diff -urN linux-4.9.37/tools/testing/selftests/powerpc/primitives/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/primitives/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/primitives/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/primitives/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -load_unaligned_zeropad diff -urN linux-4.9.37/tools/testing/selftests/powerpc/signal/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/signal/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/signal/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/signal/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -signal -signal_tm diff -urN linux-4.9.37/tools/testing/selftests/powerpc/stringloops/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/stringloops/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/stringloops/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/stringloops/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -memcmp diff -urN linux-4.9.37/tools/testing/selftests/powerpc/switch_endian/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/switch_endian/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/switch_endian/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/switch_endian/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -switch_endian_test -check-reversed.S diff -urN linux-4.9.37/tools/testing/selftests/powerpc/syscalls/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/syscalls/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/syscalls/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/syscalls/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -ipc_unmuxed diff -urN linux-4.9.37/tools/testing/selftests/powerpc/tm/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/tm/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/tm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/tm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,13 +0,0 @@ -tm-resched-dscr -tm-syscall -tm-signal-msr-resv -tm-signal-stack -tm-vmxcopy -tm-fork -tm-tar -tm-tmspr -tm-exec -tm-signal-context-chk-fpu -tm-signal-context-chk-gpr -tm-signal-context-chk-vmx -tm-signal-context-chk-vsx diff -urN linux-4.9.37/tools/testing/selftests/powerpc/vphn/.gitignore linux-4.9.y/tools/testing/selftests/powerpc/vphn/.gitignore --- linux-4.9.37/tools/testing/selftests/powerpc/vphn/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/powerpc/vphn/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -test-vphn diff -urN linux-4.9.37/tools/testing/selftests/prctl/.gitignore linux-4.9.y/tools/testing/selftests/prctl/.gitignore --- linux-4.9.37/tools/testing/selftests/prctl/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/prctl/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -disable-tsc-ctxt-sw-stress-test -disable-tsc-on-off-stress-test -disable-tsc-test diff -urN linux-4.9.37/tools/testing/selftests/ptp/.gitignore linux-4.9.y/tools/testing/selftests/ptp/.gitignore --- linux-4.9.37/tools/testing/selftests/ptp/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/ptp/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -testptp diff -urN linux-4.9.37/tools/testing/selftests/ptrace/.gitignore linux-4.9.y/tools/testing/selftests/ptrace/.gitignore --- linux-4.9.37/tools/testing/selftests/ptrace/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/ptrace/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -peeksiginfo diff -urN linux-4.9.37/tools/testing/selftests/rcutorture/.gitignore linux-4.9.y/tools/testing/selftests/rcutorture/.gitignore --- linux-4.9.37/tools/testing/selftests/rcutorture/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/rcutorture/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,6 +0,0 @@ -initrd -linux-2.6 -b[0-9]* -rcu-test-image -res -*.swp diff -urN linux-4.9.37/tools/testing/selftests/seccomp/.gitignore linux-4.9.y/tools/testing/selftests/seccomp/.gitignore --- linux-4.9.37/tools/testing/selftests/seccomp/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/seccomp/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -seccomp_bpf diff -urN linux-4.9.37/tools/testing/selftests/size/.gitignore linux-4.9.y/tools/testing/selftests/size/.gitignore --- linux-4.9.37/tools/testing/selftests/size/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/size/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -get_size diff -urN linux-4.9.37/tools/testing/selftests/timers/.gitignore linux-4.9.y/tools/testing/selftests/timers/.gitignore --- linux-4.9.37/tools/testing/selftests/timers/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/timers/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,19 +0,0 @@ -alarmtimer-suspend -change_skew -clocksource-switch -inconsistency-check -leap-a-day -leapcrash -mqueue-lat -nanosleep -nsleep-lat -posix_timers -raw_skew -rtctest -set-2038 -set-tai -set-timer-lat -skew_consistency -threadtest -valid-adjtimex -adjtick diff -urN linux-4.9.37/tools/testing/selftests/vDSO/.gitignore linux-4.9.y/tools/testing/selftests/vDSO/.gitignore --- linux-4.9.37/tools/testing/selftests/vDSO/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/vDSO/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -vdso_test -vdso_standalone_test_x86 diff -urN linux-4.9.37/tools/testing/selftests/vm/.gitignore linux-4.9.y/tools/testing/selftests/vm/.gitignore --- linux-4.9.37/tools/testing/selftests/vm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/vm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,10 +0,0 @@ -hugepage-mmap -hugepage-shm -map_hugetlb -thuge-gen -compaction_test -mlock2-tests -on-fault-limit -transhuge-stress -userfaultfd -mlock-intersect-test diff -urN linux-4.9.37/tools/testing/selftests/watchdog/.gitignore linux-4.9.y/tools/testing/selftests/watchdog/.gitignore --- linux-4.9.37/tools/testing/selftests/watchdog/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/watchdog/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -watchdog-test diff -urN linux-4.9.37/tools/testing/selftests/x86/.gitignore linux-4.9.y/tools/testing/selftests/x86/.gitignore --- linux-4.9.37/tools/testing/selftests/x86/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/testing/selftests/x86/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -*_32 -*_64 diff -urN linux-4.9.37/tools/thermal/tmon/.gitignore linux-4.9.y/tools/thermal/tmon/.gitignore --- linux-4.9.37/tools/thermal/tmon/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/thermal/tmon/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1 +0,0 @@ -/tmon diff -urN linux-4.9.37/tools/usb/usbip/.gitignore linux-4.9.y/tools/usb/usbip/.gitignore --- linux-4.9.37/tools/usb/usbip/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/usb/usbip/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,28 +0,0 @@ -Makefile -Makefile.in -aclocal.m4 -autom4te.cache/ -config.guess -config.h -config.h.in -config.log -config.status -config.sub -configure -depcomp -install-sh -libsrc/Makefile -libsrc/Makefile.in -libtool -ltmain.sh -missing -src/Makefile -src/Makefile.in -stamp-h1 -libsrc/libusbip.la -libsrc/libusbip_la-names.lo -libsrc/libusbip_la-usbip_common.lo -libsrc/libusbip_la-usbip_host_driver.lo -libsrc/libusbip_la-vhci_driver.lo -src/usbip -src/usbipd diff -urN linux-4.9.37/tools/virtio/.gitignore linux-4.9.y/tools/virtio/.gitignore --- linux-4.9.37/tools/virtio/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/virtio/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,3 +0,0 @@ -*.d -virtio_test -vringh_test diff -urN linux-4.9.37/tools/vm/.gitignore linux-4.9.y/tools/vm/.gitignore --- linux-4.9.37/tools/vm/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/tools/vm/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,2 +0,0 @@ -slabinfo -page-types diff -urN linux-4.9.37/usr/.gitignore linux-4.9.y/usr/.gitignore --- linux-4.9.37/usr/.gitignore 2017-07-12 16:42:41.000000000 +0300 +++ linux-4.9.y/usr/.gitignore 1970-01-01 03:00:00.000000000 +0300 @@ -1,10 +0,0 @@ -# -# Generated files -# -gen_init_cpio -initramfs_data.cpio -initramfs_data.cpio.gz -initramfs_data.cpio.bz2 -initramfs_data.cpio.lzma -initramfs_list -include