diff --git a/0001-yotco-add-hipico-image.patch b/0001-yotco-add-hipico-image.patch deleted file mode 100644 index 0bbc0b5a24f41df496ca03d23ff8fcf63e214ba4..0000000000000000000000000000000000000000 --- a/0001-yotco-add-hipico-image.patch +++ /dev/null @@ -1,77664 +0,0 @@ -From 725dd8adb09654dbf2aa8c5092f3f63333635ffd Mon Sep 17 00:00:00 2001 -From: weiyuchen -Date: Mon, 2 Sep 2024 16:23:15 +0800 -Subject: [PATCH] yotco: add hipico image - -1 add hipico config -2 add kernel patch -3 add hipico compilation code - -Signed-off-by: weiyuchen ---- - .oebuild/platform/hipico.yaml | 10 + - bsp/meta-hisilicon/conf/machine/hipico.conf | 26 + - .../recipes-core/images/bsp-hipico.inc | 4 + - .../recipes-core/images/hipico.inc | 23 + - .../images/image-early-config-hipico.inc | 8 + - .../recipes-core/images/image-hipico.inc | 16 + - .../config/hipico/hipico_debug_defconfig | 198 + - .../linux/files/dtbs/hipico.dts | 757 + - .../linux/files/its/linux_image.its | 38 + - ...01-hipico-kernel-510-patch-d8e3bcbbe.patch | 76427 ++++++++++++++++ - .../recipes-kernel/linux/linux-hipico.inc | 42 + - .../linux/linux-openeuler.bbappend | 2 +- - 12 files changed, 77550 insertions(+), 1 deletion(-) - create mode 100644 .oebuild/platform/hipico.yaml - create mode 100644 bsp/meta-hisilicon/conf/machine/hipico.conf - create mode 100644 bsp/meta-hisilicon/recipes-core/images/bsp-hipico.inc - create mode 100644 bsp/meta-hisilicon/recipes-core/images/hipico.inc - create mode 100644 bsp/meta-hisilicon/recipes-core/images/image-early-config-hipico.inc - create mode 100644 bsp/meta-hisilicon/recipes-core/images/image-hipico.inc - create mode 100644 bsp/meta-hisilicon/recipes-kernel/linux/files/config/hipico/hipico_debug_defconfig - create mode 100644 bsp/meta-hisilicon/recipes-kernel/linux/files/dtbs/hipico.dts - create mode 100644 bsp/meta-hisilicon/recipes-kernel/linux/files/its/linux_image.its - create mode 100644 bsp/meta-hisilicon/recipes-kernel/linux/files/patch/0001-hipico-kernel-510-patch-d8e3bcbbe.patch - create mode 100644 bsp/meta-hisilicon/recipes-kernel/linux/linux-hipico.inc - -diff --git a/.oebuild/platform/hipico.yaml b/.oebuild/platform/hipico.yaml -new file mode 100644 -index 00000000000..08e12be919d ---- /dev/null -+++ b/.oebuild/platform/hipico.yaml -@@ -0,0 +1,10 @@ -+type: platform -+ -+machine: hipico -+ -+toolchain_type: EXTERNAL_TOOLCHAIN:arm -+ -+layers: -+ - yocto-meta-openeuler/bsp/meta-hisilicon -+ - yocto-meta-openembedded/meta-multimedia -+ -diff --git a/bsp/meta-hisilicon/conf/machine/hipico.conf b/bsp/meta-hisilicon/conf/machine/hipico.conf -new file mode 100644 -index 00000000000..08044fd1276 ---- /dev/null -+++ b/bsp/meta-hisilicon/conf/machine/hipico.conf -@@ -0,0 +1,26 @@ -+require conf/machine/include/arm/arch-armv7a.inc -+ -+MACHINE_FEATURES += "pci" -+MACHINEOVERRIDES =. "hipico:march32le:" -+DEFAULTTUNE = "armv7a" -+ -+ROOTFS_PACKAGE_ARCH = "armv7l" -+ -+# set IMAGETYPE and dtb -+KERNEL_IMAGETYPE = "zImage" -+# choose dtb file -+KERNEL_DEVICETREE = "" -+ENABLE_UART = "1" -+# serial port enabled in hipico -+CMDLINE_SERIAL = "ttyAMA0,115200" -+SERIAL_CONSOLES = "115200;ttyAMA0" -+ -+# arm and arm64 both support -mlittle-endian so no -+# need to consider compat32. -+TUNE_CCARGS .= " -mno-unaligned-access" -+IMAGE_INSTALL:append = " kernel-modules" -+ -+# auto load module during startup -+KERNEL_MODULE_AUTOLOAD = "" -+USE_VT ?= "1" -+ -diff --git a/bsp/meta-hisilicon/recipes-core/images/bsp-hipico.inc b/bsp/meta-hisilicon/recipes-core/images/bsp-hipico.inc -new file mode 100644 -index 00000000000..0150b47d1c4 ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-core/images/bsp-hipico.inc -@@ -0,0 +1,4 @@ -+# add bsp depends here, should use for all images(tiny, standard, etc) -+ -+IMAGE_INSTALL:append = " \ -+" -diff --git a/bsp/meta-hisilicon/recipes-core/images/hipico.inc b/bsp/meta-hisilicon/recipes-core/images/hipico.inc -new file mode 100644 -index 00000000000..8d63841f8da ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-core/images/hipico.inc -@@ -0,0 +1,23 @@ -+delete_unneeded_from_rootfs() { -+ set -x -+ test -d "${OUTPUT_DIR}" || mkdir -p "${OUTPUT_DIR}" -+ rm -rf "${OUTPUT_DIR}"/* -+ cd "${IMAGE_ROOTFS}" -+ cp -r boot/* "${OUTPUT_DIR}" -+ # just need the boot dir, others in boot are not needed to reduce the size of image. -+ rm -rf ./boot/* -+ cd - -+ set +x -+} -+IMAGE_PREPROCESS_COMMAND += "delete_unneeded_from_rootfs;" -+ -+copy_pico_distro() { -+ set -x -+ for IMAGETYPE in ${IMAGE_FSTYPES} -+ do -+ rm -f "${OUTPUT_DIR}"/${IMAGE_NAME}${IMAGE_NAME_SUFFIX%.rootfs}.*${IMAGETYPE} -+ cp -fp ${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX%.rootfs}.*${IMAGETYPE} ${OUTPUT_DIR}/ -+ done -+ set +x -+} -+IMAGE_POSTPROCESS_COMMAND += "copy_pico_distro;" -diff --git a/bsp/meta-hisilicon/recipes-core/images/image-early-config-hipico.inc b/bsp/meta-hisilicon/recipes-core/images/image-early-config-hipico.inc -new file mode 100644 -index 00000000000..3dfbcda222c ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-core/images/image-early-config-hipico.inc -@@ -0,0 +1,8 @@ -+# This file should only be referenced by openeuler-image for customizing early configuration at the image level -+# ref: meta-openeuler/recipes-core/images/openeuler-image.bb: -+# line 0 | include recipes-core/images/image-early-config-${MACHINE}.inc -+# line 1 | require openeuler-image-common.inc -+ -+IMAGE_FSTYPES = "ext4 cpio.gz" -+IMAGE_FSTYPES:remove = "iso" -+IMAGE_FSTYPES_DEBUGFS = "cpio.gz" -diff --git a/bsp/meta-hisilicon/recipes-core/images/image-hipico.inc b/bsp/meta-hisilicon/recipes-core/images/image-hipico.inc -new file mode 100644 -index 00000000000..c34b41bd9da ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-core/images/image-hipico.inc -@@ -0,0 +1,16 @@ -+# This file should be included in openeuler-image.bbappend, openeuler-image-ros.bbappend, etc. -+# diff from ${MACHINE}.inc, it should not be included in live image -+ -+require recipes-core/images/bsp-${MACHINE}.inc -+ -+# all app and tools -+IMAGE_INSTALL += " \ -+" -+ -+ -+# 1. dsoftbus is not adpated to hieulerpi1 -+# 2. user-driver may provides libsecurec.so, -+# it conflicts with libboundscheck, especially in SDK -+# so, remove dsoftbus from IMAGE_INSTALL -+IMAGE_INSTALL:remove = " \ -+" -diff --git a/bsp/meta-hisilicon/recipes-kernel/linux/files/config/hipico/hipico_debug_defconfig b/bsp/meta-hisilicon/recipes-kernel/linux/files/config/hipico/hipico_debug_defconfig -new file mode 100644 -index 00000000000..7722ab9deea ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-kernel/linux/files/config/hipico/hipico_debug_defconfig -@@ -0,0 +1,198 @@ -+# CONFIG_LOCALVERSION_AUTO is not set -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_USELIB=y -+CONFIG_LOG_BUF_SHIFT=14 -+CONFIG_SYSFS_DEPRECATED=y -+CONFIG_RELAY=y -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SGETMASK_SYSCALL=y -+# CONFIG_FHANDLE is not set -+CONFIG_BPF_SYSCALL=y -+CONFIG_USERFAULTFD=y -+CONFIG_EMBEDDED=y -+# CONFIG_SLAB_MERGE_DEFAULT is not set -+CONFIG_ARCH_BSP=y -+CONFIG_ARCH_HI3516CV610=y -+# CONFIG_VDSO is not set -+# CONFIG_CACHE_L2X0 is not set -+CONFIG_SMP=y -+CONFIG_THUMB2_KERNEL=y -+# CONFIG_ARM_PATCH_IDIV is not set -+# CONFIG_CPU_SW_DOMAIN_PAN is not set -+# CONFIG_ARM_MODULE_PLTS is not set -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_VFP=y -+CONFIG_NEON=y -+# CONFIG_GCC_PLUGINS is not set -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_CMDLINE_PARTITION=y -+# CONFIG_MQ_IOSCHED_DEADLINE is not set -+# CONFIG_MQ_IOSCHED_KYBER is not set -+# CONFIG_ENABLE_IPREC_DEBUG is not set -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_IPV6 is not set -+CONFIG_NETFILTER=y -+# CONFIG_WIRELESS is not set -+# CONFIG_ETHTOOL_NETLINK is not set -+CONFIG_UEVENT_HELPER=y -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+# CONFIG_PREVENT_FIRMWARE_BUILD is not set -+CONFIG_FW_LOADER=m -+CONFIG_MTD=y -+CONFIG_MTD_CMDLINE_PARTS=y -+CONFIG_MTD_BLOCK2MTD=y -+CONFIG_MTD_SPI_NAND_BSP=y -+CONFIG_MTD_RAW_NAND=y -+CONFIG_MTD_SPI_NAND_FMC100=y -+CONFIG_MTD_SPI_NOR=y -+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -+CONFIG_SPI_BSP_SFC=y -+# CONFIG_CLOSE_SPI_8PIN_4IO is not set -+CONFIG_MTD_UBI=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=65536 -+CONFIG_SCSI=y -+CONFIG_BLK_DEV_SD=y -+CONFIG_NETDEVICES=y -+# CONFIG_NET_VENDOR_ALACRITECH is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_AQUANTIA is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_CADENCE is not set -+# CONFIG_NET_VENDOR_CAVIUM is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_NET_VENDOR_CORTINA is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_GOOGLE is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+# CONFIG_NET_VENDOR_HUAWEI is not set -+# CONFIG_NET_VENDOR_INTEL is not set -+CONFIG_VENDOR_FEMAC=y -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+# CONFIG_NET_VENDOR_MICROCHIP is not set -+# CONFIG_NET_VENDOR_MICROSEMI is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_NET_VENDOR_NI is not set -+# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -+CONFIG_MDIO_VENDOR_FEMAC=y -+CONFIG_USB_USBNET=y -+# CONFIG_USB_NET_NET1080 is not set -+CONFIG_USB_NET_RNDIS_HOST=y -+# CONFIG_USB_NET_CDC_SUBSET is not set -+# CONFIG_USB_NET_ZAURUS is not set -+# CONFIG_WLAN is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_SERIO is not set -+# CONFIG_LEGACY_PTYS is not set -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+# CONFIG_HW_RANDOM is not set -+CONFIG_I2C=y -+CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_BSP=y -+CONFIG_SPI=y -+CONFIG_SPI_PL022=y -+CONFIG_SPI_SPIDEV=y -+CONFIG_GPIOLIB=y -+CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_GENERIC_PLATFORM=y -+CONFIG_GPIO_PL061=y -+CONFIG_POWER_RESET_BSP=y -+# CONFIG_HWMON is not set -+CONFIG_MFD_BSP_FMC=y -+CONFIG_MFD_SYSCON=y -+# CONFIG_MEDIA_CEC_SUPPORT is not set -+CONFIG_MEDIA_SUPPORT=y -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=y -+# CONFIG_USB_GSPCA is not set -+# CONFIG_RADIO_ADAPTERS is not set -+CONFIG_SOUND=y -+CONFIG_SND=y -+# CONFIG_SND_ARM is not set -+CONFIG_HID_PID=y -+CONFIG_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_DWC3=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_CONFIGFS=y -+CONFIG_USB_CONFIGFS_ACM=y -+CONFIG_USB_CONFIGFS_RNDIS=y -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+CONFIG_USB_CONFIGFS_F_UAC1=y -+CONFIG_USB_CONFIGFS_F_UVC=y -+CONFIG_MPP_TO_GADGET_UVC=y -+CONFIG_MMC=y -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+# CONFIG_VIRTIO_MENU is not set -+# CONFIG_VHOST_MENU is not set -+# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -+# CONFIG_IOMMU_SUPPORT is not set -+CONFIG_PM_DEVFREQ=y -+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -+# CONFIG_NVMEM is not set -+CONFIG_USB_WING=y -+CONFIG_WING_UPS_PHY=y -+CONFIG_WING_UPS_XVP_PHY=y -+CONFIG_WING_UPS_MISSILE_PHY=y -+CONFIG_MMC_SDHCI_NEBULA=y -+# CONFIG_DNOTIFY is not set -+CONFIG_VFAT_FS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_JFFS2_FS=y -+CONFIG_UBIFS_FS=y -+CONFIG_CRAMFS=y -+CONFIG_SQUASHFS=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_CRYPTO_ECB=y -+CONFIG_CRYPTO_CMAC=y -+CONFIG_CRYPTO_SHA256=y -+CONFIG_CRYPTO_AES=y -+CONFIG_CRC_CCITT=y -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_PANIC_ON_OOPS=y -+CONFIG_DETECT_HUNG_TASK=y -+CONFIG_SCHEDSTATS=y -+CONFIG_STACKTRACE=y -+# CONFIG_RCU_TRACE is not set -+# CONFIG_FTRACE is not set -+CONFIG_DEBUG_USER=y -diff --git a/bsp/meta-hisilicon/recipes-kernel/linux/files/dtbs/hipico.dts b/bsp/meta-hisilicon/recipes-kernel/linux/files/dtbs/hipico.dts -new file mode 100644 -index 00000000000..95208242f8f ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-kernel/linux/files/dtbs/hipico.dts -@@ -0,0 +1,757 @@ -+/dts-v1/; -+ -+/ { -+ model = "Hisilicon Hi3516CV610 DEMO Board"; -+ compatible = "hisilicon,hi3516cv610"; -+ #address-cells = <0x01>; -+ #size-cells = <0x01>; -+ interrupt-parent = <0x01>; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x40000000 0xc0000000>; -+ }; -+ -+ chosen { -+ bootargs = [00]; -+ }; -+ -+ aliases { -+ serial0 = "/soc/amba/uart@11040000"; -+ serial1 = "/soc/amba/uart@11041000"; -+ serial2 = "/soc/amba/uart@11042000"; -+ i2c0 = "/soc/amba/i2c@11060000"; -+ i2c1 = "/soc/amba/i2c@11061000"; -+ i2c2 = "/soc/amba/i2c@11062000"; -+ spi0 = "/soc/amba/spi@11070000"; -+ spi1 = "/soc/amba/spi@11071000"; -+ gpio0 = "/soc/amba/gpio_chip@11090000"; -+ gpio1 = "/soc/amba/gpio_chip@11091000"; -+ gpio2 = "/soc/amba/gpio_chip@11092000"; -+ gpio3 = "/soc/amba/gpio_chip@11093000"; -+ gpio4 = "/soc/amba/gpio_chip@11094000"; -+ gpio5 = "/soc/amba/gpio_chip@11095000"; -+ gpio6 = "/soc/amba/gpio_chip@11096000"; -+ gpio7 = "/soc/amba/gpio_chip@11097000"; -+ gpio8 = "/soc/amba/gpio_chip@11098000"; -+ gpio9 = "/soc/amba/gpio_chip@11099000"; -+ gpio10 = "/soc/amba/gpio_chip@1109a000"; -+ }; -+ -+ cpus { -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ enable-method = "hisilicon,hi35xx"; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ clock-frequency = <0x02>; -+ reg = <0x00>; -+ }; -+ -+ cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ clock-frequency = <0x02>; -+ reg = <0x01>; -+ }; -+ }; -+ -+ clock0 { -+ compatible = "vendor,hi3516cv610_clock\0syscon"; -+ #clock-cells = <0x01>; -+ #reset-cells = <0x02>; -+ #address-cells = <0x01>; -+ #size-cells = <0x01>; -+ reg = <0x11010000 0x5000>; -+ phandle = <0x02>; -+ }; -+ -+ interrupt-controller@12400000 { -+ compatible = "arm,cortex-a7-gic"; -+ #interrupt-cells = <0x03>; -+ #address-cells = <0x00>; -+ interrupt-controller; -+ reg = <0x12401000 0x1000 0x12402000 0x2000>; -+ phandle = <0x01>; -+ }; -+ -+ syscounter { -+ compatible = "arm,armv7-timer"; -+ interrupts = <0x01 0x0d 0xf08 0x01 0x0e 0xf08>; -+ clock-frequency = <0x16e3600>; -+ always-on; -+ }; -+ -+ soc { -+ #address-cells = <0x01>; -+ #size-cells = <0x01>; -+ compatible = "simple-bus"; -+ ranges; -+ -+ pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = <0x00 0x58 0x04 0x00 0x5b 0x04>; -+ }; -+ -+ edma-controller@10280000 { -+ compatible = "vendor,edmacv310"; -+ reg = <0x10280000 0x1000>; -+ interrupts = <0x00 0x27 0x04>; -+ clocks = <0x02 0x45 0x02 0x44>; -+ clock-names = "apb_pclk\0axi_aclk"; -+ clock-cells = <0x02>; -+ resets = <0x02 0x2a80 0x00>; -+ reset-names = "dma-reset"; -+ dma-requests = <0x20>; -+ dma-channels = <0x04>; -+ devid = <0x00>; -+ #dma-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ edma_n-controller@10280000 { -+ compatible = "vendor,edmacv310_n"; -+ reg = <0x10280000 0x1000>; -+ interrupts = <0x00 0x27 0x04>; -+ clocks = <0x02 0x45 0x02 0x44>; -+ clock-names = "apb_pclk\0axi_aclk"; -+ clock-cells = <0x02>; -+ resets = <0x02 0x2a80 0x00>; -+ reset-names = "dma-reset"; -+ dma-requests = <0x20>; -+ dma-channels = <0x04>; -+ devid = <0x00>; -+ #dma-cells = <0x02>; -+ status = "disabled"; -+ }; -+ -+ flash-memory-controller@10000000 { -+ compatible = "vendor,fmc"; -+ reg = <0x10000000 0x1000 0xf000000 0x1000000>; -+ reg-names = "control\0memory"; -+ clocks = <0x02 0x42>; -+ max-dma-size = <0x2000>; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ -+ spi_nor_controller { -+ compatible = "vendor,fmc-spi-nor"; -+ assigned-clocks = <0x02 0x42>; -+ assigned-clock-rates = <0x16e3600>; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ -+ sfc@0 { -+ compatible = "jedec,spi-nor"; -+ reg = <0x00>; -+ spi-max-frequency = <0xbebc200>; -+ }; -+ }; -+ -+ spi_nand_controller { -+ compatible = "vendor,fmc-spi-nand"; -+ assigned-clocks = <0x02 0x42>; -+ assigned-clock-rates = <0x16e3600>; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ -+ nand@0 { -+ compatible = "jedec,spi-nand"; -+ reg = <0x00>; -+ spi-max-frequency = <0xbebc200>; -+ }; -+ }; -+ }; -+ -+ mdio@10291100 { -+ compatible = "vendor,femac-mdio"; -+ reg = <0x10291100 0x20 0x17950104 0x10 0x101e0114 0x04>; -+ clocks = <0x02 0x43 0x02 0x56>; -+ clock-names = "mdio\0phy"; -+ resets = <0x02 0x37cc 0x03>; -+ reset-names = "internal-phy"; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ phy-reset-delays-us = <0x2710 0x4e20 0x249f0>; -+ status = "disabled"; -+ -+ ethernet-phy@1 { -+ phandle = <0x03>; -+ }; -+ }; -+ -+ ethernet@10290000 { -+ compatible = "vendor,femac-v2"; -+ reg = <0x10290000 0x1000 0x10291300 0x200>; -+ interrupts = <0x00 0x2c 0x04>; -+ clocks = <0x02 0x43>; -+ resets = <0x02 0x37cc 0x00 0x02 0x37cc 0x03>; -+ reset-names = "mac\0phy"; -+ mac-address = [00 00 00 00 00 00]; -+ phy-mode = "mii"; -+ phy-handle = <0x03>; -+ status = "disabled"; -+ }; -+ -+ hlethernet@10290000 { -+ compatible = "vendor,femac-v2"; -+ reg = <0x10290000 0x10000 0x17950104 0x04 0x101e0114 0x04>; -+ reg-names = "glb_base\0fephy_sysctrl0\0fephy_trim0"; -+ interrupts = <0x00 0x2c 0x04>; -+ clocks = <0x02 0x43 0x02 0x56>; -+ clock-names = "hleth_clk\0phy_clk0"; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ phy-handle = <0x04>; -+ resets = <0x02 0x37cc 0x00 0x02 0x37cc 0x03>; -+ reset-names = "mac_reset\0reset_phy0"; -+ -+ ethernet-phy-up@0 { -+ reg = <0x00>; -+ internal-phy; -+ phyaddr-bit-offset = <0x00>; -+ mac-address = [00 00 00 00 00 00]; -+ phy-mode = "mii"; -+ phy-gpio-base = <0x00>; -+ phy-gpio-bit = <0x00>; -+ phandle = <0x04>; -+ }; -+ }; -+ -+ system-controller@11020000 { -+ compatible = "vendor,sysctrl"; -+ reg = <0x11020000 0x4000>; -+ reboot-offset = <0x04>; -+ #clock-cells = <0x01>; -+ }; -+ -+ amba { -+ #address-cells = <0x01>; -+ #size-cells = <0x01>; -+ compatible = "arm,amba-bus"; -+ ranges; -+ -+ uart@11040000 { -+ compatible = "arm,pl011\0arm,primecell"; -+ reg = <0x11040000 0x1000>; -+ interrupts = <0x00 0x0a 0x04>; -+ clocks = <0x02 0x3f>; -+ clock-names = "apb_pclk"; -+ resets = <0x02 0x4180 0x00>; -+ reset-names = "bsp_uart_rst"; -+ status = "okay"; -+ }; -+ -+ uart@11041000 { -+ compatible = "arm,pl011\0arm,primecell"; -+ reg = <0x11041000 0x1000>; -+ interrupts = <0x00 0x0b 0x04>; -+ clocks = <0x02 0x40>; -+ clock-names = "apb_pclk"; -+ resets = <0x02 0x4188 0x00>; -+ reset-names = "bsp_uart_rst"; -+ status = "okay"; -+ }; -+ -+ uart@11042000 { -+ compatible = "arm,pl011\0arm,primecell"; -+ reg = <0x11042000 0x1000>; -+ interrupts = <0x00 0x0c 0x04>; -+ clocks = <0x02 0x41>; -+ clock-names = "apb_pclk"; -+ resets = <0x02 0x4190 0x00>; -+ reset-names = "bsp_uart_rst"; -+ status = "okay"; -+ }; -+ -+ i2c@11060000 { -+ compatible = "vendor,i2c"; -+ reg = <0x11060000 0x1000>; -+ clocks = <0x02 0x4b>; -+ clock-frequency = <0x61a80>; -+ resets = <0x02 0x4280 0x00>; -+ reset-names = "i2c_reset"; -+ status = "okay"; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ }; -+ -+ i2c@11061000 { -+ compatible = "vendor,i2c"; -+ reg = <0x11061000 0x1000>; -+ clocks = <0x02 0x4c>; -+ clock-frequency = <0x61a80>; -+ resets = <0x02 0x4288 0x00>; -+ reset-names = "i2c_reset"; -+ status = "okay"; -+ }; -+ -+ i2c@11062000 { -+ compatible = "vendor,i2c"; -+ reg = <0x11062000 0x1000>; -+ clocks = <0x02 0x4d>; -+ clock-frequency = <0x61a80>; -+ resets = <0x02 0x4290 0x00>; -+ reset-names = "i2c_reset"; -+ status = "okay"; -+ }; -+ -+ spi@11070000 { -+ compatible = "arm,pl022\0arm,primecell"; -+ arm,primecell-periphid = <0x800022>; -+ reg = <0x11070000 0x1000 0x1795000c 0x04>; -+ interrupts = <0x00 0x13 0x04>; -+ clocks = <0x02 0x46>; -+ clock-names = "apb_pclk"; -+ resets = <0x02 0x4480 0x00>; -+ reset-names = "bsp_spi_rst"; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ vendor,slave_mode = <0x00>; -+ vendor,slave_tx_disable = <0x00>; -+ num-cs = <0x02>; -+ spi_cs_sb = <0x02>; -+ spi_cs_mask_bit = <0x04>; -+ status = "okay"; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0x00>; -+ pl022,interface = <0x00>; -+ pl022,com-mode = <0x00>; -+ spi-max-frequency = <0x17d7840>; -+ }; -+ -+ spidev@1 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0x01>; -+ pl022,interface = <0x00>; -+ pl022,com-mode = <0x00>; -+ spi-max-frequency = <0x17d7840>; -+ }; -+ }; -+ -+ spi@11071000 { -+ compatible = "arm,pl022\0arm,primecell"; -+ arm,primecell-periphid = <0x800022>; -+ reg = <0x11071000 0x1000>; -+ interrupts = <0x00 0x14 0x04>; -+ clocks = <0x02 0x47>; -+ clock-names = "apb_pclk"; -+ resets = <0x02 0x4488 0x00>; -+ reset-names = "bsp_spi_rst"; -+ #address-cells = <0x01>; -+ #size-cells = <0x00>; -+ vendor,slave_mode = <0x00>; -+ vendor,slave_tx_disable = <0x00>; -+ num-cs = <0x01>; -+ status = "okay"; -+ -+ spidev@0 { -+ compatible = "rohm,dh2228fv"; -+ reg = <0x00>; -+ pl022,interface = <0x00>; -+ pl022,com-mode = <0x00>; -+ spi-max-frequency = <0x17d7840>; -+ }; -+ }; -+ -+ ioconfig0@10260000 { -+ compatible = "vendor,ioconfig\0syscon"; -+ reg = <0x10260000 0x10000>; -+ phandle = <0x05>; -+ }; -+ -+ ioconfig1@11130000 { -+ compatible = "vendor,ioconfig\0syscon"; -+ reg = <0x11130000 0x10000>; -+ phandle = <0x06>; -+ }; -+ -+ eMMC@0x10030000 { -+ compatible = "nebula,sdhci"; -+ reg = <0x10030000 0x1000>; -+ interrupts = <0x00 0x2a 0x04>; -+ clocks = <0x02 0x48 0x02 0x54>; -+ clock-names = "mmc_clk\0mmc_hclk"; -+ resets = <0x02 0x35c0 0x10 0x02 0x35c0 0x11 0x02 0x35c0 0x12 0x02 0x35c4 0x01>; -+ reset-names = "crg_reset\0crg_tx\0crg_rx\0dll_reset"; -+ max-frequency = <0x8f0d180>; -+ crg_regmap = <0x02>; -+ non-removable; -+ iocfg_regmap = <0x05>; -+ bus-width = <0x08>; -+ cap-mmc-highspeed; -+ mmc-hs200-1_8v; -+ mmc-hs400-1_8v; -+ cap-mmc-hw-reset; -+ no-sdio; -+ no-sd; -+ devid = <0x00>; -+ status = "disabled"; -+ }; -+ -+ SDIO@0x10030000 { -+ compatible = "nebula,sdhci"; -+ reg = <0x10030000 0x1000>; -+ interrupts = <0x00 0x2a 0x04>; -+ clocks = <0x02 0x48 0x02 0x54>; -+ clock-names = "mmc_clk\0mmc_hclk"; -+ resets = <0x02 0x35c0 0x10 0x02 0x35c0 0x11 0x02 0x35c0 0x12 0x02 0x35c4 0x01>; -+ reset-names = "crg_reset\0crg_tx\0crg_rx\0dll_reset"; -+ max-frequency = <0x2faf080>; -+ crg_regmap = <0x02>; -+ iocfg_regmap = <0x05>; -+ bus-width = <0x04>; -+ cap-sd-highspeed; -+ full-pwr-cycle; -+ disable-wp; -+ no-mmc; -+ devid = <0x01>; -+ status = "okay"; -+ }; -+ -+ SDIO1@0x10040000 { -+ compatible = "nebula,sdhci"; -+ reg = <0x10040000 0x1000>; -+ interrupts = <0x00 0x2b 0x04>; -+ clocks = <0x02 0x49 0x02 0x55>; -+ clock-names = "mmc_clk\0mmc_hclk"; -+ resets = <0x02 0x36c0 0x10 0x02 0x36c0 0x11 0x02 0x36c0 0x12 0x02 0x36c4 0x01>; -+ reset-names = "crg_reset\0crg_tx\0crg_rx\0dll_reset"; -+ max-frequency = <0x2faf080>; -+ crg_regmap = <0x02>; -+ iocfg_regmap = <0x06>; -+ bus-width = <0x04>; -+ cap-sd-highspeed; -+ full-pwr-cycle; -+ disable-wp; -+ no-mmc; -+ devid = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11090000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11090000 0x1000>; -+ interrupts = <0x00 0x17 0x04>; -+ clocks = <0x02 0x57>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11091000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11091000 0x1000>; -+ interrupts = <0x00 0x18 0x04>; -+ clocks = <0x02 0x58>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11092000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11092000 0x1000>; -+ interrupts = <0x00 0x19 0x04>; -+ clocks = <0x02 0x59>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11093000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11093000 0x1000>; -+ interrupts = <0x00 0x1a 0x04>; -+ clocks = <0x02 0x5a>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11094000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11094000 0x1000>; -+ interrupts = <0x00 0x1b 0x04>; -+ clocks = <0x02 0x5b>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11095000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11095000 0x1000>; -+ interrupts = <0x00 0x1c 0x04>; -+ clocks = <0x02 0x5c>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11096000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11096000 0x1000>; -+ interrupts = <0x00 0x1d 0x04>; -+ clocks = <0x02 0x5d>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11097000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11097000 0x1000>; -+ interrupts = <0x00 0x1e 0x04>; -+ clocks = <0x02 0x5e>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11098000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11098000 0x1000>; -+ interrupts = <0x00 0x1f 0x04>; -+ clocks = <0x02 0x5f>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@11099000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x11099000 0x1000>; -+ interrupts = <0x00 0x20 0x04>; -+ clocks = <0x02 0x60>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ gpio_chip@1109a000 { -+ compatible = "arm,pl061\0arm,primecell"; -+ reg = <0x1109a000 0x1000>; -+ interrupts = <0x00 0x21 0x04>; -+ clocks = <0x02 0x61>; -+ clock-names = "apb_pclk"; -+ #gpio-cells = <0x02>; -+ status = "okay"; -+ }; -+ -+ rtc@11110000 { -+ compatible = "vendor,rtc"; -+ reg = <0x11110000 0x10000>; -+ interrupts = <0x00 0x25 0x04>; -+ status = "disabled"; -+ }; -+ -+ adc@11100000 { -+ compatible = "vendor,lsadc"; -+ reg = <0x11100000 0x1000>; -+ interrupts = <0x00 0x24 0x04>; -+ interrupt-names = "adc"; -+ resets = <0x02 0x46c0 0x00>; -+ reset-names = "lsadc-crg"; -+ status = "okay"; -+ }; -+ -+ wdg@0x11030000 { -+ compatible = "vendor,wdg"; -+ reg = <0x11030000 0x1000>; -+ reg-names = "wdg"; -+ interrupts = <0x00 0x03 0x04>; -+ interrupt-names = "wdg"; -+ }; -+ }; -+ }; -+ -+ media { -+ #address-cells = <0x01>; -+ #size-cells = <0x01>; -+ compatible = "simple-bus"; -+ interrupt-parent = <0x01>; -+ ranges; -+ -+ sys@11010000 { -+ compatible = "vendor,sys"; -+ reg = <0x11015000 0xb000 0x11020000 0x4000 0x11140000 0x20000 0x11024000 0x5000 0x10270000 0x1000>; -+ reg-names = "crg\0sys\0ddr\0misc\0ahb_misc"; -+ }; -+ -+ vi@0x17400000 { -+ compatible = "vendor,vi"; -+ reg = <0x17400000 0x100000 0x17800000 0x40000>; -+ reg-names = "vi_cap0\0vi_proc0"; -+ interrupts = <0x00 0x41 0x04 0x00 0x42 0x04 0x00 0x43 0x04>; -+ interrupt-names = "vi_cap0\0vi_cap1\0vi_proc0"; -+ }; -+ -+ mipi_rx@0x173c0000 { -+ compatible = "vendor,mipi_rx"; -+ reg = <0x173c0000 0x10000>; -+ reg-names = "mipi_rx"; -+ interrupts = <0x00 0x40 0x04>; -+ interrupt-names = "mipi_rx"; -+ }; -+ -+ vpss@0x17900000 { -+ compatible = "vendor,vpss"; -+ reg = <0x17900000 0x10000>; -+ reg-names = "vpss0"; -+ interrupts = <0x00 0x47 0x04>; -+ interrupt-names = "vpss0"; -+ }; -+ -+ vgs@0x17240000 { -+ compatible = "vendor,vgs"; -+ reg = <0x17240000 0x10000>; -+ reg-names = "vgs0"; -+ interrupts = <0x00 0x48 0x04>; -+ interrupt-names = "vgs0"; -+ }; -+ -+ venc@0x17140000 { -+ compatible = "vendor,venc"; -+ reg = <0x17140000 0x10000 0x171c0000 0x10000>; -+ reg-names = "vedu0\0jpge"; -+ interrupts = <0x00 0x45 0x04 0x00 0x46 0x04>; -+ interrupt-names = "vedu0\0jpge"; -+ }; -+ -+ aiao@17c00000 { -+ compatible = "vendor,aiao"; -+ reg = <0x17c00000 0x10000 0x17c40000 0x10000>; -+ reg-names = "aiao\0acodec"; -+ interrupts = <0x00 0x3f 0x04>; -+ interrupt-names = "AIO"; -+ }; -+ -+ cipher@0x101F0000 { -+ compatible = "vendor,cipher"; -+ reg = <0x101f0000 0x10000 0x101ec000 0x2000>; -+ reg-names = "spacc\0pke"; -+ interrupts = <0x00 0x32 0x04 0x00 0x33 0x04 0x00 0x34 0x04 0x00 0x35 0x04>; -+ interrupt-names = "spacc_tee\0spacc_ree\0pke_tee\0pke_ree"; -+ }; -+ -+ km@0x101EA000 { -+ compatible = "vendor,km"; -+ reg = <0x101ea000 0x2000>; -+ reg-names = "km"; -+ interrupts = <0x00 0x36 0x04 0x00 0x37 0x04 0x00 0x38 0x04 0x00 0x39 0x04>; -+ interrupt-names = "rkp_tee\0rkp_ree\0klad_tee\0klad_ree"; -+ }; -+ -+ otp@0x101E0000 { -+ compatible = "vendor,otp"; -+ reg = <0x101e0000 0x2000>; -+ reg-names = "otp"; -+ }; -+ -+ trng@0x101EE000 { -+ compatible = "vendor,trng"; -+ reg = <0x101ee000 0x1000>; -+ reg-names = "trng"; -+ }; -+ }; -+ -+ firmware { -+ -+ optee { -+ compatible = "linaro,optee-tz"; -+ method = "smc"; -+ }; -+ }; -+ -+ npu@0x14000000 { -+ compatible = "vendor,svp_npu"; -+ reg = <0x14000000 0x800000>; -+ reg-names = "svp_npu"; -+ interrupts = <0x00 0x4b 0x04>; -+ interrupt-names = "svp_npu_ns0"; -+ }; -+ -+ ive@0x14000000 { -+ compatible = "vendor,ive"; -+ reg = <0x14000000 0x800000>; -+ reg-names = "ive"; -+ interrupts = <0x00 0x4c 0x04>; -+ interrupt-names = "ive0"; -+ }; -+ -+ pwm@0x11080000 { -+ compatible = "vendor,pwm"; -+ reg = <0x11080000 0x1000>; -+ reg-names = "pwm1"; -+ clocks = <0x02 0x64>; -+ clock-names = "pwm1"; -+ resets = <0x02 0x4598 0x00>; -+ reset-names = "pwm1"; -+ status = "okay"; -+ }; -+ -+ ups_clock { -+ compatible = "basedrv-ip,clock"; -+ reg = <0x11010000 0x10000 0x11024000 0x5000>; -+ reg-names = "peri_crg\0peri_ctrl"; -+ #clock-cells = <0x01>; -+ #reset-cells = <0x02>; -+ #address-cells = <0x01>; -+ #size-cells = <0x01>; -+ status = "okay"; -+ phandle = <0x07>; -+ }; -+ -+ usb2phy@0x10310000 { -+ compatible = "usb2phy,xvpphy"; -+ reg = <0x10310000 0x1000 0x11024000 0x5000 0x101e0110 0x04>; -+ reg-names = "u2_phy\0peri_ctrl\0otp_trim"; -+ otp-phy-trim-bitshift = <0x15>; -+ clocks = <0x07 0x08>; -+ clock-names = "phy-clk"; -+ #phy-cells = <0x00>; -+ u2phy-trim = <0xa33c82b 0x50f0f>; -+ status = "okay"; -+ phandle = <0x08>; -+ }; -+ -+ usb20drd@0x10300000 { -+ compatible = "wing-usb,drd"; -+ reg = <0x10300000 0x10000>; -+ reg-names = "u2_ctrl"; -+ controller_id = <0x00>; -+ support-drd; -+ is-usb2; -+ filter-se0-fsls; -+ phys = <0x08>; -+ phy-names = "usb2-phy"; -+ clocks = <0x07 0x00>; -+ clock-names = "ctrl-clk"; -+ #clock-cells = <0x01>; -+ init_mode = "device"; -+ status = "okay"; -+ ranges; -+ #address-cells = <0x01>; -+ #size-cells = <0x01>; -+ phandle = <0x09>; -+ -+ dwc3@10300000 { -+ compatible = "snps,dwc3"; -+ reg = <0x10300000 0x10000>; -+ interrupts = <0x00 0x30 0x04>; -+ interrupt-names = "peripheral"; -+ maximum-speed = "high-speed"; -+ dr_mode = "otg"; -+ usb-role-switch; -+ snps,dis_u2_susphy_quirk; -+ snps,usb2-lpm-disable; -+ linux,sysdev_is_parent; -+ extcon = <0x09>; -+ }; -+ }; -+}; -diff --git a/bsp/meta-hisilicon/recipes-kernel/linux/files/its/linux_image.its b/bsp/meta-hisilicon/recipes-kernel/linux/files/its/linux_image.its -new file mode 100644 -index 00000000000..990d205ffaa ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-kernel/linux/files/its/linux_image.its -@@ -0,0 +1,38 @@ -+/dts-v1/; -+ -+/ { -+ description = "Linux Kernel"; -+ #address-cells = <1>; -+ -+ images { -+ fdt-1 { -+ description = "dtb"; -+ data = /incbin/("./devicetree.dtb"); -+ type = "flat_dt"; -+ arch = "arm"; -+ compression = "none"; -+ load = <0x40000000>; -+ }; -+ -+ linux_kernel { -+ description = "Linux"; -+ data = /incbin/("./zImage"); -+ type = "kernel"; -+ arch = "arm"; -+ os = "Linux"; -+ compression = "none"; -+ load = <0x40018000>; -+ entry = <0x40018000>; -+ }; -+ }; -+ -+ configurations { -+ default = "config-1"; -+ config-1 { -+ description = "Linux"; -+ kernel = "linux_kernel"; -+ fdt = "fdt-1"; -+ loadables = "linux_kernel", "fdt-1"; -+ }; -+ }; -+}; -diff --git a/bsp/meta-hisilicon/recipes-kernel/linux/files/patch/0001-hipico-kernel-510-patch-d8e3bcbbe.patch b/bsp/meta-hisilicon/recipes-kernel/linux/files/patch/0001-hipico-kernel-510-patch-d8e3bcbbe.patch -new file mode 100644 -index 00000000000..1b82b2d78c0 ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-kernel/linux/files/patch/0001-hipico-kernel-510-patch-d8e3bcbbe.patch -@@ -0,0 +1,76427 @@ -+From ac2d028bb050bd2a0c5dc35e4e57ba543cd56e0b Mon Sep 17 00:00:00 2001 -+From: wgm2022 <1480559020@qq.com> -+Date: Tue, 20 Aug 2024 17:01:55 +0800 -+Subject: [PATCH] test -+ -+--- -+ Makefile | 36 +- -+ arch/Kconfig | 8 + -+ arch/arm/Kconfig | 11 + -+ arch/arm/Kconfig.debug | 10 + -+ arch/arm/Makefile | 1 + -+ arch/arm/boot/Makefile | 4 +- -+ arch/arm/boot/compressed/head.S | 12 + -+ arch/arm/boot/dts/Makefile | 11 + -+ arch/arm/boot/dts/hi3516cv608-demb-emmc.dts | 12 + -+ arch/arm/boot/dts/hi3516cv608-demb-flash.dts | 12 + -+ arch/arm/boot/dts/hi3516cv608-demb.dts | 177 ++ -+ arch/arm/boot/dts/hi3516cv608.dtsi | 683 +++++ -+ arch/arm/boot/dts/hi3516cv608_family_usb.dtsi | 59 + -+ arch/arm/boot/dts/hi3516cv610-demb-emmc.dts | 12 + -+ arch/arm/boot/dts/hi3516cv610-demb-flash.dts | 12 + -+ arch/arm/boot/dts/hi3516cv610-demb.dts | 177 ++ -+ arch/arm/boot/dts/hi3516cv610.dtsi | 683 +++++ -+ arch/arm/boot/dts/hi3516cv610_family_usb.dtsi | 59 + -+ arch/arm/configs/hi3516cv608_debug_defconfig | 188 ++ -+ arch/arm/configs/hi3516cv608_defconfig | 190 ++ -+ .../configs/hi3516cv608_emmc_debug_defconfig | 175 ++ -+ arch/arm/configs/hi3516cv608_emmc_defconfig | 177 ++ -+ .../configs/hi3516cv608_nand_mini_defconfig | 132 + -+ .../configs/hi3516cv608_nor_mini_defconfig | 129 + -+ .../hi3516cv608_nor_quickboot_defconfig | 115 + -+ arch/arm/configs/hi3516cv610_debug_defconfig | 198 ++ -+ arch/arm/configs/hi3516cv610_defconfig | 198 ++ -+ .../configs/hi3516cv610_emmc_debug_defconfig | 184 ++ -+ arch/arm/configs/hi3516cv610_emmc_defconfig | 186 ++ -+ .../configs/hi3516cv610_nand_mini_defconfig | 132 + -+ .../configs/hi3516cv610_nor_mini_defconfig | 129 + -+ .../hi3516cv610_nor_quickboot_defconfig | 115 + -+ arch/arm/mach-vendor/Kconfig | 59 + -+ arch/arm/mach-vendor/Makefile | 3 + -+ arch/arm/mach-vendor/Makefile.boot | 3 + -+ arch/arm/mach-vendor/mach_common.h | 29 + -+ arch/arm/mach-vendor/mach_hi3516cv610.c | 85 + -+ arch/arm/mach-vendor/platsmp.c | 62 + -+ arch/arm64/Kconfig | 21 + -+ arch/arm64/Kconfig.platforms | 54 + -+ arch/arm64/Makefile | 5 + -+ arch/arm64/boot/Makefile | 29 + -+ arch/arm64/boot/dts/Makefile | 7 + -+ arch/arm64/boot/dts/vendor/Makefile | 5 + -+ .../dts/vendor/hi3516dv500-demb-emmc-tee.dts | 9 + -+ .../boot/dts/vendor/hi3516dv500-demb-emmc.dts | 9 + -+ .../dts/vendor/hi3516dv500-demb-flash-tee.dts | 9 + -+ .../dts/vendor/hi3516dv500-demb-flash.dts | 9 + -+ .../boot/dts/vendor/hi3516dv500-demb-tee.dts | 326 +++ -+ .../boot/dts/vendor/hi3516dv500-demb.dts | 315 +++ -+ arch/arm64/boot/dts/vendor/hi3516dv500.dtsi | 859 ++++++ -+ .../dts/vendor/hi3519dv500-demb-emmc-tee.dts | 9 + -+ .../boot/dts/vendor/hi3519dv500-demb-emmc.dts | 9 + -+ .../dts/vendor/hi3519dv500-demb-flash-tee.dts | 9 + -+ .../dts/vendor/hi3519dv500-demb-flash.dts | 9 + -+ .../boot/dts/vendor/hi3519dv500-demb-tee.dts | 326 +++ -+ .../boot/dts/vendor/hi3519dv500-demb.dts | 315 +++ -+ arch/arm64/boot/dts/vendor/hi3519dv500.dtsi | 859 ++++++ -+ .../dts/vendor/hi3519dv500_family_usb.dtsi | 65 + -+ .../dts/vendor/hi3559v300-demb-emmc-tee.dts | 9 + -+ .../boot/dts/vendor/hi3559v300-demb-emmc.dts | 9 + -+ .../dts/vendor/hi3559v300-demb-flash-tee.dts | 9 + -+ .../boot/dts/vendor/hi3559v300-demb-flash.dts | 9 + -+ .../boot/dts/vendor/hi3559v300-demb-tee.dts | 326 +++ -+ .../arm64/boot/dts/vendor/hi3559v300-demb.dts | 315 +++ -+ arch/arm64/boot/dts/vendor/hi3559v300.dtsi | 853 ++++++ -+ arch/arm64/configs/hi3516dv500_defconfig | 317 +++ -+ arch/arm64/configs/hi3516dv500_emmc_defconfig | 308 ++ -+ .../configs/hi3516dv500_emmc_tee_defconfig | 312 ++ -+ arch/arm64/configs/hi3516dv500_tee_defconfig | 321 +++ -+ arch/arm64/configs/hi3519dv500_defconfig | 317 +++ -+ arch/arm64/configs/hi3519dv500_emmc_defconfig | 308 ++ -+ .../configs/hi3519dv500_emmc_mini_defconfig | 65 + -+ .../configs/hi3519dv500_emmc_tee_defconfig | 312 ++ -+ arch/arm64/configs/hi3519dv500_mini_defconfig | 67 + -+ arch/arm64/configs/hi3519dv500_tee_defconfig | 321 +++ -+ arch/arm64/configs/hi3559v300_defconfig | 317 +++ -+ arch/arm64/configs/hi3559v300_emmc_defconfig | 308 ++ -+ .../configs/hi3559v300_emmc_tee_defconfig | 312 ++ -+ arch/arm64/configs/hi3559v300_tee_defconfig | 321 +++ -+ arch/arm64/include/mach/platform.h | 11 + -+ .../arm64/include/mach/platform_hi3519dv500.h | 11 + -+ arch/arm64/kernel/process.c | 7 + -+ arch/arm64/kernel/stacktrace.c | 3 + -+ block/blk-sysfs.c | 8 + -+ drivers/Kconfig | 14 +- -+ drivers/Makefile | 5 + -+ drivers/base/core.c | 5 +- -+ drivers/base/devtmpfs.c | 37 + -+ drivers/block/brd.c | 31 + -+ drivers/char/hw_random/Makefile | 3 + -+ drivers/char/hw_random/bsp_trng.c | 210 ++ -+ drivers/clk/Kconfig | 4 + -+ drivers/clk/Makefile | 1 + -+ drivers/clk/vendor/Kconfig | 8 + -+ drivers/clk/vendor/Makefile | 8 + -+ drivers/clk/vendor/clk.c | 298 ++ -+ drivers/clk/vendor/clk.h | 130 + -+ drivers/clk/vendor/clk_hi3516cv610.c | 424 +++ -+ drivers/clk/vendor/clk_hi3519dv500.c | 520 ++++ -+ drivers/clk/vendor/clkgate_separated.c | 108 + -+ drivers/clk/vendor/crg.h | 24 + -+ drivers/clk/vendor/reset.c | 118 + -+ drivers/clk/vendor/reset.h | 29 + -+ drivers/clocksource/arm_arch_timer.c | 20 +- -+ drivers/dma/Kconfig | 15 + -+ drivers/dma/Makefile | 4 +- -+ drivers/dma/edmacv310.c | 1445 ++++++++++ -+ drivers/dma/edmacv310.h | 136 + -+ drivers/edmac/Kconfig | 31 + -+ drivers/edmac/Makefile | 6 + -+ drivers/edmac/edma_hi3516cv610.h | 83 + -+ drivers/edmac/edma_hi3519dv500.h | 85 + -+ drivers/edmac/edmacv310.c | 957 +++++++ -+ drivers/edmac/edmacv310.h | 175 ++ -+ drivers/gpio/Makefile | 1 + -+ drivers/gpio/gpio-pl061.c | 13 +- -+ drivers/gpio/vendor/Makefile | 1 + -+ drivers/gpio/vendor/vendor_gpio.c | 92 + -+ drivers/gpio/vendor/vendor_gpio.h | 27 + -+ drivers/i2c/Makefile | 1 + -+ drivers/i2c/busses/Kconfig | 29 + -+ drivers/i2c/busses/Makefile | 3 + -+ drivers/i2c/busses/i2c-bsp.c | 1536 ++++++++++ -+ drivers/i2c/i2c-dev.c | 7 + -+ drivers/i2c/vendor/Makefile | 1 + -+ drivers/i2c/vendor/vendor_i2c_dev.c | 72 + -+ drivers/i2c/vendor/vendor_i2c_dev.h | 18 + -+ drivers/media/usb/uvc/uvc_driver.c | 7 + -+ drivers/media/usb/uvc/uvcvideo.h | 5 + -+ drivers/mfd/Kconfig | 12 + -+ drivers/mfd/Makefile | 3 + -+ drivers/mfd/bsp_fmc.c | 123 + -+ drivers/mmc/core/bus.c | 4 + -+ drivers/mmc/core/core.c | 20 + -+ drivers/mmc/core/core.h | 4 + -+ drivers/mmc/core/core_complement.h | 29 + -+ drivers/mmc/core/mmc.c | 319 ++- -+ drivers/mmc/core/sdio.c | 37 + -+ drivers/mmc/host/Makefile | 2 +- -+ drivers/mmc/host/cqhci.c | 59 + -+ drivers/mmc/host/cqhci.h | 14 + -+ drivers/mmc/host/cqhci_complement.h | 33 + -+ drivers/mmc/host/sdhci.c | 61 +- -+ drivers/mmc/host/sdhci.h | 19 +- -+ drivers/mmc/host/sdhci_complement.c | 66 + -+ drivers/mmc/host/sdhci_complement.h | 40 + -+ drivers/mtd/Makefile | 2 +- -+ drivers/mtd/nand/Kconfig | 26 + -+ drivers/mtd/nand/Makefile | 3 + -+ drivers/mtd/nand/fmc100/Kconfig | 19 + -+ drivers/mtd/nand/fmc100/Makefile | 29 + -+ drivers/mtd/nand/fmc100/fmc100.c | 1265 +++++++++ -+ drivers/mtd/nand/fmc100/fmc100.h | 371 +++ -+ drivers/mtd/nand/fmc100/fmc100_os.c | 252 ++ -+ drivers/mtd/nand/fmc100/fmc100_spi_general.c | 331 +++ -+ drivers/mtd/nand/fmc100/fmc_spi_nand_ids.c | 1639 +++++++++++ -+ drivers/mtd/nand/raw/Makefile | 5 +- -+ drivers/mtd/nand/raw/internals.h | 10 + -+ drivers/mtd/nand/raw/match_table.c | 98 + -+ drivers/mtd/nand/raw/match_table.h | 48 + -+ drivers/mtd/nand/raw/nand_base.c | 42 + -+ drivers/mtd/nand/raw/nand_ids.c | 9 + -+ drivers/mtd/nand/raw/nand_macronix.c | 9 +- -+ drivers/mtd/nand/raw/nfc_gen.c | 214 ++ -+ drivers/mtd/nand/raw/nfc_gen.h | 265 ++ -+ drivers/mtd/nand/raw/nfc_spl_ids.c | 963 +++++++ -+ drivers/mtd/spi-nor/Makefile | 1 + -+ drivers/mtd/spi-nor/bsp-generic.c | 149 + -+ drivers/mtd/spi-nor/controllers/Kconfig | 39 + -+ drivers/mtd/spi-nor/controllers/Makefile | 3 + -+ drivers/mtd/spi-nor/controllers/bsp-sfc.c | 796 ++++++ -+ drivers/mtd/spi-nor/core.c | 425 ++- -+ drivers/mtd/spi-nor/core.h | 224 ++ -+ drivers/net/ethernet/Kconfig | 3 + -+ drivers/net/ethernet/Makefile | 3 + -+ drivers/net/ethernet/vendor/Kconfig | 33 + -+ drivers/net/ethernet/vendor/Makefile | 7 + -+ drivers/net/ethernet/vendor/eth/Kconfig | 19 + -+ drivers/net/ethernet/vendor/eth/Makefile | 12 + -+ drivers/net/ethernet/vendor/eth/autoeee.c | 225 ++ -+ drivers/net/ethernet/vendor/eth/driver_obj.mk | 3 + -+ drivers/net/ethernet/vendor/eth/festa.h | 534 ++++ -+ drivers/net/ethernet/vendor/eth/hleth.c | 2503 +++++++++++++++++ -+ drivers/net/ethernet/vendor/eth/hleth.h | 507 ++++ -+ drivers/net/ethernet/vendor/eth/hleth_dbg.c | 445 +++ -+ drivers/net/ethernet/vendor/eth/hleth_dbg.h | 18 + -+ .../net/ethernet/vendor/eth/huanglong_phy.h | 25 + -+ drivers/net/ethernet/vendor/eth/mdio.c | 243 ++ -+ drivers/net/ethernet/vendor/eth/mdio.h | 74 + -+ drivers/net/ethernet/vendor/eth/phy.c | 368 +++ -+ drivers/net/ethernet/vendor/eth/phy.h | 24 + -+ drivers/net/ethernet/vendor/eth/pm.c | 360 +++ -+ drivers/net/ethernet/vendor/femac/Makefile | 6 + -+ drivers/net/ethernet/vendor/femac/bsp_femac.c | 1580 +++++++++++ -+ drivers/net/ethernet/vendor/femac/bsp_femac.h | 277 ++ -+ .../vendor/femac/festa_s28v115_2c02.h | 199 ++ -+ .../vendor/femac/festa_s28v202_2e01.h | 92 + -+ .../ethernet/vendor/femac/festa_v272_2723.h | 52 + -+ drivers/net/ethernet/vendor/femac/phy_fix.c | 117 + -+ drivers/net/ethernet/vendor/femac/phy_fix.h | 30 + -+ drivers/net/ethernet/vendor/femac/util.c | 321 +++ -+ drivers/net/ethernet/vendor/femac/util.h | 33 + -+ drivers/net/ethernet/vendor/gmac/Kconfig | 106 + -+ drivers/net/ethernet/vendor/gmac/Makefile | 2 + -+ .../ethernet/vendor/gmac/autoeee/autoeee.c | 137 + -+ .../ethernet/vendor/gmac/autoeee/autoeee.h | 49 + -+ .../vendor/gmac/autoeee/phy_id_table.c | 181 ++ -+ drivers/net/ethernet/vendor/gmac/gmac.c | 2289 +++++++++++++++ -+ drivers/net/ethernet/vendor/gmac/gmac.h | 778 +++++ -+ .../ethernet/vendor/gmac/gmac_ethtool_ops.c | 401 +++ -+ .../ethernet/vendor/gmac/gmac_ethtool_ops.h | 35 + -+ .../ethernet/vendor/gmac/gmac_netdev_ops.c | 730 +++++ -+ .../ethernet/vendor/gmac/gmac_netdev_ops.h | 22 + -+ .../net/ethernet/vendor/gmac/gmac_phy_fixup.c | 110 + -+ .../net/ethernet/vendor/gmac/gmac_phy_fixup.h | 13 + -+ drivers/net/ethernet/vendor/gmac/gmac_pm.c | 340 +++ -+ drivers/net/ethernet/vendor/gmac/gmac_pm.h | 56 + -+ drivers/net/ethernet/vendor/gmac/gmac_proc.c | 80 + -+ drivers/net/ethernet/vendor/gmac/gmac_proc.h | 21 + -+ drivers/net/phy/Kconfig | 15 + -+ drivers/net/phy/Makefile | 4 + -+ drivers/net/phy/mdio_bsp_femac.c | 494 ++++ -+ drivers/net/phy/mdio_gemac.c | 221 ++ -+ drivers/net/phy/mdio_gemac.h | 24 + -+ drivers/net/phy/realtek.c | 18 + -+ drivers/of/base.c | 2 + -+ drivers/of/fdt.c | 4 + -+ drivers/phy/Kconfig | 6 + -+ drivers/phy/Makefile | 1 + -+ drivers/phy/vendor/Kconfig | 0 -+ drivers/phy/vendor/Makefile | 3 + -+ drivers/power/reset/Kconfig | 7 + -+ drivers/power/reset/Makefile | 7 + -+ drivers/power/reset/bsp-reboot-hi3516cv610.c | 114 + -+ drivers/power/reset/bsp-reboot.c | 73 + -+ drivers/pwm/Kconfig | 11 + -+ drivers/pwm/Makefile | 6 + -+ drivers/pwm/core.c | 5 + -+ drivers/pwm/pwm-bsp.c | 486 ++++ -+ drivers/pwm/sysfs.c | 13 + -+ drivers/pwm/sysfs_bsp.c | 320 +++ -+ drivers/rtc/Kconfig | 11 + -+ drivers/rtc/Makefile | 3 + -+ drivers/rtc/rtc-bsp.c | 628 +++++ -+ drivers/spi/Makefile | 1 + -+ drivers/spi/spi-pl022.c | 43 +- -+ drivers/spi/vendor/Makefile | 1 + -+ drivers/spi/vendor/vendor_spi.c | 211 ++ -+ drivers/spi/vendor/vendor_spi.h | 85 + -+ drivers/tee/optee/Kconfig | 13 + -+ drivers/tee/optee/optee_msg.h | 16 + -+ drivers/tee/optee/rpc.c | 45 + -+ drivers/tee/tee_core.c | 37 + -+ drivers/tee/tee_private.h | 7 + -+ drivers/tty/serial/amba-pl011.c | 30 +- -+ drivers/usb/dwc3/core.h | 34 +- -+ drivers/usb/dwc3/ep0.c | 242 +- -+ drivers/usb/dwc3/gadget.c | 353 ++- -+ drivers/usb/gadget/Kconfig | 9 + -+ drivers/usb/gadget/composite.c | 4 + -+ drivers/usb/gadget/configfs.c | 9 +- -+ drivers/usb/gadget/epautoconf.c | 21 +- -+ drivers/usb/gadget/function/f_mass_storage.c | 19 +- -+ drivers/usb/gadget/function/f_uac1.c | 71 + -+ drivers/usb/gadget/function/f_uvc.c | 531 +++- -+ drivers/usb/gadget/function/u_uvc.h | 8 + -+ drivers/usb/gadget/function/uvc.h | 52 + -+ drivers/usb/gadget/function/uvc_configfs.c | 1002 ++++++- -+ drivers/usb/gadget/function/uvc_v4l2.c | 46 +- -+ drivers/usb/gadget/function/uvc_video.c | 514 +++- -+ drivers/vdmav100/Kconfig | 30 + -+ drivers/vdmav100/Makefile | 4 + -+ drivers/vdmav100/vdma.h | 28 + -+ drivers/vdmav100/vdmav100.c | 444 +++ -+ drivers/vdmav100/vdmav100.h | 114 + -+ drivers/vdmav100/vdmav100_misc.c | 94 + -+ drivers/vendor/Kconfig | 9 + -+ drivers/vendor/Makefile | 5 + -+ drivers/vendor/basedrv_clk/Kconfig | 3 + -+ drivers/vendor/basedrv_clk/Makefile | 7 + -+ drivers/vendor/basedrv_clk/basedrv-clock.h | 17 + -+ drivers/vendor/basedrv_clk/basedrv_clk.c | 338 +++ -+ drivers/vendor/basedrv_clk/basedrv_clk.h | 103 + -+ .../vendor/basedrv_clk/hi3516cv610/Makefile | 4 + -+ .../basedrv_clk/hi3516cv610/clk_hi3516cv610.c | 85 + -+ .../basedrv_clk/hi3516cv610/clk_hi3516cv610.h | 13 + -+ .../vendor/basedrv_clk/hi3516cv610/clk_ups.c | 221 ++ -+ .../vendor/basedrv_clk/hi3519dv500/Makefile | 4 + -+ .../basedrv_clk/hi3519dv500/clk_hi3519dv500.c | 93 + -+ .../basedrv_clk/hi3519dv500/clk_hi3519dv500.h | 14 + -+ .../vendor/basedrv_clk/hi3519dv500/clk_ups.c | 283 ++ -+ drivers/vendor/cma/Kconfig | 16 + -+ drivers/vendor/cma/Makefile | 2 + -+ drivers/vendor/cma/cma.c | 176 ++ -+ drivers/vendor/mmc/ChangLog | 7 + -+ drivers/vendor/mmc/Kconfig | 23 + -+ drivers/vendor/mmc/Makefile | 42 + -+ drivers/vendor/mmc/adapter/nebula_adapter.c | 1141 ++++++++ -+ drivers/vendor/mmc/adapter/nebula_fmea.c | 123 + -+ drivers/vendor/mmc/adapter/nebula_quick.c | 252 ++ -+ drivers/vendor/mmc/adapter/nebula_quick.h | 86 + -+ drivers/vendor/mmc/adapter/nebula_quirk_ids.h | 54 + -+ drivers/vendor/mmc/dfx/mci_proc.c | 304 ++ -+ drivers/vendor/mmc/dfx/mci_proc.h | 16 + -+ drivers/vendor/mmc/dfx/nebula_dfx.c | 493 ++++ -+ drivers/vendor/mmc/dfx/nebula_dfx.h | 36 + -+ drivers/vendor/mmc/driver_obj.mk | 3 + -+ drivers/vendor/mmc/dtsi_usage.txt | 58 + -+ drivers/vendor/mmc/nebula_fmea.h | 25 + -+ drivers/vendor/mmc/nebula_intf.c | 93 + -+ drivers/vendor/mmc/nebula_intf.h | 14 + -+ drivers/vendor/mmc/platform/platform_comm.c | 501 ++++ -+ drivers/vendor/mmc/platform/platform_priv.h | 221 ++ -+ drivers/vendor/mmc/platform/platform_timing.h | 71 + -+ .../vendor/mmc/platform/sdhci_hi3516cv610.c | 362 +++ -+ .../vendor/mmc/platform/sdhci_hi3519dv500.c | 351 +++ -+ drivers/vendor/mmc/sdhci_nebula.c | 183 ++ -+ drivers/vendor/mmc/sdhci_nebula.h | 319 +++ -+ drivers/vendor/mmc/version.mak | 1 + -+ drivers/vendor/ups_phy/Kconfig | 28 + -+ drivers/vendor/ups_phy/Makefile | 21 + -+ drivers/vendor/ups_phy/common.c | 45 + -+ drivers/vendor/ups_phy/missile.c | 214 ++ -+ drivers/vendor/ups_phy/nano.c | 379 +++ -+ drivers/vendor/ups_phy/phy.c | 224 ++ -+ drivers/vendor/ups_phy/phy.h | 90 + -+ drivers/vendor/ups_phy/reg.h | 138 + -+ drivers/vendor/ups_phy/xvp.c | 111 + -+ drivers/vendor/usb/Kconfig | 6 + -+ drivers/vendor/usb/Makefile | 12 + -+ drivers/vendor/usb/proc.c | 145 + -+ drivers/vendor/usb/proc.h | 15 + -+ drivers/vendor/usb/version.mak | 1 + -+ drivers/vendor/usb/wing_usb.c | 1024 +++++++ -+ drivers/vendor/usb/wing_usb.h | 145 + -+ fs/fat/Kconfig | 12 + -+ fs/fat/dir.c | 401 ++- -+ fs/fat/fat.h | 4 + -+ fs/fat/fatent.c | 7 + -+ fs/fat/file.c | 26 +- -+ fs/fat/inode.c | 79 +- -+ fs/fat/misc.c | 28 + -+ fs/sysfs/file.c | 7 + -+ include/asm-generic/vmlinux.lds.h | 19 + -+ include/dt-bindings/clock/basedrv-clock.h | 17 + -+ include/dt-bindings/clock/hi3516cv610-clock.h | 132 + -+ include/dt-bindings/clock/hi3519dv500_clock.h | 143 + -+ include/linux/annotated_initcalls.h | 112 + -+ include/linux/blkdev.h | 4 + -+ include/linux/bsp_cma.h | 41 + -+ include/linux/dma-debug.h | 209 ++ -+ include/linux/dma_remapping.h | 59 + -+ include/linux/driver_ids.h | 451 +++ -+ include/linux/drv_def.h | 43 + -+ include/linux/edmac.h | 71 + -+ include/linux/i2c.h | 1 + -+ include/linux/init.h | 4 + -+ include/linux/iprec.h | 55 + -+ include/linux/kobject.h | 9 +- -+ include/linux/mfd/bsp_fmc.h | 493 ++++ -+ include/linux/mmc/host.h | 9 + -+ include/linux/mtd/mtd.h | 46 +- -+ include/linux/mtd/spi-nor.h | 97 +- -+ include/linux/of.h | 5 + -+ include/linux/pwm.h | 6 +- -+ include/linux/securec.h | 631 +++++ -+ include/linux/securectype.h | 587 ++++ -+ include/linux/tee_drv.h | 16 + -+ include/linux/vendor/sva_ext.h | 82 + -+ include/linux/vendor/vendor_i2c.h | 27 + -+ include/uapi/linux/i2c-dev.h | 1 - -+ include/uapi/linux/i2c.h | 2 +- -+ include/uapi/linux/msdos_fs.h | 20 +- -+ include/uapi/linux/usb/g_uvc.h | 18 + -+ include/uapi/linux/usb/video.h | 62 + -+ include/uapi/linux/videodev2.h | 3 + -+ init/Kconfig.faststartup | 69 + -+ init/Kconfig.timestamp | 7 + -+ init/Makefile | 8 + -+ init/dependencies.c | 452 +++ -+ init/do_mounts_rd.c | 8 +- -+ init/initramfs.c | 10 + -+ init/main.c | 14 +- -+ init/vendor/Makefile | 1 + -+ init/vendor/faststartup.c | 117 + -+ init/vendor/faststartup.h | 11 + -+ kernel/Kconfig.freezer | 8 + -+ kernel/Makefile | 2 + -+ kernel/dma/contiguous.c | 16 + -+ kernel/iprec.c | 417 +++ -+ kernel/irq/irqdesc.c | 5 + -+ kernel/ksysfs.c | 6 + -+ kernel/module.c | 3 + -+ kernel/params.c | 8 + -+ kernel/printk/printk.c | 7 + -+ kernel/sched/core.c | 6 +- -+ lib/Kconfig.debug | 5 + -+ lib/kobject.c | 8 + -+ lib/kobject_uevent.c | 13 + -+ lib/securec/LICENSE | 124 + -+ lib/securec/Makefile | 3 + -+ lib/securec/README.en.md | 59 + -+ lib/securec/README.md | 56 + -+ lib/securec/src/Makefile | 17 + -+ lib/securec/src/input.inl | 2229 +++++++++++++++ -+ lib/securec/src/memcpy_s.c | 555 ++++ -+ lib/securec/src/memmove_s.c | 123 + -+ lib/securec/src/memset_s.c | 510 ++++ -+ lib/securec/src/output.inl | 1720 +++++++++++ -+ lib/securec/src/scanf_s.c | 51 + -+ lib/securec/src/secinput.h | 181 ++ -+ lib/securec/src/securecutil.c | 81 + -+ lib/securec/src/securecutil.h | 574 ++++ -+ lib/securec/src/secureinput_a.c | 38 + -+ lib/securec/src/secureprintoutput.h | 146 + -+ lib/securec/src/secureprintoutput_a.c | 112 + -+ lib/securec/src/snprintf_s.c | 110 + -+ lib/securec/src/sprintf_s.c | 58 + -+ lib/securec/src/sscanf_s.c | 58 + -+ lib/securec/src/strcat_s.c | 101 + -+ lib/securec/src/strcpy_s.c | 353 +++ -+ lib/securec/src/strncat_s.c | 119 + -+ lib/securec/src/strncpy_s.c | 145 + -+ lib/securec/src/strtok_s.c | 116 + -+ lib/securec/src/vscanf_s.c | 63 + -+ lib/securec/src/vsnprintf_s.c | 138 + -+ lib/securec/src/vsprintf_s.c | 67 + -+ lib/securec/src/vsscanf_s.c | 87 + -+ mm/slab_common.c | 5 + -+ mm/slub.c | 10 +- -+ scripts/Makefile.lib | 5 + -+ scripts/Makefile.modpost | 2 +- -+ scripts/checksyscalls.sh | 3 +- -+ 434 files changed, 69936 insertions(+), 181 deletions(-) -+ create mode 100755 arch/arm/boot/dts/hi3516cv608-demb-emmc.dts -+ create mode 100755 arch/arm/boot/dts/hi3516cv608-demb-flash.dts -+ create mode 100755 arch/arm/boot/dts/hi3516cv608-demb.dts -+ create mode 100755 arch/arm/boot/dts/hi3516cv608.dtsi -+ create mode 100755 arch/arm/boot/dts/hi3516cv608_family_usb.dtsi -+ create mode 100755 arch/arm/boot/dts/hi3516cv610-demb-emmc.dts -+ create mode 100755 arch/arm/boot/dts/hi3516cv610-demb-flash.dts -+ create mode 100755 arch/arm/boot/dts/hi3516cv610-demb.dts -+ create mode 100755 arch/arm/boot/dts/hi3516cv610.dtsi -+ create mode 100755 arch/arm/boot/dts/hi3516cv610_family_usb.dtsi -+ create mode 100755 arch/arm/configs/hi3516cv608_debug_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv608_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv608_emmc_debug_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv608_emmc_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv608_nand_mini_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv608_nor_mini_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv608_nor_quickboot_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv610_debug_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv610_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv610_emmc_debug_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv610_emmc_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv610_nand_mini_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv610_nor_mini_defconfig -+ create mode 100755 arch/arm/configs/hi3516cv610_nor_quickboot_defconfig -+ create mode 100755 arch/arm/mach-vendor/Kconfig -+ create mode 100755 arch/arm/mach-vendor/Makefile -+ create mode 100755 arch/arm/mach-vendor/Makefile.boot -+ create mode 100755 arch/arm/mach-vendor/mach_common.h -+ create mode 100755 arch/arm/mach-vendor/mach_hi3516cv610.c -+ create mode 100755 arch/arm/mach-vendor/platsmp.c -+ create mode 100755 arch/arm64/boot/dts/vendor/Makefile -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3516dv500-demb-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3516dv500-demb.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3516dv500.dtsi -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500-demb-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500-demb.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500.dtsi -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3519dv500_family_usb.dtsi -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3559v300-demb-flash-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3559v300-demb-flash.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3559v300-demb-tee.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3559v300-demb.dts -+ create mode 100755 arch/arm64/boot/dts/vendor/hi3559v300.dtsi -+ create mode 100755 arch/arm64/configs/hi3516dv500_defconfig -+ create mode 100755 arch/arm64/configs/hi3516dv500_emmc_defconfig -+ create mode 100755 arch/arm64/configs/hi3516dv500_emmc_tee_defconfig -+ create mode 100755 arch/arm64/configs/hi3516dv500_tee_defconfig -+ create mode 100755 arch/arm64/configs/hi3519dv500_defconfig -+ create mode 100755 arch/arm64/configs/hi3519dv500_emmc_defconfig -+ create mode 100755 arch/arm64/configs/hi3519dv500_emmc_mini_defconfig -+ create mode 100755 arch/arm64/configs/hi3519dv500_emmc_tee_defconfig -+ create mode 100755 arch/arm64/configs/hi3519dv500_mini_defconfig -+ create mode 100755 arch/arm64/configs/hi3519dv500_tee_defconfig -+ create mode 100755 arch/arm64/configs/hi3559v300_defconfig -+ create mode 100755 arch/arm64/configs/hi3559v300_emmc_defconfig -+ create mode 100755 arch/arm64/configs/hi3559v300_emmc_tee_defconfig -+ create mode 100755 arch/arm64/configs/hi3559v300_tee_defconfig -+ create mode 100755 arch/arm64/include/mach/platform.h -+ create mode 100755 arch/arm64/include/mach/platform_hi3519dv500.h -+ create mode 100644 drivers/char/hw_random/bsp_trng.c -+ create mode 100644 drivers/clk/vendor/Kconfig -+ create mode 100644 drivers/clk/vendor/Makefile -+ create mode 100644 drivers/clk/vendor/clk.c -+ create mode 100644 drivers/clk/vendor/clk.h -+ create mode 100644 drivers/clk/vendor/clk_hi3516cv610.c -+ create mode 100644 drivers/clk/vendor/clk_hi3519dv500.c -+ create mode 100644 drivers/clk/vendor/clkgate_separated.c -+ create mode 100644 drivers/clk/vendor/crg.h -+ create mode 100644 drivers/clk/vendor/reset.c -+ create mode 100644 drivers/clk/vendor/reset.h -+ create mode 100644 drivers/dma/edmacv310.c -+ create mode 100644 drivers/dma/edmacv310.h -+ create mode 100755 drivers/edmac/Kconfig -+ create mode 100755 drivers/edmac/Makefile -+ create mode 100755 drivers/edmac/edma_hi3516cv610.h -+ create mode 100755 drivers/edmac/edma_hi3519dv500.h -+ create mode 100755 drivers/edmac/edmacv310.c -+ create mode 100755 drivers/edmac/edmacv310.h -+ create mode 100755 drivers/gpio/vendor/Makefile -+ create mode 100755 drivers/gpio/vendor/vendor_gpio.c -+ create mode 100755 drivers/gpio/vendor/vendor_gpio.h -+ create mode 100755 drivers/i2c/busses/i2c-bsp.c -+ create mode 100755 drivers/i2c/vendor/Makefile -+ create mode 100755 drivers/i2c/vendor/vendor_i2c_dev.c -+ create mode 100755 drivers/i2c/vendor/vendor_i2c_dev.h -+ create mode 100755 drivers/mfd/bsp_fmc.c -+ create mode 100755 drivers/mmc/core/core_complement.h -+ create mode 100755 drivers/mmc/host/cqhci_complement.h -+ create mode 100755 drivers/mmc/host/sdhci_complement.c -+ create mode 100755 drivers/mmc/host/sdhci_complement.h -+ create mode 100755 drivers/mtd/nand/fmc100/Kconfig -+ create mode 100755 drivers/mtd/nand/fmc100/Makefile -+ create mode 100755 drivers/mtd/nand/fmc100/fmc100.c -+ create mode 100755 drivers/mtd/nand/fmc100/fmc100.h -+ create mode 100755 drivers/mtd/nand/fmc100/fmc100_os.c -+ create mode 100755 drivers/mtd/nand/fmc100/fmc100_spi_general.c -+ create mode 100755 drivers/mtd/nand/fmc100/fmc_spi_nand_ids.c -+ create mode 100755 drivers/mtd/nand/raw/match_table.c -+ create mode 100755 drivers/mtd/nand/raw/match_table.h -+ create mode 100755 drivers/mtd/nand/raw/nfc_gen.c -+ create mode 100755 drivers/mtd/nand/raw/nfc_gen.h -+ create mode 100755 drivers/mtd/nand/raw/nfc_spl_ids.c -+ create mode 100755 drivers/mtd/spi-nor/bsp-generic.c -+ create mode 100755 drivers/mtd/spi-nor/controllers/bsp-sfc.c -+ create mode 100755 drivers/net/ethernet/vendor/Kconfig -+ create mode 100755 drivers/net/ethernet/vendor/Makefile -+ create mode 100755 drivers/net/ethernet/vendor/eth/Kconfig -+ create mode 100755 drivers/net/ethernet/vendor/eth/Makefile -+ create mode 100755 drivers/net/ethernet/vendor/eth/autoeee.c -+ create mode 100755 drivers/net/ethernet/vendor/eth/driver_obj.mk -+ create mode 100755 drivers/net/ethernet/vendor/eth/festa.h -+ create mode 100755 drivers/net/ethernet/vendor/eth/hleth.c -+ create mode 100755 drivers/net/ethernet/vendor/eth/hleth.h -+ create mode 100755 drivers/net/ethernet/vendor/eth/hleth_dbg.c -+ create mode 100755 drivers/net/ethernet/vendor/eth/hleth_dbg.h -+ create mode 100755 drivers/net/ethernet/vendor/eth/huanglong_phy.h -+ create mode 100755 drivers/net/ethernet/vendor/eth/mdio.c -+ create mode 100755 drivers/net/ethernet/vendor/eth/mdio.h -+ create mode 100755 drivers/net/ethernet/vendor/eth/phy.c -+ create mode 100755 drivers/net/ethernet/vendor/eth/phy.h -+ create mode 100755 drivers/net/ethernet/vendor/eth/pm.c -+ create mode 100755 drivers/net/ethernet/vendor/femac/Makefile -+ create mode 100755 drivers/net/ethernet/vendor/femac/bsp_femac.c -+ create mode 100755 drivers/net/ethernet/vendor/femac/bsp_femac.h -+ create mode 100755 drivers/net/ethernet/vendor/femac/festa_s28v115_2c02.h -+ create mode 100755 drivers/net/ethernet/vendor/femac/festa_s28v202_2e01.h -+ create mode 100755 drivers/net/ethernet/vendor/femac/festa_v272_2723.h -+ create mode 100755 drivers/net/ethernet/vendor/femac/phy_fix.c -+ create mode 100755 drivers/net/ethernet/vendor/femac/phy_fix.h -+ create mode 100755 drivers/net/ethernet/vendor/femac/util.c -+ create mode 100755 drivers/net/ethernet/vendor/femac/util.h -+ create mode 100755 drivers/net/ethernet/vendor/gmac/Kconfig -+ create mode 100755 drivers/net/ethernet/vendor/gmac/Makefile -+ create mode 100755 drivers/net/ethernet/vendor/gmac/autoeee/autoeee.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/autoeee/autoeee.h -+ create mode 100755 drivers/net/ethernet/vendor/gmac/autoeee/phy_id_table.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac.h -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.h -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.h -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.h -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_pm.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_pm.h -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_proc.c -+ create mode 100755 drivers/net/ethernet/vendor/gmac/gmac_proc.h -+ create mode 100755 drivers/net/phy/mdio_bsp_femac.c -+ create mode 100755 drivers/net/phy/mdio_gemac.c -+ create mode 100755 drivers/net/phy/mdio_gemac.h -+ create mode 100755 drivers/phy/vendor/Kconfig -+ create mode 100755 drivers/phy/vendor/Makefile -+ create mode 100755 drivers/power/reset/bsp-reboot-hi3516cv610.c -+ create mode 100755 drivers/power/reset/bsp-reboot.c -+ create mode 100755 drivers/pwm/pwm-bsp.c -+ create mode 100755 drivers/pwm/sysfs_bsp.c -+ create mode 100755 drivers/rtc/rtc-bsp.c -+ create mode 100755 drivers/spi/vendor/Makefile -+ create mode 100755 drivers/spi/vendor/vendor_spi.c -+ create mode 100755 drivers/spi/vendor/vendor_spi.h -+ create mode 100755 drivers/vdmav100/Kconfig -+ create mode 100755 drivers/vdmav100/Makefile -+ create mode 100755 drivers/vdmav100/vdma.h -+ create mode 100755 drivers/vdmav100/vdmav100.c -+ create mode 100755 drivers/vdmav100/vdmav100.h -+ create mode 100755 drivers/vdmav100/vdmav100_misc.c -+ create mode 100755 drivers/vendor/Kconfig -+ create mode 100755 drivers/vendor/Makefile -+ create mode 100755 drivers/vendor/basedrv_clk/Kconfig -+ create mode 100755 drivers/vendor/basedrv_clk/Makefile -+ create mode 100755 drivers/vendor/basedrv_clk/basedrv-clock.h -+ create mode 100755 drivers/vendor/basedrv_clk/basedrv_clk.c -+ create mode 100755 drivers/vendor/basedrv_clk/basedrv_clk.h -+ create mode 100755 drivers/vendor/basedrv_clk/hi3516cv610/Makefile -+ create mode 100755 drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.c -+ create mode 100755 drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.h -+ create mode 100755 drivers/vendor/basedrv_clk/hi3516cv610/clk_ups.c -+ create mode 100755 drivers/vendor/basedrv_clk/hi3519dv500/Makefile -+ create mode 100755 drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.c -+ create mode 100755 drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.h -+ create mode 100755 drivers/vendor/basedrv_clk/hi3519dv500/clk_ups.c -+ create mode 100755 drivers/vendor/cma/Kconfig -+ create mode 100755 drivers/vendor/cma/Makefile -+ create mode 100755 drivers/vendor/cma/cma.c -+ create mode 100755 drivers/vendor/mmc/ChangLog -+ create mode 100755 drivers/vendor/mmc/Kconfig -+ create mode 100755 drivers/vendor/mmc/Makefile -+ create mode 100755 drivers/vendor/mmc/adapter/nebula_adapter.c -+ create mode 100755 drivers/vendor/mmc/adapter/nebula_fmea.c -+ create mode 100755 drivers/vendor/mmc/adapter/nebula_quick.c -+ create mode 100755 drivers/vendor/mmc/adapter/nebula_quick.h -+ create mode 100755 drivers/vendor/mmc/adapter/nebula_quirk_ids.h -+ create mode 100755 drivers/vendor/mmc/dfx/mci_proc.c -+ create mode 100755 drivers/vendor/mmc/dfx/mci_proc.h -+ create mode 100755 drivers/vendor/mmc/dfx/nebula_dfx.c -+ create mode 100755 drivers/vendor/mmc/dfx/nebula_dfx.h -+ create mode 100755 drivers/vendor/mmc/driver_obj.mk -+ create mode 100755 drivers/vendor/mmc/dtsi_usage.txt -+ create mode 100755 drivers/vendor/mmc/nebula_fmea.h -+ create mode 100755 drivers/vendor/mmc/nebula_intf.c -+ create mode 100755 drivers/vendor/mmc/nebula_intf.h -+ create mode 100755 drivers/vendor/mmc/platform/platform_comm.c -+ create mode 100755 drivers/vendor/mmc/platform/platform_priv.h -+ create mode 100755 drivers/vendor/mmc/platform/platform_timing.h -+ create mode 100755 drivers/vendor/mmc/platform/sdhci_hi3516cv610.c -+ create mode 100755 drivers/vendor/mmc/platform/sdhci_hi3519dv500.c -+ create mode 100755 drivers/vendor/mmc/sdhci_nebula.c -+ create mode 100755 drivers/vendor/mmc/sdhci_nebula.h -+ create mode 100755 drivers/vendor/mmc/version.mak -+ create mode 100755 drivers/vendor/ups_phy/Kconfig -+ create mode 100755 drivers/vendor/ups_phy/Makefile -+ create mode 100755 drivers/vendor/ups_phy/common.c -+ create mode 100755 drivers/vendor/ups_phy/missile.c -+ create mode 100755 drivers/vendor/ups_phy/nano.c -+ create mode 100755 drivers/vendor/ups_phy/phy.c -+ create mode 100755 drivers/vendor/ups_phy/phy.h -+ create mode 100755 drivers/vendor/ups_phy/reg.h -+ create mode 100755 drivers/vendor/ups_phy/xvp.c -+ create mode 100755 drivers/vendor/usb/Kconfig -+ create mode 100755 drivers/vendor/usb/Makefile -+ create mode 100755 drivers/vendor/usb/proc.c -+ create mode 100755 drivers/vendor/usb/proc.h -+ create mode 100755 drivers/vendor/usb/version.mak -+ create mode 100755 drivers/vendor/usb/wing_usb.c -+ create mode 100755 drivers/vendor/usb/wing_usb.h -+ create mode 100755 include/dt-bindings/clock/basedrv-clock.h -+ create mode 100755 include/dt-bindings/clock/hi3516cv610-clock.h -+ create mode 100755 include/dt-bindings/clock/hi3519dv500_clock.h -+ create mode 100755 include/linux/annotated_initcalls.h -+ create mode 100755 include/linux/bsp_cma.h -+ create mode 100755 include/linux/dma-debug.h -+ create mode 100755 include/linux/dma_remapping.h -+ create mode 100755 include/linux/driver_ids.h -+ create mode 100755 include/linux/drv_def.h -+ create mode 100755 include/linux/edmac.h -+ create mode 100755 include/linux/iprec.h -+ create mode 100755 include/linux/mfd/bsp_fmc.h -+ create mode 100755 include/linux/securec.h -+ create mode 100755 include/linux/securectype.h -+ create mode 100755 include/linux/vendor/sva_ext.h -+ create mode 100755 include/linux/vendor/vendor_i2c.h -+ create mode 100755 init/Kconfig.faststartup -+ create mode 100755 init/Kconfig.timestamp -+ create mode 100755 init/dependencies.c -+ create mode 100755 init/vendor/Makefile -+ create mode 100755 init/vendor/faststartup.c -+ create mode 100755 init/vendor/faststartup.h -+ create mode 100755 kernel/iprec.c -+ create mode 100755 lib/securec/LICENSE -+ create mode 100755 lib/securec/Makefile -+ create mode 100755 lib/securec/README.en.md -+ create mode 100755 lib/securec/README.md -+ create mode 100755 lib/securec/src/Makefile -+ create mode 100755 lib/securec/src/input.inl -+ create mode 100755 lib/securec/src/memcpy_s.c -+ create mode 100755 lib/securec/src/memmove_s.c -+ create mode 100755 lib/securec/src/memset_s.c -+ create mode 100755 lib/securec/src/output.inl -+ create mode 100755 lib/securec/src/scanf_s.c -+ create mode 100755 lib/securec/src/secinput.h -+ create mode 100755 lib/securec/src/securecutil.c -+ create mode 100755 lib/securec/src/securecutil.h -+ create mode 100755 lib/securec/src/secureinput_a.c -+ create mode 100755 lib/securec/src/secureprintoutput.h -+ create mode 100755 lib/securec/src/secureprintoutput_a.c -+ create mode 100755 lib/securec/src/snprintf_s.c -+ create mode 100755 lib/securec/src/sprintf_s.c -+ create mode 100755 lib/securec/src/sscanf_s.c -+ create mode 100755 lib/securec/src/strcat_s.c -+ create mode 100755 lib/securec/src/strcpy_s.c -+ create mode 100755 lib/securec/src/strncat_s.c -+ create mode 100755 lib/securec/src/strncpy_s.c -+ create mode 100755 lib/securec/src/strtok_s.c -+ create mode 100755 lib/securec/src/vscanf_s.c -+ create mode 100755 lib/securec/src/vsnprintf_s.c -+ create mode 100755 lib/securec/src/vsprintf_s.c -+ create mode 100755 lib/securec/src/vsscanf_s.c -+ -+diff --git a/Makefile b/Makefile -+index e1e4ca473..a30ff6e24 100644 -+--- a/Makefile -++++ b/Makefile -+@@ -417,9 +417,24 @@ HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null) -+ HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null) -+ HOST_LFS_LIBS := $(shell getconf LFS_LIBS 2>/dev/null) -+ -++ifdef CONFIG_ARCH_BSP -++HOST_TARGET_TRIPLE := -++HOSTCFLAGS = -++HOSTCXXFLAGS = -++HOSTLDFLAGS = -++endif -++ -+ ifneq ($(LLVM),) -+ HOSTCC = clang -+ HOSTCXX = clang++ -++ -++ifdef CONFIG_ARCH_BSP -++HOST_TARGET_TRIPLE := $(shell gcc -dumpmachine 2>/dev/null) -++HOSTCFLAGS = --target=$(HOST_TARGET_TRIPLE) -++HOSTCXXFLAGS = --target=$(HOST_TARGET_TRIPLE) -++HOSTLDFLAGS = --target=$(HOST_TARGET_TRIPLE) -rtlib=platform -unwindlib=platform -++endif -++ -+ else -+ HOSTCC = gcc -+ HOSTCXX = g++ -+@@ -663,6 +678,9 @@ endif -+ ifeq ($(KBUILD_EXTMOD),) -+ # Objects we will link into vmlinux / subdirs we need to visit -+ core-y := init/ usr/ -++ifdef CONFIG_ARCH_BSP -++sec-y := lib/securec/src/ -++endif -+ drivers-y := drivers/ sound/ -+ drivers-$(CONFIG_SAMPLES) += samples/ -+ drivers-y += net/ virt/ -+@@ -1154,7 +1172,15 @@ export MODULES_NSDEPS := $(extmod-prefix)modules.nsdeps -+ -+ ifeq ($(KBUILD_EXTMOD),) -+ core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ io_uring/ -++ifdef CONFIG_ARCH_BSP -++vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ -++ $(sec-y) $(sec-m) $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ -++ $(libs-y) $(libs-m))) -+ -++vmlinux-alldirs := $(sort $(vmlinux-dirs) Documentation \ -++ $(patsubst %/,%,$(filter %/, $(sec-) $(core-) \ -++ $(drivers-) $(libs-)))) -++else -+ vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ -+ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ -+ $(libs-y) $(libs-m))) -+@@ -1162,14 +1188,18 @@ vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ -+ vmlinux-alldirs := $(sort $(vmlinux-dirs) Documentation \ -+ $(patsubst %/,%,$(filter %/, $(core-) \ -+ $(drivers-) $(libs-)))) -+- -++endif -+ build-dirs := $(vmlinux-dirs) -+ clean-dirs := $(vmlinux-alldirs) -+ -+ subdir-modorder := $(addsuffix /modules.order, $(build-dirs)) -+ -+ # Externally visible symbols (used by link-vmlinux.sh) -++ifdef CONFIG_ARCH_BSP -++KBUILD_VMLINUX_OBJS := $(head-y) $(patsubst %/,%/built-in.a, $(sec-y) $(core-y)) -++else -+ KBUILD_VMLINUX_OBJS := $(head-y) $(patsubst %/,%/built-in.a, $(core-y)) -++endif -+ KBUILD_VMLINUX_OBJS += $(addsuffix built-in.a, $(filter %/, $(libs-y))) -+ ifdef CONFIG_MODULES -+ KBUILD_VMLINUX_OBJS += $(patsubst %/, %/lib.a, $(filter %/, $(libs-y))) -+@@ -1217,6 +1247,10 @@ cmd_link-vmlinux = \ -+ -+ vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE -+ +$(call if_changed,link-vmlinux) -++ifdef CONFIG_ARCH_BSP -++ $(Q)$(MAKE) $(build)=scripts scripts/module.lds -++ @cp vmlinux.symvers Module.symvers -++endif -+ -+ targets := vmlinux -+ -+diff --git a/arch/Kconfig b/arch/Kconfig -+index 0fc9c6d59..9a86d35a8 100644 -+--- a/arch/Kconfig -++++ b/arch/Kconfig -+@@ -9,6 +9,14 @@ -+ # -+ source "arch/$(SRCARCH)/Kconfig" -+ -++config ARCH_CONFIGURES_CPU_MITIGATIONS -++ bool -++ -++if !ARCH_CONFIGURES_CPU_MITIGATIONS -++config CPU_MITIGATIONS -++ def_bool y -++endif -++ -+ menu "General architecture-dependent options" -+ -+ config CRASH_CORE -+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -+index 370b9048e..6da72c29d 100644 -+--- a/arch/arm/Kconfig -++++ b/arch/arm/Kconfig -+@@ -754,6 +754,17 @@ source "arch/arm/mach-zx/Kconfig" -+ -+ source "arch/arm/mach-zynq/Kconfig" -+ -++config ARCH_BSP -++ bool "Vendor SoC Family" -++ select ARM_AMBA -++ select ARM_GIC if ARCH_MULTI_V7 -++ select POWER_RESET -++ select POWER_SUPPLY -++ -++if ARCH_BSP -++source "arch/arm/mach-vendor/Kconfig" -++endif -++ -+ # ARMv7-M architecture -+ config ARCH_EFM32 -+ bool "Energy Micro efm32" -+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -+index dd1cf7035..6e8df9c4a 100644 -+--- a/arch/arm/Kconfig.debug -++++ b/arch/arm/Kconfig.debug -+@@ -346,6 +346,14 @@ choice -+ Say Y here if you want kernel low-level debugging support -+ on HI3620 UART. -+ -++ config DEBUG_HI3516CV610_UART -++ bool "Hisilicon HI3516CV610 Debug UART" -++ depends on ARCH_HI3516CV610_FAMILY -++ select DEBUG_UART_PL01X -++ help -++ Say Y here if you want kernel low-level debugging support -++ on HI3516CV610 UART. -++ -+ config DEBUG_HIGHBANK_UART -+ bool "Kernel low-level debugging messages via Highbank UART" -+ depends on ARCH_HIGHBANK -+@@ -1767,6 +1775,7 @@ config DEBUG_UART_PHYS -+ default 0xfffe8600 if DEBUG_BCM63XX_UART -+ default 0xffffee00 if DEBUG_AT91_SAM9263_DBGU -+ default 0xfffff200 if DEBUG_AT91_RM9200_DBGU -++ default 0x12040000 if DEBUG_HI3516CV610_UART -+ depends on ARCH_EP93XX || \ -+ DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \ -+ DEBUG_LL_UART_EFM32 || \ -+@@ -1869,6 +1878,7 @@ config DEBUG_UART_VIRT -+ default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0 -+ default 0xfec20000 if DEBUG_SIRFATLAS7_UART1 -+ default 0xfec60000 if DEBUG_SIRFPRIMA2_UART1 -++ default 0xfe440000 if DEBUG_HI3516CV610_UART -+ default 0xfec90000 if DEBUG_RK32_UART2 -+ default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1 -+ default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_SD5203_UART -+diff --git a/arch/arm/Makefile b/arch/arm/Makefile -+index d6817de42..0a8cab1f8 100644 -+--- a/arch/arm/Makefile -++++ b/arch/arm/Makefile -+@@ -234,6 +234,7 @@ machine-$(CONFIG_ARCH_VT8500) += vt8500 -+ machine-$(CONFIG_ARCH_ZX) += zx -+ machine-$(CONFIG_ARCH_ZYNQ) += zynq -+ machine-$(CONFIG_PLAT_SPEAR) += spear -++machine-$(CONFIG_ARCH_BSP) += vendor -+ -+ # Platform directory name. This list is sorted alphanumerically -+ # by CONFIG_* macro name. -+diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile -+index 0b3cd7a33..1189a5664 100644 -+--- a/arch/arm/boot/Makefile -++++ b/arch/arm/boot/Makefile -+@@ -12,7 +12,9 @@ -+ # -+ -+ OBJCOPYFLAGS :=-O binary -R .comment -S -+- -++ifeq ($(CONFIG_ARCH_BSP), y) -++include $(srctree)/arch/arm/mach-vendor/Makefile.boot -++endif -+ ifneq ($(MACHINE),) -+ include $(MACHINE)/Makefile.boot -+ endif -+diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S -+index 25cee93b9..684a7e2f0 100644 -+--- a/arch/arm/boot/compressed/head.S -++++ b/arch/arm/boot/compressed/head.S -+@@ -307,6 +307,18 @@ not_angel: -+ addcc r0, r0, pc -+ cmpcc r4, r0 -+ orrcc r4, r4, #1 @ remember we skipped cache_on -++/* all the Cortex-A7 Single Core must fix this bug */ -++#if defined(CONFIG_ARCH_BSP) && defined(CONFIG_ARCH_HI3516CV610_FAMILY) -++/* -++ * 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_l r0, LC1 -+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -+index d93f01ddd..b0be5b0fa 100644 -+--- a/arch/arm/boot/dts/Makefile -++++ b/arch/arm/boot/dts/Makefile -+@@ -1410,3 +1410,14 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ -+ aspeed-bmc-opp-zaius.dtb \ -+ aspeed-bmc-portwell-neptune.dtb \ -+ aspeed-bmc-quanta-q71l.dtb -++ -++ifdef CONFIG_ARCH_BSP -++dtb-$(CONFIG_ARCH_HI3516CV610) += \ -++ hi3516cv610-demb.dtb \ -++ hi3516cv610-demb-flash.dtb \ -++ hi3516cv610-demb-emmc.dtb -++dtb-$(CONFIG_ARCH_HI3516CV608) += \ -++ hi3516cv608-demb.dtb \ -++ hi3516cv608-demb-flash.dtb \ -++ hi3516cv608-demb-emmc.dtb -++endif -+diff --git a/arch/arm/boot/dts/hi3516cv608-demb-emmc.dts b/arch/arm/boot/dts/hi3516cv608-demb-emmc.dts -+new file mode 100755 -+index 000000000..f252b9bfa -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv608-demb-emmc.dts -+@@ -0,0 +1,12 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516cv608-demb.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -++&sdio0 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv608-demb-flash.dts b/arch/arm/boot/dts/hi3516cv608-demb-flash.dts -+new file mode 100755 -+index 000000000..19bc6bc68 -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv608-demb-flash.dts -+@@ -0,0 +1,12 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516cv608-demb.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -++&sdio0 { -++ status = "okay"; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv608-demb.dts b/arch/arm/boot/dts/hi3516cv608-demb.dts -+new file mode 100755 -+index 000000000..f9b10dcaa -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv608-demb.dts -+@@ -0,0 +1,177 @@ -++/* -++ * Copyright (c) 2013-2014 Linaro Ltd. -++ * Copyright (c) 2015-2017 HiSilicon 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 . -++ * -++ */ -++ -++/dts-v1/; -++ -++/ { -++ model = "Hisilicon Hi3516CV608 DEMO Board"; -++ compatible = "hisilicon,hi3516cv608"; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x40000000 0xC0000000>; -++ }; -++}; -++#include "hi3516cv608.dtsi" -++#include "hi3516cv608_family_usb.dtsi" -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "okay"; -++}; -++ -++&uart2 { -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++ clock-frequency = <400000>; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++ clock-frequency = <400000>; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++ clock-frequency = <400000>; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1 { -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&mdio0 { -++ phy-reset-delays-us = <10000 20000 150000>; -++ status = "disabled"; -++ phy0: ethernet-phy@1 { -++ // reg = <0>; -++ }; -++}; -++ -++&femac0 { -++ mac-address = [00 00 00 00 00 00]; -++ phy-mode = "mii"; -++ phy-handle = <&phy0>; -++ status = "disabled"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -++&sdio0 { -++ status = "disabled"; -++}; -++ -++&sdio1 { -++ 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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv608.dtsi b/arch/arm/boot/dts/hi3516cv608.dtsi -+new file mode 100755 -+index 000000000..7fede2aa6 -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv608.dtsi -+@@ -0,0 +1,683 @@ -++/* -++ * Copyright (c) 2013-2014 Linaro Ltd. -++ * Copyright (c) 2015-2017 HiSilicon 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 . -++ * -++ */ -++#include "../../../../include/generated/autoconf.h" -++#include -++#include -++/ { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ interrupt-parent = <&gic>; -++ -++ chosen { -++ bootargs = ""; -++ }; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ }; -++ -++ cpus { -++ #address-cells = <1>; -++ #size-cells = <0>; -++ enable-method = "hisilicon,hi35xx"; -++ -++ cpu@0 { -++ device_type = "cpu"; -++ compatible = "arm,cortex-a7"; -++ clock-frequency = ; -++ reg = <0>; -++ }; -++ -++ cpu@1 { -++ device_type = "cpu"; -++ compatible = "arm,cortex-a7"; -++ clock-frequency = ; -++ reg = <1>; -++ }; -++ -++ }; -++ -++ clock: clock0 { -++ compatible = "vendor,hi3516cv610_clock", "syscon"; -++ #clock-cells = <1>; -++ #reset-cells = <2>; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ reg = <0x11010000 0x5000>; -++ }; -++ -++ gic: interrupt-controller@12400000 { -++ compatible = "arm,cortex-a7-gic"; -++ #interrupt-cells = <3>; -++ #address-cells = <0>; -++ interrupt-controller; -++ /* gic dist base, gic cpu base , no virtual support */ -++ reg = <0x12401000 0x1000>, -++ <0x12402000 0x2000>; -++ }; -++ -++ syscounter { -++ compatible = "arm,armv7-timer"; -++ interrupts = <1 13 0xf08>, -++ <1 14 0xf08>; -++ clock-frequency = <24000000>; -++ always-on; -++ }; -++ -++ soc { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "simple-bus"; -++ ranges; -++ -++ pmu { -++ compatible = "arm,cortex-a7-pmu"; -++ interrupts = <0 88 4>, <0 91 4>; -++ }; -++ -++ edmacv310_0: edma-controller@10280000 { -++ compatible = "vendor,edmacv310"; -++ reg = <0x10280000 0x1000>; -++ interrupts = <0 39 4>; -++ clocks = <&clock HI3516CV610_EDMAC_APBCLK>, <&clock HI3516CV610_EDMAC_AXICLK>; -++ clock-names = "apb_pclk", "axi_aclk"; -++ clock-cells = <2>; -++ resets = <&clock 0x2a80 0>; -++ reset-names = "dma-reset"; -++ dma-requests = <32>; -++ dma-channels = <4>; -++ devid = <0>; -++ #dma-cells = <2>; -++ status = "okay"; -++ }; -++ -++ edmacv310_n_0: edma_n-controller@10280000 { -++ compatible = "vendor,edmacv310_n"; -++ reg = <0x10280000 0x1000>; -++ interrupts = <0 39 4>; -++ clocks = <&clock HI3516CV610_EDMAC_APBCLK>, <&clock HI3516CV610_EDMAC_AXICLK>; -++ clock-names = "apb_pclk", "axi_aclk"; -++ clock-cells = <2>; -++ resets = <&clock 0x2a80 0>; -++ reset-names = "dma-reset"; -++ dma-requests = <32>; -++ dma-channels = <4>; -++ devid = <0>; -++ #dma-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ fmc: flash-memory-controller@10000000 { -++ compatible = "vendor,fmc"; -++ reg = <0x10000000 0x1000>, <0x0f000000 0x1000000>; -++ reg-names = "control", "memory"; -++ clocks = <&clock HI3516CV610_FMC_CLK>; -++ max-dma-size = <0x2000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ -++ sfc:spi_nor_controller { -++ compatible = "vendor,fmc-spi-nor"; -++ assigned-clocks = <&clock HI3516CV610_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ snfc:spi_nand_controller { -++ compatible = "vendor,fmc-spi-nand"; -++ assigned-clocks = <&clock HI3516CV610_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ }; -++ -++ mdio0: mdio@10291100 { -++ compatible = "vendor,femac-mdio"; -++ reg = <0x10291100 0x20>, <0x17950104 0x10>, <0x101e0114 0x4>; -++ clocks = <&clock HI3516CV610_ETH0_CLK>, <&clock HI3516CV610_FEPHY_CLK>; -++ clock-names = "mdio", "phy"; -++ resets = <&clock 0x37cc 3>; -++ reset-names = "internal-phy"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ femac0: ethernet@10290000 { -++ compatible = "vendor,femac-v2"; -++ reg = <0x10290000 0x1000>,<0x10291300 0x200>; -++ interrupts = <0 44 4>; -++ clocks = <&clock HI3516CV610_ETH0_CLK>; -++ resets = <&clock 0x37cc 0>, <&clock 0x37cc 3>; -++ reset-names = "mac", "phy"; -++ }; -++ -++ eth0: hlethernet@10290000 { -++ compatible = "vendor,femac-v2"; -++ reg = <0x10290000 0x10000>, <0x17950104 0x4>, <0x101e0114 0x4>; -++ reg-names = "glb_base", "fephy_sysctrl0", "fephy_trim0"; -++ interrupts = <0 44 4>; -++ clocks = <&clock HI3516CV610_ETH0_CLK>, <&clock HI3516CV610_FEPHY_CLK>; -++ clock-names = "hleth_clk", "phy_clk0"; -++ -++ #address-cells = <1>; -++ #size-cells = <0>; -++ phy-handle = <&hlphy0>; -++ -++ resets = <&clock 0x37cc 0>, <&clock 0x37cc 3>; -++ reset-names = "mac_reset", "reset_phy0"; -++ -++ hlphy0: ethernet-phy-up@0 { -++ reg = <0>; -++ internal-phy; -++ phyaddr-bit-offset = <0>; -++ mac-address = [00 00 00 00 00 00]; -++ phy-mode = "mii"; -++ phy-gpio-base = <0>; -++ phy-gpio-bit = <0>; -++ }; -++ }; -++ -++ sysctrl: system-controller@11020000 { -++ compatible = "vendor,sysctrl"; -++ reg = <0x11020000 0x4000>; -++ reboot-offset = <0x4>; -++ #clock-cells = <1>; -++ }; -++ -++ amba { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "arm,amba-bus"; -++ ranges; -++ -++ uart0: uart@11040000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11040000 0x1000>; -++ interrupts = <0 10 4>; -++ clocks = <&clock HI3516CV610_UART0_CLK>; -++ clock-names = "apb_pclk"; -++ /* dmas = <&edmacv310_0 11 11>, <&edmacv310_0 10 10>; -++ dma-names = "tx","rx"; */ -++ resets = <&clock 0x4180 0>; -++ reset-names = "bsp_uart_rst"; -++ status = "okay"; -++ }; -++ -++ uart1: uart@11041000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11041000 0x1000>; -++ interrupts = <0 11 4>; -++ clocks = <&clock HI3516CV610_UART1_CLK>; -++ clock-names = "apb_pclk"; -++ /* dmas = <&edmacv310_0 13 13>, <&edmacv310_0 12 12>; -++ dma-names = "tx","rx"; */ -++ resets = <&clock 0x4188 0>; -++ reset-names = "bsp_uart_rst"; -++ status = "disabled"; -++ }; -++ -++ uart2: uart@11042000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11042000 0x1000>; -++ interrupts = <0 12 4>; -++ clocks = <&clock HI3516CV610_UART2_CLK>; -++ clock-names = "apb_pclk"; -++ /* dmas = <&edmacv310_0 15 15>, <&edmacv310_0 14 14>; -++ dma-names = "tx","rx"; */ -++ resets = <&clock 0x4190 0>; -++ reset-names = "bsp_uart_rst"; -++ status = "disabled"; -++ }; -++ -++ i2c_bus0: i2c@11060000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11060000 0x1000>; -++ clocks = <&clock HI3516CV610_I2C0_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4280 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ i2c_bus1: i2c@11061000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11061000 0x1000>; -++ clocks = <&clock HI3516CV610_I2C1_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4288 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ }; -++ -++ i2c_bus2: i2c@11062000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11062000 0x1000>; -++ clocks = <&clock HI3516CV610_I2C2_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4290 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ }; -++ -++ spi_bus0: spi@11070000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11070000 0x1000>, <0x1795000c 0x4>; -++ interrupts = <0 19 4>; -++ clocks = <&clock HI3516CV610_SPI0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4480 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ vendor,slave_mode = <0>; -++ vendor,slave_tx_disable = <0>; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 7 7>, <&edmacv310_0 6 6>; -++ dma-names = "tx","rx"; */ -++ status = "disabled"; -++ }; -++ -++ spi_bus1: spi@11071000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11071000 0x1000>; -++ interrupts = <0 20 4>; -++ clocks = <&clock HI3516CV610_SPI1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4488 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ vendor,slave_mode = <0>; -++ vendor,slave_tx_disable = <0>; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 9 9>, <&edmacv310_0 8 8>; -++ dma-names = "tx","rx"; */ -++ status = "disabled"; -++ }; -++ -++ ioconfig0: ioconfig0@10260000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x10260000 0x10000>; -++ }; -++ -++ ioconfig1: ioconfig1@11130000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x11130000 0x10000>; -++ }; -++ -++ /* EMMC/SD/SDIO DTS nodes */ -++ mmc0: eMMC@0x10030000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10030000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3516CV610_MMC0_CLK>, <&clock HI3516CV610_MMC0_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x35c0 16>, <&clock 0x35c0 17>, <&clock 0x35c0 18>, <&clock 0x35c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ non-removable; -++ iocfg_regmap = <&ioconfig0>; -++ bus-width = <8>; -++ cap-mmc-highspeed; -++ mmc-hs200-1_8v; -++ mmc-hs400-1_8v; -++ //mmc-hs400-enhanced-strobe; -++ cap-mmc-hw-reset; -++ no-sdio; -++ no-sd; -++ devid = <0>; -++ status = "okay"; -++ }; -++ -++ /* EMMC/SD/SDIO DTS nodes */ -++ sdio0: SDIO@0x10030000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10030000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3516CV610_MMC0_CLK>, <&clock HI3516CV610_MMC0_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x35c0 16>, <&clock 0x35c0 17>, <&clock 0x35c0 18>, <&clock 0x35c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <50000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig0>; -++ bus-width = <4>; -++ cap-sd-highspeed; -++ full-pwr-cycle; -++ disable-wp; -++ no-mmc; -++ devid = <1>; -++ status = "okay"; -++ }; -++ -++ sdio1: SDIO1@0x10040000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3516CV610_MMC1_CLK>, <&clock HI3516CV610_MMC1_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x36c0 16>, <&clock 0x36c0 17>, <&clock 0x36c0 18>, <&clock 0x36c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <50000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = <4>; -++ cap-sd-highspeed; -++ full-pwr-cycle; -++ disable-wp; -++ no-mmc; -++ devid = <2>; -++ status = "okay"; -++ }; -++ -++ gpio_chip0: gpio_chip@11090000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11090000 0x1000>; -++ interrupts = <0 23 4>; -++ clocks = <&clock HI3516CV610_GPIO0_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip1: gpio_chip@11091000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11091000 0x1000>; -++ interrupts = <0 24 4>; -++ clocks = <&clock HI3516CV610_GPIO1_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip2: gpio_chip@11092000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11092000 0x1000>; -++ interrupts = <0 25 4>; -++ clocks = <&clock HI3516CV610_GPIO2_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip3: gpio_chip@11093000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11093000 0x1000>; -++ interrupts = <0 26 4>; -++ clocks = <&clock HI3516CV610_GPIO3_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip4: gpio_chip@11094000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11094000 0x1000>; -++ interrupts = <0 27 4>; -++ clocks = <&clock HI3516CV610_GPIO4_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip5: gpio_chip@11095000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11095000 0x1000>; -++ interrupts = <0 28 4>; -++ clocks = <&clock HI3516CV610_GPIO5_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip6: gpio_chip@11096000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11096000 0x1000>; -++ interrupts = <0 29 4>; -++ clocks = <&clock HI3516CV610_GPIO6_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip7: gpio_chip@11097000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11097000 0x1000>; -++ interrupts = <0 30 4>; -++ clocks = <&clock HI3516CV610_GPIO7_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip8: gpio_chip@11098000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11098000 0x1000>; -++ interrupts = <0 31 4>; -++ clocks = <&clock HI3516CV610_GPIO8_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip9: gpio_chip@11099000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11099000 0x1000>; -++ interrupts = <0 32 4>; -++ clocks = <&clock HI3516CV610_GPIO9_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip10: gpio_chip@1109a000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109a000 0x1000>; -++ interrupts = <0 33 4>; -++ clocks = <&clock HI3516CV610_GPIO10_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ rtc: rtc@11110000 { -++ compatible = "vendor,rtc"; -++ reg = <0x11110000 0x10000>; -++ interrupts = <0 37 4>; -++ status = "disabled"; -++ }; -++ -++ adc: adc@11100000 { -++ compatible = "vendor,lsadc"; -++ reg = <0x11100000 0x1000>; -++ interrupts = <0 36 4>; -++ interrupt-names = "adc"; -++ resets = <&clock 0x46c0 0>; -++ reset-names = "lsadc-crg"; -++ status = "okay"; -++ }; -++ -++ wdg: wdg@0x11030000 { -++ compatible = "vendor,wdg"; -++ reg = <0x11030000 0x1000>; -++ reg-names = "wdg"; -++ interrupts = <0 3 4>; -++ interrupt-names = "wdg"; -++ }; -++ }; -++ }; -++ -++ media { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "simple-bus"; -++ interrupt-parent = <&gic>; -++ ranges; -++ -++ /*SDK DTS nodes*/ -++ sys: sys@11010000 { -++ compatible = "vendor,sys"; -++ reg = <0x11015000 0xB000>, -++ <0x11020000 0x4000>, -++ <0x11140000 0x20000>, -++ <0X11024000 0x5000>, -++ <0x10270000 0x1000>; -++ reg-names = "crg", "sys", "ddr", "misc", "ahb_misc"; -++ }; -++ -++ vi: vi@0x17400000 { -++ compatible = "vendor,vi"; -++ reg = <0x17400000 0x100000>, -++ <0x17800000 0x40000>; -++ reg-names = "vi_cap0", "vi_proc0"; -++ interrupts = <0 65 4>, <0 66 4>, <0 67 4>; -++ interrupt-names = "vi_cap0", "vi_cap1", "vi_proc0"; -++ }; -++ -++ mipi_rx: mipi_rx@0x173c0000 { -++ compatible = "vendor,mipi_rx"; -++ reg = <0x173c0000 0x10000>; -++ reg-names = "mipi_rx"; -++ interrupts = <0 64 4>; -++ interrupt-names = "mipi_rx"; -++ }; -++ -++ vpss: vpss@0x17900000 { -++ compatible = "vendor,vpss"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "vpss0"; -++ interrupts = <0 71 4>; -++ interrupt-names = "vpss0"; -++ }; -++ -++ vgs: vgs@0x17240000 { -++ compatible = "vendor,vgs"; -++ reg = <0x17240000 0x10000>; -++ reg-names = "vgs0"; -++ interrupts = <0 72 4>; -++ interrupt-names = "vgs0"; -++ }; -++ -++ venc: venc@0x17140000 { -++ compatible = "vendor,venc"; -++ reg = <0x17140000 0x10000>,<0x171c0000 0x10000>; -++ reg-names = "vedu0","jpge"; -++ interrupts = <0 69 4>, <0 70 4>; -++ interrupt-names = "vedu0", "jpge"; -++ }; -++ -++ aiao: aiao@17c00000 { -++ compatible = "vendor,aiao"; -++ reg = <0x17c00000 0x10000>,<0x17c40000 0x10000>; -++ reg-names = "aiao","acodec"; -++ interrupts = <0 63 4>; -++ interrupt-names = "AIO"; -++ }; -++ -++ cipher: cipher@0x101F0000 { -++ compatible = "vendor,cipher"; -++ reg = <0x101F0000 0x10000>,<0x101EC000 0x2000>; -++ reg-names = "spacc","pke"; -++ interrupts = <0 50 4>,<0 51 4>, -++ <0 52 4>,<0 53 4>; -++ interrupt-names = "spacc_tee","spacc_ree","pke_tee","pke_ree"; -++ }; -++ -++ km: km@0x101EA000 { -++ compatible = "vendor,km"; -++ reg = <0x101EA000 0x2000>; -++ reg-names = "km"; -++ interrupts = <0 54 4>,<0 55 4>, -++ <0 56 4>,<0 57 4>; -++ interrupt-names = "rkp_tee","rkp_ree","klad_tee","klad_ree"; -++ }; -++ -++ otp: otp@0x101E0000 { -++ compatible = "vendor,otp"; -++ reg = <0x101E0000 0x2000>; -++ reg-names = "otp"; -++ }; -++ -++ trng: trng@0x101EE000 { -++ compatible = "vendor,trng"; -++ reg = <0x101EE000 0x1000>; -++ reg-names = "trng"; -++ }; -++ }; -++ -++ firmware { -++ optee { -++ compatible = "linaro,optee-tz"; -++ method = "smc"; -++ }; -++ }; -++ -++ npu: npu@0x14000000 { -++ compatible = "vendor,svp_npu"; -++ reg = <0x14000000 0x800000>; -++ reg-names = "svp_npu"; -++ interrupts = <0 75 4>; -++ interrupt-names = "svp_npu_ns0"; -++ }; -++ -++ ive: ive@0x14000000 { -++ compatible = "vendor,ive"; -++ reg = <0x14000000 0x800000>; -++ reg-names = "ive"; -++ interrupts = <0 76 4>; -++ interrupt-names = "ive0"; -++ }; -++ pwm1: pwm@0x11080000 { -++ compatible = "vendor,pwm"; -++ reg = <0x11080000 0x1000>; -++ reg-names = "pwm1"; -++ clocks = <&clock HI3516CV610_PWM1_CLK>; -++ clock-names = "pwm1"; -++ resets = <&clock 0x4598 0>; -++ reset-names = "pwm1"; -++ status = "okay"; -++ }; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv608_family_usb.dtsi b/arch/arm/boot/dts/hi3516cv608_family_usb.dtsi -+new file mode 100755 -+index 000000000..21b38058c -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv608_family_usb.dtsi -+@@ -0,0 +1,59 @@ -++#include -++ -++/ { -++ ups_clock:ups_clock { -++ compatible = "basedrv-ip,clock"; -++ reg = <0x11010000 0x10000>,<0x11024000 0x5000>; -++ reg-names = "peri_crg","peri_ctrl"; -++ #clock-cells = <1>; -++ #reset-cells = <2>; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ status = "okay"; -++ }; -++ -++ usb2phy0:usb2phy@0x10310000 { -++ compatible = "usb2phy,xvpphy"; -++ reg = <0x10310000 0x1000 0x11024000 0x5000 0x101E0110 0x4>; -++ reg-names = "u2_phy", "peri_ctrl", "otp_trim"; -++ otp-phy-trim-bitshift = <21>; -++ clocks = <&ups_clock PERI_CRG3632_USB2_PHY0>; -++ clock-names = "phy-clk"; -++ #phy-cells = <0>; -++ u2phy-trim = <0xA33C82B 0x0050F0F>; -++ status = "okay"; -++ }; -++ -++ usb20drd:usb20drd@0x10300000 { -++ compatible = "wing-usb,drd"; -++ reg = <0x10300000 0x10000>; -++ reg-names = "u2_ctrl"; -++ controller_id = <0>; -++ support-drd; -++ is-usb2; -++ filter-se0-fsls; -++ phys = <&usb2phy0>; -++ phy-names = "usb2-phy"; -++ clocks = <&ups_clock PERI_CRG3664_USB30_CTRL0>; -++ clock-names = "ctrl-clk"; -++ #clock-cells = <1>; -++ init_mode="device"; -++ status = "okay"; -++ ranges; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ dwc3@10300000{ -++ compatible = "snps,dwc3"; -++ reg = <0x10300000 0x10000>; -++ interrupts = ; -++ interrupt-names = "peripheral"; -++ maximum-speed = "high-speed"; -++ dr_mode = "otg"; -++ usb-role-switch; -++ snps,dis_u2_susphy_quirk; -++ snps,usb2-lpm-disable; -++ linux,sysdev_is_parent; -++ extcon = <&usb20drd>; -++ }; -++ }; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv610-demb-emmc.dts b/arch/arm/boot/dts/hi3516cv610-demb-emmc.dts -+new file mode 100755 -+index 000000000..75df83019 -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv610-demb-emmc.dts -+@@ -0,0 +1,12 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516cv610-demb.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -++&sdio0 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv610-demb-flash.dts b/arch/arm/boot/dts/hi3516cv610-demb-flash.dts -+new file mode 100755 -+index 000000000..a9874d96b -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv610-demb-flash.dts -+@@ -0,0 +1,12 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516cv610-demb.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -++&sdio0 { -++ status = "okay"; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv610-demb.dts b/arch/arm/boot/dts/hi3516cv610-demb.dts -+new file mode 100755 -+index 000000000..7b8346f4a -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv610-demb.dts -+@@ -0,0 +1,177 @@ -++/* -++ * Copyright (c) 2013-2014 Linaro Ltd. -++ * Copyright (c) 2015-2017 HiSilicon 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 . -++ * -++ */ -++ -++/dts-v1/; -++ -++/ { -++ model = "Hisilicon Hi3516CV610 DEMO Board"; -++ compatible = "hisilicon,hi3516cv610"; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x40000000 0xC0000000>; -++ }; -++}; -++#include "hi3516cv610.dtsi" -++#include "hi3516cv610_family_usb.dtsi" -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "okay"; -++}; -++ -++&uart2 { -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++ clock-frequency = <400000>; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++ clock-frequency = <400000>; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++ clock-frequency = <400000>; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1 { -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&mdio0 { -++ phy-reset-delays-us = <10000 20000 150000>; -++ status = "disabled"; -++ phy0: ethernet-phy@1 { -++ // reg = <0>; -++ }; -++}; -++ -++&femac0 { -++ mac-address = [00 00 00 00 00 00]; -++ phy-mode = "mii"; -++ phy-handle = <&phy0>; -++ status = "disabled"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -++&sdio0 { -++ status = "disabled"; -++}; -++ -++&sdio1 { -++ 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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv610.dtsi b/arch/arm/boot/dts/hi3516cv610.dtsi -+new file mode 100755 -+index 000000000..7fede2aa6 -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv610.dtsi -+@@ -0,0 +1,683 @@ -++/* -++ * Copyright (c) 2013-2014 Linaro Ltd. -++ * Copyright (c) 2015-2017 HiSilicon 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 . -++ * -++ */ -++#include "../../../../include/generated/autoconf.h" -++#include -++#include -++/ { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ interrupt-parent = <&gic>; -++ -++ chosen { -++ bootargs = ""; -++ }; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ }; -++ -++ cpus { -++ #address-cells = <1>; -++ #size-cells = <0>; -++ enable-method = "hisilicon,hi35xx"; -++ -++ cpu@0 { -++ device_type = "cpu"; -++ compatible = "arm,cortex-a7"; -++ clock-frequency = ; -++ reg = <0>; -++ }; -++ -++ cpu@1 { -++ device_type = "cpu"; -++ compatible = "arm,cortex-a7"; -++ clock-frequency = ; -++ reg = <1>; -++ }; -++ -++ }; -++ -++ clock: clock0 { -++ compatible = "vendor,hi3516cv610_clock", "syscon"; -++ #clock-cells = <1>; -++ #reset-cells = <2>; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ reg = <0x11010000 0x5000>; -++ }; -++ -++ gic: interrupt-controller@12400000 { -++ compatible = "arm,cortex-a7-gic"; -++ #interrupt-cells = <3>; -++ #address-cells = <0>; -++ interrupt-controller; -++ /* gic dist base, gic cpu base , no virtual support */ -++ reg = <0x12401000 0x1000>, -++ <0x12402000 0x2000>; -++ }; -++ -++ syscounter { -++ compatible = "arm,armv7-timer"; -++ interrupts = <1 13 0xf08>, -++ <1 14 0xf08>; -++ clock-frequency = <24000000>; -++ always-on; -++ }; -++ -++ soc { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "simple-bus"; -++ ranges; -++ -++ pmu { -++ compatible = "arm,cortex-a7-pmu"; -++ interrupts = <0 88 4>, <0 91 4>; -++ }; -++ -++ edmacv310_0: edma-controller@10280000 { -++ compatible = "vendor,edmacv310"; -++ reg = <0x10280000 0x1000>; -++ interrupts = <0 39 4>; -++ clocks = <&clock HI3516CV610_EDMAC_APBCLK>, <&clock HI3516CV610_EDMAC_AXICLK>; -++ clock-names = "apb_pclk", "axi_aclk"; -++ clock-cells = <2>; -++ resets = <&clock 0x2a80 0>; -++ reset-names = "dma-reset"; -++ dma-requests = <32>; -++ dma-channels = <4>; -++ devid = <0>; -++ #dma-cells = <2>; -++ status = "okay"; -++ }; -++ -++ edmacv310_n_0: edma_n-controller@10280000 { -++ compatible = "vendor,edmacv310_n"; -++ reg = <0x10280000 0x1000>; -++ interrupts = <0 39 4>; -++ clocks = <&clock HI3516CV610_EDMAC_APBCLK>, <&clock HI3516CV610_EDMAC_AXICLK>; -++ clock-names = "apb_pclk", "axi_aclk"; -++ clock-cells = <2>; -++ resets = <&clock 0x2a80 0>; -++ reset-names = "dma-reset"; -++ dma-requests = <32>; -++ dma-channels = <4>; -++ devid = <0>; -++ #dma-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ fmc: flash-memory-controller@10000000 { -++ compatible = "vendor,fmc"; -++ reg = <0x10000000 0x1000>, <0x0f000000 0x1000000>; -++ reg-names = "control", "memory"; -++ clocks = <&clock HI3516CV610_FMC_CLK>; -++ max-dma-size = <0x2000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ -++ sfc:spi_nor_controller { -++ compatible = "vendor,fmc-spi-nor"; -++ assigned-clocks = <&clock HI3516CV610_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ snfc:spi_nand_controller { -++ compatible = "vendor,fmc-spi-nand"; -++ assigned-clocks = <&clock HI3516CV610_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ }; -++ -++ mdio0: mdio@10291100 { -++ compatible = "vendor,femac-mdio"; -++ reg = <0x10291100 0x20>, <0x17950104 0x10>, <0x101e0114 0x4>; -++ clocks = <&clock HI3516CV610_ETH0_CLK>, <&clock HI3516CV610_FEPHY_CLK>; -++ clock-names = "mdio", "phy"; -++ resets = <&clock 0x37cc 3>; -++ reset-names = "internal-phy"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ femac0: ethernet@10290000 { -++ compatible = "vendor,femac-v2"; -++ reg = <0x10290000 0x1000>,<0x10291300 0x200>; -++ interrupts = <0 44 4>; -++ clocks = <&clock HI3516CV610_ETH0_CLK>; -++ resets = <&clock 0x37cc 0>, <&clock 0x37cc 3>; -++ reset-names = "mac", "phy"; -++ }; -++ -++ eth0: hlethernet@10290000 { -++ compatible = "vendor,femac-v2"; -++ reg = <0x10290000 0x10000>, <0x17950104 0x4>, <0x101e0114 0x4>; -++ reg-names = "glb_base", "fephy_sysctrl0", "fephy_trim0"; -++ interrupts = <0 44 4>; -++ clocks = <&clock HI3516CV610_ETH0_CLK>, <&clock HI3516CV610_FEPHY_CLK>; -++ clock-names = "hleth_clk", "phy_clk0"; -++ -++ #address-cells = <1>; -++ #size-cells = <0>; -++ phy-handle = <&hlphy0>; -++ -++ resets = <&clock 0x37cc 0>, <&clock 0x37cc 3>; -++ reset-names = "mac_reset", "reset_phy0"; -++ -++ hlphy0: ethernet-phy-up@0 { -++ reg = <0>; -++ internal-phy; -++ phyaddr-bit-offset = <0>; -++ mac-address = [00 00 00 00 00 00]; -++ phy-mode = "mii"; -++ phy-gpio-base = <0>; -++ phy-gpio-bit = <0>; -++ }; -++ }; -++ -++ sysctrl: system-controller@11020000 { -++ compatible = "vendor,sysctrl"; -++ reg = <0x11020000 0x4000>; -++ reboot-offset = <0x4>; -++ #clock-cells = <1>; -++ }; -++ -++ amba { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "arm,amba-bus"; -++ ranges; -++ -++ uart0: uart@11040000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11040000 0x1000>; -++ interrupts = <0 10 4>; -++ clocks = <&clock HI3516CV610_UART0_CLK>; -++ clock-names = "apb_pclk"; -++ /* dmas = <&edmacv310_0 11 11>, <&edmacv310_0 10 10>; -++ dma-names = "tx","rx"; */ -++ resets = <&clock 0x4180 0>; -++ reset-names = "bsp_uart_rst"; -++ status = "okay"; -++ }; -++ -++ uart1: uart@11041000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11041000 0x1000>; -++ interrupts = <0 11 4>; -++ clocks = <&clock HI3516CV610_UART1_CLK>; -++ clock-names = "apb_pclk"; -++ /* dmas = <&edmacv310_0 13 13>, <&edmacv310_0 12 12>; -++ dma-names = "tx","rx"; */ -++ resets = <&clock 0x4188 0>; -++ reset-names = "bsp_uart_rst"; -++ status = "disabled"; -++ }; -++ -++ uart2: uart@11042000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11042000 0x1000>; -++ interrupts = <0 12 4>; -++ clocks = <&clock HI3516CV610_UART2_CLK>; -++ clock-names = "apb_pclk"; -++ /* dmas = <&edmacv310_0 15 15>, <&edmacv310_0 14 14>; -++ dma-names = "tx","rx"; */ -++ resets = <&clock 0x4190 0>; -++ reset-names = "bsp_uart_rst"; -++ status = "disabled"; -++ }; -++ -++ i2c_bus0: i2c@11060000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11060000 0x1000>; -++ clocks = <&clock HI3516CV610_I2C0_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4280 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ i2c_bus1: i2c@11061000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11061000 0x1000>; -++ clocks = <&clock HI3516CV610_I2C1_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4288 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ }; -++ -++ i2c_bus2: i2c@11062000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11062000 0x1000>; -++ clocks = <&clock HI3516CV610_I2C2_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4290 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ }; -++ -++ spi_bus0: spi@11070000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11070000 0x1000>, <0x1795000c 0x4>; -++ interrupts = <0 19 4>; -++ clocks = <&clock HI3516CV610_SPI0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4480 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ vendor,slave_mode = <0>; -++ vendor,slave_tx_disable = <0>; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 7 7>, <&edmacv310_0 6 6>; -++ dma-names = "tx","rx"; */ -++ status = "disabled"; -++ }; -++ -++ spi_bus1: spi@11071000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11071000 0x1000>; -++ interrupts = <0 20 4>; -++ clocks = <&clock HI3516CV610_SPI1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4488 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ vendor,slave_mode = <0>; -++ vendor,slave_tx_disable = <0>; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 9 9>, <&edmacv310_0 8 8>; -++ dma-names = "tx","rx"; */ -++ status = "disabled"; -++ }; -++ -++ ioconfig0: ioconfig0@10260000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x10260000 0x10000>; -++ }; -++ -++ ioconfig1: ioconfig1@11130000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x11130000 0x10000>; -++ }; -++ -++ /* EMMC/SD/SDIO DTS nodes */ -++ mmc0: eMMC@0x10030000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10030000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3516CV610_MMC0_CLK>, <&clock HI3516CV610_MMC0_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x35c0 16>, <&clock 0x35c0 17>, <&clock 0x35c0 18>, <&clock 0x35c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ non-removable; -++ iocfg_regmap = <&ioconfig0>; -++ bus-width = <8>; -++ cap-mmc-highspeed; -++ mmc-hs200-1_8v; -++ mmc-hs400-1_8v; -++ //mmc-hs400-enhanced-strobe; -++ cap-mmc-hw-reset; -++ no-sdio; -++ no-sd; -++ devid = <0>; -++ status = "okay"; -++ }; -++ -++ /* EMMC/SD/SDIO DTS nodes */ -++ sdio0: SDIO@0x10030000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10030000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3516CV610_MMC0_CLK>, <&clock HI3516CV610_MMC0_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x35c0 16>, <&clock 0x35c0 17>, <&clock 0x35c0 18>, <&clock 0x35c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <50000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig0>; -++ bus-width = <4>; -++ cap-sd-highspeed; -++ full-pwr-cycle; -++ disable-wp; -++ no-mmc; -++ devid = <1>; -++ status = "okay"; -++ }; -++ -++ sdio1: SDIO1@0x10040000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3516CV610_MMC1_CLK>, <&clock HI3516CV610_MMC1_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x36c0 16>, <&clock 0x36c0 17>, <&clock 0x36c0 18>, <&clock 0x36c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <50000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = <4>; -++ cap-sd-highspeed; -++ full-pwr-cycle; -++ disable-wp; -++ no-mmc; -++ devid = <2>; -++ status = "okay"; -++ }; -++ -++ gpio_chip0: gpio_chip@11090000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11090000 0x1000>; -++ interrupts = <0 23 4>; -++ clocks = <&clock HI3516CV610_GPIO0_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip1: gpio_chip@11091000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11091000 0x1000>; -++ interrupts = <0 24 4>; -++ clocks = <&clock HI3516CV610_GPIO1_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip2: gpio_chip@11092000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11092000 0x1000>; -++ interrupts = <0 25 4>; -++ clocks = <&clock HI3516CV610_GPIO2_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip3: gpio_chip@11093000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11093000 0x1000>; -++ interrupts = <0 26 4>; -++ clocks = <&clock HI3516CV610_GPIO3_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip4: gpio_chip@11094000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11094000 0x1000>; -++ interrupts = <0 27 4>; -++ clocks = <&clock HI3516CV610_GPIO4_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip5: gpio_chip@11095000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11095000 0x1000>; -++ interrupts = <0 28 4>; -++ clocks = <&clock HI3516CV610_GPIO5_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip6: gpio_chip@11096000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11096000 0x1000>; -++ interrupts = <0 29 4>; -++ clocks = <&clock HI3516CV610_GPIO6_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip7: gpio_chip@11097000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11097000 0x1000>; -++ interrupts = <0 30 4>; -++ clocks = <&clock HI3516CV610_GPIO7_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip8: gpio_chip@11098000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11098000 0x1000>; -++ interrupts = <0 31 4>; -++ clocks = <&clock HI3516CV610_GPIO8_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip9: gpio_chip@11099000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11099000 0x1000>; -++ interrupts = <0 32 4>; -++ clocks = <&clock HI3516CV610_GPIO9_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ gpio_chip10: gpio_chip@1109a000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109a000 0x1000>; -++ interrupts = <0 33 4>; -++ clocks = <&clock HI3516CV610_GPIO10_CLK>; -++ clock-names = "apb_pclk"; -++ #gpio-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ rtc: rtc@11110000 { -++ compatible = "vendor,rtc"; -++ reg = <0x11110000 0x10000>; -++ interrupts = <0 37 4>; -++ status = "disabled"; -++ }; -++ -++ adc: adc@11100000 { -++ compatible = "vendor,lsadc"; -++ reg = <0x11100000 0x1000>; -++ interrupts = <0 36 4>; -++ interrupt-names = "adc"; -++ resets = <&clock 0x46c0 0>; -++ reset-names = "lsadc-crg"; -++ status = "okay"; -++ }; -++ -++ wdg: wdg@0x11030000 { -++ compatible = "vendor,wdg"; -++ reg = <0x11030000 0x1000>; -++ reg-names = "wdg"; -++ interrupts = <0 3 4>; -++ interrupt-names = "wdg"; -++ }; -++ }; -++ }; -++ -++ media { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "simple-bus"; -++ interrupt-parent = <&gic>; -++ ranges; -++ -++ /*SDK DTS nodes*/ -++ sys: sys@11010000 { -++ compatible = "vendor,sys"; -++ reg = <0x11015000 0xB000>, -++ <0x11020000 0x4000>, -++ <0x11140000 0x20000>, -++ <0X11024000 0x5000>, -++ <0x10270000 0x1000>; -++ reg-names = "crg", "sys", "ddr", "misc", "ahb_misc"; -++ }; -++ -++ vi: vi@0x17400000 { -++ compatible = "vendor,vi"; -++ reg = <0x17400000 0x100000>, -++ <0x17800000 0x40000>; -++ reg-names = "vi_cap0", "vi_proc0"; -++ interrupts = <0 65 4>, <0 66 4>, <0 67 4>; -++ interrupt-names = "vi_cap0", "vi_cap1", "vi_proc0"; -++ }; -++ -++ mipi_rx: mipi_rx@0x173c0000 { -++ compatible = "vendor,mipi_rx"; -++ reg = <0x173c0000 0x10000>; -++ reg-names = "mipi_rx"; -++ interrupts = <0 64 4>; -++ interrupt-names = "mipi_rx"; -++ }; -++ -++ vpss: vpss@0x17900000 { -++ compatible = "vendor,vpss"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "vpss0"; -++ interrupts = <0 71 4>; -++ interrupt-names = "vpss0"; -++ }; -++ -++ vgs: vgs@0x17240000 { -++ compatible = "vendor,vgs"; -++ reg = <0x17240000 0x10000>; -++ reg-names = "vgs0"; -++ interrupts = <0 72 4>; -++ interrupt-names = "vgs0"; -++ }; -++ -++ venc: venc@0x17140000 { -++ compatible = "vendor,venc"; -++ reg = <0x17140000 0x10000>,<0x171c0000 0x10000>; -++ reg-names = "vedu0","jpge"; -++ interrupts = <0 69 4>, <0 70 4>; -++ interrupt-names = "vedu0", "jpge"; -++ }; -++ -++ aiao: aiao@17c00000 { -++ compatible = "vendor,aiao"; -++ reg = <0x17c00000 0x10000>,<0x17c40000 0x10000>; -++ reg-names = "aiao","acodec"; -++ interrupts = <0 63 4>; -++ interrupt-names = "AIO"; -++ }; -++ -++ cipher: cipher@0x101F0000 { -++ compatible = "vendor,cipher"; -++ reg = <0x101F0000 0x10000>,<0x101EC000 0x2000>; -++ reg-names = "spacc","pke"; -++ interrupts = <0 50 4>,<0 51 4>, -++ <0 52 4>,<0 53 4>; -++ interrupt-names = "spacc_tee","spacc_ree","pke_tee","pke_ree"; -++ }; -++ -++ km: km@0x101EA000 { -++ compatible = "vendor,km"; -++ reg = <0x101EA000 0x2000>; -++ reg-names = "km"; -++ interrupts = <0 54 4>,<0 55 4>, -++ <0 56 4>,<0 57 4>; -++ interrupt-names = "rkp_tee","rkp_ree","klad_tee","klad_ree"; -++ }; -++ -++ otp: otp@0x101E0000 { -++ compatible = "vendor,otp"; -++ reg = <0x101E0000 0x2000>; -++ reg-names = "otp"; -++ }; -++ -++ trng: trng@0x101EE000 { -++ compatible = "vendor,trng"; -++ reg = <0x101EE000 0x1000>; -++ reg-names = "trng"; -++ }; -++ }; -++ -++ firmware { -++ optee { -++ compatible = "linaro,optee-tz"; -++ method = "smc"; -++ }; -++ }; -++ -++ npu: npu@0x14000000 { -++ compatible = "vendor,svp_npu"; -++ reg = <0x14000000 0x800000>; -++ reg-names = "svp_npu"; -++ interrupts = <0 75 4>; -++ interrupt-names = "svp_npu_ns0"; -++ }; -++ -++ ive: ive@0x14000000 { -++ compatible = "vendor,ive"; -++ reg = <0x14000000 0x800000>; -++ reg-names = "ive"; -++ interrupts = <0 76 4>; -++ interrupt-names = "ive0"; -++ }; -++ pwm1: pwm@0x11080000 { -++ compatible = "vendor,pwm"; -++ reg = <0x11080000 0x1000>; -++ reg-names = "pwm1"; -++ clocks = <&clock HI3516CV610_PWM1_CLK>; -++ clock-names = "pwm1"; -++ resets = <&clock 0x4598 0>; -++ reset-names = "pwm1"; -++ status = "okay"; -++ }; -++}; -+diff --git a/arch/arm/boot/dts/hi3516cv610_family_usb.dtsi b/arch/arm/boot/dts/hi3516cv610_family_usb.dtsi -+new file mode 100755 -+index 000000000..21b38058c -+--- /dev/null -++++ b/arch/arm/boot/dts/hi3516cv610_family_usb.dtsi -+@@ -0,0 +1,59 @@ -++#include -++ -++/ { -++ ups_clock:ups_clock { -++ compatible = "basedrv-ip,clock"; -++ reg = <0x11010000 0x10000>,<0x11024000 0x5000>; -++ reg-names = "peri_crg","peri_ctrl"; -++ #clock-cells = <1>; -++ #reset-cells = <2>; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ status = "okay"; -++ }; -++ -++ usb2phy0:usb2phy@0x10310000 { -++ compatible = "usb2phy,xvpphy"; -++ reg = <0x10310000 0x1000 0x11024000 0x5000 0x101E0110 0x4>; -++ reg-names = "u2_phy", "peri_ctrl", "otp_trim"; -++ otp-phy-trim-bitshift = <21>; -++ clocks = <&ups_clock PERI_CRG3632_USB2_PHY0>; -++ clock-names = "phy-clk"; -++ #phy-cells = <0>; -++ u2phy-trim = <0xA33C82B 0x0050F0F>; -++ status = "okay"; -++ }; -++ -++ usb20drd:usb20drd@0x10300000 { -++ compatible = "wing-usb,drd"; -++ reg = <0x10300000 0x10000>; -++ reg-names = "u2_ctrl"; -++ controller_id = <0>; -++ support-drd; -++ is-usb2; -++ filter-se0-fsls; -++ phys = <&usb2phy0>; -++ phy-names = "usb2-phy"; -++ clocks = <&ups_clock PERI_CRG3664_USB30_CTRL0>; -++ clock-names = "ctrl-clk"; -++ #clock-cells = <1>; -++ init_mode="device"; -++ status = "okay"; -++ ranges; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ dwc3@10300000{ -++ compatible = "snps,dwc3"; -++ reg = <0x10300000 0x10000>; -++ interrupts = ; -++ interrupt-names = "peripheral"; -++ maximum-speed = "high-speed"; -++ dr_mode = "otg"; -++ usb-role-switch; -++ snps,dis_u2_susphy_quirk; -++ snps,usb2-lpm-disable; -++ linux,sysdev_is_parent; -++ extcon = <&usb20drd>; -++ }; -++ }; -++}; -+diff --git a/arch/arm/configs/hi3516cv608_debug_defconfig b/arch/arm/configs/hi3516cv608_debug_defconfig -+new file mode 100755 -+index 000000000..681594126 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv608_debug_defconfig -+@@ -0,0 +1,188 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV608=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++CONFIG_V4L_PLATFORM_DRIVERS=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++# CONFIG_NVMEM is not set -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_WING_UPS_MISSILE_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv608_defconfig b/arch/arm/configs/hi3516cv608_defconfig -+new file mode 100755 -+index 000000000..f22c61b28 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv608_defconfig -+@@ -0,0 +1,190 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV608=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++CONFIG_V4L_PLATFORM_DRIVERS=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++# CONFIG_NVMEM is not set -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_WING_UPS_MISSILE_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_STRICT_DEVMEM=y -++CONFIG_IO_STRICT_DEVMEM=y -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv608_emmc_debug_defconfig b/arch/arm/configs/hi3516cv608_emmc_debug_defconfig -+new file mode 100755 -+index 000000000..c7c087ad7 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv608_emmc_debug_defconfig -+@@ -0,0 +1,175 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV608=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_SCSI=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++CONFIG_V4L_PLATFORM_DRIVERS=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++# CONFIG_PWRSEQ_SIMPLE is not set -++CONFIG_MMC_BLOCK_MINORS=256 -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_EXT2_FS=y -++CONFIG_EXT2_FS_XATTR=y -++CONFIG_EXT2_FS_POSIX_ACL=y -++CONFIG_EXT2_FS_SECURITY=y -++CONFIG_EXT3_FS=y -++CONFIG_EXT3_FS_POSIX_ACL=y -++CONFIG_EXT3_FS_SECURITY=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv608_emmc_defconfig b/arch/arm/configs/hi3516cv608_emmc_defconfig -+new file mode 100755 -+index 000000000..37506ba03 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv608_emmc_defconfig -+@@ -0,0 +1,177 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV608=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_SCSI=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++CONFIG_V4L_PLATFORM_DRIVERS=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++# CONFIG_PWRSEQ_SIMPLE is not set -++CONFIG_MMC_BLOCK_MINORS=256 -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_EXT2_FS=y -++CONFIG_EXT2_FS_XATTR=y -++CONFIG_EXT2_FS_POSIX_ACL=y -++CONFIG_EXT2_FS_SECURITY=y -++CONFIG_EXT3_FS=y -++CONFIG_EXT3_FS_POSIX_ACL=y -++CONFIG_EXT3_FS_SECURITY=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_STRICT_DEVMEM=y -++CONFIG_IO_STRICT_DEVMEM=y -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv608_nand_mini_defconfig b/arch/arm/configs/hi3516cv608_nand_mini_defconfig -+new file mode 100755 -+index 000000000..167bf8d96 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv608_nand_mini_defconfig -+@@ -0,0 +1,132 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++CONFIG_KERNEL_XZ=y -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++# CONFIG_CROSS_MEMORY_ATTACH is not set -++# CONFIG_CPU_ISOLATION is not set -++CONFIG_LOG_BUF_SHIFT=12 -++CONFIG_LOG_CPU_MAX_BUF_SHIFT=1 -++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=10 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_SYSFS_SYSCALL is not set -++# CONFIG_FHANDLE is not set -++# CONFIG_BUG is not set -++# CONFIG_BASE_FULL is not set -++# CONFIG_SHMEM is not set -++# CONFIG_AIO is not set -++# CONFIG_IO_URING is not set -++# CONFIG_ADVISE_SYSCALLS is not set -++# CONFIG_MEMBARRIER is not set -++# CONFIG_KALLSYMS is not set -++# CONFIG_RSEQ is not set -++CONFIG_EMBEDDED=y -++# CONFIG_VM_EVENT_COUNTERS is not set -++# CONFIG_SLUB_DEBUG is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV608=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_NR_CPUS=2 -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_SUSPEND is not set -++# CONFIG_SECCOMP is not set -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_BLK_CMDLINE_PARSER=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++# CONFIG_COREDUMP is not set -++# CONFIG_COMPACTION is not set -++CONFIG_NET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++# CONFIG_INET_DIAG is not set -++# CONFIG_IPV6 is not set -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_DEVTMPFS=y -++# CONFIG_STANDALONE is not set -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++# CONFIG_FW_LOADER is not set -++# CONFIG_ALLOW_DEV_COREDUMP is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++# CONFIG_MTD_OF_PARTS is not set -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NAND=y -++CONFIG_MTD_UBI=y -++# CONFIG_BLK_DEV is not set -++CONFIG_NETDEVICES=y -++# CONFIG_NET_CORE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -++CONFIG_I2C=y -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++# CONFIG_NVMEM is not set -++# CONFIG_DNOTIFY is not set -++CONFIG_UBIFS_FS=y -++# CONFIG_UBIFS_FS_XATTR is not set -++CONFIG_NFS_FS=y -++# CONFIG_NFS_V2 is not set -++CONFIG_NLS=y -++# CONFIG_CRYPTO_HW is not set -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_ENABLE_MUST_CHECK is not set -++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -++# CONFIG_DEBUG_MISC is not set -++# CONFIG_SCHED_DEBUG is not set -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++# CONFIG_RUNTIME_TESTING_MENU is not set -+diff --git a/arch/arm/configs/hi3516cv608_nor_mini_defconfig b/arch/arm/configs/hi3516cv608_nor_mini_defconfig -+new file mode 100755 -+index 000000000..12371a1d7 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv608_nor_mini_defconfig -+@@ -0,0 +1,129 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++CONFIG_KERNEL_XZ=y -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++# CONFIG_CROSS_MEMORY_ATTACH is not set -++# CONFIG_CPU_ISOLATION is not set -++CONFIG_LOG_BUF_SHIFT=12 -++CONFIG_LOG_CPU_MAX_BUF_SHIFT=1 -++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=10 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_SYSFS_SYSCALL is not set -++# CONFIG_FHANDLE is not set -++# CONFIG_BUG is not set -++# CONFIG_BASE_FULL is not set -++# CONFIG_SHMEM is not set -++# CONFIG_AIO is not set -++# CONFIG_IO_URING is not set -++# CONFIG_ADVISE_SYSCALLS is not set -++# CONFIG_MEMBARRIER is not set -++# CONFIG_KALLSYMS is not set -++# CONFIG_RSEQ is not set -++CONFIG_EMBEDDED=y -++# CONFIG_VM_EVENT_COUNTERS is not set -++# CONFIG_SLUB_DEBUG is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV608=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_NR_CPUS=2 -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_SUSPEND is not set -++# CONFIG_SECCOMP is not set -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_BLK_CMDLINE_PARSER=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++# CONFIG_COREDUMP is not set -++# CONFIG_COMPACTION is not set -++CONFIG_NET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++# CONFIG_INET_DIAG is not set -++# CONFIG_IPV6 is not set -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_DEVTMPFS=y -++# CONFIG_STANDALONE is not set -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++# CONFIG_FW_LOADER is not set -++# CONFIG_ALLOW_DEV_COREDUMP is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++# CONFIG_MTD_OF_PARTS is not set -++CONFIG_MTD_BLOCK=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++# CONFIG_BLK_DEV is not set -++CONFIG_NETDEVICES=y -++# CONFIG_NET_CORE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -++CONFIG_I2C=y -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++# CONFIG_NVMEM is not set -++# CONFIG_DNOTIFY is not set -++CONFIG_JFFS2_FS=y -++CONFIG_NFS_FS=y -++CONFIG_NLS=y -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_ENABLE_MUST_CHECK is not set -++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -++# CONFIG_DEBUG_MISC is not set -++# CONFIG_SCHED_DEBUG is not set -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++# CONFIG_RUNTIME_TESTING_MENU is not set -+diff --git a/arch/arm/configs/hi3516cv608_nor_quickboot_defconfig b/arch/arm/configs/hi3516cv608_nor_quickboot_defconfig -+new file mode 100755 -+index 000000000..ef0a5b8ec -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv608_nor_quickboot_defconfig -+@@ -0,0 +1,115 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++CONFIG_KERNEL_XZ=y -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++# CONFIG_CROSS_MEMORY_ATTACH is not set -++CONFIG_HIGH_RES_TIMERS=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_BLK_DEV_INITRD=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_SYSFS_SYSCALL is not set -++# CONFIG_FHANDLE is not set -++# CONFIG_BUG is not set -++# CONFIG_BASE_FULL is not set -++# CONFIG_SHMEM is not set -++# CONFIG_AIO is not set -++# CONFIG_IO_URING is not set -++# CONFIG_ADVISE_SYSCALLS is not set -++# CONFIG_MEMBARRIER is not set -++# CONFIG_KALLSYMS is not set -++# CONFIG_RSEQ is not set -++CONFIG_EMBEDDED=y -++# CONFIG_VM_EVENT_COUNTERS is not set -++# CONFIG_SLUB_DEBUG is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV608=y -++CONFIG_VENDOR_RAMDISK_ZERO_COPY=y -++CONFIG_VENDOR_TIMER_TRIGGER_RCU=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_NR_CPUS=2 -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_SUSPEND is not set -++# CONFIG_SECCOMP is not set -++# CONFIG_STRICT_KERNEL_RWX is not set -++# CONFIG_STRICT_MODULE_RWX is not set -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_BLK_CMDLINE_PARSER=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_COREDUMP is not set -++# CONFIG_COMPACTION is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_STANDALONE is not set -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++# CONFIG_FW_LOADER is not set -++# CONFIG_ALLOW_DEV_COREDUMP is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++# CONFIG_MTD_OF_PARTS is not set -++CONFIG_MTD_BLOCK=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -++CONFIG_I2C=y -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++# CONFIG_NVMEM is not set -++# CONFIG_DNOTIFY is not set -++CONFIG_JFFS2_FS=y -++CONFIG_ROMFS_FS=y -++CONFIG_NLS=y -++CONFIG_PRINTK_TIME=y -++CONFIG_CMD_TIMESTAMP=y -++CONFIG_BSP_FAST_STARTUP=y -++CONFIG_STARTUP_PARALLEL_CREATION_NODE_OPT=y -++CONFIG_STARTUP_PARALLEL_OPT=y -++CONFIG_DEPENDENCIES=y -++CONFIG_DEPENDENCIES_PARALLEL=y -++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=8 -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_ENABLE_MUST_CHECK is not set -++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -++# CONFIG_DEBUG_MISC is not set -++# CONFIG_SCHED_DEBUG is not set -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++# CONFIG_RUNTIME_TESTING_MENU is not set -+diff --git a/arch/arm/configs/hi3516cv610_debug_defconfig b/arch/arm/configs/hi3516cv610_debug_defconfig -+new file mode 100755 -+index 000000000..7722ab9de -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv610_debug_defconfig -+@@ -0,0 +1,198 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV610=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++CONFIG_USB_USBNET=y -++# CONFIG_USB_NET_NET1080 is not set -++CONFIG_USB_NET_RNDIS_HOST=y -++# CONFIG_USB_NET_CDC_SUBSET is not set -++# CONFIG_USB_NET_ZAURUS is not set -++# CONFIG_WLAN is not set -++CONFIG_INPUT_EVDEV=y -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_USB_GSPCA is not set -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_SOUND=y -++CONFIG_SND=y -++# CONFIG_SND_ARM is not set -++CONFIG_HID_PID=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++# CONFIG_NVMEM is not set -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_WING_UPS_MISSILE_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv610_defconfig b/arch/arm/configs/hi3516cv610_defconfig -+new file mode 100755 -+index 000000000..222e44a36 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv610_defconfig -+@@ -0,0 +1,198 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV610=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++CONFIG_USB_USBNET=y -++CONFIG_USB_NET_RNDIS_HOST=y -++# CONFIG_USB_NET_CDC_SUBSET is not set -++# CONFIG_USB_NET_ZAURUS is not set -++# CONFIG_WLAN is not set -++CONFIG_INPUT_EVDEV=y -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_USB_GSPCA is not set -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_SOUND=y -++CONFIG_SND=y -++# CONFIG_SND_ARM is not set -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++# CONFIG_NVMEM is not set -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_WING_UPS_MISSILE_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_STRICT_DEVMEM=y -++CONFIG_IO_STRICT_DEVMEM=y -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv610_emmc_debug_defconfig b/arch/arm/configs/hi3516cv610_emmc_debug_defconfig -+new file mode 100755 -+index 000000000..798a5995e -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv610_emmc_debug_defconfig -+@@ -0,0 +1,184 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV610=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++CONFIG_USB_USBNET=y -++# CONFIG_USB_NET_NET1080 is not set -++CONFIG_USB_NET_RNDIS_HOST=y -++# CONFIG_USB_NET_CDC_SUBSET is not set -++# CONFIG_USB_NET_ZAURUS is not set -++# CONFIG_WLAN is not set -++CONFIG_INPUT_EVDEV=y -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_USB_GSPCA is not set -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_SOUND=y -++CONFIG_SND=y -++# CONFIG_SND_ARM is not set -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++# CONFIG_PWRSEQ_SIMPLE is not set -++CONFIG_MMC_BLOCK_MINORS=256 -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_EXT2_FS=y -++CONFIG_EXT2_FS_XATTR=y -++CONFIG_EXT2_FS_POSIX_ACL=y -++CONFIG_EXT2_FS_SECURITY=y -++CONFIG_EXT3_FS=y -++CONFIG_EXT3_FS_POSIX_ACL=y -++CONFIG_EXT3_FS_SECURITY=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv610_emmc_defconfig b/arch/arm/configs/hi3516cv610_emmc_defconfig -+new file mode 100755 -+index 000000000..c4b346dee -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv610_emmc_defconfig -+@@ -0,0 +1,186 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_SLAB_MERGE_DEFAULT is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV610=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_ARM_PATCH_IDIV is not set -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++# CONFIG_IPV6 is not set -++CONFIG_NETFILTER=y -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_FW_LOADER=m -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_PENSANDO 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT 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_NET_VENDOR_XILINX is not set -++CONFIG_MDIO_VENDOR_FEMAC=y -++CONFIG_USB_USBNET=y -++# CONFIG_USB_NET_NET1080 is not set -++CONFIG_USB_NET_RNDIS_HOST=y -++# CONFIG_USB_NET_CDC_SUBSET is not set -++# CONFIG_USB_NET_ZAURUS is not set -++# CONFIG_WLAN is not set -++CONFIG_INPUT_EVDEV=y -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++CONFIG_I2C=y -++CONFIG_I2C_CHARDEV=y -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_SYSCON=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_USB_GSPCA is not set -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_SOUND=y -++CONFIG_SND=y -++# CONFIG_SND_ARM is not set -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++# CONFIG_PWRSEQ_SIMPLE is not set -++CONFIG_MMC_BLOCK_MINORS=256 -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_PLTFM=y -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_USB_WING=y -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_EXT2_FS=y -++CONFIG_EXT2_FS_XATTR=y -++CONFIG_EXT2_FS_POSIX_ACL=y -++CONFIG_EXT2_FS_SECURITY=y -++CONFIG_EXT3_FS=y -++CONFIG_EXT3_FS_POSIX_ACL=y -++CONFIG_EXT3_FS_SECURITY=y -++# CONFIG_DNOTIFY is not set -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++CONFIG_NLS_CODEPAGE_437=y -++CONFIG_NLS_ISO8859_1=y -++CONFIG_CRC_CCITT=y -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++CONFIG_STRICT_DEVMEM=y -++CONFIG_IO_STRICT_DEVMEM=y -++CONFIG_DEBUG_USER=y -+diff --git a/arch/arm/configs/hi3516cv610_nand_mini_defconfig b/arch/arm/configs/hi3516cv610_nand_mini_defconfig -+new file mode 100755 -+index 000000000..96cf44b41 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv610_nand_mini_defconfig -+@@ -0,0 +1,132 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++CONFIG_KERNEL_XZ=y -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++# CONFIG_CROSS_MEMORY_ATTACH is not set -++# CONFIG_CPU_ISOLATION is not set -++CONFIG_LOG_BUF_SHIFT=12 -++CONFIG_LOG_CPU_MAX_BUF_SHIFT=1 -++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=10 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_SYSFS_SYSCALL is not set -++# CONFIG_FHANDLE is not set -++# CONFIG_BUG is not set -++# CONFIG_BASE_FULL is not set -++# CONFIG_SHMEM is not set -++# CONFIG_AIO is not set -++# CONFIG_IO_URING is not set -++# CONFIG_ADVISE_SYSCALLS is not set -++# CONFIG_MEMBARRIER is not set -++# CONFIG_KALLSYMS is not set -++# CONFIG_RSEQ is not set -++CONFIG_EMBEDDED=y -++# CONFIG_VM_EVENT_COUNTERS is not set -++# CONFIG_SLUB_DEBUG is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV610=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_NR_CPUS=2 -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_SUSPEND is not set -++# CONFIG_SECCOMP is not set -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_BLK_CMDLINE_PARSER=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++# CONFIG_COREDUMP is not set -++# CONFIG_COMPACTION is not set -++CONFIG_NET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++# CONFIG_INET_DIAG is not set -++# CONFIG_IPV6 is not set -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_DEVTMPFS=y -++# CONFIG_STANDALONE is not set -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++# CONFIG_FW_LOADER is not set -++# CONFIG_ALLOW_DEV_COREDUMP is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++# CONFIG_MTD_OF_PARTS is not set -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NAND=y -++CONFIG_MTD_UBI=y -++# CONFIG_BLK_DEV is not set -++CONFIG_NETDEVICES=y -++# CONFIG_NET_CORE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -++CONFIG_I2C=y -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++# CONFIG_NVMEM is not set -++# CONFIG_DNOTIFY is not set -++CONFIG_UBIFS_FS=y -++# CONFIG_UBIFS_FS_XATTR is not set -++CONFIG_NFS_FS=y -++# CONFIG_NFS_V2 is not set -++CONFIG_NLS=y -++# CONFIG_CRYPTO_HW is not set -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_ENABLE_MUST_CHECK is not set -++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -++# CONFIG_DEBUG_MISC is not set -++# CONFIG_SCHED_DEBUG is not set -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++# CONFIG_RUNTIME_TESTING_MENU is not set -+diff --git a/arch/arm/configs/hi3516cv610_nor_mini_defconfig b/arch/arm/configs/hi3516cv610_nor_mini_defconfig -+new file mode 100755 -+index 000000000..bfd531348 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv610_nor_mini_defconfig -+@@ -0,0 +1,129 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++CONFIG_KERNEL_XZ=y -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++# CONFIG_CROSS_MEMORY_ATTACH is not set -++# CONFIG_CPU_ISOLATION is not set -++CONFIG_LOG_BUF_SHIFT=12 -++CONFIG_LOG_CPU_MAX_BUF_SHIFT=1 -++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=10 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_SYSFS_SYSCALL is not set -++# CONFIG_FHANDLE is not set -++# CONFIG_BUG is not set -++# CONFIG_BASE_FULL is not set -++# CONFIG_SHMEM is not set -++# CONFIG_AIO is not set -++# CONFIG_IO_URING is not set -++# CONFIG_ADVISE_SYSCALLS is not set -++# CONFIG_MEMBARRIER is not set -++# CONFIG_KALLSYMS is not set -++# CONFIG_RSEQ is not set -++CONFIG_EMBEDDED=y -++# CONFIG_VM_EVENT_COUNTERS is not set -++# CONFIG_SLUB_DEBUG is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV610=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_NR_CPUS=2 -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_SUSPEND is not set -++# CONFIG_SECCOMP is not set -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_BLK_CMDLINE_PARSER=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_ENABLE_IPREC_DEBUG is not set -++# CONFIG_COREDUMP is not set -++# CONFIG_COMPACTION is not set -++CONFIG_NET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++# CONFIG_INET_DIAG is not set -++# CONFIG_IPV6 is not set -++# CONFIG_WIRELESS is not set -++# CONFIG_ETHTOOL_NETLINK is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_DEVTMPFS=y -++# CONFIG_STANDALONE is not set -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++# CONFIG_FW_LOADER is not set -++# CONFIG_ALLOW_DEV_COREDUMP is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++# CONFIG_MTD_OF_PARTS is not set -++CONFIG_MTD_BLOCK=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++# CONFIG_BLK_DEV is not set -++CONFIG_NETDEVICES=y -++# CONFIG_NET_CORE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CIRRUS is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_FARADAY is not set -++# CONFIG_NET_VENDOR_GOOGLE is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_VENDOR_FEMAC=y -++CONFIG_MDIO_VENDOR_FEMAC=y -++# CONFIG_WLAN is not set -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -++CONFIG_I2C=y -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++# CONFIG_NVMEM is not set -++# CONFIG_DNOTIFY is not set -++CONFIG_JFFS2_FS=y -++CONFIG_NFS_FS=y -++CONFIG_NLS=y -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_ENABLE_MUST_CHECK is not set -++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -++# CONFIG_DEBUG_MISC is not set -++# CONFIG_SCHED_DEBUG is not set -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++# CONFIG_RUNTIME_TESTING_MENU is not set -+diff --git a/arch/arm/configs/hi3516cv610_nor_quickboot_defconfig b/arch/arm/configs/hi3516cv610_nor_quickboot_defconfig -+new file mode 100755 -+index 000000000..8fae1f6f8 -+--- /dev/null -++++ b/arch/arm/configs/hi3516cv610_nor_quickboot_defconfig -+@@ -0,0 +1,115 @@ -++# CONFIG_LOCALVERSION_AUTO is not set -++CONFIG_KERNEL_XZ=y -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++# CONFIG_CROSS_MEMORY_ATTACH is not set -++CONFIG_HIGH_RES_TIMERS=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_SYSFS_DEPRECATED=y -++CONFIG_RELAY=y -++CONFIG_BLK_DEV_INITRD=y -++CONFIG_CC_OPTIMIZE_FOR_SIZE=y -++CONFIG_SGETMASK_SYSCALL=y -++# CONFIG_SYSFS_SYSCALL is not set -++# CONFIG_FHANDLE is not set -++# CONFIG_BUG is not set -++# CONFIG_BASE_FULL is not set -++# CONFIG_SHMEM is not set -++# CONFIG_AIO is not set -++# CONFIG_IO_URING is not set -++# CONFIG_ADVISE_SYSCALLS is not set -++# CONFIG_MEMBARRIER is not set -++# CONFIG_KALLSYMS is not set -++# CONFIG_RSEQ is not set -++CONFIG_EMBEDDED=y -++# CONFIG_VM_EVENT_COUNTERS is not set -++# CONFIG_SLUB_DEBUG is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516CV610=y -++CONFIG_VENDOR_RAMDISK_ZERO_COPY=y -++CONFIG_VENDOR_TIMER_TRIGGER_RCU=y -++# CONFIG_VDSO is not set -++# CONFIG_CACHE_L2X0 is not set -++CONFIG_SMP=y -++CONFIG_NR_CPUS=2 -++CONFIG_THUMB2_KERNEL=y -++# CONFIG_CPU_SW_DOMAIN_PAN is not set -++# CONFIG_ARM_MODULE_PLTS is not set -++CONFIG_ARM_APPENDED_DTB=y -++CONFIG_ARM_ATAG_DTB_COMPAT=y -++CONFIG_VFP=y -++CONFIG_NEON=y -++# CONFIG_SUSPEND is not set -++# CONFIG_SECCOMP is not set -++# CONFIG_STRICT_KERNEL_RWX is not set -++# CONFIG_STRICT_MODULE_RWX is not set -++# CONFIG_GCC_PLUGINS is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_BLK_CMDLINE_PARSER=y -++# CONFIG_MQ_IOSCHED_DEADLINE is not set -++# CONFIG_MQ_IOSCHED_KYBER is not set -++# CONFIG_COREDUMP is not set -++# CONFIG_COMPACTION is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_STANDALONE is not set -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++# CONFIG_FW_LOADER is not set -++# CONFIG_ALLOW_DEV_COREDUMP is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++# CONFIG_MTD_OF_PARTS is not set -++CONFIG_MTD_BLOCK=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++# CONFIG_INPUT_KEYBOARD is not set -++# CONFIG_INPUT_MOUSE is not set -++# CONFIG_SERIO is not set -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set -++CONFIG_I2C=y -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_POWER_RESET_BSP=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++# CONFIG_VHOST_MENU is not set -++# CONFIG_ARM_ARCH_TIMER_EVTSTREAM is not set -++# CONFIG_IOMMU_SUPPORT is not set -++# CONFIG_NVMEM is not set -++# CONFIG_DNOTIFY is not set -++CONFIG_JFFS2_FS=y -++CONFIG_ROMFS_FS=y -++CONFIG_NLS=y -++CONFIG_PRINTK_TIME=y -++CONFIG_CMD_TIMESTAMP=y -++CONFIG_BSP_FAST_STARTUP=y -++CONFIG_STARTUP_PARALLEL_CREATION_NODE_OPT=y -++CONFIG_STARTUP_PARALLEL_OPT=y -++CONFIG_DEPENDENCIES=y -++CONFIG_DEPENDENCIES_PARALLEL=y -++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=8 -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_ENABLE_MUST_CHECK is not set -++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -++# CONFIG_DEBUG_MISC is not set -++# CONFIG_SCHED_DEBUG is not set -++# CONFIG_RCU_TRACE is not set -++# CONFIG_FTRACE is not set -++# CONFIG_RUNTIME_TESTING_MENU is not set -+diff --git a/arch/arm/mach-vendor/Kconfig b/arch/arm/mach-vendor/Kconfig -+new file mode 100755 -+index 000000000..1bfea17f9 -+--- /dev/null -++++ b/arch/arm/mach-vendor/Kconfig -+@@ -0,0 +1,59 @@ -++if ARCH_BSP -++ -++menu "Hisilicon BSP platform type" -++ -++config BSP_ZRELADDR -++ depends on ARCH_BSP -++ depends on ARCH_MULTI_V7 -++ hex 'bsp zreladdr' -++ default "0x40020000" if ARCH_HI3516CV610_FAMILY -++ -++config ARCH_HI3516CV610 -++ bool "Vendor hi3516cv610 platform" -++ depends on ARCH_BSP -++ select ARCH_HI3516CV610_FAMILY -++ help -++ Support for Vendor HI3516CV610 platform -++ -++config ARCH_HI3516CV608 -++ bool "Vendor hi3516cv608 platform" -++ depends on ARCH_BSP -++ select ARCH_HI3516CV610_FAMILY -++ help -++ Support for Vendor HI3516CV608 platform -++ -++config ARCH_HI3516CV610_FAMILY -++ bool "Vendor hi3516cv610 family" -++ depends on ARCH_BSP -++ depends on ARCH_MULTI_V7 -++ select HAVE_ARM_ARCH_TIMER -++ select RESET_BSP -++ help -++ Support for Hisilicon HI3516CV610 Soc family. -++ -++ -++config SOC_FAMILY -++ string -++ default "hi3516cv610" if ARCH_HI3516CV610_FAMILY -++ -++config VENDOR_RAMDISK_ZERO_COPY -++ bool "Vendor ramdisk zero copy" -++ default n -++ depends on ROMFS_FS && BLK_DEV_INITRD && BLK_DEV_RAM && ARCH_BSP -++ help -++ Select this to reduce copy ramdisk times in DDR -++ -++config VENDOR_TIMER_TRIGGER_RCU -++ bool "Fast trigger rcu" -++ default n -++ depends on ARCH_BSP -++ help -++ Select this to reduce boot time when RCU takes a lot time. If -++ CONFIG_HIGH_RES_TIMERS is enabled, the RCU time consumption can -++ be reduced to almost 0, but be careful to open CONFIG_HIGH_RES_TIMERS! -++ -++ -++endmenu -++ -++endif -++ -+diff --git a/arch/arm/mach-vendor/Makefile b/arch/arm/mach-vendor/Makefile -+new file mode 100755 -+index 000000000..3204b6d74 -+--- /dev/null -++++ b/arch/arm/mach-vendor/Makefile -+@@ -0,0 +1,3 @@ -++vendor_soc_family_name := $(subst $\",,$(CONFIG_SOC_FAMILY)) -++obj-y += mach_$(vendor_soc_family_name).o -++obj-$(CONFIG_SMP) += platsmp.o -+diff --git a/arch/arm/mach-vendor/Makefile.boot b/arch/arm/mach-vendor/Makefile.boot -+new file mode 100755 -+index 000000000..98e4352a1 -+--- /dev/null -++++ b/arch/arm/mach-vendor/Makefile.boot -+@@ -0,0 +1,3 @@ -++zreladdr-y := $(CONFIG_BSP_ZRELADDR) -++params_phys-y := 0x00000100 -++initrd_phys-y := 0x00800000 -+diff --git a/arch/arm/mach-vendor/mach_common.h b/arch/arm/mach-vendor/mach_common.h -+new file mode 100755 -+index 000000000..a6ba8d917 -+--- /dev/null -++++ b/arch/arm/mach-vendor/mach_common.h -+@@ -0,0 +1,29 @@ -++/* -++ * Copyright (c) 2016-2017 HiSilicon 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 . -++ * -++*/ -++ -++#ifndef __SMP_COMMON_H -++#define __SMP_COMMON_H -++ -++#ifdef CONFIG_SMP -++#include -++#include -++ -++void hi35xx_set_cpu(unsigned int cpu, bool enable); -++void hi35xx_set_entrypoint(phys_addr_t jumpaddr); -++#endif /* CONFIG_SMP */ -++#endif /* __SMP_COMMON_H */ -+diff --git a/arch/arm/mach-vendor/mach_hi3516cv610.c b/arch/arm/mach-vendor/mach_hi3516cv610.c -+new file mode 100755 -+index 000000000..bd6eda573 -+--- /dev/null -++++ b/arch/arm/mach-vendor/mach_hi3516cv610.c -+@@ -0,0 +1,85 @@ -++/* -++ * Copyright (c) 2016-2017 HiSilicon 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 . -++ * -++*/ -++ -++#include "mach_common.h" -++ -++#include -++#include -++ -++#ifdef CONFIG_SMP -++ -++#define CPU1_RST_REQ BIT(8) -++#define REG_CPU_RST 0x204C -++ -++#define REG_CPU_FRQ_CRG 0x2040 -++#define DBG1_SRST_REQ BIT(10) -++ -++void hi35xx_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, "vendor,hi3516cv610_clock"); -++ if (!np) { -++ pr_err("failed to find hisilicon 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_FRQ_CRG); -++ regval &= ~DBG1_SRST_REQ; -++ writel(regval, (crg_base + REG_CPU_FRQ_CRG)); -++ -++ regval = readl(crg_base + REG_CPU_RST); -++ regval &= ~CPU1_RST_REQ; -++ writel(regval, (crg_base + REG_CPU_RST)); -++ } else { -++ regval = readl(crg_base + REG_CPU_FRQ_CRG); -++ regval |= DBG1_SRST_REQ; -++ writel(regval, (crg_base + REG_CPU_FRQ_CRG)); -++ -++ regval = readl(crg_base + REG_CPU_RST); -++ regval |= CPU1_RST_REQ; -++ writel(regval, (crg_base + REG_CPU_RST)); -++ } -++} -++ -++#define TEE_GEN_REG0 0x500 -++#define REG_START_WARM_ENTRYPOINT TEE_GEN_REG0 -++ -++ -++void hi35xx_set_entrypoint(phys_addr_t jumpaddr) -++{ -++ struct device_node *np; -++ void *sysctrl_reg_base; -++ -++ np = of_find_compatible_node(NULL, NULL, "vendor,sysctrl"); -++ sysctrl_reg_base = of_iomap(np, 0); -++ -++ writel(jumpaddr, sysctrl_reg_base + REG_START_WARM_ENTRYPOINT); -++} -++ -++#endif -+diff --git a/arch/arm/mach-vendor/platsmp.c b/arch/arm/mach-vendor/platsmp.c -+new file mode 100755 -+index 000000000..387b9eec9 -+--- /dev/null -++++ b/arch/arm/mach-vendor/platsmp.c -+@@ -0,0 +1,62 @@ -++/* -++ * Copyright (c) 2016-2017 HiSilicon 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 . -++ * -++*/ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "mach_common.h" -++ -++void __init hi35xx_smp_prepare_cpus(unsigned int max_cpus) -++{ -++ unsigned long base = 0; -++ void __iomem *scu_base = NULL; -++ -++ if (scu_a9_has_base()) { -++ base = scu_a9_get_base(); -++ scu_base = ioremap(base, PAGE_SIZE); -++ if (!scu_base) { -++ pr_err("ioremap(scu_base) failed\n"); -++ return; -++ } -++ -++ scu_enable(scu_base); -++ iounmap(scu_base); -++ } -++} -++ -++int hi35xx_boot_secondary(unsigned int cpu, struct task_struct *idle) -++{ -++ phys_addr_t jumpaddr; -++ jumpaddr = virt_to_phys(secondary_startup); -++ -++ hi35xx_set_entrypoint(jumpaddr); -++ hi35xx_set_cpu(cpu, true); -++ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); -++ return 0; -++} -++ -++static const struct smp_operations hi35xx_smp_ops __initconst = { -++ .smp_prepare_cpus = hi35xx_smp_prepare_cpus, -++ .smp_boot_secondary = hi35xx_boot_secondary, -++}; -++ -++CPU_METHOD_OF_DECLARE(hi35xx_smp, "hisilicon,hi35xx", &hi35xx_smp_ops); -+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -+index 273a58b74..99ee601c1 100644 -+--- a/arch/arm64/Kconfig -++++ b/arch/arm64/Kconfig -+@@ -1676,6 +1676,27 @@ endmenu -+ -+ menu "ARMv8.2 architectural features" -+ -++config ARM64_UAO -++ bool "Enable support for User Access Override (UAO)" -++ default y -++ help -++ User Access Override (UAO; part of the ARMv8.2 Extensions) -++ causes the 'unprivileged' variant of the load/store instructions to -++ be overridden to be privileged. -++ -++ This option changes get_user() and friends to use the 'unprivileged' -++ variant of the load/store instructions. This ensures that user-space -++ really did have access to the supplied memory. When addr_limit is -++ set to kernel memory the UAO bit will be set, allowing privileged -++ access to kernel memory. -++ -++ Choosing this option will cause copy_to_user() et al to use user-space -++ memory permissions. -++ -++ The feature is detected at runtime, the kernel will use the -++ regular load/store instructions if the cpu does not implement the -++ feature. -++ -+ config ARM64_PMEM -+ bool "Enable support for persistent memory" -+ select ARCH_HAS_PMEM_API -+diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms -+index c924fce75..63231a330 100644 -+--- a/arch/arm64/Kconfig.platforms -++++ b/arch/arm64/Kconfig.platforms -+@@ -141,6 +141,60 @@ config ARCH_KEEMBAY -+ help -+ This enables support for Intel Movidius SoC code-named Keem Bay. -+ -++config ARCH_BSP -++ bool "Vendor SoC Family" -++ select ARM_TIMER_SP804 -++ select PINCTRL -++ help -++ This enables support for Vendor ARMv8 SoC family -++ -++if ARCH_BSP -++ -++config ARCH_HI3519DV500 -++ bool "Vendor hi3519dv500 platform" -++ select ARM_TIMER_SP804 -++ select PINCTRL -++ select ARCH_HI3519DV500_FAMILY -++ help -++ Support for Vendor HI3519DV500 platform -++ -++config ARCH_HI3516DV500 -++ bool "Vendor hi3516dv500 platform" -++ select ARM_TIMER_SP804 -++ select PINCTRL -++ select ARCH_HI3519DV500_FAMILY -++ help -++ Support for Vendor HI3516DV500 platform -++ -++config ARCH_HI3559V300 -++ bool "Vendor hi3559v300 platform" -++ select ARM_TIMER_SP804 -++ select PINCTRL -++ select ARCH_HI3519DV500_FAMILY -++ help -++ Support for Vendor HI3559V300 platform -++ -++config ARCH_HI3519DV500_FAMILY -++ bool "Vendor hi3519dv500 family" -++ help -++ Support for Vendor HI3519DV500 Soc family -++ -++config VENDOR_RAMDISK_ZERO_COPY -++ bool "Vendor ramdisk zero copy" -++ default n -++ depends on ROMFS_FS && BLK_DEV_INITRD && BLK_DEV_RAM -++ help -++ Select this to reduce copy ramdisk times in DDR -++ -++config VENDOR_TIMER_TRIGGER_RCU -++ bool "Fast trigger rcu" -++ default n -++ help -++ Select this to reduce boot time when RCU takes a lot time. If -++ CONFIG_HIGH_RES_TIMERS is enabled, the RCU time consumption can -++ be reduced to almost 0, but be careful to open CONFIG_HIGH_RES_TIMERS! -++endif # ARCH_BSP -++ -+ config ARCH_MEDIATEK -+ bool "MediaTek SoC Family" -+ select ARM_GIC -+diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile -+index e6b71f720..5e836df8c 100644 -+--- a/arch/arm64/Makefile -++++ b/arch/arm64/Makefile -+@@ -162,6 +162,11 @@ all: Image.gz -+ Image: vmlinux -+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -+ -++ifdef CONFIG_ARCH_BSP -++uImage: Image dtbs -++ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -++endif -++ -+ Image.%: Image -+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -+ -+diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile -+index cd3414898..86041631a 100644 -+--- a/arch/arm64/boot/Makefile -++++ b/arch/arm64/boot/Makefile -+@@ -17,6 +17,9 @@ -+ OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S -+ -+ targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo -++ifdef CONFIG_ARCH_BSP -++targets += uImage uImage-fdt -++endif -+ -+ $(obj)/Image: vmlinux FORCE -+ $(call if_changed,objcopy) -+@@ -36,6 +39,32 @@ $(obj)/Image.lzma: $(obj)/Image FORCE -+ $(obj)/Image.lzo: $(obj)/Image FORCE -+ $(call if_changed,lzo) -+ -++ifdef CONFIG_ARCH_BSP -++TEXT_OFFSET := 0x0 -++UIMAGE_LOADADDR := $(TEXT_OFFSET) -++UIMAGE_ENTRYADDR := $(TEXT_OFFSET) -++check_for_multiple_loadaddr = \ -++if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \ -++ echo 'multiple (or no) load addresses: $(UIMAGE_LOADADDR)'; \ -++ echo 'This is incompatible with uImages'; \ -++ echo 'Specify LOADADDR on the commandline to build an uImage'; \ -++ false; \ -++fi -++ -++DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES)) -++DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES)) -++DTB_OBJS := $(addprefix $(obj)/dts/,$(DTB_LIST)) -++ -++$(obj)/uImage: $(obj)/Image FORCE -++ @$(check_for_multiple_loadaddr) -++ @dd if=$< of=$<.dd ibs=4096 conv=sync && mv $<.dd $< -++ $(call cmd,uimage) -++ @cp $@ $@-fdt -++ $(if $(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),@$(kecho) ' CAT $(DTB_OBJS) to $@-fdt') -++ $(if $(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),@cat $(DTB_OBJS) >>$@-fdt,) -++ @$(kecho) ' Image $@ is ready' -++endif -++ -+ install: -+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ -+ $(obj)/Image System.map "$(INSTALL_PATH)" -+diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile -+index 9b1170658..32a6888b6 100644 -+--- a/arch/arm64/boot/dts/Makefile -++++ b/arch/arm64/boot/dts/Makefile -+@@ -30,3 +30,10 @@ subdir-y += ti -+ subdir-y += toshiba -+ subdir-y += xilinx -+ subdir-y += zte -++ifdef CONFIG_ARCH_BSP -++subdir-y += vendor -++ -++dtbs: $(addprefix $(obj)/, $(DTB_LIST)) -++ -++clean-files := dts/*.dtb *.dtb -++endif -+diff --git a/arch/arm64/boot/dts/vendor/Makefile b/arch/arm64/boot/dts/vendor/Makefile -+new file mode 100755 -+index 000000000..278dfbda8 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/Makefile -+@@ -0,0 +1,5 @@ -++# SPDX-License-Identifier: GPL-2.0 -++ -++DTB_PATH := $(subst ",,$(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES)) -++ -++dtb-$(CONFIG_ARCH_BSP) += $(notdir $(DTB_PATH)).dtb -+diff --git a/arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc-tee.dts b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc-tee.dts -+new file mode 100755 -+index 000000000..9976867ea -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc-tee.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516dv500-demb-tee.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc.dts b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc.dts -+new file mode 100755 -+index 000000000..3fc03e195 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-emmc.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516dv500-demb.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash-tee.dts b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash-tee.dts -+new file mode 100755 -+index 000000000..c75ac77f8 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash-tee.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516dv500-demb-tee.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash.dts b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash.dts -+new file mode 100755 -+index 000000000..f06a74d5f -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-flash.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3516dv500-demb.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3516dv500-demb-tee.dts b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-tee.dts -+new file mode 100755 -+index 000000000..02ed382b5 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3516dv500-demb-tee.dts -+@@ -0,0 +1,326 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/dts-v1/; -++/* reserved for warmreset */ -++/* reserved for arm trustedfirmware */ -++/* Modify this configuration according to the system framework */ -++ -++#include "hi3516dv500.dtsi" -++#include -++ -++/ { -++ model = "Vendor HI3516DV500 DEMO Board"; -++ compatible = "vendor,hi3516dv500"; -++ -++ aliases { -++ serial0 = &uart0; -++ -++ serial1 = &uart1; -++ serial2 = &uart2; -++ serial3 = &uart3; -++ serial4 = &uart4; -++ serial5 = &uart5; -++ -++ i2c0 = &i2c_bus0; -++ i2c1 = &i2c_bus1; -++ i2c2 = &i2c_bus2; -++ i2c3 = &i2c_bus3; -++ i2c4 = &i2c_bus4; -++ i2c5 = &i2c_bus5; -++ i2c6 = &i2c_bus6; -++ i2c7 = &i2c_bus7; -++ -++ spi0 = &spi_bus0; -++ spi1 = &spi_bus1; -++ spi2 = &spi_bus2; -++ spi3 = &spi_bus3; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ gpio11 = &gpio_chip11; -++ gpio12 = &gpio_chip12; -++ gpio13 = &gpio_chip13; -++ gpio14 = &gpio_chip14; -++ }; -++ -++ chosen { -++ bootargs = "earlycon=pl011,0x11040000 mem=512M console=ttyAMA0,115200 clk_ignore_unused root=/dev/mtdblock2 rootfstype=yaffs2 rw mtdparts=bspnand:1M(boot),9M(kernel),32M(rootfs),1M(this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!)"; -++ -++ linux,initrd-start = <0x60000040>; -++ linux,initrd-end = <0x61000000>; -++ }; -++ -++ cpus { -++ #address-cells = <2>; -++ #size-cells = <0>; -++ -++ cpu@0 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x0>; -++ enable-method = "psci"; -++ //clock-latency = <100000>; /* From legacy driver */ -++ }; -++ -++ cpu@1 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x100>; -++ enable-method = "psci"; -++ //clock-latency = <200000>; /* From legacy driver */ -++ }; -++ }; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x0 0x45030000 0x0 0x40000000>; -++ }; -++ -++ reserved-memory { -++ #address-cells = <2>; -++ #size-cells = <2>; -++ ranges; -++ -++ optee_shm@48600000 { -++ reg = <0x0 0x48600000 0x0 0x00400000>; -++ }; -++ }; -++}; -++ -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "disabled"; -++}; -++ -++&uart2 { -++ status = "disabled"; -++}; -++ -++&uart3 { -++ status = "disabled"; -++}; -++ -++&uart4 { -++ status = "disabled"; -++}; -++&uart5 { -++ status = "disabled"; -++}; -++ -++&rtc{ -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++}; -++ -++&i2c_bus3 { -++ status = "okay"; -++}; -++ -++&i2c_bus4 { -++ status = "okay"; -++}; -++ -++&i2c_bus5 { -++ status = "okay"; -++}; -++ -++&i2c_bus6 { -++ status = "okay"; -++}; -++ -++&i2c_bus7 { -++ status = "okay"; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus2{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus3{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -++ -++&gpio_chip11 { -++ status = "okay"; -++}; -++ -++&gpio_chip12 { -++ status = "okay"; -++}; -++ -++&gpio_chip13 { -++ status = "okay"; -++}; -++ -++&gpio_chip14 { -++ status = "okay"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ m25p,fast-read; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mdio { -++ ethphy: ethernet-phy@1 { -++ reg = <1>; -++ }; -++}; -++ -++&gmac { -++ phy-handle = <ðphy>; -++ phy-mode = "rgmii-id"; -++}; -++ -++&edmacv310_0 { -++ status = "disabled"; -++}; -++ -++&adc { -++ status = "okay"; -++}; -++ -++&pwm { -++ status = "okay"; -++}; -++ -++&mmc1 { -++ status = "okay"; -++}; -++ -++&mmc2 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3516dv500-demb.dts b/arch/arm64/boot/dts/vendor/hi3516dv500-demb.dts -+new file mode 100755 -+index 000000000..b5e4c6dd7 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3516dv500-demb.dts -+@@ -0,0 +1,315 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/dts-v1/; -++/* reserved for warmreset */ -++/* reserved for arm trustedfirmware */ -++/* Modify this configuration according to the system framework */ -++ -++#include "hi3516dv500.dtsi" -++ -++/ { -++ model = "Vendor HI3516DV500 DEMO Board"; -++ compatible = "vendor,hi3516dv500"; -++ -++ aliases { -++ serial0 = &uart0; -++ -++ serial1 = &uart1; -++ serial2 = &uart2; -++ serial3 = &uart3; -++ serial4 = &uart4; -++ serial5 = &uart5; -++ -++ i2c0 = &i2c_bus0; -++ i2c1 = &i2c_bus1; -++ i2c2 = &i2c_bus2; -++ i2c3 = &i2c_bus3; -++ i2c4 = &i2c_bus4; -++ i2c5 = &i2c_bus5; -++ i2c6 = &i2c_bus6; -++ i2c7 = &i2c_bus7; -++ -++ spi0 = &spi_bus0; -++ spi1 = &spi_bus1; -++ spi2 = &spi_bus2; -++ spi3 = &spi_bus3; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ gpio11 = &gpio_chip11; -++ gpio12 = &gpio_chip12; -++ gpio13 = &gpio_chip13; -++ gpio14 = &gpio_chip14; -++ }; -++ -++ chosen { -++ bootargs = "earlycon=pl011,0x11040000 mem=512M console=ttyAMA0,115200 clk_ignore_unused root=/dev/mtdblock2 rootfstype=yaffs2 rw mtdparts=bspnand:1M(boot),9M(kernel),32M(rootfs),1M(this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!)"; -++ -++ linux,initrd-start = <0x60000040>; -++ linux,initrd-end = <0x61000000>; -++ }; -++ -++ cpus { -++ #address-cells = <2>; -++ #size-cells = <0>; -++ -++ cpu@0 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x0>; -++ enable-method = "psci"; -++ //clock-latency = <100000>; /* From legacy driver */ -++ }; -++ -++ cpu@1 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x100>; -++ enable-method = "psci"; -++ //clock-latency = <200000>; /* From legacy driver */ -++ }; -++ }; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x0 0x40030000 0x0 0x40000000>; -++ }; -++}; -++ -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "disabled"; -++}; -++ -++&uart2 { -++ status = "disabled"; -++}; -++ -++&uart3 { -++ status = "disabled"; -++}; -++ -++&uart4 { -++ status = "disabled"; -++}; -++&uart5 { -++ status = "disabled"; -++}; -++ -++&rtc{ -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++}; -++ -++&i2c_bus3 { -++ status = "okay"; -++}; -++ -++&i2c_bus4 { -++ status = "okay"; -++}; -++ -++&i2c_bus5 { -++ status = "okay"; -++}; -++ -++&i2c_bus6 { -++ status = "okay"; -++}; -++ -++&i2c_bus7 { -++ status = "okay"; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus2{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus3{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -++ -++&gpio_chip11 { -++ status = "okay"; -++}; -++ -++&gpio_chip12 { -++ status = "okay"; -++}; -++ -++&gpio_chip13 { -++ status = "okay"; -++}; -++ -++&gpio_chip14 { -++ status = "okay"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ m25p,fast-read; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mdio { -++ ethphy: ethernet-phy@1 { -++ reg = <1>; -++ }; -++}; -++ -++&gmac { -++ phy-handle = <ðphy>; -++ phy-mode = "rgmii-id"; -++}; -++ -++&edmacv310_0 { -++ status = "disabled"; -++}; -++ -++&adc { -++ status = "okay"; -++}; -++ -++&pwm { -++ status = "okay"; -++}; -++ -++&mmc1 { -++ status = "okay"; -++}; -++ -++&mmc2 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3516dv500.dtsi b/arch/arm64/boot/dts/vendor/hi3516dv500.dtsi -+new file mode 100755 -+index 000000000..629cdf839 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3516dv500.dtsi -+@@ -0,0 +1,859 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/* reserved for arm trustedfirmware */ -++#include -++#include -++#include -++ -++#include "hi3519dv500_family_usb.dtsi" -++/ { -++ #address-cells = <2>; -++ #size-cells = <2>; -++ -++ interrupt-parent = <&gic>; -++ -++ gic: interrupt-controller@12400000 { -++ compatible = "arm,gic-v3"; -++ #interrupt-cells = <3>; -++ #address-cells = <0>; -++ interrupt-controller; -++ reg = <0x0 0x12400000 0x0 0x10000>, /* gic distributor base */ -++ <0x0 0x12440000 0x0 0x140000>; /* gic redistributor base */ -++ }; -++ -++ psci { -++ compatible = "arm,psci-0.2"; -++ method = "smc"; -++ }; -++ -++ pmu { -++ compatible = "arm,armv8-pmuv3"; -++ interrupts = ; -++ }; -++ -++ clock: clock0 { -++ compatible = "vendor,hi3519dv500_clock", "syscon"; -++ #clock-cells = <1>; -++ #reset-cells = <2>; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ reg = <0x0 0x11010000 0x0 0x44a0>; -++ }; -++ -++ firmware { -++ optee { -++ compatible = "linaro,optee-tz"; -++ method = "smc"; -++ }; -++ }; -++ -++ soc { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "simple-bus"; -++ device_type = "soc"; -++ ranges = <0x0 0x00000000 0x0 0xffffffff>; -++ -++ clk_3m: clk_3m { -++ compatible = "fixed-clock"; -++ #clock-cells = <0>; -++ clock-frequency = <3000000>; -++ }; -++ -++ amba { -++ compatible = "arm,amba-bus"; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ ranges; -++ -++ arm-timer { -++ compatible = "arm,armv8-timer"; -++ interrupts = , -++ ; -++ clock-frequency = <24000000>; -++ always-on; -++ }; -++ -++ uart0: uart@11040000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4180 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 20 20>, <&edmacv310_0 21 21>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart1: uart@11041000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11041000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4188 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 22 22>, <&edmacv310_0 23 23>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart2: uart@11042000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11042000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART2_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4190 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 24 24>, <&edmacv310_0 25 25>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart3: uart@11043000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11043000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART3_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4198 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 26 26>, <&edmacv310_0 27 27>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart4: uart@11044000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11044000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART4_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x41a0 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 28 28>, <&edmacv310_0 29 29>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart5: uart@11045000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11045000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART5_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x41a8 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 30 30>, <&edmacv310_0 31 31>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ rtc: rtc@11110000 { -++ compatible = "vendor,rtc"; -++ reg = <0x11110000 0x10000>; -++ interrupts = ; -++ status = "disabled"; -++ }; -++ -++ i2c_bus0: i2c@11060000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11060000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C0_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4280 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ /* dmas = <&edmacv310_0 0 0>, <&edmacv310_0 1 1>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ i2c_bus1: i2c@11061000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11061000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C1_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4288 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 2 2>, <&edmacv310_0 3 3>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus2: i2c@11062000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11062000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C2_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4290 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 4 4>, <&edmacv310_0 5 5>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus3: i2c@11063000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11063000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C3_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4298 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 6 6>, <&edmacv310_0 7 7>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus4: i2c@11064000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11064000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C4_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42A0 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 8 8>, <&edmacv310_0 9 9>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus5: i2c@11065000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11065000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C5_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42A8 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus6: i2c@11066000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11066000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C6_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42B0 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus7: i2c@11067000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11067000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C7_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42B8 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ spi_bus0: spi@11070000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11070000 0x1000>, <0x17a40220 0x4>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4480 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 12 12>, <&edmacv310_0 13 13>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus1: spi@11071000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11071000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4488 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 14 14>, <&edmacv310_0 15 15>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus2: spi@11072000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11072000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI2_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4490 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 16 16>, <&edmacv310_0 17 17>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus3: spi@11073000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11073000 0x1000>, <0x11024610 0x4>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI3_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4498 0>; -++ reset-names = "bsp_spi_rst"; -++ vendor,slave_mode = <0>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 18 18>, <&edmacv310_0 19 19>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ gpio_chip0: gpio_chip@11090000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11090000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip1: gpio_chip@11091000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11091000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip2: gpio_chip@11092000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11092000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip3: gpio_chip@11093000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11093000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip4: gpio_chip@11094000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11094000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip5: gpio_chip@11095000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11095000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip6: gpio_chip@11096000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11096000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip7: gpio_chip@11097000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11097000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip8: gpio_chip@11098000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11098000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip9: gpio_chip@11099000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11099000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip10: gpio_chip@1109A000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109A000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip11: gpio_chip@1109B000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109B000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip12: gpio_chip@1109C000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109C000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip13: gpio_chip@1109D000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109D000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip14: gpio_chip@1109E000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109E000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ }; -++ -++ misc_ctrl: misc-controller@11024000 { -++ compatible = "vendor,miscctrl", "syscon"; -++ reg = <0x11024000 0x5000>; -++ }; -++ -++ ioconfig0: ioconfig0@0eff0000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x0eff0000 0x10000>; -++ }; -++ -++ ioconfig1: ioconfig1@10260000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x10260000 0x10000>; -++ }; -++ -++ /*FLASH DTS nodes*/ -++ fmc: flash-memory-controller@10000000 { -++ compatible = "vendor,fmc"; -++ reg = <0x10000000 0x1000>, <0x0f000000 0x1000000>; -++ reg-names = "control", "memory"; -++ clocks = <&clock HI3519DV500_FMC_CLK>; -++ max-dma-size = <0x2000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ -++ sfc:spi_nor_controller { -++ compatible = "vendor,fmc-spi-nor"; -++ assigned-clocks = <&clock HI3519DV500_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ snfc:spi_nand_controller { -++ compatible = "vendor,fmc-spi-nand"; -++ assigned-clocks = <&clock HI3519DV500_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ }; -++ -++ /*ethernet DTS nodes*/ -++ mdio: mdio@102903c0 { -++ compatible = "vendor,gemac-mdio"; -++ reg = <0x102903c0 0x20>; -++ clocks = <&clock HI3519DV500_ETH_CLK>; -++ resets = <&clock 0x37cc 0>; -++ reset-names = "phy_reset"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ gmac: ethernet@10290000 { -++ compatible = "vendor,gmac-v5"; -++ reg = <0x10290000 0x1000>,<0x1029300c 0x4>; -++ interrupts = , , -++ , ; -++ -++ clocks = <&clock HI3519DV500_ETH_CLK>, -++ <&clock HI3519DV500_ETH_MACIF_CLK>; -++ clock-names = "gmac_clk", -++ "macif_clk"; -++ -++ resets = <&clock 0x37c4 0>, -++ <&clock 0x37c0 0>; -++ reset-names = "port_reset", -++ "macif_reset"; -++ -++ mac-address = [00 00 00 00 00 00]; -++ }; -++ -++ /*EMMC/SD/SDIO DTS nodes*/ -++ mmc0: eMMC@0x10020000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10020000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC0_CLK>, <&clock HI3519DV500_MMC0_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x34c0 16>, <&clock 0x34c0 17>, <&clock 0x34c0 18>, <&clock 0x34c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ non-removable; -++ iocfg_regmap = <&ioconfig0>; -++ bus-width = <8>; -++ cap-mmc-highspeed; -++ mmc-hs200-1_8v; -++ mmc-hs400-1_8v; -++ mmc-hs400-enhanced-strobe; -++ cap-mmc-hw-reset; -++ no-sdio; -++ no-sd; -++ devid = <0>; -++ status = "okay"; -++ }; -++ -++ mmc1: SDIO@0x10030000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10030000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC1_CLK>, <&clock HI3519DV500_MMC1_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x35c0 16>, <&clock 0x35c0 17>, <&clock 0x35c0 18>, <&clock 0x35c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = ; -++ cap-sd-highspeed; -++ sd-uhs-sdr12; -++ sd-uhs-sdr25; -++ sd-uhs-sdr50; -++ sd-uhs-sdr104; -++ full-pwr-cycle; -++ disable-wp; -++ no-mmc; -++ no-sdio; -++ devid = <1>; -++ status = "okay"; -++ }; -++ -++ mmc2: SDIO1@0x10040000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC2_CLK>, <&clock HI3519DV500_MMC2_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x36c0 16>, <&clock 0x36c0 17>, <&clock 0x36c0 18>, <&clock 0x36c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = <4>; -++ cap-sd-highspeed; -++ devid = <2>; -++ status = "okay"; -++ }; -++ -++ edmacv310_0: edma-controller@10280000 { -++ compatible = "vendor,edmacv310"; -++ reg = <0x10280000 0x1000>; -++ reg-names = "dmac"; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_EDMAC_CLK>, -++ <&clock HI3519DV500_EDMAC_AXICLK>; -++ clock-names = "apb_pclk", "axi_aclk"; -++ #clock-cells = <2>; -++ resets = <&clock 0x2A80 0>; -++ reset-names = "dma-reset"; -++ dma-requests = <32>; -++ dma-channels = <8>; -++ devid = <0>; -++ #dma-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ /*SDK DTS nodes*/ -++ sys: sys@11010000 { -++ compatible = "vendor,sys"; -++ reg = <0x11014500 0xBB00>, -++ <0x11020000 0x4000>, -++ <0x11140000 0x20000>, -++ <0X11024000 0x5000>; -++ reg-names = "crg", "sys", "ddr", "misc"; -++ }; -++ -++ mipi_rx: mipi_rx@0x173c0000 { -++ compatible = "vendor,mipi_rx"; -++ reg = <0x173c0000 0x10000>; -++ reg-names = "mipi_rx"; -++ interrupts = ; -++ interrupt-names = "mipi_rx"; -++ }; -++ -++ vi: vi@0x17400000 { -++ compatible = "vendor,vi"; -++ reg = <0x17400000 0x200000>, -++ <0x17800000 0x40000>; -++ reg-names = "vi_cap0", "vi_proc0"; -++ interrupts = , , -++ ; -++ interrupt-names = "vi_cap0", "vi_cap1", "vi_proc0"; -++ }; -++ -++ vpss: vpss@0x17900000 { -++ compatible = "vendor,vpss"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "vpss0"; -++ interrupts = ; -++ interrupt-names = "vpss0"; -++ }; -++ -++ vo: vo@0x17A00000 { -++ compatible = "vendor,vo"; -++ reg = <0x17A00000 0x40000>; -++ reg-names = "vo"; -++ interrupts = ; -++ interrupt-names = "vo"; -++ }; -++ -++ gfbg: gfbg@0x17A00000 { -++ compatible = "vendor,gfbg"; -++ reg = <0x17A00000 0x40000>; -++ reg-names = "gfbg"; -++ interrupts = ; -++ interrupt-names = "gfbg"; -++ }; -++ -++ -++ mipi_tx: mipi_tx@0x10270000 { -++ compatible = "vendor,mipi_tx"; -++ reg = <0x10270000 0x2000>; -++ reg-names = "mipi_tx"; -++ interrupts = ; -++ interrupt-names = "mipi_tx"; -++ }; -++ -++ vgs: vgs@0x17240000 { -++ compatible = "vendor,vgs"; -++ reg = <0x17240000 0x20000>; -++ reg-names = "vgs0"; -++ interrupts = ; -++ interrupt-names = "vgs0"; -++ }; -++ -++ gdc: gdc@0x172c0000 { -++ compatible = "vendor,gdc"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "gdc"; -++ interrupts = ; -++ interrupt-names = "gdc"; -++ }; -++ -++ tde: tde@0x17240000 { -++ compatible = "vendor,tde"; -++ reg = <0x17240000 0x20000>; -++ reg-names = "tde"; -++ interrupts = ; -++ interrupt-names = "tde_osr_isr"; -++ }; -++ -++ jpegd: jpegd@0x17180000 { -++ compatible = "vendor,jpegd"; -++ reg = <0x17180000 0x10000>; -++ reg-names = "jpegd"; -++ interrupts = , ; -++ interrupt-names = "jpegd0", "jpegd1"; -++ }; -++ -++ venc: venc@0x17140000 { -++ compatible = "vendor,venc"; -++ reg = <0x17140000 0x10000>,<0x171c0000 0x10000>; -++ reg-names = "vedu0","jpge"; -++ interrupts = , ; -++ interrupt-names = "vedu0", "jpge"; -++ }; -++ -++ vfmw: vfmw@0x17100000 { -++ compatible = "vendor,vfmw"; -++ reg = <0x17100000 0x10000>, <0x17140000 0x10000>; -++ reg-names = "scd", "vedu1"; -++ interrupts = , ; -++ interrupt-names = "scd", "vedu1"; -++ }; -++ -++ npu: npu@0x14000000 { -++ compatible = "vendor,svp_npu"; -++ reg = <0x14000000 0x800000>,<0x13fff000 0x1000>; -++ reg-names = "svp_npu","pres_dec_brg"; -++ interrupts = , ; -++ interrupt-names = "svp_npu_ns0", "svp_npu_ns1"; -++ }; -++ -++ ive: ive@0x17000000 { -++ compatible = "vendor,ive"; -++ reg = <0x17000000 0x10000>; -++ reg-names = "ive"; -++ interrupts = , ; -++ interrupt-names = "ive0", "ive1"; -++ }; -++ -++ dpu_rect: dpu_rect@0x17030000 { -++ compatible = "vendor,dpu_rect"; -++ reg = <0x17030000 0x10000>; -++ reg-names = "dpu_rect"; -++ interrupts = , ; -++ interrupt-names = "rect0", "rect1"; -++ }; -++ -++ dpu_match: dpu_match@0x17030000 { -++ compatible = "vendor,dpu_match"; -++ reg = <0x17030000 0x10000>; -++ reg-names = "dpu_match"; -++ interrupts = , ; -++ interrupt-names = "match0", "match1"; -++ }; -++ -++ -++ aiao: aiao@17c00000 { -++ compatible = "vendor,aiao"; -++ reg = <0x17c00000 0x10000>,<0x17c40000 0x10000>,<0x17c10000 0x4000>; -++ reg-names = "aiao","acodec","dmic"; -++ interrupts = ; -++ interrupt-names = "AIO"; -++ }; -++ -++ cipher: cipher@0x101F0000 { -++ compatible = "vendor,cipher"; -++ reg = <0x101F0000 0x10000>,<0x101EC000 0x2000>; -++ reg-names = "spacc","pke"; -++ interrupts = ,, -++ ,; -++ interrupt-names = "spacc_tee","spacc_ree","pke_tee","pke_ree"; -++ }; -++ -++ km: km@0x101EA000 { -++ compatible = "vendor,km"; -++ reg = <0x101EA000 0x2000>; -++ reg-names = "km"; -++ interrupts = ,, -++ ,; -++ interrupt-names = "rkp_tee","rkp_ree","klad_tee","klad_ree"; -++ }; -++ -++ otp: otp@0x101E0000 { -++ compatible = "vendor,otp"; -++ reg = <0x101E0000 0x2000>; -++ reg-names = "otp"; -++ }; -++ -++ trng: trng@0x101EE000 { -++ compatible = "vendor,trng"; -++ reg = <0x101EE000 0x1000>; -++ reg-names = "trng"; -++ }; -++ adc: adc@0x11080000 { -++ compatible = "vendor,lsadc"; -++ reg = <0x11100000 0x1000>; -++ reg-names = "lsadc"; -++ interrupts = <0 47 4>; -++ interrupt-names = "lsadc"; -++ clocks = <&clock HI3519DV500_LSADC_CLK>; -++ clock-names = "lsadc-clk"; -++ resets = <&clock 0x46c0 0>; -++ reset-names = "lsadc-crg"; -++ status = "disabled"; -++ }; -++ -++ -++ wdg: wdg@0x11030000 { -++ compatible = "vendor,wdg"; -++ reg = <0x11030000 0x1000>; -++ reg-names = "wdg0"; -++ interrupts = ; -++ interrupt-names = "wdg"; -++ }; -++ -++ pwm: pwm@0x11080000 { -++ compatible = "vendor,pwm"; -++ reg = <0x11080000 0x1000>, <0x11081000 0x1000>, <0x11082000 0x1000>; -++ reg-names = "pwm0", "pwm1", "pwm2"; -++ clocks = <&clock HI3519DV500_PWM0_CLK>, <&clock HI3519DV500_PWM1_CLK>, <&clock HI3519DV500_PWM2_CLK>; -++ clock-names = "pwm0", "pwm1", "pwm2"; -++ resets = <&clock 0x4588 0>, <&clock 0x4590 0>, <&clock 0x4598 0>; -++ reset-names = "pwm0", "pwm1", "pwm2"; -++ status = "disabled"; -++ }; -++ }; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc-tee.dts b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc-tee.dts -+new file mode 100755 -+index 000000000..2c25f023f -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc-tee.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3519dv500-demb-tee.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc.dts b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc.dts -+new file mode 100755 -+index 000000000..1f0b59aba -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-emmc.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3519dv500-demb.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash-tee.dts b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash-tee.dts -+new file mode 100755 -+index 000000000..86cc5317c -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash-tee.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3519dv500-demb-tee.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash.dts b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash.dts -+new file mode 100755 -+index 000000000..53ee1bf11 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-flash.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3519dv500-demb.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500-demb-tee.dts b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-tee.dts -+new file mode 100755 -+index 000000000..9d10c01c0 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500-demb-tee.dts -+@@ -0,0 +1,326 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/dts-v1/; -++/* reserved for warmreset */ -++/* reserved for arm trustedfirmware */ -++/* Modify this configuration according to the system framework */ -++ -++#include "hi3519dv500.dtsi" -++#include -++ -++/ { -++ model = "Vendor HI3519DV500 DEMO Board"; -++ compatible = "vendor,hi3519dv500"; -++ -++ aliases { -++ serial0 = &uart0; -++ -++ serial1 = &uart1; -++ serial2 = &uart2; -++ serial3 = &uart3; -++ serial4 = &uart4; -++ serial5 = &uart5; -++ -++ i2c0 = &i2c_bus0; -++ i2c1 = &i2c_bus1; -++ i2c2 = &i2c_bus2; -++ i2c3 = &i2c_bus3; -++ i2c4 = &i2c_bus4; -++ i2c5 = &i2c_bus5; -++ i2c6 = &i2c_bus6; -++ i2c7 = &i2c_bus7; -++ -++ spi0 = &spi_bus0; -++ spi1 = &spi_bus1; -++ spi2 = &spi_bus2; -++ spi3 = &spi_bus3; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ gpio11 = &gpio_chip11; -++ gpio12 = &gpio_chip12; -++ gpio13 = &gpio_chip13; -++ gpio14 = &gpio_chip14; -++ }; -++ -++ chosen { -++ bootargs = "earlycon=pl011,0x11040000 mem=512M console=ttyAMA0,115200 clk_ignore_unused root=/dev/mtdblock2 rootfstype=yaffs2 rw mtdparts=bspnand:1M(boot),9M(kernel),32M(rootfs),1M(this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!)"; -++ -++ linux,initrd-start = <0x60000040>; -++ linux,initrd-end = <0x61000000>; -++ }; -++ -++ cpus { -++ #address-cells = <2>; -++ #size-cells = <0>; -++ -++ cpu@0 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x0>; -++ enable-method = "psci"; -++ //clock-latency = <100000>; /* From legacy driver */ -++ }; -++ -++ cpu@1 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x100>; -++ enable-method = "psci"; -++ //clock-latency = <200000>; /* From legacy driver */ -++ }; -++ }; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x0 0x45030000 0x0 0x40000000>; -++ }; -++ -++ reserved-memory { -++ #address-cells = <2>; -++ #size-cells = <2>; -++ ranges; -++ -++ optee_shm@48600000 { -++ reg = <0x0 0x48600000 0x0 0x00400000>; -++ }; -++ }; -++}; -++ -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "disabled"; -++}; -++ -++&uart2 { -++ status = "disabled"; -++}; -++ -++&uart3 { -++ status = "disabled"; -++}; -++ -++&uart4 { -++ status = "disabled"; -++}; -++&uart5 { -++ status = "disabled"; -++}; -++ -++&rtc{ -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++}; -++ -++&i2c_bus3 { -++ status = "okay"; -++}; -++ -++&i2c_bus4 { -++ status = "okay"; -++}; -++ -++&i2c_bus5 { -++ status = "okay"; -++}; -++ -++&i2c_bus6 { -++ status = "okay"; -++}; -++ -++&i2c_bus7 { -++ status = "okay"; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus2{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus3{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -++ -++&gpio_chip11 { -++ status = "okay"; -++}; -++ -++&gpio_chip12 { -++ status = "okay"; -++}; -++ -++&gpio_chip13 { -++ status = "okay"; -++}; -++ -++&gpio_chip14 { -++ status = "okay"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ m25p,fast-read; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mdio { -++ ethphy: ethernet-phy@1 { -++ reg = <1>; -++ }; -++}; -++ -++&gmac { -++ phy-handle = <ðphy>; -++ phy-mode = "rgmii-id"; -++}; -++ -++&edmacv310_0 { -++ status = "disabled"; -++}; -++ -++&adc { -++ status = "okay"; -++}; -++ -++&pwm { -++ status = "okay"; -++}; -++ -++&mmc1 { -++ status = "okay"; -++}; -++ -++&mmc2 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500-demb.dts b/arch/arm64/boot/dts/vendor/hi3519dv500-demb.dts -+new file mode 100755 -+index 000000000..fac31f24e -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500-demb.dts -+@@ -0,0 +1,315 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/dts-v1/; -++/* reserved for warmreset */ -++/* reserved for arm trustedfirmware */ -++/* Modify this configuration according to the system framework */ -++ -++#include "hi3519dv500.dtsi" -++ -++/ { -++ model = "Vendor HI3519DV500 DEMO Board"; -++ compatible = "vendor,hi3519dv500"; -++ -++ aliases { -++ serial0 = &uart0; -++ -++ serial1 = &uart1; -++ serial2 = &uart2; -++ serial3 = &uart3; -++ serial4 = &uart4; -++ serial5 = &uart5; -++ -++ i2c0 = &i2c_bus0; -++ i2c1 = &i2c_bus1; -++ i2c2 = &i2c_bus2; -++ i2c3 = &i2c_bus3; -++ i2c4 = &i2c_bus4; -++ i2c5 = &i2c_bus5; -++ i2c6 = &i2c_bus6; -++ i2c7 = &i2c_bus7; -++ -++ spi0 = &spi_bus0; -++ spi1 = &spi_bus1; -++ spi2 = &spi_bus2; -++ spi3 = &spi_bus3; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ gpio11 = &gpio_chip11; -++ gpio12 = &gpio_chip12; -++ gpio13 = &gpio_chip13; -++ gpio14 = &gpio_chip14; -++ }; -++ -++ chosen { -++ bootargs = "earlycon=pl011,0x11040000 mem=512M console=ttyAMA0,115200 clk_ignore_unused root=/dev/mtdblock2 rootfstype=yaffs2 rw mtdparts=bspnand:1M(boot),9M(kernel),32M(rootfs),1M(this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!)"; -++ -++ linux,initrd-start = <0x60000040>; -++ linux,initrd-end = <0x61000000>; -++ }; -++ -++ cpus { -++ #address-cells = <2>; -++ #size-cells = <0>; -++ -++ cpu@0 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x0>; -++ enable-method = "psci"; -++ //clock-latency = <100000>; /* From legacy driver */ -++ }; -++ -++ cpu@1 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x100>; -++ enable-method = "psci"; -++ //clock-latency = <200000>; /* From legacy driver */ -++ }; -++ }; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x0 0x40030000 0x0 0x40000000>; -++ }; -++}; -++ -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "disabled"; -++}; -++ -++&uart2 { -++ status = "disabled"; -++}; -++ -++&uart3 { -++ status = "disabled"; -++}; -++ -++&uart4 { -++ status = "disabled"; -++}; -++&uart5 { -++ status = "disabled"; -++}; -++ -++&rtc{ -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++}; -++ -++&i2c_bus3 { -++ status = "okay"; -++}; -++ -++&i2c_bus4 { -++ status = "okay"; -++}; -++ -++&i2c_bus5 { -++ status = "okay"; -++}; -++ -++&i2c_bus6 { -++ status = "okay"; -++}; -++ -++&i2c_bus7 { -++ status = "okay"; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus2{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus3{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -++ -++&gpio_chip11 { -++ status = "okay"; -++}; -++ -++&gpio_chip12 { -++ status = "okay"; -++}; -++ -++&gpio_chip13 { -++ status = "okay"; -++}; -++ -++&gpio_chip14 { -++ status = "okay"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ m25p,fast-read; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mdio { -++ ethphy: ethernet-phy@1 { -++ reg = <1>; -++ }; -++}; -++ -++&gmac { -++ phy-handle = <ðphy>; -++ phy-mode = "rgmii-id"; -++}; -++ -++&edmacv310_0 { -++ status = "disabled"; -++}; -++ -++&adc { -++ status = "okay"; -++}; -++ -++&pwm { -++ status = "okay"; -++}; -++ -++&mmc1 { -++ status = "okay"; -++}; -++ -++&mmc2 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500.dtsi b/arch/arm64/boot/dts/vendor/hi3519dv500.dtsi -+new file mode 100755 -+index 000000000..629cdf839 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500.dtsi -+@@ -0,0 +1,859 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/* reserved for arm trustedfirmware */ -++#include -++#include -++#include -++ -++#include "hi3519dv500_family_usb.dtsi" -++/ { -++ #address-cells = <2>; -++ #size-cells = <2>; -++ -++ interrupt-parent = <&gic>; -++ -++ gic: interrupt-controller@12400000 { -++ compatible = "arm,gic-v3"; -++ #interrupt-cells = <3>; -++ #address-cells = <0>; -++ interrupt-controller; -++ reg = <0x0 0x12400000 0x0 0x10000>, /* gic distributor base */ -++ <0x0 0x12440000 0x0 0x140000>; /* gic redistributor base */ -++ }; -++ -++ psci { -++ compatible = "arm,psci-0.2"; -++ method = "smc"; -++ }; -++ -++ pmu { -++ compatible = "arm,armv8-pmuv3"; -++ interrupts = ; -++ }; -++ -++ clock: clock0 { -++ compatible = "vendor,hi3519dv500_clock", "syscon"; -++ #clock-cells = <1>; -++ #reset-cells = <2>; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ reg = <0x0 0x11010000 0x0 0x44a0>; -++ }; -++ -++ firmware { -++ optee { -++ compatible = "linaro,optee-tz"; -++ method = "smc"; -++ }; -++ }; -++ -++ soc { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "simple-bus"; -++ device_type = "soc"; -++ ranges = <0x0 0x00000000 0x0 0xffffffff>; -++ -++ clk_3m: clk_3m { -++ compatible = "fixed-clock"; -++ #clock-cells = <0>; -++ clock-frequency = <3000000>; -++ }; -++ -++ amba { -++ compatible = "arm,amba-bus"; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ ranges; -++ -++ arm-timer { -++ compatible = "arm,armv8-timer"; -++ interrupts = , -++ ; -++ clock-frequency = <24000000>; -++ always-on; -++ }; -++ -++ uart0: uart@11040000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4180 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 20 20>, <&edmacv310_0 21 21>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart1: uart@11041000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11041000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4188 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 22 22>, <&edmacv310_0 23 23>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart2: uart@11042000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11042000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART2_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4190 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 24 24>, <&edmacv310_0 25 25>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart3: uart@11043000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11043000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART3_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4198 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 26 26>, <&edmacv310_0 27 27>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart4: uart@11044000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11044000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART4_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x41a0 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 28 28>, <&edmacv310_0 29 29>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart5: uart@11045000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11045000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART5_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x41a8 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 30 30>, <&edmacv310_0 31 31>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ rtc: rtc@11110000 { -++ compatible = "vendor,rtc"; -++ reg = <0x11110000 0x10000>; -++ interrupts = ; -++ status = "disabled"; -++ }; -++ -++ i2c_bus0: i2c@11060000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11060000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C0_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4280 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ /* dmas = <&edmacv310_0 0 0>, <&edmacv310_0 1 1>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ i2c_bus1: i2c@11061000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11061000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C1_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4288 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 2 2>, <&edmacv310_0 3 3>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus2: i2c@11062000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11062000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C2_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4290 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 4 4>, <&edmacv310_0 5 5>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus3: i2c@11063000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11063000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C3_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4298 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 6 6>, <&edmacv310_0 7 7>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus4: i2c@11064000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11064000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C4_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42A0 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 8 8>, <&edmacv310_0 9 9>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus5: i2c@11065000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11065000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C5_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42A8 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus6: i2c@11066000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11066000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C6_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42B0 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus7: i2c@11067000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11067000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C7_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42B8 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ spi_bus0: spi@11070000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11070000 0x1000>, <0x17a40220 0x4>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4480 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 12 12>, <&edmacv310_0 13 13>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus1: spi@11071000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11071000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4488 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 14 14>, <&edmacv310_0 15 15>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus2: spi@11072000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11072000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI2_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4490 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 16 16>, <&edmacv310_0 17 17>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus3: spi@11073000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11073000 0x1000>, <0x11024610 0x4>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI3_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4498 0>; -++ reset-names = "bsp_spi_rst"; -++ vendor,slave_mode = <0>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 18 18>, <&edmacv310_0 19 19>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ gpio_chip0: gpio_chip@11090000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11090000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip1: gpio_chip@11091000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11091000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip2: gpio_chip@11092000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11092000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip3: gpio_chip@11093000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11093000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip4: gpio_chip@11094000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11094000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip5: gpio_chip@11095000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11095000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip6: gpio_chip@11096000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11096000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip7: gpio_chip@11097000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11097000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip8: gpio_chip@11098000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11098000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip9: gpio_chip@11099000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11099000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip10: gpio_chip@1109A000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109A000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip11: gpio_chip@1109B000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109B000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip12: gpio_chip@1109C000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109C000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip13: gpio_chip@1109D000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109D000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip14: gpio_chip@1109E000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109E000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ }; -++ -++ misc_ctrl: misc-controller@11024000 { -++ compatible = "vendor,miscctrl", "syscon"; -++ reg = <0x11024000 0x5000>; -++ }; -++ -++ ioconfig0: ioconfig0@0eff0000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x0eff0000 0x10000>; -++ }; -++ -++ ioconfig1: ioconfig1@10260000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x10260000 0x10000>; -++ }; -++ -++ /*FLASH DTS nodes*/ -++ fmc: flash-memory-controller@10000000 { -++ compatible = "vendor,fmc"; -++ reg = <0x10000000 0x1000>, <0x0f000000 0x1000000>; -++ reg-names = "control", "memory"; -++ clocks = <&clock HI3519DV500_FMC_CLK>; -++ max-dma-size = <0x2000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ -++ sfc:spi_nor_controller { -++ compatible = "vendor,fmc-spi-nor"; -++ assigned-clocks = <&clock HI3519DV500_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ snfc:spi_nand_controller { -++ compatible = "vendor,fmc-spi-nand"; -++ assigned-clocks = <&clock HI3519DV500_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ }; -++ -++ /*ethernet DTS nodes*/ -++ mdio: mdio@102903c0 { -++ compatible = "vendor,gemac-mdio"; -++ reg = <0x102903c0 0x20>; -++ clocks = <&clock HI3519DV500_ETH_CLK>; -++ resets = <&clock 0x37cc 0>; -++ reset-names = "phy_reset"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ gmac: ethernet@10290000 { -++ compatible = "vendor,gmac-v5"; -++ reg = <0x10290000 0x1000>,<0x1029300c 0x4>; -++ interrupts = , , -++ , ; -++ -++ clocks = <&clock HI3519DV500_ETH_CLK>, -++ <&clock HI3519DV500_ETH_MACIF_CLK>; -++ clock-names = "gmac_clk", -++ "macif_clk"; -++ -++ resets = <&clock 0x37c4 0>, -++ <&clock 0x37c0 0>; -++ reset-names = "port_reset", -++ "macif_reset"; -++ -++ mac-address = [00 00 00 00 00 00]; -++ }; -++ -++ /*EMMC/SD/SDIO DTS nodes*/ -++ mmc0: eMMC@0x10020000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10020000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC0_CLK>, <&clock HI3519DV500_MMC0_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x34c0 16>, <&clock 0x34c0 17>, <&clock 0x34c0 18>, <&clock 0x34c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ non-removable; -++ iocfg_regmap = <&ioconfig0>; -++ bus-width = <8>; -++ cap-mmc-highspeed; -++ mmc-hs200-1_8v; -++ mmc-hs400-1_8v; -++ mmc-hs400-enhanced-strobe; -++ cap-mmc-hw-reset; -++ no-sdio; -++ no-sd; -++ devid = <0>; -++ status = "okay"; -++ }; -++ -++ mmc1: SDIO@0x10030000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10030000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC1_CLK>, <&clock HI3519DV500_MMC1_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x35c0 16>, <&clock 0x35c0 17>, <&clock 0x35c0 18>, <&clock 0x35c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = ; -++ cap-sd-highspeed; -++ sd-uhs-sdr12; -++ sd-uhs-sdr25; -++ sd-uhs-sdr50; -++ sd-uhs-sdr104; -++ full-pwr-cycle; -++ disable-wp; -++ no-mmc; -++ no-sdio; -++ devid = <1>; -++ status = "okay"; -++ }; -++ -++ mmc2: SDIO1@0x10040000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC2_CLK>, <&clock HI3519DV500_MMC2_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x36c0 16>, <&clock 0x36c0 17>, <&clock 0x36c0 18>, <&clock 0x36c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = <4>; -++ cap-sd-highspeed; -++ devid = <2>; -++ status = "okay"; -++ }; -++ -++ edmacv310_0: edma-controller@10280000 { -++ compatible = "vendor,edmacv310"; -++ reg = <0x10280000 0x1000>; -++ reg-names = "dmac"; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_EDMAC_CLK>, -++ <&clock HI3519DV500_EDMAC_AXICLK>; -++ clock-names = "apb_pclk", "axi_aclk"; -++ #clock-cells = <2>; -++ resets = <&clock 0x2A80 0>; -++ reset-names = "dma-reset"; -++ dma-requests = <32>; -++ dma-channels = <8>; -++ devid = <0>; -++ #dma-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ /*SDK DTS nodes*/ -++ sys: sys@11010000 { -++ compatible = "vendor,sys"; -++ reg = <0x11014500 0xBB00>, -++ <0x11020000 0x4000>, -++ <0x11140000 0x20000>, -++ <0X11024000 0x5000>; -++ reg-names = "crg", "sys", "ddr", "misc"; -++ }; -++ -++ mipi_rx: mipi_rx@0x173c0000 { -++ compatible = "vendor,mipi_rx"; -++ reg = <0x173c0000 0x10000>; -++ reg-names = "mipi_rx"; -++ interrupts = ; -++ interrupt-names = "mipi_rx"; -++ }; -++ -++ vi: vi@0x17400000 { -++ compatible = "vendor,vi"; -++ reg = <0x17400000 0x200000>, -++ <0x17800000 0x40000>; -++ reg-names = "vi_cap0", "vi_proc0"; -++ interrupts = , , -++ ; -++ interrupt-names = "vi_cap0", "vi_cap1", "vi_proc0"; -++ }; -++ -++ vpss: vpss@0x17900000 { -++ compatible = "vendor,vpss"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "vpss0"; -++ interrupts = ; -++ interrupt-names = "vpss0"; -++ }; -++ -++ vo: vo@0x17A00000 { -++ compatible = "vendor,vo"; -++ reg = <0x17A00000 0x40000>; -++ reg-names = "vo"; -++ interrupts = ; -++ interrupt-names = "vo"; -++ }; -++ -++ gfbg: gfbg@0x17A00000 { -++ compatible = "vendor,gfbg"; -++ reg = <0x17A00000 0x40000>; -++ reg-names = "gfbg"; -++ interrupts = ; -++ interrupt-names = "gfbg"; -++ }; -++ -++ -++ mipi_tx: mipi_tx@0x10270000 { -++ compatible = "vendor,mipi_tx"; -++ reg = <0x10270000 0x2000>; -++ reg-names = "mipi_tx"; -++ interrupts = ; -++ interrupt-names = "mipi_tx"; -++ }; -++ -++ vgs: vgs@0x17240000 { -++ compatible = "vendor,vgs"; -++ reg = <0x17240000 0x20000>; -++ reg-names = "vgs0"; -++ interrupts = ; -++ interrupt-names = "vgs0"; -++ }; -++ -++ gdc: gdc@0x172c0000 { -++ compatible = "vendor,gdc"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "gdc"; -++ interrupts = ; -++ interrupt-names = "gdc"; -++ }; -++ -++ tde: tde@0x17240000 { -++ compatible = "vendor,tde"; -++ reg = <0x17240000 0x20000>; -++ reg-names = "tde"; -++ interrupts = ; -++ interrupt-names = "tde_osr_isr"; -++ }; -++ -++ jpegd: jpegd@0x17180000 { -++ compatible = "vendor,jpegd"; -++ reg = <0x17180000 0x10000>; -++ reg-names = "jpegd"; -++ interrupts = , ; -++ interrupt-names = "jpegd0", "jpegd1"; -++ }; -++ -++ venc: venc@0x17140000 { -++ compatible = "vendor,venc"; -++ reg = <0x17140000 0x10000>,<0x171c0000 0x10000>; -++ reg-names = "vedu0","jpge"; -++ interrupts = , ; -++ interrupt-names = "vedu0", "jpge"; -++ }; -++ -++ vfmw: vfmw@0x17100000 { -++ compatible = "vendor,vfmw"; -++ reg = <0x17100000 0x10000>, <0x17140000 0x10000>; -++ reg-names = "scd", "vedu1"; -++ interrupts = , ; -++ interrupt-names = "scd", "vedu1"; -++ }; -++ -++ npu: npu@0x14000000 { -++ compatible = "vendor,svp_npu"; -++ reg = <0x14000000 0x800000>,<0x13fff000 0x1000>; -++ reg-names = "svp_npu","pres_dec_brg"; -++ interrupts = , ; -++ interrupt-names = "svp_npu_ns0", "svp_npu_ns1"; -++ }; -++ -++ ive: ive@0x17000000 { -++ compatible = "vendor,ive"; -++ reg = <0x17000000 0x10000>; -++ reg-names = "ive"; -++ interrupts = , ; -++ interrupt-names = "ive0", "ive1"; -++ }; -++ -++ dpu_rect: dpu_rect@0x17030000 { -++ compatible = "vendor,dpu_rect"; -++ reg = <0x17030000 0x10000>; -++ reg-names = "dpu_rect"; -++ interrupts = , ; -++ interrupt-names = "rect0", "rect1"; -++ }; -++ -++ dpu_match: dpu_match@0x17030000 { -++ compatible = "vendor,dpu_match"; -++ reg = <0x17030000 0x10000>; -++ reg-names = "dpu_match"; -++ interrupts = , ; -++ interrupt-names = "match0", "match1"; -++ }; -++ -++ -++ aiao: aiao@17c00000 { -++ compatible = "vendor,aiao"; -++ reg = <0x17c00000 0x10000>,<0x17c40000 0x10000>,<0x17c10000 0x4000>; -++ reg-names = "aiao","acodec","dmic"; -++ interrupts = ; -++ interrupt-names = "AIO"; -++ }; -++ -++ cipher: cipher@0x101F0000 { -++ compatible = "vendor,cipher"; -++ reg = <0x101F0000 0x10000>,<0x101EC000 0x2000>; -++ reg-names = "spacc","pke"; -++ interrupts = ,, -++ ,; -++ interrupt-names = "spacc_tee","spacc_ree","pke_tee","pke_ree"; -++ }; -++ -++ km: km@0x101EA000 { -++ compatible = "vendor,km"; -++ reg = <0x101EA000 0x2000>; -++ reg-names = "km"; -++ interrupts = ,, -++ ,; -++ interrupt-names = "rkp_tee","rkp_ree","klad_tee","klad_ree"; -++ }; -++ -++ otp: otp@0x101E0000 { -++ compatible = "vendor,otp"; -++ reg = <0x101E0000 0x2000>; -++ reg-names = "otp"; -++ }; -++ -++ trng: trng@0x101EE000 { -++ compatible = "vendor,trng"; -++ reg = <0x101EE000 0x1000>; -++ reg-names = "trng"; -++ }; -++ adc: adc@0x11080000 { -++ compatible = "vendor,lsadc"; -++ reg = <0x11100000 0x1000>; -++ reg-names = "lsadc"; -++ interrupts = <0 47 4>; -++ interrupt-names = "lsadc"; -++ clocks = <&clock HI3519DV500_LSADC_CLK>; -++ clock-names = "lsadc-clk"; -++ resets = <&clock 0x46c0 0>; -++ reset-names = "lsadc-crg"; -++ status = "disabled"; -++ }; -++ -++ -++ wdg: wdg@0x11030000 { -++ compatible = "vendor,wdg"; -++ reg = <0x11030000 0x1000>; -++ reg-names = "wdg0"; -++ interrupts = ; -++ interrupt-names = "wdg"; -++ }; -++ -++ pwm: pwm@0x11080000 { -++ compatible = "vendor,pwm"; -++ reg = <0x11080000 0x1000>, <0x11081000 0x1000>, <0x11082000 0x1000>; -++ reg-names = "pwm0", "pwm1", "pwm2"; -++ clocks = <&clock HI3519DV500_PWM0_CLK>, <&clock HI3519DV500_PWM1_CLK>, <&clock HI3519DV500_PWM2_CLK>; -++ clock-names = "pwm0", "pwm1", "pwm2"; -++ resets = <&clock 0x4588 0>, <&clock 0x4590 0>, <&clock 0x4598 0>; -++ reset-names = "pwm0", "pwm1", "pwm2"; -++ status = "disabled"; -++ }; -++ }; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3519dv500_family_usb.dtsi b/arch/arm64/boot/dts/vendor/hi3519dv500_family_usb.dtsi -+new file mode 100755 -+index 000000000..bdb835a31 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3519dv500_family_usb.dtsi -+@@ -0,0 +1,65 @@ -++#include -++ -++/ { -++ ups_clock:ups_clock { -++ compatible = "basedrv-ip,clock"; -++ reg = <0x0 0x11010000 0x0 0x10000>,<0x0 0x17a40000 0x0 0x5000>; -++ reg-names = "peri_crg","peri_ctrl"; -++ #clock-cells = <1>; -++ status = "okay"; -++ }; -++ -++ usb2phy0:usb2phy@0x17350000 { -++ compatible = "usb2phy,xvpphy"; -++ reg = <0x0 0x17350000 0x0 0x1000>,<0x0 0x17a40000 0x0 0x5000>,<0x0 0x101E0124 0x0 0x4>; -++ reg-names = "u2_phy","peri_ctrl"; -++ clocks = <&ups_clock PERI_CRG3632_USB2_PHY0>; -++ clock-names = "phy-clk"; -++ u2phy-trim = <0x0A33C42B 0x0035180F>; -++ #phy-cells = <0>; -++ status = "okay"; -++ }; -++ -++ usb3phy0:usb3phy0@0x17361000 { -++ compatible = "combophy,common"; -++ reg = <0x0 0x17361000 0x0 0x1000>,<0x0 0x17a40000 0x0 0x5000>; -++ reg-names = "combophy","peri_ctrl"; -++ clocks = <&ups_clock PERI_CRG3665_COMBPHY0_CLK>; -++ clock-names = "phy-clk"; -++ #phy-cells = <0>; -++ status = "okay"; -++ }; -++ -++ usb30drd:usb30drd@0x10320000 { -++ compatible = "wing-usb,drd"; -++ reg = <0x0 0x10320000 0x0 0x10000>; -++ controller_id = <0>; -++ support-drd; -++ tx-thrcfg = <0x22080000>; -++ rx-thrcfg = <0x22200000>; -++ phys = <&usb2phy0>,<&usb3phy0>; -++ phy-names = "usb2-phy", "usb3-phy"; -++ clocks = <&ups_clock PERI_CRG3664_USB30_CTRL0>; -++ clock-names = "ctrl-clk"; -++ init_mode="device"; -++ status = "okay"; -++ ranges; -++ #address-cells = <2>; -++ #size-cells = <2>; -++ dwc3@10320000{ -++ compatible = "snps,dwc3"; -++ reg = <0x0 0x10320000 0x0 0x10000>; -++ interrupts = ; -++ interrupt-names = "peripheral"; -++ maximum-speed = "super-speed"; -++ dr_mode = "otg"; -++ usb-role-switch; -++ snps,dis-u1-entry-quirk; -++ snps,dis-u2-entry-quirk; -++ snps,dis_u2_susphy_quirk; -++ snps,dis_u3_susphy_quirk; -++ linux,sysdev_is_parent; -++ extcon = <&usb30drd>; -++ }; -++ }; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc-tee.dts b/arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc-tee.dts -+new file mode 100755 -+index 000000000..dd466d056 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc-tee.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3559v300-demb-tee.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc.dts b/arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc.dts -+new file mode 100755 -+index 000000000..19d418c0e -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3559v300-demb-emmc.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3559v300-demb.dts" -++ -++&mmc0 { -++ status = "okay"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3559v300-demb-flash-tee.dts b/arch/arm64/boot/dts/vendor/hi3559v300-demb-flash-tee.dts -+new file mode 100755 -+index 000000000..41af46c8f -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3559v300-demb-flash-tee.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3559v300-demb-tee.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3559v300-demb-flash.dts b/arch/arm64/boot/dts/vendor/hi3559v300-demb-flash.dts -+new file mode 100755 -+index 000000000..14117f607 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3559v300-demb-flash.dts -+@@ -0,0 +1,9 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "hi3559v300-demb.dts" -++ -++&mmc0 { -++ status = "disabled"; -++}; -++ -+diff --git a/arch/arm64/boot/dts/vendor/hi3559v300-demb-tee.dts b/arch/arm64/boot/dts/vendor/hi3559v300-demb-tee.dts -+new file mode 100755 -+index 000000000..19b294a91 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3559v300-demb-tee.dts -+@@ -0,0 +1,326 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/dts-v1/; -++/* reserved for warmreset */ -++/* reserved for arm trustedfirmware */ -++/* Modify this configuration according to the system framework */ -++ -++#include "hi3559v300.dtsi" -++#include -++ -++/ { -++ model = "Vendor HI3559V300 DEMO Board"; -++ compatible = "vendor,hi3559v300"; -++ -++ aliases { -++ serial0 = &uart0; -++ -++ serial1 = &uart1; -++ serial2 = &uart2; -++ serial3 = &uart3; -++ serial4 = &uart4; -++ serial5 = &uart5; -++ -++ i2c0 = &i2c_bus0; -++ i2c1 = &i2c_bus1; -++ i2c2 = &i2c_bus2; -++ i2c3 = &i2c_bus3; -++ i2c4 = &i2c_bus4; -++ i2c5 = &i2c_bus5; -++ i2c6 = &i2c_bus6; -++ i2c7 = &i2c_bus7; -++ -++ spi0 = &spi_bus0; -++ spi1 = &spi_bus1; -++ spi2 = &spi_bus2; -++ spi3 = &spi_bus3; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ gpio11 = &gpio_chip11; -++ gpio12 = &gpio_chip12; -++ gpio13 = &gpio_chip13; -++ gpio14 = &gpio_chip14; -++ }; -++ -++ chosen { -++ bootargs = "earlycon=pl011,0x11040000 mem=512M console=ttyAMA0,115200 clk_ignore_unused root=/dev/mtdblock2 rootfstype=yaffs2 rw mtdparts=bspnand:1M(boot),9M(kernel),32M(rootfs),1M(this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!)"; -++ -++ linux,initrd-start = <0x60000040>; -++ linux,initrd-end = <0x61000000>; -++ }; -++ -++ cpus { -++ #address-cells = <2>; -++ #size-cells = <0>; -++ -++ cpu@0 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x0>; -++ enable-method = "psci"; -++ //clock-latency = <100000>; /* From legacy driver */ -++ }; -++ -++ cpu@1 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x100>; -++ enable-method = "psci"; -++ //clock-latency = <200000>; /* From legacy driver */ -++ }; -++ }; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x0 0x45030000 0x0 0x40000000>; -++ }; -++ -++ reserved-memory { -++ #address-cells = <2>; -++ #size-cells = <2>; -++ ranges; -++ -++ optee_shm@48600000 { -++ reg = <0x0 0x48600000 0x0 0x00400000>; -++ }; -++ }; -++}; -++ -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "disabled"; -++}; -++ -++&uart2 { -++ status = "disabled"; -++}; -++ -++&uart3 { -++ status = "disabled"; -++}; -++ -++&uart4 { -++ status = "disabled"; -++}; -++&uart5 { -++ status = "disabled"; -++}; -++ -++&rtc{ -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++}; -++ -++&i2c_bus3 { -++ status = "okay"; -++}; -++ -++&i2c_bus4 { -++ status = "okay"; -++}; -++ -++&i2c_bus5 { -++ status = "okay"; -++}; -++ -++&i2c_bus6 { -++ status = "okay"; -++}; -++ -++&i2c_bus7 { -++ status = "okay"; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus2{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus3{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -++ -++&gpio_chip11 { -++ status = "okay"; -++}; -++ -++&gpio_chip12 { -++ status = "okay"; -++}; -++ -++&gpio_chip13 { -++ status = "okay"; -++}; -++ -++&gpio_chip14 { -++ status = "okay"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ m25p,fast-read; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mdio { -++ ethphy: ethernet-phy@1 { -++ reg = <1>; -++ }; -++}; -++ -++&gmac { -++ phy-handle = <ðphy>; -++ phy-mode = "rgmii-id"; -++}; -++ -++&edmacv310_0 { -++ status = "disabled"; -++}; -++ -++&adc { -++ status = "okay"; -++}; -++ -++&pwm { -++ status = "okay"; -++}; -++ -++&mmc1 { -++ status = "okay"; -++}; -++ -++&mmc2 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3559v300-demb.dts b/arch/arm64/boot/dts/vendor/hi3559v300-demb.dts -+new file mode 100755 -+index 000000000..fd4b296c7 -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3559v300-demb.dts -+@@ -0,0 +1,315 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/dts-v1/; -++/* reserved for warmreset */ -++/* reserved for arm trustedfirmware */ -++/* Modify this configuration according to the system framework */ -++ -++#include "hi3559v300.dtsi" -++ -++/ { -++ model = "Vendor HI3559V300 DEMO Board"; -++ compatible = "vendor,hi3559v300"; -++ -++ aliases { -++ serial0 = &uart0; -++ -++ serial1 = &uart1; -++ serial2 = &uart2; -++ serial3 = &uart3; -++ serial4 = &uart4; -++ serial5 = &uart5; -++ -++ i2c0 = &i2c_bus0; -++ i2c1 = &i2c_bus1; -++ i2c2 = &i2c_bus2; -++ i2c3 = &i2c_bus3; -++ i2c4 = &i2c_bus4; -++ i2c5 = &i2c_bus5; -++ i2c6 = &i2c_bus6; -++ i2c7 = &i2c_bus7; -++ -++ spi0 = &spi_bus0; -++ spi1 = &spi_bus1; -++ spi2 = &spi_bus2; -++ spi3 = &spi_bus3; -++ -++ 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; -++ gpio10 = &gpio_chip10; -++ gpio11 = &gpio_chip11; -++ gpio12 = &gpio_chip12; -++ gpio13 = &gpio_chip13; -++ gpio14 = &gpio_chip14; -++ }; -++ -++ chosen { -++ bootargs = "earlycon=pl011,0x11040000 mem=512M console=ttyAMA0,115200 clk_ignore_unused root=/dev/mtdblock2 rootfstype=yaffs2 rw mtdparts=bspnand:1M(boot),9M(kernel),32M(rootfs),1M(this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!_this_bootargs_string_is_reserved_for_bootargs_form_uboot!!!_it_must_be_longer_than_bootargs_form_uboot!!!)"; -++ -++ linux,initrd-start = <0x60000040>; -++ linux,initrd-end = <0x61000000>; -++ }; -++ -++ cpus { -++ #address-cells = <2>; -++ #size-cells = <0>; -++ -++ cpu@0 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x0>; -++ enable-method = "psci"; -++ //clock-latency = <100000>; /* From legacy driver */ -++ }; -++ -++ cpu@1 { -++ compatible = "arm,cortex-a55"; -++ device_type = "cpu"; -++ reg = <0x0 0x100>; -++ enable-method = "psci"; -++ //clock-latency = <200000>; /* From legacy driver */ -++ }; -++ }; -++ -++ memory { -++ device_type = "memory"; -++ reg = <0x0 0x40030000 0x0 0x40000000>; -++ }; -++}; -++ -++&uart0 { -++ status = "okay"; -++}; -++ -++&uart1 { -++ status = "disabled"; -++}; -++ -++&uart2 { -++ status = "disabled"; -++}; -++ -++&uart3 { -++ status = "disabled"; -++}; -++ -++&uart4 { -++ status = "disabled"; -++}; -++&uart5 { -++ status = "disabled"; -++}; -++ -++&rtc{ -++ status = "okay"; -++}; -++ -++&i2c_bus0 { -++ status = "okay"; -++}; -++ -++&i2c_bus1 { -++ status = "okay"; -++}; -++ -++&i2c_bus2 { -++ status = "okay"; -++}; -++ -++&i2c_bus3 { -++ status = "okay"; -++}; -++ -++&i2c_bus4 { -++ status = "okay"; -++}; -++ -++&i2c_bus5 { -++ status = "okay"; -++}; -++ -++&i2c_bus6 { -++ status = "okay"; -++}; -++ -++&i2c_bus7 { -++ status = "okay"; -++}; -++ -++&spi_bus0{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus1{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus2{ -++ status = "okay"; -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&spi_bus3{ -++ status = "okay"; -++ -++ spidev@0 { -++ compatible = "rohm,dh2228fv"; -++ reg = <0>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++ spidev@1 { -++ compatible = "rohm,dh2228fv"; -++ reg = <1>; -++ pl022,interface = <0>; -++ pl022,com-mode = <0>; -++ spi-max-frequency = <25000000>; -++ }; -++}; -++ -++&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"; -++}; -++ -++&gpio_chip10 { -++ status = "okay"; -++}; -++ -++&gpio_chip11 { -++ status = "okay"; -++}; -++ -++&gpio_chip12 { -++ status = "okay"; -++}; -++ -++&gpio_chip13 { -++ status = "okay"; -++}; -++ -++&gpio_chip14 { -++ status = "okay"; -++}; -++ -++&sfc { -++ sfc@0 { -++ compatible = "jedec,spi-nor"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ m25p,fast-read; -++ }; -++}; -++ -++&snfc { -++ nand@0 { -++ compatible = "jedec,spi-nand"; -++ reg = <0>; -++ spi-max-frequency = <200000000>; -++ }; -++}; -++ -++&mdio { -++ ethphy: ethernet-phy@1 { -++ reg = <1>; -++ }; -++}; -++ -++&gmac { -++ phy-handle = <ðphy>; -++ phy-mode = "rgmii-id"; -++}; -++ -++&edmacv310_0 { -++ status = "disabled"; -++}; -++ -++&adc { -++ status = "okay"; -++}; -++ -++&pwm { -++ status = "okay"; -++}; -++ -++&mmc1 { -++ status = "okay"; -++}; -++ -++&mmc2 { -++ status = "disabled"; -++}; -+diff --git a/arch/arm64/boot/dts/vendor/hi3559v300.dtsi b/arch/arm64/boot/dts/vendor/hi3559v300.dtsi -+new file mode 100755 -+index 000000000..9b6928c0f -+--- /dev/null -++++ b/arch/arm64/boot/dts/vendor/hi3559v300.dtsi -+@@ -0,0 +1,853 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++/* reserved for arm trustedfirmware */ -++#include -++#include -++#include -++ -++#include "hi3519dv500_family_usb.dtsi" -++/ { -++ #address-cells = <2>; -++ #size-cells = <2>; -++ -++ interrupt-parent = <&gic>; -++ -++ gic: interrupt-controller@12400000 { -++ compatible = "arm,gic-v3"; -++ #interrupt-cells = <3>; -++ #address-cells = <0>; -++ interrupt-controller; -++ reg = <0x0 0x12400000 0x0 0x10000>, /* gic distributor base */ -++ <0x0 0x12440000 0x0 0x140000>; /* gic redistributor base */ -++ }; -++ -++ psci { -++ compatible = "arm,psci-0.2"; -++ method = "smc"; -++ }; -++ -++ pmu { -++ compatible = "arm,armv8-pmuv3"; -++ interrupts = ; -++ }; -++ -++ clock: clock0 { -++ compatible = "vendor,hi3519dv500_clock", "syscon"; -++ #clock-cells = <1>; -++ #reset-cells = <2>; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ reg = <0x0 0x11010000 0x0 0x44a0>; -++ }; -++ -++ firmware { -++ optee { -++ compatible = "linaro,optee-tz"; -++ method = "smc"; -++ }; -++ }; -++ -++ soc { -++ #address-cells = <1>; -++ #size-cells = <1>; -++ compatible = "simple-bus"; -++ device_type = "soc"; -++ ranges = <0x0 0x00000000 0x0 0xffffffff>; -++ -++ clk_3m: clk_3m { -++ compatible = "fixed-clock"; -++ #clock-cells = <0>; -++ clock-frequency = <3000000>; -++ }; -++ -++ amba { -++ compatible = "arm,amba-bus"; -++ #address-cells = <1>; -++ #size-cells = <1>; -++ ranges; -++ -++ arm-timer { -++ compatible = "arm,armv8-timer"; -++ interrupts = , -++ ; -++ clock-frequency = <24000000>; -++ always-on; -++ }; -++ -++ uart0: uart@11040000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4180 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 20 20>, <&edmacv310_0 21 21>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart1: uart@11041000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11041000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4188 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 22 22>, <&edmacv310_0 23 23>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart2: uart@11042000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11042000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART2_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4190 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 24 24>, <&edmacv310_0 25 25>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart3: uart@11043000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11043000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART3_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4198 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 26 26>, <&edmacv310_0 27 27>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart4: uart@11044000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11044000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART4_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x41a0 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 28 28>, <&edmacv310_0 29 29>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ uart5: uart@11045000 { -++ compatible = "arm,pl011", "arm,primecell"; -++ reg = <0x11045000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_UART5_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x41a8 0>; -++ reset-names = "bsp_uart_rst"; -++ /* dmas = <&edmacv310_0 30 30>, <&edmacv310_0 31 31>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ rtc: rtc@11110000 { -++ compatible = "vendor,rtc"; -++ reg = <0x11110000 0x10000>; -++ interrupts = ; -++ status = "disabled"; -++ }; -++ -++ i2c_bus0: i2c@11060000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11060000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C0_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4280 0>; -++ reset-names = "i2c_reset"; -++ status = "disabled"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ /* dmas = <&edmacv310_0 0 0>, <&edmacv310_0 1 1>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ i2c_bus1: i2c@11061000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11061000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C1_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4288 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 2 2>, <&edmacv310_0 3 3>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus2: i2c@11062000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11062000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C2_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4290 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 4 4>, <&edmacv310_0 5 5>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus3: i2c@11063000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11063000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C3_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x4298 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 6 6>, <&edmacv310_0 7 7>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus4: i2c@11064000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11064000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C4_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42A0 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 8 8>, <&edmacv310_0 9 9>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus5: i2c@11065000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11065000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C5_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42A8 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus6: i2c@11066000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11066000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C6_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42B0 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ i2c_bus7: i2c@11067000 { -++ compatible = "vendor,i2c"; -++ reg = <0x11067000 0x1000>; -++ clocks = <&clock HI3519DV500_I2C7_CLK>; -++ clock-frequency = <100000>; -++ resets = <&clock 0x42B8 0>; -++ reset-names = "i2c_reset"; -++ /* dmas = <&edmacv310_0 10 10>, <&edmacv310_0 11 11>; */ -++ /* dma-names = "rx","tx"; */ -++ status = "disabled"; -++ }; -++ -++ spi_bus0: spi@11070000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11070000 0x1000>, <0x17a40220 0x4>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI0_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4480 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 12 12>, <&edmacv310_0 13 13>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus1: spi@11071000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11071000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI1_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4488 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 14 14>, <&edmacv310_0 15 15>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus2: spi@11072000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11072000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI2_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4490 0>; -++ reset-names = "bsp_spi_rst"; -++ #address-cells = <1>; -++ vendor,slave_mode = <0>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <1>; -++ /* dmas = <&edmacv310_0 16 16>, <&edmacv310_0 17 17>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ spi_bus3: spi@11073000 { -++ compatible = "arm,pl022", "arm,primecell"; -++ arm,primecell-periphid = <0x00800022>; -++ reg = <0x11073000 0x1000>, <0x11024610 0x4>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_SPI3_CLK>; -++ clock-names = "apb_pclk"; -++ resets = <&clock 0x4498 0>; -++ reset-names = "bsp_spi_rst"; -++ vendor,slave_mode = <0>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ status = "disabled"; -++ num-cs = <2>; -++ spi_cs_sb = <2>; -++ spi_cs_mask_bit = <0x4>; -++ /* dmas = <&edmacv310_0 18 18>, <&edmacv310_0 19 19>; */ -++ /* dma-names = "rx","tx"; */ -++ }; -++ -++ gpio_chip0: gpio_chip@11090000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11090000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip1: gpio_chip@11091000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11091000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip2: gpio_chip@11092000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11092000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip3: gpio_chip@11093000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11093000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip4: gpio_chip@11094000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11094000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip5: gpio_chip@11095000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11095000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip6: gpio_chip@11096000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11096000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip7: gpio_chip@11097000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11097000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip8: gpio_chip@11098000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11098000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip9: gpio_chip@11099000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x11099000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip10: gpio_chip@1109A000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109A000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip11: gpio_chip@1109B000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109B000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip12: gpio_chip@1109C000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109C000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip13: gpio_chip@1109D000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109D000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ gpio_chip14: gpio_chip@1109E000 { -++ compatible = "arm,pl061", "arm,primecell"; -++ reg = <0x1109E000 0x1000>; -++ interrupts = ; -++ #gpio-cells = <2>; -++ clocks = <&clock HI3519DV500_FIXED_50M>; -++ clock-names = "apb_pclk"; -++ status = "disabled"; -++ }; -++ -++ }; -++ -++ misc_ctrl: misc-controller@11024000 { -++ compatible = "vendor,miscctrl", "syscon"; -++ reg = <0x11024000 0x5000>; -++ }; -++ -++ ioconfig0: ioconfig0@0eff0000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x0eff0000 0x10000>; -++ }; -++ -++ ioconfig1: ioconfig1@10260000 { -++ compatible = "vendor,ioconfig", "syscon"; -++ reg = <0x10260000 0x10000>; -++ }; -++ -++ /*FLASH DTS nodes*/ -++ fmc: flash-memory-controller@10000000 { -++ compatible = "vendor,fmc"; -++ reg = <0x10000000 0x1000>, <0x0f000000 0x1000000>; -++ reg-names = "control", "memory"; -++ clocks = <&clock HI3519DV500_FMC_CLK>; -++ max-dma-size = <0x2000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ -++ sfc:spi_nor_controller { -++ compatible = "vendor,fmc-spi-nor"; -++ assigned-clocks = <&clock HI3519DV500_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ snfc:spi_nand_controller { -++ compatible = "vendor,fmc-spi-nand"; -++ assigned-clocks = <&clock HI3519DV500_FMC_CLK>; -++ assigned-clock-rates = <24000000>; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ }; -++ -++ /*ethernet DTS nodes*/ -++ mdio: mdio@102903c0 { -++ compatible = "vendor,gemac-mdio"; -++ reg = <0x102903c0 0x20>; -++ clocks = <&clock HI3519DV500_ETH_CLK>; -++ resets = <&clock 0x37cc 0>; -++ reset-names = "phy_reset"; -++ #address-cells = <1>; -++ #size-cells = <0>; -++ }; -++ -++ gmac: ethernet@10290000 { -++ compatible = "vendor,gmac-v5"; -++ reg = <0x10290000 0x1000>,<0x1029300c 0x4>; -++ interrupts = , , -++ , ; -++ -++ clocks = <&clock HI3519DV500_ETH_CLK>, -++ <&clock HI3519DV500_ETH_MACIF_CLK>; -++ clock-names = "gmac_clk", -++ "macif_clk"; -++ -++ resets = <&clock 0x37c4 0>, -++ <&clock 0x37c0 0>; -++ reset-names = "port_reset", -++ "macif_reset"; -++ -++ mac-address = [00 00 00 00 00 00]; -++ }; -++ -++ /*EMMC/SD/SDIO DTS nodes*/ -++ mmc0: eMMC@0x10020000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10020000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC0_CLK>, <&clock HI3519DV500_MMC0_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x34c0 16>, <&clock 0x34c0 17>, <&clock 0x34c0 18>, <&clock 0x34c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ non-removable; -++ iocfg_regmap = <&ioconfig0>; -++ bus-width = <8>; -++ cap-mmc-highspeed; -++ mmc-hs200-1_8v; -++ mmc-hs400-1_8v; -++ mmc-hs400-enhanced-strobe; -++ cap-mmc-hw-reset; -++ no-sdio; -++ no-sd; -++ devid = <0>; -++ status = "okay"; -++ }; -++ -++ mmc1: SDIO@0x10030000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10030000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC1_CLK>, <&clock HI3519DV500_MMC1_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x35c0 16>, <&clock 0x35c0 17>, <&clock 0x35c0 18>, <&clock 0x35c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = ; -++ cap-sd-highspeed; -++ sd-uhs-sdr12; -++ sd-uhs-sdr25; -++ sd-uhs-sdr50; -++ sd-uhs-sdr104; -++ full-pwr-cycle; -++ disable-wp; -++ no-mmc; -++ no-sdio; -++ devid = <1>; -++ status = "okay"; -++ }; -++ -++ mmc2: SDIO1@0x10040000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x10040000 0x1000>; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_MMC2_CLK>, <&clock HI3519DV500_MMC2_HCLK>; -++ clock-names = "mmc_clk", "mmc_hclk"; -++ resets = <&clock 0x36c0 16>, <&clock 0x36c0 17>, <&clock 0x36c0 18>, <&clock 0x36c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ max-frequency = <150000000>; -++ crg_regmap = <&clock>; -++ iocfg_regmap = <&ioconfig1>; -++ bus-width = <4>; -++ cap-sd-highspeed; -++ devid = <2>; -++ status = "okay"; -++ }; -++ -++ edmacv310_0: edma-controller@10280000 { -++ compatible = "vendor,edmacv310"; -++ reg = <0x10280000 0x1000>; -++ reg-names = "dmac"; -++ interrupts = ; -++ clocks = <&clock HI3519DV500_EDMAC_CLK>, -++ <&clock HI3519DV500_EDMAC_AXICLK>; -++ clock-names = "apb_pclk", "axi_aclk"; -++ #clock-cells = <2>; -++ resets = <&clock 0x2A80 0>; -++ reset-names = "dma-reset"; -++ dma-requests = <32>; -++ dma-channels = <8>; -++ devid = <0>; -++ #dma-cells = <2>; -++ status = "disabled"; -++ }; -++ -++ /*SDK DTS nodes*/ -++ sys: sys@11010000 { -++ compatible = "vendor,sys"; -++ reg = <0x11014500 0xBB00>, -++ <0x11020000 0x4000>, -++ <0x11140000 0x20000>, -++ <0X11024000 0x5000>; -++ reg-names = "crg", "sys", "ddr", "misc"; -++ }; -++ -++ mipi_rx: mipi_rx@0x173c0000 { -++ compatible = "vendor,mipi_rx"; -++ reg = <0x173c0000 0x10000>; -++ reg-names = "mipi_rx"; -++ interrupts = ; -++ interrupt-names = "mipi_rx"; -++ }; -++ -++ vi: vi@0x17400000 { -++ compatible = "vendor,vi"; -++ reg = <0x17400000 0x200000>, -++ <0x17800000 0x40000>; -++ reg-names = "vi_cap0", "vi_proc0"; -++ interrupts = , , -++ ; -++ interrupt-names = "vi_cap0", "vi_cap1", "vi_proc0"; -++ }; -++ -++ vpss: vpss@0x17900000 { -++ compatible = "vendor,vpss"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "vpss0"; -++ interrupts = ; -++ interrupt-names = "vpss0"; -++ }; -++ -++ vo: vo@0x17A00000 { -++ compatible = "vendor,vo"; -++ reg = <0x17A00000 0x40000>; -++ reg-names = "vo"; -++ interrupts = ; -++ interrupt-names = "vo"; -++ }; -++ -++ gfbg: gfbg@0x17A00000 { -++ compatible = "vendor,gfbg"; -++ reg = <0x17A00000 0x40000>; -++ reg-names = "gfbg"; -++ interrupts = ; -++ interrupt-names = "gfbg"; -++ }; -++ -++ -++ mipi_tx: mipi_tx@0x10270000 { -++ compatible = "vendor,mipi_tx"; -++ reg = <0x10270000 0x2000>; -++ reg-names = "mipi_tx"; -++ interrupts = ; -++ interrupt-names = "mipi_tx"; -++ }; -++ -++ vgs: vgs@0x17240000 { -++ compatible = "vendor,vgs"; -++ reg = <0x17240000 0x20000>; -++ reg-names = "vgs0"; -++ interrupts = ; -++ interrupt-names = "vgs0"; -++ }; -++ -++ gdc: gdc@0x172c0000 { -++ compatible = "vendor,gdc"; -++ reg = <0x17900000 0x10000>; -++ reg-names = "gdc"; -++ interrupts = ; -++ interrupt-names = "gdc"; -++ }; -++ -++ tde: tde@0x17240000 { -++ compatible = "vendor,tde"; -++ reg = <0x17240000 0x20000>; -++ reg-names = "tde"; -++ interrupts = ; -++ interrupt-names = "tde_osr_isr"; -++ }; -++ -++ jpegd: jpegd@0x17180000 { -++ compatible = "vendor,jpegd"; -++ reg = <0x17180000 0x10000>; -++ reg-names = "jpegd"; -++ interrupts = , ; -++ interrupt-names = "jpegd0", "jpegd1"; -++ }; -++ -++ venc: venc@0x17140000 { -++ compatible = "vendor,venc"; -++ reg = <0x17140000 0x10000>,<0x171c0000 0x10000>; -++ reg-names = "vedu0","jpge"; -++ interrupts = , ; -++ interrupt-names = "vedu0", "jpge"; -++ }; -++ -++ vfmw: vfmw@0x17100000 { -++ compatible = "vendor,vfmw"; -++ reg = <0x17100000 0x10000>, <0x17140000 0x10000>; -++ reg-names = "scd", "vedu1"; -++ interrupts = , ; -++ interrupt-names = "scd", "vedu1"; -++ }; -++ -++ npu: npu@0x14000000 { -++ compatible = "vendor,svp_npu"; -++ reg = <0x14000000 0x800000>,<0x13fff000 0x1000>; -++ reg-names = "svp_npu","pres_dec_brg"; -++ interrupts = , ; -++ interrupt-names = "svp_npu_ns0", "svp_npu_ns1"; -++ }; -++ -++ ive: ive@0x17000000 { -++ compatible = "vendor,ive"; -++ reg = <0x17000000 0x10000>; -++ reg-names = "ive"; -++ interrupts = , ; -++ interrupt-names = "ive0", "ive1"; -++ }; -++ -++ dpu_rect: dpu_rect@0x17030000 { -++ compatible = "vendor,dpu_rect"; -++ reg = <0x17030000 0x10000>; -++ reg-names = "dpu_rect"; -++ interrupts = , ; -++ interrupt-names = "rect0", "rect1"; -++ }; -++ -++ dpu_match: dpu_match@0x17030000 { -++ compatible = "vendor,dpu_match"; -++ reg = <0x17030000 0x10000>; -++ reg-names = "dpu_match"; -++ interrupts = , ; -++ interrupt-names = "match0", "match1"; -++ }; -++ -++ -++ aiao: aiao@17c00000 { -++ compatible = "vendor,aiao"; -++ reg = <0x17c00000 0x10000>,<0x17c40000 0x10000>,<0x17c10000 0x4000>; -++ reg-names = "aiao","acodec","dmic"; -++ interrupts = ; -++ interrupt-names = "AIO"; -++ }; -++ -++ cipher: cipher@0x101F0000 { -++ compatible = "vendor,cipher"; -++ reg = <0x101F0000 0x10000>,<0x101EC000 0x2000>; -++ reg-names = "spacc","pke"; -++ interrupts = ,, -++ ,; -++ interrupt-names = "spacc_tee","spacc_ree","pke_tee","pke_ree"; -++ }; -++ -++ km: km@0x101EA000 { -++ compatible = "vendor,km"; -++ reg = <0x101EA000 0x2000>; -++ reg-names = "km"; -++ interrupts = ,, -++ ,; -++ interrupt-names = "rkp_tee","rkp_ree","klad_tee","klad_ree"; -++ }; -++ -++ otp: otp@0x101E0000 { -++ compatible = "vendor,otp"; -++ reg = <0x101E0000 0x2000>; -++ reg-names = "otp"; -++ }; -++ adc: adc@0x11080000 { -++ compatible = "vendor,lsadc"; -++ reg = <0x11100000 0x1000>; -++ reg-names = "lsadc"; -++ interrupts = <0 47 4>; -++ interrupt-names = "lsadc"; -++ clocks = <&clock HI3519DV500_LSADC_CLK>; -++ clock-names = "lsadc-clk"; -++ resets = <&clock 0x46c0 0>; -++ reset-names = "lsadc-crg"; -++ status = "disabled"; -++ }; -++ -++ -++ wdg: wdg@0x11030000 { -++ compatible = "vendor,wdg"; -++ reg = <0x11030000 0x1000>; -++ reg-names = "wdg0"; -++ interrupts = ; -++ interrupt-names = "wdg"; -++ }; -++ -++ pwm: pwm@0x11080000 { -++ compatible = "vendor,pwm"; -++ reg = <0x11080000 0x1000>, <0x11081000 0x1000>, <0x11082000 0x1000>; -++ reg-names = "pwm0", "pwm1", "pwm2"; -++ clocks = <&clock HI3519DV500_PWM0_CLK>, <&clock HI3519DV500_PWM1_CLK>, <&clock HI3519DV500_PWM2_CLK>; -++ clock-names = "pwm0", "pwm1", "pwm2"; -++ resets = <&clock 0x4588 0>, <&clock 0x4590 0>, <&clock 0x4598 0>; -++ reset-names = "pwm0", "pwm1", "pwm2"; -++ status = "disabled"; -++ }; -++ }; -++}; -+diff --git a/arch/arm64/configs/hi3516dv500_defconfig b/arch/arm64/configs/hi3516dv500_defconfig -+new file mode 100755 -+index 000000000..9cecba03e -+--- /dev/null -++++ b/arch/arm64/configs/hi3516dv500_defconfig -+@@ -0,0 +1,317 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3516dv500-demb-flash" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3516dv500_emmc_defconfig b/arch/arm64/configs/hi3516dv500_emmc_defconfig -+new file mode 100755 -+index 000000000..2ed758517 -+--- /dev/null -++++ b/arch/arm64/configs/hi3516dv500_emmc_defconfig -+@@ -0,0 +1,308 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3516dv500-demb-emmc" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRYPTO_DEFLATE=y -++CONFIG_CRYPTO_LZO=y -++CONFIG_CRYPTO_ZSTD=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3516dv500_emmc_tee_defconfig b/arch/arm64/configs/hi3516dv500_emmc_tee_defconfig -+new file mode 100755 -+index 000000000..e07087aca -+--- /dev/null -++++ b/arch/arm64/configs/hi3516dv500_emmc_tee_defconfig -+@@ -0,0 +1,312 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3516dv500-demb-emmc-tee" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_TEE=y -++CONFIG_OPTEE=y -++CONFIG_SYNC_OPTEE_MEMORY_LAYOUT=y -++CONFIG_OPTEE_DIR="../../optee/optee_os-3.20.0" -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRYPTO_DEFLATE=y -++CONFIG_CRYPTO_LZO=y -++CONFIG_CRYPTO_ZSTD=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3516dv500_tee_defconfig b/arch/arm64/configs/hi3516dv500_tee_defconfig -+new file mode 100755 -+index 000000000..e3859aba9 -+--- /dev/null -++++ b/arch/arm64/configs/hi3516dv500_tee_defconfig -+@@ -0,0 +1,321 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3516DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3516dv500-demb-flash-tee" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_TEE=y -++CONFIG_OPTEE=y -++CONFIG_SYNC_OPTEE_MEMORY_LAYOUT=y -++CONFIG_OPTEE_DIR="../../optee/optee_os-3.20.0" -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3519dv500_defconfig b/arch/arm64/configs/hi3519dv500_defconfig -+new file mode 100755 -+index 000000000..a97199e88 -+--- /dev/null -++++ b/arch/arm64/configs/hi3519dv500_defconfig -+@@ -0,0 +1,317 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3519DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3519dv500-demb-flash" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3519dv500_emmc_defconfig b/arch/arm64/configs/hi3519dv500_emmc_defconfig -+new file mode 100755 -+index 000000000..9a712e789 -+--- /dev/null -++++ b/arch/arm64/configs/hi3519dv500_emmc_defconfig -+@@ -0,0 +1,308 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3519DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3519dv500-demb-emmc" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRYPTO_DEFLATE=y -++CONFIG_CRYPTO_LZO=y -++CONFIG_CRYPTO_ZSTD=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3519dv500_emmc_mini_defconfig b/arch/arm64/configs/hi3519dv500_emmc_mini_defconfig -+new file mode 100755 -+index 000000000..4619cf3ff -+--- /dev/null -++++ b/arch/arm64/configs/hi3519dv500_emmc_mini_defconfig -+@@ -0,0 +1,65 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++CONFIG_BLK_DEV_INITRD=y -++CONFIG_VENDOR_RAMDISK_ZERO_COPY=y -++# CONFIG_FHANDLE is not set -++# CONFIG_KALLSYMS is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3519DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3519dv500-demb-emmc" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_HWMON is not set -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_ROMFS_FS=y -++CONFIG_PRINTK_TIME=y -++CONFIG_CMD_TIMESTAMP=y -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_DEBUG_BUGVERBOSE is not set -++# CONFIG_DEBUG_MISC is not set -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -+diff --git a/arch/arm64/configs/hi3519dv500_emmc_tee_defconfig b/arch/arm64/configs/hi3519dv500_emmc_tee_defconfig -+new file mode 100755 -+index 000000000..e6efdfa5f -+--- /dev/null -++++ b/arch/arm64/configs/hi3519dv500_emmc_tee_defconfig -+@@ -0,0 +1,312 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3519DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3519dv500-demb-emmc-tee" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_TEE=y -++CONFIG_OPTEE=y -++CONFIG_SYNC_OPTEE_MEMORY_LAYOUT=y -++CONFIG_OPTEE_DIR="../../optee/optee_os-3.20.0" -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRYPTO_DEFLATE=y -++CONFIG_CRYPTO_LZO=y -++CONFIG_CRYPTO_ZSTD=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3519dv500_mini_defconfig b/arch/arm64/configs/hi3519dv500_mini_defconfig -+new file mode 100755 -+index 000000000..d4f7bdd0f -+--- /dev/null -++++ b/arch/arm64/configs/hi3519dv500_mini_defconfig -+@@ -0,0 +1,67 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++CONFIG_BLK_DEV_INITRD=y -++CONFIG_VENDOR_RAMDISK_ZERO_COPY=y -++# CONFIG_FHANDLE is not set -++# CONFIG_KALLSYMS is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3519DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3519dv500-demb-flash" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_HWMON is not set -++# CONFIG_HID is not set -++# CONFIG_USB_SUPPORT is not set -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_ROMFS_FS=y -++CONFIG_PRINTK_TIME=y -++CONFIG_CMD_TIMESTAMP=y -++# CONFIG_SYMBOLIC_ERRNAME is not set -++# CONFIG_DEBUG_BUGVERBOSE is not set -++# CONFIG_DEBUG_MISC is not set -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -+diff --git a/arch/arm64/configs/hi3519dv500_tee_defconfig b/arch/arm64/configs/hi3519dv500_tee_defconfig -+new file mode 100755 -+index 000000000..1a3ccb0e4 -+--- /dev/null -++++ b/arch/arm64/configs/hi3519dv500_tee_defconfig -+@@ -0,0 +1,321 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3519DV500=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3519dv500-demb-flash-tee" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_TEE=y -++CONFIG_OPTEE=y -++CONFIG_SYNC_OPTEE_MEMORY_LAYOUT=y -++CONFIG_OPTEE_DIR="../../optee/optee_os-3.20.0" -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3559v300_defconfig b/arch/arm64/configs/hi3559v300_defconfig -+new file mode 100755 -+index 000000000..85a6222bc -+--- /dev/null -++++ b/arch/arm64/configs/hi3559v300_defconfig -+@@ -0,0 +1,317 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3559V300=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3559v300-demb-flash" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3559v300_emmc_defconfig b/arch/arm64/configs/hi3559v300_emmc_defconfig -+new file mode 100755 -+index 000000000..196e5c056 -+--- /dev/null -++++ b/arch/arm64/configs/hi3559v300_emmc_defconfig -+@@ -0,0 +1,308 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3559V300=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3559v300-demb-emmc" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRYPTO_DEFLATE=y -++CONFIG_CRYPTO_LZO=y -++CONFIG_CRYPTO_ZSTD=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3559v300_emmc_tee_defconfig b/arch/arm64/configs/hi3559v300_emmc_tee_defconfig -+new file mode 100755 -+index 000000000..04e8c1b74 -+--- /dev/null -++++ b/arch/arm64/configs/hi3559v300_emmc_tee_defconfig -+@@ -0,0 +1,312 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3559V300=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3559v300-demb-emmc-tee" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_MMC_QUICKBOOT=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_TEE=y -++CONFIG_OPTEE=y -++CONFIG_SYNC_OPTEE_MEMORY_LAYOUT=y -++CONFIG_OPTEE_DIR="../../optee/optee_os-3.20.0" -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRYPTO_DEFLATE=y -++CONFIG_CRYPTO_LZO=y -++CONFIG_CRYPTO_ZSTD=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/configs/hi3559v300_tee_defconfig b/arch/arm64/configs/hi3559v300_tee_defconfig -+new file mode 100755 -+index 000000000..f885941e8 -+--- /dev/null -++++ b/arch/arm64/configs/hi3559v300_tee_defconfig -+@@ -0,0 +1,321 @@ -++# CONFIG_SWAP is not set -++CONFIG_SYSVIPC=y -++CONFIG_USELIB=y -++CONFIG_LOG_BUF_SHIFT=14 -++CONFIG_NAMESPACES=y -++CONFIG_RELAY=y -++# CONFIG_FHANDLE is not set -++CONFIG_BPF_SYSCALL=y -++CONFIG_USERFAULTFD=y -++CONFIG_EMBEDDED=y -++# CONFIG_COMPAT_BRK is not set -++CONFIG_ARCH_BSP=y -++CONFIG_ARCH_HI3559V300=y -++CONFIG_SCHED_MC=y -++CONFIG_NR_CPUS=2 -++CONFIG_HZ_100=y -++CONFIG_CMDLINE="mem=128M console=ttyAMA0,115200 console=ttyMTD,blackbox" -++# CONFIG_EFI is not set -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y -++CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="vendor/hi3559v300-demb-flash-tee" -++CONFIG_CPU_FREQ=y -++CONFIG_CPU_FREQ_STAT=y -++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -++CONFIG_CPU_FREQ_GOV_POWERSAVE=y -++CONFIG_CPU_FREQ_GOV_ONDEMAND=y -++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -++CONFIG_CPUFREQ_DT=y -++# CONFIG_SECCOMP is not set -++CONFIG_MODULES=y -++CONFIG_MODULE_UNLOAD=y -++CONFIG_PARTITION_ADVANCED=y -++CONFIG_CMDLINE_PARTITION=y -++CONFIG_KSM=y -++CONFIG_CMA=y -++CONFIG_NET=y -++CONFIG_PACKET=y -++CONFIG_UNIX=y -++CONFIG_INET=y -++CONFIG_IP_MULTICAST=y -++CONFIG_IPV6_ROUTER_PREF=y -++CONFIG_IPV6_SIT=m -++CONFIG_NETFILTER=y -++CONFIG_PCI=y -++CONFIG_PCIEPORTBUS=y -++# CONFIG_PCIEASPM is not set -++CONFIG_UEVENT_HELPER=y -++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -++CONFIG_DEVTMPFS=y -++CONFIG_DEVTMPFS_MOUNT=y -++# CONFIG_PREVENT_FIRMWARE_BUILD is not set -++CONFIG_MTD=y -++CONFIG_MTD_CMDLINE_PARTS=y -++CONFIG_MTD_BLOCK2MTD=y -++CONFIG_MTD_SPI_NAND_BSP=y -++CONFIG_MTD_RAW_NAND=y -++CONFIG_MTD_SPI_NAND_FMC100=y -++CONFIG_MTD_SPI_NOR=y -++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -++CONFIG_SPI_BSP_SFC=y -++# CONFIG_CLOSE_SPI_8PIN_4IO is not set -++CONFIG_MTD_UBI=y -++CONFIG_BLK_DEV_LOOP=y -++CONFIG_BLK_DEV_RAM=y -++CONFIG_BLK_DEV_RAM_SIZE=65536 -++CONFIG_SCSI=y -++CONFIG_BLK_DEV_SD=y -++CONFIG_NETDEVICES=y -++# CONFIG_NET_VENDOR_3COM is not set -++# CONFIG_NET_VENDOR_ADAPTEC is not set -++# CONFIG_NET_VENDOR_AGERE is not set -++# CONFIG_NET_VENDOR_ALACRITECH is not set -++# CONFIG_NET_VENDOR_ALTEON is not set -++# CONFIG_NET_VENDOR_AMAZON is not set -++# CONFIG_NET_VENDOR_AMD is not set -++# CONFIG_NET_VENDOR_AQUANTIA is not set -++# CONFIG_NET_VENDOR_ARC is not set -++# CONFIG_NET_VENDOR_ATHEROS is not set -++# CONFIG_NET_VENDOR_AURORA is not set -++# CONFIG_NET_VENDOR_BROADCOM is not set -++# CONFIG_NET_VENDOR_BROCADE is not set -++# CONFIG_NET_VENDOR_CADENCE is not set -++# CONFIG_NET_VENDOR_CAVIUM is not set -++# CONFIG_NET_VENDOR_CHELSIO is not set -++# CONFIG_NET_VENDOR_CISCO is not set -++# CONFIG_NET_VENDOR_CORTINA is not set -++# CONFIG_NET_VENDOR_DEC is not set -++# CONFIG_NET_VENDOR_DLINK is not set -++# CONFIG_NET_VENDOR_EMULEX is not set -++# CONFIG_NET_VENDOR_EZCHIP is not set -++# CONFIG_NET_VENDOR_HISILICON is not set -++# CONFIG_NET_VENDOR_HUAWEI is not set -++# CONFIG_NET_VENDOR_INTEL is not set -++CONFIG_ETH_GMAC=y -++CONFIG_GMAC_DDR_64BIT=y -++# CONFIG_NET_VENDOR_MARVELL is not set -++# CONFIG_NET_VENDOR_MELLANOX is not set -++# CONFIG_NET_VENDOR_MICREL is not set -++# CONFIG_NET_VENDOR_MICROCHIP is not set -++# CONFIG_NET_VENDOR_MICROSEMI is not set -++# CONFIG_NET_VENDOR_MYRI is not set -++# CONFIG_NET_VENDOR_NATSEMI is not set -++# CONFIG_NET_VENDOR_NETERION is not set -++# CONFIG_NET_VENDOR_NETRONOME is not set -++# CONFIG_NET_VENDOR_NI is not set -++# CONFIG_NET_VENDOR_NVIDIA is not set -++# CONFIG_NET_VENDOR_OKI is not set -++# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -++# CONFIG_NET_VENDOR_QLOGIC is not set -++# CONFIG_NET_VENDOR_QUALCOMM is not set -++# CONFIG_NET_VENDOR_RDC is not set -++# CONFIG_NET_VENDOR_REALTEK 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_SOLARFLARE is not set -++# CONFIG_NET_VENDOR_SILAN is not set -++# CONFIG_NET_VENDOR_SIS is not set -++# CONFIG_NET_VENDOR_SMSC is not set -++# CONFIG_NET_VENDOR_SOCIONEXT is not set -++# CONFIG_NET_VENDOR_STMICRO is not set -++# CONFIG_NET_VENDOR_SUN is not set -++# CONFIG_NET_VENDOR_SYNOPSYS is not set -++# CONFIG_NET_VENDOR_TEHUTI is not set -++# CONFIG_NET_VENDOR_TI is not set -++# CONFIG_NET_VENDOR_VIA is not set -++# CONFIG_NET_VENDOR_WIZNET is not set -++CONFIG_MDIO_VENDOR_GEMAC=y -++# CONFIG_WLAN is not set -++CONFIG_INPUT_MOUSEDEV=y -++CONFIG_INPUT_MOUSEDEV_PSAUX=y -++CONFIG_INPUT_JOYDEV=y -++CONFIG_INPUT_EVDEV=y -++CONFIG_INPUT_JOYSTICK=y -++CONFIG_INPUT_MISC=y -++CONFIG_INPUT_UINPUT=y -++CONFIG_GAMEPORT=y -++# CONFIG_LEGACY_PTYS is not set -++CONFIG_SERIAL_AMBA_PL011=y -++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -++# CONFIG_HW_RANDOM is not set -++# CONFIG_I2C_COMPAT is not set -++CONFIG_I2C_CHARDEV=y -++# CONFIG_I2C_HELPER_AUTO is not set -++CONFIG_I2C_BSP=y -++CONFIG_SPI=y -++CONFIG_SPI_PL022=y -++CONFIG_SPI_SPIDEV=y -++CONFIG_PINCTRL_SINGLE=y -++CONFIG_GPIOLIB=y -++CONFIG_GPIO_SYSFS=y -++CONFIG_GPIO_GENERIC_PLATFORM=y -++CONFIG_GPIO_PL061=y -++# CONFIG_HWMON is not set -++CONFIG_MFD_BSP_FMC=y -++CONFIG_MFD_SYSCON=y -++CONFIG_REGULATOR=y -++# CONFIG_MEDIA_CEC_SUPPORT is not set -++CONFIG_MEDIA_SUPPORT=y -++CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -++# CONFIG_MEDIA_CONTROLLER is not set -++CONFIG_MEDIA_USB_SUPPORT=y -++CONFIG_USB_VIDEO_CLASS=y -++# CONFIG_RADIO_ADAPTERS is not set -++CONFIG_FB=y -++CONFIG_SOUND=y -++CONFIG_SND=y -++CONFIG_HID_A4TECH=y -++CONFIG_HID_APPLE=y -++CONFIG_HID_BELKIN=y -++CONFIG_HID_CHERRY=y -++CONFIG_HID_CHICONY=y -++CONFIG_HID_CYPRESS=y -++CONFIG_HID_EZKEY=y -++CONFIG_HID_KENSINGTON=y -++CONFIG_HID_MICROSOFT=y -++CONFIG_HID_MONTEREY=y -++CONFIG_HID_PID=y -++CONFIG_USB_HIDDEV=y -++CONFIG_USB=y -++CONFIG_USB_XHCI_HCD=y -++CONFIG_USB_STORAGE=y -++CONFIG_USB_DWC3=y -++# CONFIG_USB_DWC3_HOST is not set -++# CONFIG_USB_DWC3_GADGET is not set -++CONFIG_USB_DWC3_DUAL_ROLE=y -++# CONFIG_USB_DWC3_HAPS is not set -++# CONFIG_USB_DWC3_OF_SIMPLE is not set -++CONFIG_USB_GADGET=y -++CONFIG_USB_CONFIGFS=y -++CONFIG_USB_CONFIGFS_ACM=y -++CONFIG_USB_CONFIGFS_RNDIS=y -++CONFIG_USB_CONFIGFS_MASS_STORAGE=y -++CONFIG_USB_CONFIGFS_F_UAC1=y -++CONFIG_USB_CONFIGFS_F_UVC=y -++CONFIG_MPP_TO_GADGET_UVC=y -++CONFIG_MMC=y -++CONFIG_MMC_SDHCI=y -++CONFIG_MMC_SDHCI_NEBULA=y -++CONFIG_MMC_SDHCI_PLTFM=y -++CONFIG_RTC_CLASS=y -++CONFIG_RTC_DRV_BSP=y -++CONFIG_DMADEVICES=y -++# CONFIG_VIRTIO_MENU is not set -++CONFIG_RESET_BSP=y -++# CONFIG_FSL_ERRATUM_A008585 is not set -++# CONFIG_IOMMU_SUPPORT is not set -++CONFIG_PM_DEVFREQ=y -++CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -++CONFIG_GENERIC_PHY=y -++CONFIG_REALTEK_PHY=y -++CONFIG_TEE=y -++CONFIG_OPTEE=y -++CONFIG_SYNC_OPTEE_MEMORY_LAYOUT=y -++CONFIG_OPTEE_DIR="../../optee/optee_os-3.20.0" -++CONFIG_EXT4_FS=y -++CONFIG_EXT4_FS_POSIX_ACL=y -++CONFIG_EXT4_FS_SECURITY=y -++CONFIG_XFS_FS=y -++CONFIG_XFS_QUOTA=y -++CONFIG_XFS_POSIX_ACL=y -++CONFIG_XFS_RT=y -++CONFIG_QUOTA=y -++CONFIG_QFMT_V1=m -++CONFIG_QFMT_V2=m -++CONFIG_AUTOFS4_FS=m -++CONFIG_FUSE_FS=y -++CONFIG_ISO9660_FS=y -++CONFIG_UDF_FS=y -++CONFIG_MSDOS_FS=y -++CONFIG_VFAT_FS=y -++CONFIG_TMPFS=y -++CONFIG_TMPFS_POSIX_ACL=y -++CONFIG_JFFS2_FS=y -++CONFIG_UBIFS_FS=y -++CONFIG_CRAMFS=y -++CONFIG_SQUASHFS=y -++CONFIG_SQUASHFS_LZO=y -++CONFIG_SQUASHFS_XZ=y -++CONFIG_NFS_FS=y -++CONFIG_NFS_V3_ACL=y -++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_UTF8=y -++CONFIG_CRYPTO_CCM=m -++CONFIG_CRYPTO_SEQIV=m -++CONFIG_CRYPTO_ECHAINIV=m -++CONFIG_CRYPTO_ECB=y -++CONFIG_CRYPTO_CMAC=y -++CONFIG_CRYPTO_SHA256=y -++CONFIG_CRYPTO_AES=y -++CONFIG_CRC_CCITT=y -++CONFIG_DMA_CMA=y -++CONFIG_CMA_SIZE_MBYTES=4 -++CONFIG_MAGIC_SYSRQ=y -++CONFIG_PANIC_ON_OOPS=y -++CONFIG_DETECT_HUNG_TASK=y -++CONFIG_SCHEDSTATS=y -++CONFIG_STACKTRACE=y -++CONFIG_RCU_CPU_STALL_TIMEOUT=60 -++# CONFIG_FTRACE is not set -++CONFIG_EXTCON=y -++ -++# -++# Extcon Device Drivers -++# -++# CONFIG_EXTCON_FSA9480 is not set -++# CONFIG_EXTCON_GPIO is not set -++# CONFIG_EXTCON_MAX3355 is not set -++# CONFIG_EXTCON_PTN5150 is not set -++# CONFIG_EXTCON_RT8973A is not set -++# CONFIG_EXTCON_SM5502 is not set -++# CONFIG_EXTCON_USB_GPIO is not set -++CONFIG_USB_WING=y -++ -++# -++# Wing UPS Phy -++# -++CONFIG_WING_UPS_PHY=y -++CONFIG_WING_UPS_XVP_PHY=y -++# CONFIG_WING_UPS_NANO_PHY is not set -++CONFIG_WING_UPS_MISSILE_PHY=y -++# end of Wing UPS Phy -++ -++CONFIG_BASEDRV_CLK=y -+diff --git a/arch/arm64/include/mach/platform.h b/arch/arm64/include/mach/platform.h -+new file mode 100755 -+index 000000000..c92af0c19 -+--- /dev/null -++++ b/arch/arm64/include/mach/platform.h -+@@ -0,0 +1,11 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __PLATFORM_H__ -++#define __PLATFORM_H__ -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++#include "platform_hi3519dv500.h" -++#endif -++ -++#endif /* End of __PLATFORM_H__ */ -+diff --git a/arch/arm64/include/mach/platform_hi3519dv500.h b/arch/arm64/include/mach/platform_hi3519dv500.h -+new file mode 100755 -+index 000000000..afda98762 -+--- /dev/null -++++ b/arch/arm64/include/mach/platform_hi3519dv500.h -+@@ -0,0 +1,11 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __BSP_CHIP_REGS_H__ -++#define __BSP_CHIP_REGS_H__ -++ -++#define GET_SYS_BOOT_MODE(_reg) (((_reg) >> 4) & 0x3) -++#define BOOT_FROM_SPI 0 -++#define BOOT_FROM_NAND 1 -++#endif /* End of __BSP_CHIP_REGS_H__ */ -+diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c -+index 14300c9e0..06b125fee 100644 -+--- a/arch/arm64/kernel/process.c -++++ b/arch/arm64/kernel/process.c -+@@ -310,6 +310,9 @@ void __show_regs(struct pt_regs *regs) -+ pr_cont("\n"); -+ } -+ } -++#ifdef CONFIG_ARCH_BSP -++EXPORT_SYMBOL(__show_regs); -++#endif -+ -+ void show_regs(struct pt_regs * regs) -+ { -+@@ -772,3 +775,7 @@ int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state, -+ return prot; -+ } -+ #endif -++#ifdef CONFIG_ARCH_BSP -++EXPORT_SYMBOL(put_task_stack); -++EXPORT_SYMBOL(__entry_task); -++#endif -+diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c -+index c445828ec..6b20b092f 100644 -+--- a/arch/arm64/kernel/stacktrace.c -++++ b/arch/arm64/kernel/stacktrace.c -+@@ -116,6 +116,9 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) -+ return 0; -+ } -+ NOKPROBE_SYMBOL(unwind_frame); -++#ifdef CONFIG_ARCH_BSP -++EXPORT_SYMBOL(unwind_frame); -++#endif -+ -+ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame, -+ bool (*fn)(void *, unsigned long), void *data) -+diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c -+index c95be9626..41238b9c9 100644 -+--- a/block/blk-sysfs.c -++++ b/block/blk-sysfs.c -+@@ -868,6 +868,14 @@ int blk_register_queue(struct gendisk *disk) -+ mutex_lock(&q->sysfs_dir_lock); -+ -+ ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue"); -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_SYSFS_MINI_OPT -++ q->kobj.sysfs_file_suppress = 1; -++#endif -++#ifdef CONFIG_KUEVENT_MINI_OPT -++ q->kobj.uevent_suppress = 1; -++#endif -++#endif -+ if (ret < 0) { -+ blk_trace_remove_sysfs(dev); -+ goto unlock; -+diff --git a/drivers/Kconfig b/drivers/Kconfig -+index f765c3a68..461a6d4f3 100644 -+--- a/drivers/Kconfig -++++ b/drivers/Kconfig -+@@ -202,7 +202,9 @@ source "drivers/ras/Kconfig" -+ -+ source "drivers/thunderbolt/Kconfig" -+ -+-source "drivers/android/Kconfig" -++if ARCH_BSP -++# source "drivers/android/Kconfig" -++endif # ARCH_BSP -+ -+ source "drivers/hooks/Kconfig" -+ -+@@ -244,4 +246,14 @@ source "drivers/ub/Kconfig" -+ -+ source "drivers/cpuinspect/Kconfig" -+ -++if ARCH_BSP -++ -++source "drivers/edmac/Kconfig" -++ -++source "drivers/vendor/Kconfig" -++ -++source "drivers/vdmav100/Kconfig" -++ -++endif # ARCH_BSP -++ -+ endmenu -+diff --git a/drivers/Makefile b/drivers/Makefile -+index 4e390005d..e4fe92088 100644 -+--- a/drivers/Makefile -++++ b/drivers/Makefile -+@@ -195,3 +195,8 @@ obj-$(CONFIG_COUNTER) += counter/ -+ obj-$(CONFIG_MOST) += most/ -+ obj-$(CONFIG_ROH) += roh/ -+ obj-$(CONFIG_UB) += ub/ -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_EDMAC) += edmac/ -++obj-$(CONFIG_ARCH_BSP) += vendor/ -++obj-$(CONFIG_VDMA_V100) += vdmav100/ -++endif -+diff --git a/drivers/base/core.c b/drivers/base/core.c -+index 698162104..a01f27fcc 100644 -+--- a/drivers/base/core.c -++++ b/drivers/base/core.c -+@@ -2702,15 +2702,18 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) -+ -+ static int device_add_class_symlinks(struct device *dev) -+ { -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ struct device_node *of_node = dev_of_node(dev); -++#endif -+ int error; -+- -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ if (of_node) { -+ error = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node"); -+ if (error) -+ dev_warn(dev, "Error %d creating of_node link\n",error); -+ /* An error here doesn't warrant bringing down the device */ -+ } -++#endif -+ -+ if (!dev->class) -+ return 0; -+diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c -+index b5cbaa61c..5342decb7 100644 -+--- a/drivers/base/devtmpfs.c -++++ b/drivers/base/devtmpfs.c -+@@ -99,7 +99,9 @@ static inline int is_blockdev(struct device *dev) { return 0; } -+ -+ static int devtmpfs_submit_req(struct req *req, const char *tmp) -+ { -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_STARTUP_PARALLEL_CREATION_NODE_OPT) -+ init_completion(&req->done); -++#endif -+ -+ spin_lock(&req_lock); -+ req->next = requests; -+@@ -107,13 +109,16 @@ static int devtmpfs_submit_req(struct req *req, const char *tmp) -+ spin_unlock(&req_lock); -+ -+ wake_up_process(thread); -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_STARTUP_PARALLEL_CREATION_NODE_OPT) -+ wait_for_completion(&req->done); -++#endif -+ -+ kfree(tmp); -+ -+ return req->err; -+ } -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_STARTUP_PARALLEL_CREATION_NODE_OPT) -+ int devtmpfs_create_node(struct device *dev) -+ { -+ const char *tmp = NULL; -+@@ -140,6 +145,30 @@ int devtmpfs_create_node(struct device *dev) -+ -+ return devtmpfs_submit_req(&req, tmp); -+ } -++#else -++int devtmpfs_create_node(struct device *dev) -++{ -++ const char *tmp = NULL; -++ struct req *req; -++ if (!thread) -++ return 0; -++ req = kmalloc(sizeof(*req), GFP_KERNEL); -++ req->mode = 0; -++ req->uid = GLOBAL_ROOT_UID; -++ req->gid = GLOBAL_ROOT_GID; -++ req->name = device_get_devnode(dev, &req->mode, &req->uid, &req->gid, &tmp); -++ if (!req->name) -++ return -ENOMEM; -++ if (req->mode == 0) -++ req->mode = 0600; -++ if (is_blockdev(dev)) -++ req->mode |= S_IFBLK; -++ else -++ req->mode |= S_IFCHR; -++ req->dev = dev; -++ return devtmpfs_submit_req(req, tmp); -++} -++#endif -+ -+ int devtmpfs_delete_node(struct device *dev) -+ { -+@@ -398,7 +427,15 @@ static void __noreturn devtmpfs_work_loop(void) -+ struct req *next = req->next; -+ req->err = handle(req->name, req->mode, -+ req->uid, req->gid, req->dev); -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_STARTUP_PARALLEL_CREATION_NODE_OPT) -+ complete(&req->done); -++#endif -++ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_STARTUP_PARALLEL_CREATION_NODE_OPT -++ kfree(req); -++#endif -++#endif -+ req = next; -+ } -+ spin_lock(&req_lock); -+diff --git a/drivers/block/brd.c b/drivers/block/brd.c -+index bb3ccaebc..41f7895cd 100644 -+--- a/drivers/block/brd.c -++++ b/drivers/block/brd.c -+@@ -24,6 +24,9 @@ -+ #include -+ #include -+ -++#if (defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY) -++#include -++#endif -+ #include -+ -+ #define PAGE_SECTORS_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) -+@@ -192,6 +195,19 @@ static int copy_to_brd_setup(struct brd_device *brd, sector_t sector, size_t n) -+ static void copy_to_brd(struct brd_device *brd, const void *src, -+ sector_t sector, size_t n) -+ { -++#if (defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY) -++ if (initrd_start == 0) { -++ pr_err("initrd_start is zero ! %s, %d\n", __func__, __LINE__); -++ return; -++ } -++ void *dst = (void *)(initrd_start + (sector << SECTOR_SHIFT)); -++ int ret; -++ -++ ret = memcpy_s(dst, n, src, n); -++ if (ret) { -++ pr_err("memcpy_s failed : %d in %s, %d\n", ret, __func__, __LINE__); -++ }; -++#else -+ struct page *page; -+ void *dst; -+ unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; -+@@ -216,6 +232,7 @@ static void copy_to_brd(struct brd_device *brd, const void *src, -+ memcpy(dst, src, copy); -+ kunmap_atomic(dst); -+ } -++#endif -+ } -+ -+ /* -+@@ -224,6 +241,19 @@ static void copy_to_brd(struct brd_device *brd, const void *src, -+ static void copy_from_brd(void *dst, struct brd_device *brd, -+ sector_t sector, size_t n) -+ { -++#if (defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY) -++ if (initrd_start == 0) { -++ pr_err("initrd_start is zero ! %s, %d\n", __func__, __LINE__); -++ return; -++ } -++ void *src = (void *)(initrd_start + (sector << SECTOR_SHIFT)); -++ int ret; -++ -++ ret = memcpy_s(dst, n, src, n); -++ if (ret) { -++ pr_err("memcpy_s failed : %d in %s, %d\n", ret, __func__, __LINE__); -++ } -++#else -+ struct page *page; -+ void *src; -+ unsigned int offset = (sector & (PAGE_SECTORS-1)) << SECTOR_SHIFT; -+@@ -250,6 +280,7 @@ static void copy_from_brd(void *dst, struct brd_device *brd, -+ } else -+ memset(dst, 0, copy); -+ } -++#endif -+ } -+ -+ /* -+diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile -+index 67377d9e1..4e9a998cd 100644 -+--- a/drivers/char/hw_random/Makefile -++++ b/drivers/char/hw_random/Makefile -+@@ -47,3 +47,6 @@ obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o -+ obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o -+ obj-$(CONFIG_HW_RANDOM_CCTRNG) += cctrng.o -+ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphera-trng.o -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_HW_RANDOM) += bsp_trng.o -++endif -+diff --git a/drivers/char/hw_random/bsp_trng.c b/drivers/char/hw_random/bsp_trng.c -+new file mode 100644 -+index 000000000..10047e78a -+--- /dev/null -++++ b/drivers/char/hw_random/bsp_trng.c -+@@ -0,0 +1,210 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define CA_MISC_REG_BASE_ADDR 0x101e8000 -++#define CA_MISC_REG_SIZE 0x1000 -++#define CPU_ID_STAT 0x0018 -++#define CRYPTO_CPU_ID_SCPU 0xa5 -++#define CRYPTO_CPU_ID_ACPU 0xaa -++#define TRNG_TIMEOUT_IN_US 1000000 -++/*! \Define the offset of TRNG reg */ -++#define HISC_COM_TRNG_FIFO_DATA 0x100 -++#define HISC_COM_TRNG_FIFO_READY 0x104 -++#define HISC_COM_TRNG_DATA_ST 0x108 -++ -++#define TRNG_DONE 1 -++#define TRNG_DATA_READY 1 -++ -++#define HWRNG_READ_BYTE 4 -++ -++void *g_trng_base_addr; -++void *g_ca_misc_base_addr; -++resource_size_t g_trng_reg_addr; -++phys_addr_t g_trng_reg_size; -++struct hwrng *g_rng; -++ -++/* Define the union hisc_com_trng_fifo_ready */ -++typedef union { -++ /* Define the struct bits */ -++ struct { -++ u32 trng_data_ready : 1; /* [0] */ -++ u32 trng_done : 1; /* [1] */ -++ u32 reserved_0 : 30; /* [31..2] */ -++ } bits; -++ -++ /* Define an unsigned member */ -++ u32 all; -++} hisc_com_trng_fifo_ready; -++ -++typedef enum { -++ CRYPTO_CPU_TYPE_SCPU, -++ CRYPTO_CPU_TYPE_ACPU, -++ CRYPTO_CPU_TYPE_INVALID -++} crypto_cpu_type; -++ -++static u32 crypto_reg_read(volatile void *reg_addr) -++{ -++ return ioread32(reg_addr); -++} -++ -++static u32 trng_reg_read(u32 offset) -++{ -++ return crypto_reg_read((volatile void *)(g_trng_base_addr + offset)); -++} -++ -++static u32 ca_misc_reg_read(u32 offset) -++{ -++ return crypto_reg_read((volatile void *)(g_ca_misc_base_addr + offset)); -++} -++ -++static crypto_cpu_type get_cpu_type(void) -++{ -++ u32 cpu_id = ca_misc_reg_read(CPU_ID_STAT) & 0x00ff; -++ if (cpu_id == CRYPTO_CPU_ID_SCPU) { -++ return CRYPTO_CPU_TYPE_SCPU; -++ } else if (cpu_id == CRYPTO_CPU_ID_ACPU) { -++ return CRYPTO_CPU_TYPE_ACPU; -++ } -++ return CRYPTO_CPU_TYPE_INVALID; -++} -++ -++static bool is_trng_ready(void) -++{ -++ hisc_com_trng_fifo_ready trng_ready; -++ -++ if (get_cpu_type() != CRYPTO_CPU_TYPE_SCPU) { /* Not check status on non-secure Core */ -++ return true; -++ } -++ -++ trng_ready.all = trng_reg_read(HISC_COM_TRNG_FIFO_READY); -++ -++ if ((trng_ready.bits).trng_done != TRNG_DONE || -++ (trng_ready.bits).trng_data_ready != TRNG_DATA_READY) { -++ return false; -++ } -++ return true; -++} -++ -++static int read_from_trng(void *buf, size_t max) -++{ -++ u32 data; -++ u32 chk_randnum; -++ data = trng_reg_read(HISC_COM_TRNG_FIFO_DATA); -++ chk_randnum = trng_reg_read(HISC_COM_TRNG_FIFO_DATA); -++ if ((data != 0x00000000) && (data != 0xffffffff) && (data != chk_randnum)) { -++ if (max >= HWRNG_READ_BYTE) { -++ memcpy_s(buf, max, &data, HWRNG_READ_BYTE); -++ return HWRNG_READ_BYTE; -++ } else { -++ memcpy_s(buf, max, &data, max); -++ return max; -++ } -++ } -++ return 0; -++} -++ -++static int trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) -++{ -++ u32 times = 0; -++ -++ while (times < TRNG_TIMEOUT_IN_US) { -++ times++; -++ if (is_trng_ready() == false) { -++ continue; -++ } -++ -++ if (is_trng_ready() == true) { -++ return read_from_trng(buf, max); -++ } -++ } -++ -++ return 0; -++} -++ -++static int trng_probe(struct platform_device *pdev) -++{ -++ int ret; -++ struct resource *res; -++ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -++ if (res) { -++ g_trng_reg_addr = res->start; -++ g_trng_reg_size = res->end - res->start + 1; -++ } else { -++ return -ENODEV; -++ } -++ -++ g_rng = devm_kzalloc(&pdev->dev, sizeof(*g_rng), GFP_KERNEL); -++ if (!g_rng) -++ return -ENOMEM; -++ -++ platform_set_drvdata(pdev, g_rng); -++ -++ g_rng->name = pdev->name; -++ g_rng->read = trng_read; -++ -++ g_trng_base_addr = ioremap(g_trng_reg_addr, g_trng_reg_size); -++ if (g_trng_base_addr == NULL) { -++ devm_kfree(&pdev->dev, g_rng); -++ return -EINVAL; -++ } -++ g_ca_misc_base_addr = ioremap(CA_MISC_REG_BASE_ADDR, CA_MISC_REG_SIZE); -++ if (g_ca_misc_base_addr == NULL) { -++ devm_kfree(&pdev->dev, g_rng); -++ iounmap(g_trng_base_addr); -++ return -EINVAL; -++ } -++ -++ ret = devm_hwrng_register(&pdev->dev, g_rng); -++ if (ret) { -++ dev_err(&pdev->dev, "Failed to register hwrng\n"); -++ devm_kfree(&pdev->dev, g_rng); -++ iounmap(g_ca_misc_base_addr); -++ iounmap(g_trng_base_addr); -++ return ret; -++ } -++ -++ printk("Succeed to load trng.\n"); -++ return 0; -++} -++ -++static int trng_remove(struct platform_device *pdev) -++{ -++ devm_hwrng_unregister(&pdev->dev, g_rng); -++ iounmap(g_ca_misc_base_addr); -++ iounmap(g_trng_base_addr); -++ devm_kfree(&pdev->dev, g_rng); -++ printk("Succeed to remove trng.\n"); -++ return 0; -++} -++ -++static const struct of_device_id trng_match[] = { -++ { .compatible = "vendor,trng" }, -++ { }, -++}; -++MODULE_DEVICE_TABLE(of, trng_match); -++ -++static struct platform_driver trng_driver = { -++ .probe = trng_probe, -++ .remove = trng_remove, -++ .driver = { -++ .name = "vendor,trng", -++ .of_match_table = trng_match, -++ }, -++}; -++ -++module_platform_driver(trng_driver); -++ -++MODULE_LICENSE("GPL"); -++MODULE_DESCRIPTION("Hardware random number generator driver"); -+diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig -+index df739665f..e63228ac8 100644 -+--- a/drivers/clk/Kconfig -++++ b/drivers/clk/Kconfig -+@@ -386,4 +386,8 @@ source "drivers/clk/uniphier/Kconfig" -+ source "drivers/clk/x86/Kconfig" -+ source "drivers/clk/zynqmp/Kconfig" -+ -++if ARCH_BSP -++source "drivers/clk/vendor/Kconfig" -++endif # ARCH_BSP -++ -+ endif -+diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -+index da8fcf147..16301cb4b 100644 -+--- a/drivers/clk/Makefile -++++ b/drivers/clk/Makefile -+@@ -124,3 +124,4 @@ endif -+ obj-$(CONFIG_ARCH_ZX) += zte/ -+ obj-$(CONFIG_ARCH_ZYNQ) += zynq/ -+ obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/ -++obj-$(CONFIG_ARCH_BSP) += vendor/ -+diff --git a/drivers/clk/vendor/Kconfig b/drivers/clk/vendor/Kconfig -+new file mode 100644 -+index 000000000..b94051888 -+--- /dev/null -++++ b/drivers/clk/vendor/Kconfig -+@@ -0,0 +1,8 @@ -++ -++if ARCH_BSP -++config RESET_BSP -++ bool "Vendor Reset Controller Driver" -++ select RESET_CONTROLLER -++ help -++ Build reset controller driver for Vendor device chipsets. -++endif -+diff --git a/drivers/clk/vendor/Makefile b/drivers/clk/vendor/Makefile -+new file mode 100644 -+index 000000000..2f90885dc -+--- /dev/null -++++ b/drivers/clk/vendor/Makefile -+@@ -0,0 +1,8 @@ -++# SPDX-License-Identifier: GPL-2.0 -++# -++ -++obj-y += clk.o clkgate_separated.o -++ -++obj-$(CONFIG_ARCH_HI3519DV500_FAMILY) += clk_hi3519dv500.o -++obj-$(CONFIG_ARCH_HI3516CV610_FAMILY) += clk_hi3516cv610.o -++obj-$(CONFIG_RESET_BSP) += reset.o -+diff --git a/drivers/clk/vendor/clk.c b/drivers/clk/vendor/clk.c -+new file mode 100644 -+index 000000000..2214e94fc -+--- /dev/null -++++ b/drivers/clk/vendor/clk.c -+@@ -0,0 +1,298 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "clk.h" -++ -++static DEFINE_SPINLOCK(bsp_clk_lock); -++ -++struct bsp_clock_data *bsp_clk_alloc(struct platform_device *pdev, -++ unsigned int nr_clks) -++{ -++ struct bsp_clock_data *clk_data; -++ struct resource *res; -++ struct clk **clk_table; -++ -++ clk_data = devm_kmalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); -++ if (!clk_data) -++ return NULL; -++ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -++ if (!res) -++ goto clk_data_free; -++ clk_data->base = devm_ioremap(&pdev->dev, -++ res->start, resource_size(res)); -++ if (!clk_data->base) -++ goto clk_data_free; -++ -++ clk_table = devm_kmalloc_array(&pdev->dev, nr_clks, -++ sizeof(*clk_table), -++ GFP_KERNEL); -++ if (!clk_table) -++ goto clk_data_base_unmap; -++ -++ clk_data->clk_data.clks = clk_table; -++ clk_data->clk_data.clk_num = nr_clks; -++ -++ return clk_data; -++ -++clk_data_base_unmap: -++ if (clk_data->base != NULL) -++ devm_iounmap(&pdev->dev, clk_data->base); -++clk_data_free: -++ if (clk_data != NULL) { -++ devm_kfree(&pdev->dev, clk_data); -++ clk_data = NULL; -++ } -++ return NULL; -++} -++EXPORT_SYMBOL_GPL(bsp_clk_alloc); -++ -++struct bsp_clock_data *bsp_clk_init(struct device_node *np, -++ unsigned int nr_clks) -++{ -++ struct bsp_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) -++ goto err; -++ -++ clk_data->base = base; -++ clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL); -++ if (!clk_table) -++ 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: -++ if (base) { -++ iounmap(base); -++ base = NULL; -++ } -++ kfree(clk_data); -++err: -++ return NULL; -++} -++EXPORT_SYMBOL_GPL(bsp_clk_init); -++ -++long bsp_clk_register_fixed_rate(const struct bsp_fixed_rate_clock *clks, -++ int nums, struct bsp_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(bsp_clk_register_fixed_rate); -++ -++long bsp_clk_register_fixed_factor(const struct bsp_fixed_factor_clock *clks, -++ int nums, -++ struct bsp_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(bsp_clk_register_fixed_factor); -++ -++long bsp_clk_register_mux(const struct bsp_mux_clock *clks, -++ int nums, struct bsp_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, &bsp_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(bsp_clk_register_mux); -++ -++long bsp_clk_register_divider(const struct bsp_divider_clock *clks, -++ int nums, struct bsp_clock_data *data) -++{ -++ struct clk *clk; -++ void __iomem *base = data->base; -++ int i; -++ -++ for (i = 0; i < nums; i++) { -++ clk = clk_register_divider_table(NULL, clks[i].name, -++ clks[i].parent_name, -++ clks[i].flags, -++ base + clks[i].offset, -++ clks[i].shift, clks[i].width, -++ clks[i].div_flags, -++ clks[i].table, -++ &bsp_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_divider(data->clk_data.clks[clks[i].id]); -++ -++ return PTR_ERR(clk); -++} -++EXPORT_SYMBOL_GPL(bsp_clk_register_divider); -++ -++long bsp_clk_register_gate(const struct bsp_gate_clock *clks, -++ int nums, struct bsp_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, -++ &bsp_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(bsp_clk_register_gate); -++ -++void bsp_clk_register_gate_sep(const struct bsp_gate_clock *clks, -++ int nums, struct bsp_clock_data *data) -++{ -++ struct clk *clk; -++ void __iomem *base = data->base; -++ int i; -++ -++ for (i = 0; i < nums; i++) { -++ clk = bsp_register_clkgate_sep(NULL, clks[i].name, -++ clks[i].parent_name, -++ clks[i].flags, -++ base + clks[i].offset, -++ clks[i].bit_idx, -++ clks[i].gate_flags, -++ &bsp_clk_lock); -++ if (IS_ERR(clk)) { -++ pr_err("%s: failed to register clock %s\n", -++ __func__, clks[i].name); -++ continue; -++ } -++ -++ if (clks[i].alias) -++ clk_register_clkdev(clk, clks[i].alias, NULL); -++ -++ data->clk_data.clks[clks[i].id] = clk; -++ } -++} -++EXPORT_SYMBOL_GPL(bsp_clk_register_gate_sep); -++ -+diff --git a/drivers/clk/vendor/clk.h b/drivers/clk/vendor/clk.h -+new file mode 100644 -+index 000000000..ef3888484 -+--- /dev/null -++++ b/drivers/clk/vendor/clk.h -+@@ -0,0 +1,130 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __BSP_CLK_H -++#define __BSP_CLK_H -++ -++#include -++#include -++#include -++ -++struct platform_device; -++ -++struct bsp_clock_data { -++ struct clk_onecell_data clk_data; -++ void __iomem *base; -++}; -++ -++struct bsp_fixed_rate_clock { -++ unsigned int id; -++ char *name; -++ const char *parent_name; -++ unsigned long flags; -++ unsigned long fixed_rate; -++}; -++ -++struct bsp_fixed_factor_clock { -++ unsigned int id; -++ char *name; -++ const char *parent_name; -++ unsigned long mult; -++ unsigned long div; -++ unsigned long flags; -++}; -++ -++struct bsp_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 bsp_phase_clock { -++ unsigned int id; -++ const char *name; -++ const char *parent_names; -++ unsigned long flags; -++ unsigned long offset; -++ u8 shift; -++ u8 width; -++ u32 *phase_degrees; -++ u32 *phase_regvals; -++ u8 phase_num; -++}; -++ -++struct bsp_divider_clock { -++ unsigned int id; -++ const char *name; -++ const char *parent_name; -++ unsigned long flags; -++ unsigned long offset; -++ u8 shift; -++ u8 width; -++ u8 div_flags; -++ struct clk_div_table *table; -++ const char *alias; -++}; -++ -++struct bsp_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 clk *bsp_register_clkgate_sep(struct device *dev, const char *name, -++ const char *parent_name, -++ unsigned long flags, -++ void __iomem *reg, u8 bit_idx, -++ u8 clk_gate_flags, spinlock_t *lock); -++ -++struct bsp_clock_data *bsp_clk_alloc(struct platform_device *pdev, -++ unsigned int nr_clks); -++struct bsp_clock_data *bsp_clk_init(struct device_node *np, -++ unsigned int nr_clks); -++long bsp_clk_register_fixed_rate(const struct bsp_fixed_rate_clock *clks, -++ int nums, struct bsp_clock_data *data); -++long bsp_clk_register_fixed_factor(const struct bsp_fixed_factor_clock *clks, -++ int nums, struct bsp_clock_data *data); -++long bsp_clk_register_mux(const struct bsp_mux_clock *clks, -++ int nums, struct bsp_clock_data *data); -++long bsp_clk_register_divider(const struct bsp_divider_clock *clks, -++ int nums, struct bsp_clock_data *data); -++long bsp_clk_register_gate(const struct bsp_gate_clock *clks, -++ int nums, struct bsp_clock_data *data); -++void bsp_clk_register_gate_sep(const struct bsp_gate_clock *clks, -++ int nums, struct bsp_clock_data *data); -++ -++#define bsp_clk_unregister(type) \ -++static inline \ -++void bsp_clk_unregister_##type(const struct bsp_##type##_clock *clks, \ -++ int nums, struct bsp_clock_data *data) \ -++{ \ -++ struct clk **clocks = data->clk_data.clks; \ -++ int i; \ -++ for (i = 0; i < nums; i++) { \ -++ unsigned int id = clks[i].id; \ -++ if (clocks[id]) \ -++ clk_unregister_##type(clocks[id]); \ -++ } \ -++} -++ -++bsp_clk_unregister(fixed_rate) -++bsp_clk_unregister(fixed_factor) -++bsp_clk_unregister(mux) -++bsp_clk_unregister(divider) -++bsp_clk_unregister(gate) -++ -++#endif /* __BSP_CLK_H */ -+diff --git a/drivers/clk/vendor/clk_hi3516cv610.c b/drivers/clk/vendor/clk_hi3516cv610.c -+new file mode 100644 -+index 000000000..f9311a3ec -+--- /dev/null -++++ b/drivers/clk/vendor/clk_hi3516cv610.c -+@@ -0,0 +1,424 @@ -++/* -++ * HI3516CV610 Clock Driver -++ * -++ * Copyright (c) 2016-2017 HiSilicon 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 . -++ * -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include "clk.h" -++#include "crg.h" -++#include "reset.h" -++ -++static const struct bsp_fixed_rate_clock hi3516cv610_fixed_rate_clks[] = { -++ { HI3516CV610_FIXED_2400M, "2400m", NULL, 0, 2400000000u, }, -++ { HI3516CV610_FIXED_1200M, "1200m", NULL, 0, 1200000000, }, -++ { HI3516CV610_FIXED_1188M, "1188m", NULL, 0, 1188000000, }, -++ { HI3516CV610_FIXED_896M, "896m", NULL, 0, 896000000, }, -++ { HI3516CV610_FIXED_800M, "800m", NULL, 0, 800000000, }, -++ { HI3516CV610_FIXED_792M, "792m", NULL, 0, 792000000, }, -++ { HI3516CV610_FIXED_786M, "786m", NULL, 0, 786000000, }, -++ { HI3516CV610_FIXED_750M, "750m", NULL, 0, 750000000, }, -++ { HI3516CV610_FIXED_700M, "700m", NULL, 0, 700000000, }, -++ { HI3516CV610_FIXED_672M, "672m", NULL, 0, 672000000, }, -++ { HI3516CV610_FIXED_600M, "600m", NULL, 0, 600000000, }, -++ { HI3516CV610_FIXED_594M, "594m", NULL, 0, 594000000, }, -++ { HI3516CV610_FIXED_560M, "560m", NULL, 0, 560000000, }, -++ { HI3516CV610_FIXED_500M, "500m", NULL, 0, 500000000, }, -++ { HI3516CV610_FIXED_475M, "475m", NULL, 0, 475000000, }, -++ { HI3516CV610_FIXED_396M, "396m", NULL, 0, 396000000, }, -++ { HI3516CV610_FIXED_300M, "300m", NULL, 0, 300000000, }, -++ { HI3516CV610_FIXED_297M, "297m", NULL, 0, 297000000, }, -++ { HI3516CV610_FIXED_264M, "264m", NULL, 0, 264000000, }, -++ { HI3516CV610_FIXED_257M, "257m", NULL, 0, 257000000, }, -++ { HI3516CV610_FIXED_250M, "250m", NULL, 0, 250000000, }, -++ { HI3516CV610_FIXED_237P_5M, "237p5m", NULL, 0, 237500000, }, -++ { HI3516CV610_FIXED_200M, "200m", NULL, 0, 200000000, }, -++ { HI3516CV610_FIXED_198M, "198m", NULL, 0, 198000000, }, -++ { HI3516CV610_FIXED_187P_5M, "187p5m", NULL, 0, 187500000, }, -++ { HI3516CV610_FIXED_150M, "150m", NULL, 0, 150000000, }, -++ { HI3516CV610_FIXED_148P_5M, "148p5m", NULL, 0, 148500000, }, -++ { HI3516CV610_FIXED_134M, "134m", NULL, 0, 134000000, }, -++ { HI3516CV610_FIXED_108M, "108m", NULL, 0, 108000000, }, -++ { HI3516CV610_FIXED_100M, "100m", NULL, 0, 100000000, }, -++ { HI3516CV610_FIXED_99M, "99m", NULL, 0, 99000000, }, -++ { HI3516CV610_FIXED_74P_25M, "74p25m", NULL, 0, 74250000, }, -++ { HI3516CV610_FIXED_72M, "72m", NULL, 0, 72000000, }, -++ { HI3516CV610_FIXED_64M, "64m", NULL, 0, 64000000, }, -++ { HI3516CV610_FIXED_60M, "61m", NULL, 0, 61000000, }, -++ { HI3516CV610_FIXED_60M, "60m", NULL, 0, 60000000, }, -++ { HI3516CV610_FIXED_54M, "54m", NULL, 0, 54000000, }, -++ { HI3516CV610_FIXED_50M, "50m", NULL, 0, 50000000, }, -++ { HI3516CV610_FIXED_49P_5M, "49p5m", NULL, 0, 49500000, }, -++ { HI3516CV610_FIXED_37P_125M, "37p125m", NULL, 0, 37125000, }, -++ { HI3516CV610_FIXED_36M, "36m", NULL, 0, 36000000, }, -++ { HI3516CV610_FIXED_27M, "27m", NULL, 0, 27000000, }, -++ { HI3516CV610_FIXED_25M, "25m", NULL, 0, 25000000, }, -++ { HI3516CV610_FIXED_24M, "24m", NULL, 0, 24000000, }, -++ { HI3516CV610_FIXED_12M, "12m", NULL, 0, 12000000, }, -++ { HI3516CV610_FIXED_12P_288M, "12p288m", NULL, 0, 12288000, }, -++ { HI3516CV610_FIXED_6M, "6m", NULL, 0, 6000000, }, -++ { HI3516CV610_FIXED_3M, "3m", NULL, 0, 3000000, }, -++ { HI3516CV610_FIXED_1P_6M, "1p6m", NULL, 0, 1600000, }, -++ { HI3516CV610_FIXED_1M, "1m", NULL, 0, 1000000, }, -++ { HI3516CV610_FIXED_400K, "400k", NULL, 0, 400000, }, -++ { HI3516CV610_FIXED_100K, "100k", NULL, 0, 100000, }, -++}; -++ -++static const char *fmc_mux_p[] __initdata = { -++ "24m", "100m", "148p5m", "198m", "237p5m", "264m", "297m", "396m" -++}; -++ -++static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -++ -++static const char *uart_mux_p[] __initdata = {"100m", "50m", "24m", "3m"}; -++ -++static u32 uart_mux_table[] = {0, 1, 2, 3}; -++ -++static const char *i2c_mux_p[] __initdata = { -++ "50m", "100m" -++}; -++static u32 i2c_mux_table[] = {0, 1}; -++ -++static const char *mmc_mux_p[] __initdata = { -++ "400k", "25m", "50m", "100m", "150m", "200m" -++}; -++static const char *eth_mux_p[] __initconst = {"61m", "100m"}; -++static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5}; -++static u32 eth_mux_table[] = {0, 1}; -++ -++static const char * pwm1_mux_p[] __initdata = {"1m", "24m", "198m"}; -++static u32 pwm1_mux_table[] = {0, 1, 2}; -++ -++static struct bsp_mux_clock hi3516cv610_mux_clks[] __initdata = { -++ { -++ HI3516CV610_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), -++ CLK_SET_RATE_PARENT, 0x3f40, 12, 3, 0, fmc_mux_table, -++ }, -++ { -++ HI3516CV610_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -++ CLK_SET_RATE_PARENT, 0x35c0, 24, 3, 0, mmc_mux_table, -++ }, -++ { -++ HI3516CV610_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -++ CLK_SET_RATE_PARENT, 0x36c0, 24, 3, 0, mmc_mux_table, -++ }, -++ { -++ HI3516CV610_UART0_MUX, "uart_mux0", uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4180, 12, 2, 0, uart_mux_table, -++ }, -++ { -++ HI3516CV610_UART1_MUX, "uart_mux1", uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4188, 12, 2, 0, uart_mux_table, -++ }, -++ { -++ HI3516CV610_UART2_MUX, "uart_mux2", uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4190, 12, 2, 0, uart_mux_table, -++ }, -++ { -++ HI3516CV610_I2C0_MUX, "i2c_mux0", i2c_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4280, 12, 1, 0, i2c_mux_table, -++ }, -++ { -++ HI3516CV610_I2C1_MUX, "i2c_mux1", i2c_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4288, 12, 1, 0, i2c_mux_table, -++ }, -++ { -++ HI3516CV610_I2C2_MUX, "i2c_mux2", i2c_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4290, 12, 1, 0, i2c_mux_table, -++ }, -++ { -++ HI3516CV610_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p), -++ CLK_SET_RATE_PARENT, 0x37cc, 7, 1, 0, eth_mux_table, -++ }, -++ { -++ HI3516CV610_PWM1_MUX, "pwm1_mux", -++ pwm1_mux_p, ARRAY_SIZE(pwm1_mux_p), -++ CLK_SET_RATE_PARENT, 0x4598, 12, 2, 0, pwm1_mux_table -++ }, -++}; -++ -++static struct bsp_fixed_factor_clock hi3516cv610_fixed_factor_clks[] __initdata -++ = { }; -++ -++static struct bsp_gate_clock hi3516cv610_gate_clks[] __initdata = { -++ { -++ HI3516CV610_FMC_CLK, "clk_fmc", "fmc_mux", -++ CLK_SET_RATE_PARENT, 0x3F40, 4, 0, -++ }, -++ { -++ HI3516CV610_MMC0_CLK, "clk_mmc0", "mmc0_mux", -++ CLK_SET_RATE_PARENT, 0x35c0, 0, 0, -++ }, -++ { -++ HI3516CV610_MMC0_HCLK, "hclk_mmc0", "mmc0_mux", -++ CLK_SET_RATE_PARENT, 0x35c0, 1, 0, -++ }, -++ { -++ HI3516CV610_MMC1_CLK, "clk_mmc1", "mmc1_mux", -++ CLK_SET_RATE_PARENT, 0x36c0, 0, 0, -++ }, -++ { -++ HI3516CV610_MMC1_HCLK, "hclk_mmc1", "mmc1_mux", -++ CLK_SET_RATE_PARENT, 0x36c0, 1, 0, -++ }, -++ { -++ HI3516CV610_UART0_CLK, "clk_uart0", "uart_mux0", -++ CLK_SET_RATE_PARENT, 0x4180, 4, 0, -++ }, -++ { -++ HI3516CV610_UART1_CLK, "clk_uart1", "uart_mux1", -++ CLK_SET_RATE_PARENT, 0x4188, 4, 0, -++ }, -++ { -++ HI3516CV610_UART2_CLK, "clk_uart2", "uart_mux2", -++ CLK_SET_RATE_PARENT, 0x4190, 4, 0, -++ }, -++ { -++ HI3516CV610_SPI0_CLK, "clk_spi0", "100m", -++ CLK_SET_RATE_PARENT, 0x4480, 4, 0, -++ }, -++ { -++ HI3516CV610_SPI1_CLK, "clk_spi1", "100m", -++ CLK_SET_RATE_PARENT, 0x4488, 4, 0, -++ }, -++ { -++ HI3516CV610_I2C0_CLK, "clk_i2c0", "i2c_mux0", -++ CLK_SET_RATE_PARENT, 0x4280, 4, 0, -++ }, -++ { -++ HI3516CV610_I2C1_CLK, "clk_i2c1", "i2c_mux1", -++ CLK_SET_RATE_PARENT, 0x4288, 4, 0, -++ }, -++ { -++ HI3516CV610_I2C2_CLK, "clk_i2c2", "i2c_mux2", -++ CLK_SET_RATE_PARENT, 0x4290, 4, 0, -++ }, -++ { -++ HI3516CV610_ETH0_CLK, "clk_eth0", "eth_mux", -++ CLK_SET_RATE_PARENT, 0x37cc, 1, 0, -++ }, -++ { -++ HI3516CV610_FEPHY_CLK, "clk_fephy", "eth_mux", -++ CLK_SET_RATE_PARENT, 0x37cc, 2, 0, -++ }, -++ { -++ HI3516CV610_EDMAC_AXICLK, "clk_edmac_axi", NULL, -++ CLK_SET_RATE_PARENT, 0x2a80, 5, 0, -++ }, -++ { -++ HI3516CV610_EDMAC_APBCLK, "clk_edmac_apb", NULL, -++ CLK_SET_RATE_PARENT, 0x2a80, 4, 0, -++ }, -++ { -++ HI3516CV610_GPIO0_CLK, "clk_gpio0", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 0, 0, -++ }, -++ { -++ HI3516CV610_GPIO1_CLK, "clk_gpio1", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 1, 0, -++ }, -++ { -++ HI3516CV610_GPIO2_CLK, "clk_gpio2", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 2, 0, -++ }, -++ { -++ HI3516CV610_GPIO3_CLK, "clk_gpio3", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 3, 0, -++ }, -++ { -++ HI3516CV610_GPIO4_CLK, "clk_gpio4", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 4, 0, -++ }, -++ { -++ HI3516CV610_GPIO5_CLK, "clk_gpio5", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 5, 0, -++ }, -++ { -++ HI3516CV610_GPIO6_CLK, "clk_gpio6", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 6, 0, -++ }, -++ { -++ HI3516CV610_GPIO7_CLK, "clk_gpio7", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 7, 0, -++ }, -++ { -++ HI3516CV610_GPIO8_CLK, "clk_gpio8", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 8, 0, -++ }, -++ { -++ HI3516CV610_GPIO9_CLK, "clk_gpio9", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 9, 0, -++ }, -++ { -++ HI3516CV610_GPIO10_CLK, "clk_gpio10", NULL, -++ CLK_SET_RATE_PARENT, 0x4768, 10, 0, -++ }, -++ /* pwm1 */ -++ { -++ HI3516CV610_PWM1_CLK, "clk_pwm1", "pwm1_mux", -++ CLK_SET_RATE_PARENT, 0x4598, 4, 0, -++ }, -++}; -++ -++static __init struct bsp_clock_data *hi3516cv610_clk_register( -++ struct platform_device *pdev) -++{ -++ struct bsp_clock_data *clk_data = NULL; -++ int ret; -++ -++ clk_data = bsp_clk_alloc(pdev, HI3516CV610_NR_CLKS); -++ if (clk_data == NULL) -++ return ERR_PTR(-ENOMEM); -++ -++ ret = bsp_clk_register_fixed_rate(hi3516cv610_fixed_rate_clks, -++ ARRAY_SIZE(hi3516cv610_fixed_rate_clks), clk_data); -++ if (ret) -++ return ERR_PTR(ret); -++ -++ ret = bsp_clk_register_mux(hi3516cv610_mux_clks, -++ ARRAY_SIZE(hi3516cv610_mux_clks), clk_data); -++ if (ret) -++ goto unregister_fixed_rate; -++ -++ ret = bsp_clk_register_fixed_factor(hi3516cv610_fixed_factor_clks, -++ ARRAY_SIZE(hi3516cv610_fixed_factor_clks), clk_data); -++ if (ret) -++ goto unregister_mux; -++ -++ ret = bsp_clk_register_gate(hi3516cv610_gate_clks, -++ ARRAY_SIZE(hi3516cv610_gate_clks), clk_data); -++ if (ret) -++ goto unregister_factor; -++ -++ ret = of_clk_add_provider(pdev->dev.of_node, -++ of_clk_src_onecell_get, &clk_data->clk_data); -++ if (ret) -++ goto unregister_gate; -++ -++ return clk_data; -++ -++unregister_gate: -++ bsp_clk_unregister_gate(hi3516cv610_gate_clks, -++ ARRAY_SIZE(hi3516cv610_gate_clks), clk_data); -++unregister_factor: -++ bsp_clk_unregister_fixed_factor(hi3516cv610_fixed_factor_clks, -++ ARRAY_SIZE(hi3516cv610_fixed_factor_clks), clk_data); -++unregister_mux: -++ bsp_clk_unregister_mux(hi3516cv610_mux_clks, -++ ARRAY_SIZE(hi3516cv610_mux_clks), -++ clk_data); -++unregister_fixed_rate: -++ bsp_clk_unregister_fixed_rate(hi3516cv610_fixed_rate_clks, -++ ARRAY_SIZE(hi3516cv610_fixed_rate_clks), clk_data); -++ return ERR_PTR(ret); -++} -++ -++static __init void hi3516cv610_clk_unregister(const struct platform_device *pdev) -++{ -++ struct bsp_crg_dev *crg = platform_get_drvdata(pdev); -++ -++ of_clk_del_provider(pdev->dev.of_node); -++ -++ bsp_clk_unregister_gate(hi3516cv610_gate_clks, -++ ARRAY_SIZE(hi3516cv610_gate_clks), crg->clk_data); -++ -++ bsp_clk_unregister_mux(hi3516cv610_mux_clks, -++ ARRAY_SIZE(hi3516cv610_mux_clks), crg->clk_data); -++ -++ bsp_clk_unregister_fixed_factor(hi3516cv610_fixed_factor_clks, -++ ARRAY_SIZE(hi3516cv610_fixed_factor_clks), crg->clk_data); -++ -++ bsp_clk_unregister_fixed_rate(hi3516cv610_fixed_rate_clks, -++ ARRAY_SIZE(hi3516cv610_fixed_rate_clks), crg->clk_data); -++} -++ -++static const struct bsp_crg_funcs hi3516cv610_crg_funcs = { -++ .register_clks = hi3516cv610_clk_register, -++ .unregister_clks = hi3516cv610_clk_unregister, -++}; -++ -++static const struct of_device_id hi3516cv610_crg_match_table[] = { -++ { -++ .compatible = "vendor,hi3516cv610_clock", -++ .data = &hi3516cv610_crg_funcs -++ }, -++ { } -++}; -++MODULE_DEVICE_TABLE(of, hi3516cv610_crg_match_table); -++ -++static int hi3516cv610_crg_probe(struct platform_device *pdev) -++{ -++ struct bsp_crg_dev *crg = NULL; -++ -++ crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL); -++ if (crg == NULL) -++ return -ENOMEM; -++ -++ crg->funcs = of_device_get_match_data(&pdev->dev); -++ if (crg->funcs == NULL) -++ return -ENOENT; -++ -++ crg->rstc = vendor_reset_init(pdev); -++ if (crg->rstc == NULL) -++ return -ENOMEM; -++ -++ crg->clk_data = crg->funcs->register_clks(pdev); -++ if (IS_ERR(crg->clk_data)) { -++ bsp_reset_exit(crg->rstc); -++ return PTR_ERR(crg->clk_data); -++ } -++ -++ platform_set_drvdata(pdev, crg); -++ return 0; -++} -++ -++static int hi3516cv610_crg_remove(struct platform_device *pdev) -++{ -++ struct bsp_crg_dev *crg = platform_get_drvdata(pdev); -++ -++ bsp_reset_exit(crg->rstc); -++ crg->funcs->unregister_clks(pdev); -++ return 0; -++} -++ -++static struct platform_driver hi3516cv610_crg_driver = { -++ .probe = hi3516cv610_crg_probe, -++ .remove = hi3516cv610_crg_remove, -++ .driver = { -++ .name = "hi3516cv610_clock", -++ .of_match_table = hi3516cv610_crg_match_table, -++ }, -++}; -++ -++static int __init hi3516cv610_crg_init(void) -++{ -++ return platform_driver_register(&hi3516cv610_crg_driver); -++} -++core_initcall(hi3516cv610_crg_init); -++ -++static void __exit hi3516cv610_crg_exit(void) -++{ -++ platform_driver_unregister(&hi3516cv610_crg_driver); -++} -++module_exit(hi3516cv610_crg_exit); -++ -++MODULE_LICENSE("GPL v2"); -++MODULE_DESCRIPTION("HiSilicon Hi3516CV610 CRG Driver"); -+diff --git a/drivers/clk/vendor/clk_hi3519dv500.c b/drivers/clk/vendor/clk_hi3519dv500.c -+new file mode 100644 -+index 000000000..1735bccd9 -+--- /dev/null -++++ b/drivers/clk/vendor/clk_hi3519dv500.c -+@@ -0,0 +1,520 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "clk.h" -++#include "crg.h" -++#include "reset.h" -++ -++/* soc clk config */ -++static const struct bsp_fixed_rate_clock hi3519dv500_fixed_rate_clks_crg[] = { -++ { HI3519DV500_FIXED_2400M, "2400m", NULL, 0, 2400000000, }, -++ { HI3519DV500_FIXED_1200M, "1200m", NULL, 0, 1200000000, }, -++ { HI3519DV500_FIXED_1188M, "1188m", NULL, 0, 1188000000, }, -++ { HI3519DV500_FIXED_896M, "896m", NULL, 0, 896000000, }, -++ { HI3519DV500_FIXED_800M, "800m", NULL, 0, 800000000, }, -++ { HI3519DV500_FIXED_792M, "792m", NULL, 0, 792000000, }, -++ { HI3519DV500_FIXED_786M, "786m", NULL, 0, 786000000, }, -++ { HI3519DV500_FIXED_750M, "750m", NULL, 0, 750000000, }, -++ { HI3519DV500_FIXED_700M, "700m", NULL, 0, 700000000, }, -++ { HI3519DV500_FIXED_672M, "672m", NULL, 0, 672000000, }, -++ { HI3519DV500_FIXED_600M, "600m", NULL, 0, 600000000, }, -++ { HI3519DV500_FIXED_594M, "594m", NULL, 0, 594000000, }, -++ { HI3519DV500_FIXED_560M, "560m", NULL, 0, 560000000, }, -++ { HI3519DV500_FIXED_500M, "500m", NULL, 0, 500000000, }, -++ { HI3519DV500_FIXED_475M, "475m", NULL, 0, 475000000, }, -++ { HI3519DV500_FIXED_396M, "396m", NULL, 0, 396000000, }, -++ { HI3519DV500_FIXED_300M, "300m", NULL, 0, 300000000, }, -++ { HI3519DV500_FIXED_297M, "297m", NULL, 0, 297000000, }, -++ { HI3519DV500_FIXED_257M, "257m", NULL, 0, 257000000, }, -++ { HI3519DV500_FIXED_250M, "250m", NULL, 0, 250000000, }, -++ { HI3519DV500_FIXED_200M, "200m", NULL, 0, 200000000, }, -++ { HI3519DV500_FIXED_198M, "198m", NULL, 0, 198000000, }, -++ { HI3519DV500_FIXED_187P_5M, "187p5m", NULL, 0, 187500000, }, -++ { HI3519DV500_FIXED_150M, "150m", NULL, 0, 150000000, }, -++ { HI3519DV500_FIXED_148P_5M, "148p5m", NULL, 0, 148500000, }, -++ { HI3519DV500_FIXED_134M, "134m", NULL, 0, 134000000, }, -++ { HI3519DV500_FIXED_108M, "108m", NULL, 0, 108000000, }, -++ { HI3519DV500_FIXED_100M, "100m", NULL, 0, 100000000, }, -++ { HI3519DV500_FIXED_99M, "99m", NULL, 0, 99000000, }, -++ { HI3519DV500_FIXED_74P_25M, "74p25m", NULL, 0, 74250000, }, -++ { HI3519DV500_FIXED_72M, "72m", NULL, 0, 72000000, }, -++ { HI3519DV500_FIXED_64M, "64m", NULL, 0, 64000000, }, -++ { HI3519DV500_FIXED_60M, "60m", NULL, 0, 60000000, }, -++ { HI3519DV500_FIXED_54M, "54m", NULL, 0, 54000000, }, -++ { HI3519DV500_FIXED_50M, "50m", NULL, 0, 50000000, }, -++ { HI3519DV500_FIXED_49P_5M, "49p5m", NULL, 0, 49500000, }, -++ { HI3519DV500_FIXED_37P_125M, "37p125m", NULL, 0, 37125000, }, -++ { HI3519DV500_FIXED_36M, "36m", NULL, 0, 36000000, }, -++ { HI3519DV500_FIXED_27M, "27m", NULL, 0, 27000000, }, -++ { HI3519DV500_FIXED_25M, "25m", NULL, 0, 25000000, }, -++ { HI3519DV500_FIXED_24M, "24m", NULL, 0, 24000000, }, -++ { HI3519DV500_FIXED_12M, "12m", NULL, 0, 12000000, }, -++ { HI3519DV500_FIXED_12P_288M, "12p288m", NULL, 0, 12288000, }, -++ { HI3519DV500_FIXED_6M, "6m", NULL, 0, 6000000, }, -++ { HI3519DV500_FIXED_3M, "3m", NULL, 0, 3000000, }, -++ { HI3519DV500_FIXED_1P_6M, "1p6m", NULL, 0, 1600000, }, -++ { HI3519DV500_FIXED_400K, "400k", NULL, 0, 400000, }, -++ { HI3519DV500_FIXED_100K, "100k", NULL, 0, 100000, }, -++}; -++ -++ -++static const char *fmc_mux_p[] __initdata = { -++ "24m", "100m", "150m", "198m", "237m", "300m", "396m" -++}; -++static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6}; -++ -++static const char *mmc_mux_p[] __initdata = { -++ "400k", "25m", "50m", "100m", "150m", "187p5m", "200m" -++}; -++static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -++ -++static const char *sdio0_mux_p[] __initdata = { -++ "400k", "25m", "50m", "100m", "150m", "187p5m", "200m" -++}; -++static u32 sdio0_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -++ -++static const char *sdio1_mux_p[] __initdata = { -++ "400k", "25m", "50m", "100m", "150m", "187p5m", "200m" -++}; -++static u32 sdio1_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; -++ -++static const char *uart_mux_p[] __initdata = {"100m", "50m", "24m", "3m"}; -++static u32 uart_mux_table[] = {0, 1, 2, 3}; -++ -++static const char *i2c_mux_p[] __initdata = { -++ "50m", "100m" -++}; -++static u32 i2c_mux_table[] = {0, 1}; -++ -++static const char * pwm0_mux_p[] __initdata = {"198m"}; -++static u32 pwm0_mux_table[] = {0}; -++ -++static const char * pwm1_mux_p[] __initdata = {"198m"}; -++static u32 pwm1_mux_table[] = {0}; -++ -++static const char * pwm2_mux_p[] __initdata = {"198m"}; -++static u32 pwm2_mux_table[] = {0}; -++ -++static struct bsp_mux_clock hi3519dv500_mux_clks_crg[] __initdata = { -++ { -++ HI3519DV500_FMC_MUX, "fmc_mux", -++ fmc_mux_p, ARRAY_SIZE(fmc_mux_p), -++ CLK_SET_RATE_PARENT, 0x3f40, 12, 3, 0, fmc_mux_table, -++ }, -++ { -++ HI3519DV500_MMC0_MUX, "mmc0_mux", -++ mmc_mux_p, ARRAY_SIZE(mmc_mux_p), -++ CLK_SET_RATE_PARENT, 0x34c0, 24, 3, 0, mmc_mux_table, -++ }, -++ { -++ HI3519DV500_MMC1_MUX, "mmc1_mux", -++ sdio0_mux_p, ARRAY_SIZE(sdio0_mux_p), -++ CLK_SET_RATE_PARENT, 0x35c0, 24, 3, 0, sdio0_mux_table, -++ }, -++ { -++ HI3519DV500_MMC2_MUX, "mmc2_mux", -++ sdio1_mux_p, ARRAY_SIZE(sdio1_mux_p), -++ CLK_SET_RATE_PARENT, 0x36c0, 24, 3, 0, sdio1_mux_table, -++ }, -++ { -++ HI3519DV500_UART0_MUX, "uart0_mux", -++ uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4180, 12, 2, 0, uart_mux_table -++ }, -++ { -++ HI3519DV500_UART1_MUX, "uart1_mux", -++ uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4188, 12, 2, 0, uart_mux_table -++ }, -++ { -++ HI3519DV500_UART2_MUX, "uart2_mux", -++ uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4190, 12, 2, 0, uart_mux_table -++ }, -++ { -++ HI3519DV500_UART3_MUX, "uart3_mux", -++ uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x4198, 12, 2, 0, uart_mux_table -++ }, -++ { -++ HI3519DV500_UART4_MUX, "uart4_mux", -++ uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x41a0, 12, 2, 0, uart_mux_table -++ }, -++ { -++ HI3519DV500_UART5_MUX, "uart5_mux", -++ uart_mux_p, ARRAY_SIZE(uart_mux_p), -++ CLK_SET_RATE_PARENT, 0x41a8, 12, 2, 0, uart_mux_table -++ }, -++ { -++ HI3519DV500_I2C0_MUX, "i2c0_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x4280, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_I2C1_MUX, "i2c1_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x4288, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_I2C2_MUX, "i2c2_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x4290, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_I2C3_MUX, "i2c3_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x4298, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_I2C4_MUX, "i2c4_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x42a0, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_I2C5_MUX, "i2c5_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x42a8, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_I2C6_MUX, "i2c6_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x42b0, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_I2C7_MUX, "i2c7_mux", -++ i2c_mux_p, ARRAY_SIZE(i2c_mux_p), -++ CLK_SET_RATE_PARENT, 0x42b8, 12, 1, 0, i2c_mux_table -++ }, -++ { -++ HI3519DV500_PWM0_MUX, "pwm0_mux", -++ pwm0_mux_p, ARRAY_SIZE(pwm0_mux_p), -++ CLK_SET_RATE_PARENT, 0x4588, 12, 2, 0, pwm0_mux_table -++ }, -++ { -++ HI3519DV500_PWM1_MUX, "pwm1_mux", -++ pwm1_mux_p, ARRAY_SIZE(pwm1_mux_p), -++ CLK_SET_RATE_PARENT, 0x4590, 12, 2, 0, pwm1_mux_table -++ }, -++ { -++ HI3519DV500_PWM2_MUX, "pwm2_mux", -++ pwm2_mux_p, ARRAY_SIZE(pwm2_mux_p), -++ CLK_SET_RATE_PARENT, 0x4598, 12, 2, 0, pwm2_mux_table -++ }, -++}; -++ -++static struct bsp_fixed_factor_clock -++ hi3519dv500_fixed_factor_clks[] __initdata = { -++}; -++ -++static struct bsp_gate_clock hi3519dv500_gate_clks[] __initdata = { -++ { -++ HI3519DV500_FMC_CLK, "clk_fmc", "fmc_mux", -++ CLK_SET_RATE_PARENT, 0x3f40, 4, 0, -++ }, -++ { -++ HI3519DV500_MMC0_CLK, "clk_mmc0", "mmc0_mux", -++ CLK_SET_RATE_PARENT, 0x34c0, 0, 0, -++ }, -++ { -++ HI3519DV500_MMC0_HCLK, "hclk_mmc0", NULL, -++ CLK_SET_RATE_PARENT, 0x34c0, 1, 0, -++ }, -++ { -++ HI3519DV500_MMC1_CLK, "clk_mmc1", "mmc1_mux", -++ CLK_SET_RATE_PARENT, 0x35c0, 0, 0, -++ }, -++ { -++ HI3519DV500_MMC1_HCLK, "hclk_mmc1", NULL, -++ CLK_SET_RATE_PARENT, 0x35c0, 1, 0, -++ }, -++ { -++ HI3519DV500_MMC2_CLK, "clk_mmc2", "mmc2_mux", -++ CLK_SET_RATE_PARENT, 0x36c0, 0, 0, -++ }, -++ { -++ HI3519DV500_MMC2_HCLK, "hclk_mmc2", NULL, -++ CLK_SET_RATE_PARENT, 0x36c0, 1, 0, -++ }, -++ { -++ HI3519DV500_UART0_CLK, "clk_uart0", "uart0_mux", -++ CLK_SET_RATE_PARENT, 0x4180, 4, 0, -++ }, -++ { -++ HI3519DV500_UART1_CLK, "clk_uart1", "uart1_mux", -++ CLK_SET_RATE_PARENT, 0x4188, 4, 0, -++ }, -++ { -++ HI3519DV500_UART2_CLK, "clk_uart2", "uart2_mux", -++ CLK_SET_RATE_PARENT, 0x4190, 4, 0, -++ }, -++ { -++ HI3519DV500_UART3_CLK, "clk_uart3", "uart3_mux", -++ CLK_SET_RATE_PARENT, 0x4198, 4, 0, -++ }, -++ { -++ HI3519DV500_UART4_CLK, "clk_uart4", "uart4_mux", -++ CLK_SET_RATE_PARENT, 0x41A0, 4, 0, -++ }, -++ { -++ HI3519DV500_UART5_CLK, "clk_uart5", "uart5_mux", -++ CLK_SET_RATE_PARENT, 0x41a8, 4, 0, -++ }, -++ /* ethernet mac */ -++ { -++ HI3519DV500_ETH_CLK, "clk_eth", NULL, -++ CLK_SET_RATE_PARENT, 0x37c4, 4, 0, -++ }, -++ { -++ HI3519DV500_ETH_MACIF_CLK, "clk_eth_macif", NULL, -++ CLK_SET_RATE_PARENT, 0x37c0, 4, 0, -++ }, -++ { -++ HI3519DV500_ETH1_CLK, "clk_eth1", NULL, -++ CLK_SET_RATE_PARENT, 0x3804, 4, 0, -++ }, -++ { -++ HI3519DV500_ETH1_MACIF_CLK, "clk_eth1_macif", NULL, -++ CLK_SET_RATE_PARENT, 0x3800, 4, 0, -++ }, -++ { -++ HI3519DV500_I2C0_CLK, "clk_i2c0", "i2c0_mux", -++ CLK_SET_RATE_PARENT, 0x4280, 4, 0, -++ }, -++ { -++ HI3519DV500_I2C1_CLK, "clk_i2c1", "i2c1_mux", -++ CLK_SET_RATE_PARENT, 0x4288, 4, 0, -++ }, -++ { -++ HI3519DV500_I2C2_CLK, "clk_i2c2", "i2c2_mux", -++ CLK_SET_RATE_PARENT, 0x4290, 4, 0, -++ }, -++ { -++ HI3519DV500_I2C3_CLK, "clk_i2c3", "i2c3_mux", -++ CLK_SET_RATE_PARENT, 0x4298, 4, 0, -++ }, -++ { -++ HI3519DV500_I2C4_CLK, "clk_i2c4", "i2c4_mux", -++ CLK_SET_RATE_PARENT, 0x42a0, 4, 0, -++ }, -++ { HI3519DV500_I2C5_CLK, "clk_i2c5", "i2c5_mux", -++ CLK_SET_RATE_PARENT, 0x42a8, 4, 0, -++ }, -++ { HI3519DV500_I2C6_CLK, "clk_i2c6", "i2c6_mux", -++ CLK_SET_RATE_PARENT, 0x42b0, 4, 0, -++ }, -++ { HI3519DV500_I2C7_CLK, "clk_i2c7", "i2c7_mux", -++ CLK_SET_RATE_PARENT, 0x42b8, 4, 0, -++ }, -++ /* spi */ -++ { -++ HI3519DV500_SPI0_CLK, "clk_spi0", "100m", -++ CLK_SET_RATE_PARENT, 0x4480, 4, 0, -++ }, -++ { -++ HI3519DV500_SPI1_CLK, "clk_spi1", "100m", -++ CLK_SET_RATE_PARENT, 0x4488, 4, 0, -++ }, -++ { -++ HI3519DV500_SPI2_CLK, "clk_spi2", "100m", -++ CLK_SET_RATE_PARENT, 0x4490, 4, 0, -++ }, -++ { -++ HI3519DV500_SPI3_CLK, "clk_spi3", "100m", -++ CLK_SET_RATE_PARENT, 0x4498, 4, 0, -++ }, -++ { -++ HI3519DV500_EDMAC_AXICLK, "axi_clk_edmac", NULL, -++ CLK_SET_RATE_PARENT, 0x2a80, 5, 0, -++ }, -++ { -++ HI3519DV500_EDMAC_CLK, "clk_edmac", NULL, -++ CLK_SET_RATE_PARENT, 0x2a80, 4, 0, -++ }, -++ /* lsadc */ -++ { -++ HI3519DV500_LSADC_CLK, "clk_lsadc", NULL, -++ CLK_SET_RATE_PARENT, 0x46c0, 4, 0, -++ }, -++ /* pwm0 */ -++ { -++ HI3519DV500_PWM0_CLK, "clk_pwm0", "pwm0_mux", -++ CLK_SET_RATE_PARENT, 0x4588, 4, 0, -++ }, -++ /* pwm1 */ -++ { -++ HI3519DV500_PWM1_CLK, "clk_pwm1", "pwm1_mux", -++ CLK_SET_RATE_PARENT, 0x4590, 4, 0, -++ }, -++ /* pwm2 */ -++ { -++ HI3519DV500_PWM2_CLK, "clk_pwm2", "pwm2_mux", -++ CLK_SET_RATE_PARENT, 0x4598, 4, 0, -++ }, -++}; -++ -++static __init struct bsp_clock_data *hi3519dv500_clk_register( -++ struct platform_device *pdev) -++{ -++ struct bsp_clock_data *clk_data = NULL; -++ int ret; -++ -++ clk_data = bsp_clk_alloc(pdev, HI3519DV500_CRG_NR_CLKS); -++ if (clk_data == NULL) -++ return ERR_PTR(-ENOMEM); -++ -++ ret = bsp_clk_register_fixed_rate(hi3519dv500_fixed_rate_clks_crg, -++ ARRAY_SIZE(hi3519dv500_fixed_rate_clks_crg), clk_data); -++ if (ret) -++ return ERR_PTR(ret); -++ -++ ret = bsp_clk_register_mux(hi3519dv500_mux_clks_crg, -++ ARRAY_SIZE(hi3519dv500_mux_clks_crg), -++ clk_data); -++ if (ret) -++ goto unregister_fixed_rate; -++ -++ ret = bsp_clk_register_fixed_factor(hi3519dv500_fixed_factor_clks, -++ ARRAY_SIZE(hi3519dv500_fixed_factor_clks), clk_data); -++ if (ret) -++ goto unregister_mux; -++ -++ ret = bsp_clk_register_gate(hi3519dv500_gate_clks, -++ ARRAY_SIZE(hi3519dv500_gate_clks), -++ clk_data); -++ if (ret) -++ goto unregister_factor; -++ -++ ret = of_clk_add_provider(pdev->dev.of_node, -++ of_clk_src_onecell_get, &clk_data->clk_data); -++ if (ret) -++ goto unregister_gate; -++ -++ return clk_data; -++ -++unregister_gate: -++ bsp_clk_unregister_gate(hi3519dv500_gate_clks, -++ ARRAY_SIZE(hi3519dv500_gate_clks), clk_data); -++unregister_factor: -++ bsp_clk_unregister_fixed_factor(hi3519dv500_fixed_factor_clks, -++ ARRAY_SIZE(hi3519dv500_fixed_factor_clks), clk_data); -++unregister_mux: -++ bsp_clk_unregister_mux(hi3519dv500_mux_clks_crg, -++ ARRAY_SIZE(hi3519dv500_mux_clks_crg), -++ clk_data); -++unregister_fixed_rate: -++ bsp_clk_unregister_fixed_rate(hi3519dv500_fixed_rate_clks_crg, -++ ARRAY_SIZE(hi3519dv500_fixed_rate_clks_crg), clk_data); -++ return ERR_PTR(ret); -++} -++ -++static __init void hi3519dv500_clk_unregister(const struct platform_device *pdev) -++{ -++ struct bsp_crg_dev *crg = platform_get_drvdata(pdev); -++ -++ of_clk_del_provider(pdev->dev.of_node); -++ -++ bsp_clk_unregister_gate(hi3519dv500_gate_clks, -++ ARRAY_SIZE(hi3519dv500_gate_clks), crg->clk_data); -++ bsp_clk_unregister_mux(hi3519dv500_mux_clks_crg, -++ ARRAY_SIZE(hi3519dv500_mux_clks_crg), crg->clk_data); -++ bsp_clk_unregister_fixed_factor(hi3519dv500_fixed_factor_clks, -++ ARRAY_SIZE(hi3519dv500_fixed_factor_clks), crg->clk_data); -++ bsp_clk_unregister_fixed_rate(hi3519dv500_fixed_rate_clks_crg, -++ ARRAY_SIZE(hi3519dv500_fixed_rate_clks_crg), crg->clk_data); -++} -++ -++static const struct bsp_crg_funcs hi3519dv500_crg_funcs = { -++ .register_clks = hi3519dv500_clk_register, -++ .unregister_clks = hi3519dv500_clk_unregister, -++}; -++ -++ -++static const struct of_device_id hi3519dv500_crg_match_table[] = { -++ { -++ .compatible = "vendor,hi3519dv500_clock", -++ .data = &hi3519dv500_crg_funcs -++ }, -++ { } -++}; -++MODULE_DEVICE_TABLE(of, hi3519dv500_crg_match_table); -++ -++static int hi3519dv500_crg_probe(struct platform_device *pdev) -++{ -++ struct bsp_crg_dev *crg = NULL; -++ int ret = -1; -++ -++ crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL); -++ if (crg == NULL) -++ return -ENOMEM; -++ -++ crg->funcs = of_device_get_match_data(&pdev->dev); -++ if (crg->funcs == NULL) { -++ ret = -ENOENT; -++ goto crg_free; -++ } -++ -++ crg->rstc = vendor_reset_init(pdev); -++ if (crg->rstc == NULL) { -++ ret = -ENOENT; -++ goto crg_free; -++ } -++ -++ crg->clk_data = crg->funcs->register_clks(pdev); -++ if (IS_ERR(crg->clk_data)) { -++ bsp_reset_exit(crg->rstc); -++ ret = PTR_ERR(crg->clk_data); -++ goto crg_free; -++ } -++ -++ platform_set_drvdata(pdev, crg); -++ return 0; -++ -++crg_free: -++ if (crg != NULL) { -++ devm_kfree(&pdev->dev, crg); -++ crg = NULL; -++ } -++ return ret; -++} -++ -++static int hi3519dv500_crg_remove(struct platform_device *pdev) -++{ -++ struct bsp_crg_dev *crg = platform_get_drvdata(pdev); -++ -++ bsp_reset_exit(crg->rstc); -++ crg->funcs->unregister_clks(pdev); -++ return 0; -++} -++ -++static struct platform_driver hi3519dv500_crg_driver = { -++ .probe = hi3519dv500_crg_probe, -++ .remove = hi3519dv500_crg_remove, -++ .driver = { -++ .name = "hi3519dv500_clock", -++ .of_match_table = hi3519dv500_crg_match_table, -++ }, -++}; -++ -++static int __init hi3519dv500_crg_init(void) -++{ -++ return platform_driver_register(&hi3519dv500_crg_driver); -++} -++core_initcall(hi3519dv500_crg_init); -++ -++static void __exit hi3519dv500_crg_exit(void) -++{ -++ platform_driver_unregister(&hi3519dv500_crg_driver); -++} -++module_exit(hi3519dv500_crg_exit); -++ -++MODULE_LICENSE("GPL v2"); -++MODULE_DESCRIPTION("HiSilicon HI3519DV500 CRG Driver"); -+diff --git a/drivers/clk/vendor/clkgate_separated.c b/drivers/clk/vendor/clkgate_separated.c -+new file mode 100644 -+index 000000000..d53783fb3 -+--- /dev/null -++++ b/drivers/clk/vendor/clkgate_separated.c -+@@ -0,0 +1,108 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++ -++#include "clk.h" -++ -++/* clock separated gate register offset */ -++#define CLKGATE_SEPERATED_ENABLE 0x0 -++#define CLKGATE_SEPERATED_DISABLE 0x4 -++#define CLKGATE_SEPERATED_STATUS 0x8 -++ -++struct clkgate_separated { -++ struct clk_hw hw; -++ void __iomem *enable; /* enable register */ -++ u8 bit_idx; /* bits in enable/disable register */ -++ u8 flags; -++ spinlock_t *lock; -++}; -++ -++static int clkgate_separated_enable(struct clk_hw *hw) -++{ -++ struct clkgate_separated *sclk; -++ unsigned long flags = 0; -++ u32 reg; -++ -++ sclk = container_of(hw, struct clkgate_separated, hw); -++ if (sclk->lock) -++ spin_lock_irqsave(sclk->lock, flags); -++ reg = BIT(sclk->bit_idx); -++ writel_relaxed(reg, sclk->enable); -++ readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS); -++ if (sclk->lock) -++ spin_unlock_irqrestore(sclk->lock, flags); -++ return 0; -++} -++ -++static void clkgate_separated_disable(struct clk_hw *hw) -++{ -++ struct clkgate_separated *sclk; -++ unsigned long flags = 0; -++ u32 reg; -++ -++ sclk = container_of(hw, struct clkgate_separated, hw); -++ if (sclk->lock) -++ spin_lock_irqsave(sclk->lock, flags); -++ reg = BIT(sclk->bit_idx); -++ writel_relaxed(reg, sclk->enable + CLKGATE_SEPERATED_DISABLE); -++ readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS); -++ if (sclk->lock) -++ spin_unlock_irqrestore(sclk->lock, flags); -++} -++ -++static int clkgate_separated_is_enabled(struct clk_hw *hw) -++{ -++ struct clkgate_separated *sclk; -++ u32 reg; -++ -++ sclk = container_of(hw, struct clkgate_separated, hw); -++ reg = readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS); -++ reg &= BIT(sclk->bit_idx); -++ if (reg) -++ return 1; -++ else -++ return 0; -++} -++ -++static const struct clk_ops clkgate_separated_ops = { -++ .enable = clkgate_separated_enable, -++ .disable = clkgate_separated_disable, -++ .is_enabled = clkgate_separated_is_enabled, -++}; -++ -++struct clk *bsp_register_clkgate_sep(struct device *dev, const char *name, -++ const char *parent_name, -++ unsigned long flags, -++ void __iomem *reg, u8 bit_idx, -++ u8 clk_gate_flags, spinlock_t *lock) -++{ -++ struct clkgate_separated *sclk; -++ struct clk *clk; -++ struct clk_init_data init; -++ -++ sclk = kzalloc(sizeof(*sclk), GFP_KERNEL); -++ if (!sclk) -++ return ERR_PTR(-ENOMEM); -++ -++ init.name = name; -++ init.ops = &clkgate_separated_ops; -++ init.flags = flags; -++ init.parent_names = (parent_name ? &parent_name : NULL); -++ init.num_parents = (parent_name ? 1 : 0); -++ -++ sclk->enable = reg + CLKGATE_SEPERATED_ENABLE; -++ sclk->bit_idx = bit_idx; -++ sclk->flags = clk_gate_flags; -++ sclk->hw.init = &init; -++ sclk->lock = lock; -++ -++ clk = clk_register(dev, &sclk->hw); -++ if (IS_ERR(clk)) -++ kfree(sclk); -++ return clk; -++} -+diff --git a/drivers/clk/vendor/crg.h b/drivers/clk/vendor/crg.h -+new file mode 100644 -+index 000000000..de73c36ad -+--- /dev/null -++++ b/drivers/clk/vendor/crg.h -+@@ -0,0 +1,24 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __BSP_CRG_H -++#define __BSP_CRG_H -++ -++#include -++ -++struct bsp_clock_data; -++struct bsp_reset_controller; -++ -++struct bsp_crg_funcs { -++ struct bsp_clock_data* (*register_clks)(struct platform_device *pdev); -++ void (*unregister_clks)(const struct platform_device *pdev); -++}; -++ -++struct bsp_crg_dev { -++ struct bsp_clock_data *clk_data; -++ struct bsp_reset_controller *rstc; -++ const struct bsp_crg_funcs *funcs; -++}; -++ -++#endif /* __BSP_CRG_H */ -+diff --git a/drivers/clk/vendor/reset.c b/drivers/clk/vendor/reset.c -+new file mode 100644 -+index 000000000..6eed628d5 -+--- /dev/null -++++ b/drivers/clk/vendor/reset.c -+@@ -0,0 +1,118 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include "reset.h" -++ -++#define BSP_RESET_BIT_MASK 0x1f -++#define BSP_RESET_OFFSET_SHIFT 8 -++#define BSP_RESET_OFFSET_MASK 0xffff00 -++ -++struct bsp_reset_controller { -++ spinlock_t lock; -++ void __iomem *membase; -++ struct reset_controller_dev rcdev; -++}; -++ -++static int bsp_reset_of_xlate(struct reset_controller_dev *rcdev, -++ const struct of_phandle_args *reset_spec) -++{ -++ u32 offset; -++ u8 bit; -++ -++ offset = (reset_spec->args[0] << BSP_RESET_OFFSET_SHIFT) -++ & BSP_RESET_OFFSET_MASK; -++ bit = reset_spec->args[1] & BSP_RESET_BIT_MASK; -++ -++ return (offset | bit); -++} -++ -++static int bsp_reset_assert(struct reset_controller_dev *rcdev, -++ unsigned long id) -++{ -++ struct bsp_reset_controller *rstc = container_of(rcdev, -++ struct bsp_reset_controller, rcdev); -++ unsigned long flags; -++ u32 offset, reg; -++ u8 bit; -++ -++ offset = (id & BSP_RESET_OFFSET_MASK) >> BSP_RESET_OFFSET_SHIFT; -++ bit = id & BSP_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 bsp_reset_deassert(struct reset_controller_dev *rcdev, -++ unsigned long id) -++{ -++ struct bsp_reset_controller *rstc = container_of(rcdev, -++ struct bsp_reset_controller, rcdev); -++ unsigned long flags; -++ u32 offset, reg; -++ u8 bit; -++ -++ offset = (id & BSP_RESET_OFFSET_MASK) >> BSP_RESET_OFFSET_SHIFT; -++ bit = id & BSP_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 bsp_reset_ops = { -++ .assert = bsp_reset_assert, -++ .deassert = bsp_reset_deassert, -++}; -++ -++struct bsp_reset_controller *vendor_reset_init(struct platform_device *pdev) -++{ -++ struct bsp_reset_controller *rstc; -++ struct resource *res; -++ -++ rstc = devm_kmalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL); -++ if (!rstc) -++ return NULL; -++ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -++ rstc->membase = devm_ioremap_resource(&pdev->dev, res); -++ if (IS_ERR(rstc->membase)) { -++ devm_kfree(&pdev->dev, rstc); -++ rstc = NULL; -++ return NULL; -++ } -++ -++ spin_lock_init(&rstc->lock); -++ rstc->rcdev.owner = THIS_MODULE; -++ rstc->rcdev.ops = &bsp_reset_ops; -++ rstc->rcdev.of_node = pdev->dev.of_node; -++ rstc->rcdev.of_reset_n_cells = 2; /* 2:used to parse the resets node. */ -++ rstc->rcdev.of_xlate = bsp_reset_of_xlate; -++ reset_controller_register(&rstc->rcdev); -++ -++ return rstc; -++} -++EXPORT_SYMBOL_GPL(vendor_reset_init); -++ -++void bsp_reset_exit(struct bsp_reset_controller *rstc) -++{ -++ reset_controller_unregister(&rstc->rcdev); -++} -++EXPORT_SYMBOL_GPL(bsp_reset_exit); -+diff --git a/drivers/clk/vendor/reset.h b/drivers/clk/vendor/reset.h -+new file mode 100644 -+index 000000000..a9535170c -+--- /dev/null -++++ b/drivers/clk/vendor/reset.h -+@@ -0,0 +1,29 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __BSP_RESET_H -++#define __BSP_RESET_H -++ -++#include -++ -++struct device_node; -++struct bsp_reset_controller; -++ -++#ifdef CONFIG_RESET_CONTROLLER -++struct bsp_reset_controller *vendor_reset_init(struct platform_device *pdev); -++#ifdef CONFIG_ARCH_BSP -++int __init bsp_reset_init(struct device_node *np, int nr_rsts); -++#endif -++void bsp_reset_exit(struct bsp_reset_controller *rstc); -++#else -++static inline -++struct bsp_reset_controller *vendor_reset_init(struct platform_device *pdev) -++{ -++ return 0; -++} -++static inline void bsp_reset_exit(struct bsp_reset_controller *rstc) -++{} -++#endif -++ -++#endif /* __BSP_RESET_H */ -+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -+index 3cc8c7d4c..21fd715a7 100644 -+--- a/drivers/clocksource/arm_arch_timer.c -++++ b/drivers/clocksource/arm_arch_timer.c -+@@ -1055,6 +1055,20 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) -+ return &arch_timer_kvm_info; -+ } -+ -++#if (defined CONFIG_ARCH_BSP) && (defined CONFIG_CMD_TIMESTAMP) -++static u64 arch_timer_read(void) -++{ -++ static u64 epoch = 0; -++ if (epoch == 0) { -++ epoch = arch_timer_read_counter(); -++ pr_debug("arch_timer_read timestamp add an offset: %lld here!\n", epoch); -++ return epoch; -++ } else { -++ return arch_timer_read_counter() + epoch; -++ } -++} -++#endif -++ -+ static void __init arch_counter_register(unsigned type) -+ { -+ u64 start_count; -+@@ -1097,8 +1111,12 @@ static void __init arch_counter_register(unsigned type) -+ cyclecounter.shift = clocksource_counter.shift; -+ timecounter_init(&arch_timer_kvm_info.timecounter, -+ &cyclecounter, start_count); -+- -++ /* 56 bits minimum, so we assume worst case rollover */ -++#if (defined CONFIG_ARCH_BSP) && (defined CONFIG_CMD_TIMESTAMP) -++ sched_clock_register(arch_timer_read, 56, arch_timer_rate); -++#else -+ sched_clock_register(arch_timer_read_counter, width, arch_timer_rate); -++#endif -+ } -+ -+ static void arch_timer_stop(struct clock_event_device *clk) -+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -+index 3361e2de1..5688e181e 100644 -+--- a/drivers/dma/Kconfig -++++ b/drivers/dma/Kconfig -+@@ -374,6 +374,21 @@ config K3_DMA -+ Support the DMA engine for Hisilicon K3 platform -+ devices. -+ -++if ARCH_BSP -++config EDMACV310 -++ tristate "Vendor EDMAC Controller support" -++ 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. -++ Vendor 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. -++endif -++ -+ config LPC18XX_DMAMUX -+ bool "NXP LPC18xx/43xx DMA MUX for PL080" -+ depends on ARCH_LPC18XX || COMPILE_TEST -+diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile -+index 8928816a4..262a58747 100644 -+--- a/drivers/dma/Makefile -++++ b/drivers/dma/Makefile -+@@ -82,7 +82,9 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o -+ obj-$(CONFIG_ZX_DMA) += zx_dma.o -+ obj-$(CONFIG_ST_FDMA) += st_fdma.o -+ obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/ -+- -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_EDMACV310) += edmacv310.o -++endif -+ obj-y += mediatek/ -+ obj-y += qcom/ -+ obj-y += ti/ -+diff --git a/drivers/dma/edmacv310.c b/drivers/dma/edmacv310.c -+new file mode 100644 -+index 000000000..69da3e4df -+--- /dev/null -++++ b/drivers/dma/edmacv310.c -+@@ -0,0 +1,1445 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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 "edmacv310.h" -++#include "dmaengine.h" -++#include "virt-dma.h" -++#include -++ -++#define DRIVER_NAME "edmacv310" -++ -++#define MAX_TSFR_LLIS 512 -++#define EDMACV300_LLI_WORDS 64 -++#define EDMACV300_POOL_ALIGN 64 -++#define BITS_PER_HALF_WORD 32 -++#define ERR_STATUS_REG_NUM 3 -++ -++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 edmacv310_dma_chan { -++ bool slave; -++ int signal; -++ int id; -++ struct virt_dma_chan virt_chan; -++ struct edmacv310_phy_chan *phychan; -++ struct dma_slave_config cfg; -++ struct transfer_desc *at; -++ struct edmacv310_driver_data *host; -++ enum edmac_dma_chan_state state; -++}; -++ -++struct edmacv310_phy_chan { -++ unsigned int id; -++ void __iomem *base; -++ spinlock_t lock; -++ struct edmacv310_dma_chan *serving; -++}; -++ -++struct edmacv310_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 edmacv310_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(const u64 *llis_vaddr, unsigned int num) -++{ -++ edmac_lli *plli = (edmac_lli *)llis_vaddr; -++ unsigned int i; -++ -++ edmacv310_trace(EDMACV310_CONFIG_TRACE_LEVEL, "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 >> BITS_PER_HALF_WORD) & 0xffffffff); -++ printk("lli%d:count: 0x%x\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 >> BITS_PER_HALF_WORD) & 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 >> BITS_PER_HALF_WORD) & 0xffffffff); -++ printk("lli%d:CONFIG: 0x%x\n", i, plli[i].config); -++ } -++} -++ -++#else -++void dump_lli(const u64 *llis_vaddr, unsigned int num) -++{ -++} -++#endif -++ -++static inline struct edmacv310_dma_chan *to_edamc_chan(const struct dma_chan *chan) -++{ -++ return container_of(chan, struct edmacv310_dma_chan, virt_chan.chan); -++} -++ -++static inline struct transfer_desc *to_edmac_transfer_desc( -++ const struct dma_async_tx_descriptor *tx) -++{ -++ return container_of(tx, struct transfer_desc, virt_desc.tx); -++} -++ -++static struct dma_chan *edmac_find_chan_id( -++ const struct edmacv310_driver_data *edmac, -++ int request_num) -++{ -++ struct edmacv310_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 edmacv310_driver_data *edmac = ofdma->of_dma_data; -++ struct edmacv310_dma_chan *edmac_dma_chan = NULL; -++ struct dma_chan *dma_chan = NULL; -++ struct regmap *misc = NULL; -++ unsigned int signal, request_num; -++ unsigned int reg = 0; -++ unsigned int offset = 0; -++ -++ if (!edmac) -++ return NULL; -++ -++ misc = edmac->misc_regmap; -++ -++ if (dma_spec->args_count != 2) { /* 2:check num of dts node args */ -++ edmacv310_error("args count not true!\n"); -++ return NULL; -++ } -++ -++ request_num = dma_spec->args[0]; -++ signal = dma_spec->args[1]; -++ -++ edmacv310_trace(EDMACV310_CONFIG_TRACE_LEVEL, "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, ®); -++ /* set misc for signal line */ -++ reg &= ~(0x3f << ((request_num & 0x3) << 3)); -++ reg |= signal << ((request_num & 0x3) << 3); -++ regmap_write(misc, offset, reg); -++#endif -++ } -++ -++ edmacv310_trace(EDMACV310_CONFIG_TRACE_LEVEL, "offset = 0x%x, reg = 0x%x\n", offset, reg); -++ -++ dma_chan = edmac_find_chan_id(edmac, request_num); -++ if (!dma_chan) { -++ edmacv310_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 edmacv310_devm_get(struct edmacv310_driver_data *edmac) -++{ -++ struct platform_device *platdev = edmac->dev; -++ struct resource *res = NULL; -++ -++ 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->irq = platform_get_irq(platdev, 0); -++ if (unlikely(edmac->irq < 0)) -++ return -ENODEV; -++ -++ 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) { -++ edmacv310_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); -++ -++ res = platform_get_resource_byname(platdev, IORESOURCE_MEM, "dma_peri_channel_req_sel"); -++ if (res) { -++ void *dma_peri_channel_req_sel = ioremap(res->start, res->end - res->start); -++ if (IS_ERR(dma_peri_channel_req_sel)) -++ return PTR_ERR(dma_peri_channel_req_sel); -++ writel(0xffffffff, dma_peri_channel_req_sel); -++ iounmap(dma_peri_channel_req_sel); -++ } -++ return 0; -++} -++ -++static int edmacv310_of_property_read(struct edmacv310_driver_data *edmac) -++{ -++ struct platform_device *platdev = edmac->dev; -++ struct device_node *np = platdev->dev.of_node; -++ int ret; -++ -++ if (!of_find_property(np, "misc_regmap", NULL) || -++ !of_find_property(np, "misc_ctrl_base", NULL)) { -++ edmac->misc_regmap = 0; -++ } 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(np, "misc_ctrl_base", &(edmac->misc_ctrl_base)); -++ if (ret) { -++ edmacv310_error("get dma-misc_ctrl_base fail\n"); -++ return -ENODEV; -++ } -++ } -++ ret = of_property_read_u32(np, "devid", &(edmac->id)); -++ if (ret) { -++ edmacv310_error("get edmac id fail\n"); -++ return -ENODEV; -++ } -++ ret = of_property_read_u32(np, "dma-channels", &(edmac->channels)); -++ if (ret) { -++ edmacv310_error("get dma-channels fail\n"); -++ return -ENODEV; -++ } -++ ret = of_property_read_u32(np, "dma-requests", &(edmac->slave_requests)); -++ if (ret) { -++ edmacv310_error("get dma-requests fail\n"); -++ return -ENODEV; -++ } -++ edmacv310_trace(EDMACV310_REG_TRACE_LEVEL, "dma-channels = %d, dma-requests = %d\n", -++ edmac->channels, edmac->slave_requests); -++ return 0; -++} -++ -++static int get_of_probe(struct edmacv310_driver_data *edmac) -++{ -++ struct platform_device *platdev = edmac->dev; -++ int ret; -++ -++ ret = edmacv310_devm_get(edmac); -++ if (ret) -++ return ret; -++ -++ ret = edmacv310_of_property_read(edmac); -++ if (ret) -++ return ret; -++ -++ 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 size_t read_residue_from_phychan( -++ const struct edmacv310_dma_chan *edmac_dma_chan, -++ const struct transfer_desc *tsf_desc) -++{ -++ size_t bytes; -++ u64 next_lli; -++ struct edmacv310_phy_chan *phychan = edmac_dma_chan->phychan; -++ unsigned int i, index; -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ edmac_lli *plli = NULL; -++ -++ next_lli = (edmacv310_readl(edmac->base + edmac_cx_lli_l(phychan->id)) & -++ (~(EDMAC_LLI_ALIGN - 1))); -++ next_lli |= ((u64)(edmacv310_readl(edmac->base + edmac_cx_lli_h( -++ phychan->id)) & 0xffffffff) << BITS_PER_HALF_WORD); -++ bytes = edmacv310_readl(edmac->base + edmac_cx_curr_cnt0( -++ phychan->id)); -++ if (next_lli != 0) { -++ /* It means lli mode */ -++ bytes += tsf_desc->size; -++ index = (next_lli - tsf_desc->llis_busaddr) / sizeof(*plli); -++ plli = (edmac_lli *)(tsf_desc->llis_vaddr); -++ -++ if (index > MAX_TSFR_LLIS) -++ return 0; -++ -++ for (i = 0; i < index; i++) -++ bytes -= plli[i].count; -++ } -++ return bytes; -++} -++ -++static enum dma_status edmac_tx_status(struct dma_chan *chan, -++ dma_cookie_t cookie, -++ struct dma_tx_state *txstate) -++{ -++ enum dma_status ret; -++ struct edmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -++ struct virt_dma_desc *vd = NULL; -++ struct transfer_desc *tsf_desc = NULL; -++ unsigned long flags; -++ size_t bytes; -++ -++ 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 (!(edmac_dma_chan->phychan) || !tsf_desc) { -++ spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags); -++ return ret; -++ } -++ bytes = read_residue_from_phychan(edmac_dma_chan, tsf_desc); -++ } -++ 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; -++} -++ -++static struct edmacv310_phy_chan *edmac_get_phy_channel( -++ const struct edmacv310_driver_data *edmac, -++ struct edmacv310_dma_chan *edmac_dma_chan) -++{ -++ struct edmacv310_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(const struct edmacv310_driver_data *edmac, -++ const struct edmacv310_phy_chan *phychan, -++ const struct transfer_desc *tsf_desc) -++{ -++ edmac_lli *plli = (edmac_lli *)tsf_desc->llis_vaddr; -++ -++ if (plli->next_lli != 0x0) -++ edmacv310_writel((plli->next_lli & 0xffffffff) | EDMAC_LLI_ENABLE, -++ edmac->base + edmac_cx_lli_l(phychan->id)); -++ else -++ edmacv310_writel((plli->next_lli & 0xffffffff), -++ edmac->base + edmac_cx_lli_l(phychan->id)); -++ -++ edmacv310_writel(((plli->next_lli >> 32) & 0xffffffff), -++ edmac->base + edmac_cx_lli_h(phychan->id)); -++ edmacv310_writel(plli->count, edmac->base + edmac_cx_cnt0(phychan->id)); -++ edmacv310_writel(plli->src_addr & 0xffffffff, -++ edmac->base + edmac_cx_src_addr_l(phychan->id)); -++ edmacv310_writel((plli->src_addr >> 32) & 0xffffffff, -++ edmac->base + edmac_cx_src_addr_h(phychan->id)); -++ edmacv310_writel(plli->dest_addr & 0xffffffff, -++ edmac->base + edmac_cx_dest_addr_l(phychan->id)); -++ edmacv310_writel((plli->dest_addr >> 32) & 0xffffffff, -++ edmac->base + edmac_cx_dest_addr_h(phychan->id)); -++ edmacv310_writel(plli->config, -++ edmac->base + edmac_cx_config(phychan->id)); -++} -++ -++static void edmac_start_next_txd(struct edmacv310_dma_chan *edmac_dma_chan) -++{ -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ struct edmacv310_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; -++ list_del(&tsf_desc->virt_desc.node); -++ edmac_dma_chan->at = tsf_desc; -++ edmac_write_lli(edmac, phychan, tsf_desc); -++ val = edmacv310_readl(edmac->base + edmac_cx_config(phychan->id)); -++ edmacv310_trace(EDMACV310_REG_TRACE_LEVEL, " EDMAC_Cx_CONFIG = 0x%x\n", val); -++ edmacv310_writel(val | EDMAC_CXCONFIG_LLI_START, -++ edmac->base + edmac_cx_config(phychan->id)); -++} -++ -++static void edmac_start(struct edmacv310_dma_chan *edmac_dma_chan) -++{ -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ struct edmacv310_phy_chan *ch; -++ ch = edmac_get_phy_channel(edmac, edmac_dma_chan); -++ if (!ch) { -++ edmacv310_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 edmacv310_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 edmacv310_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 edmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -++ if (!edmac_dma_chan->slave) { -++ edmacv310_error("slave is null!"); -++ return -EINVAL; -++ } -++ edmac_dma_chan->cfg = *config; -++ return 0; -++} -++ -++static void edmac_pause_phy_chan(const struct edmacv310_dma_chan *edmac_dma_chan) -++{ -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ struct edmacv310_phy_chan *phychan = edmac_dma_chan->phychan; -++ unsigned int val; -++ int timeout; -++ -++ val = edmacv310_readl(edmac->base + edmac_cx_config(phychan->id)); -++ val &= ~CCFG_EN; -++ edmacv310_writel(val, edmac->base + edmac_cx_config(phychan->id)); -++ /* 2000:Wait for channel inactive */ -++ for (timeout = 2000; timeout > 0; timeout--) { -++ if (!((0x1 << phychan->id) & edmacv310_readl(edmac->base + EDMAC_CH_STAT))) -++ break; -++ edmacv310_writel(val, edmac->base + edmac_cx_config(phychan->id)); -++ udelay(1); -++ } -++ if (timeout == 0) -++ edmacv310_error(":channel%u timeout waiting for pause, timeout:%d\n", -++ phychan->id, timeout); -++} -++ -++static int edmac_pause(struct dma_chan *chan) -++{ -++ struct edmacv310_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(const struct edmacv310_dma_chan *edmac_dma_chan) -++{ -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ struct edmacv310_phy_chan *phychan = edmac_dma_chan->phychan; -++ unsigned int val; -++ val = edmacv310_readl(edmac->base + edmac_cx_config(phychan->id)); -++ val |= CCFG_EN; -++ edmacv310_writel(val, edmac->base + edmac_cx_config(phychan->id)); -++} -++ -++static int edmac_resume(struct dma_chan *chan) -++{ -++ struct edmacv310_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 edmacv310_dma_chan *chan); -++static void edmac_desc_free(struct virt_dma_desc *vd); -++static int edmac_terminate_all(struct dma_chan *chan) -++{ -++ struct edmacv310_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 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: -++ edmacv310_error("check here, width warning!\n"); -++ return ~0; -++ } -++} -++ -++static unsigned int edmac_set_config_value(enum dma_transfer_direction direction, -++ unsigned int addr_width, -++ unsigned int burst, -++ unsigned int signal) -++{ -++ unsigned int config, width; -++ -++ if (direction == DMA_MEM_TO_DEV) -++ config = EDMAC_CONFIG_SRC_INC; -++ else -++ config = EDMAC_CONFIG_DST_INC; -++ -++ edmacv310_trace(EDMACV310_CONFIG_TRACE_LEVEL, "addr_width = 0x%x\n", addr_width); -++ width = get_width(addr_width); -++ edmacv310_trace(EDMACV310_CONFIG_TRACE_LEVEL, "width = 0x%x\n", width); -++ config |= width << EDMAC_CONFIG_SRC_WIDTH_SHIFT; -++ config |= width << EDMAC_CONFIG_DST_WIDTH_SHIFT; -++ edmacv310_trace(EDMACV310_REG_TRACE_LEVEL, "tsf_desc->ccfg = 0x%x\n", config); -++ edmacv310_trace(EDMACV310_CONFIG_TRACE_LEVEL, "burst = 0x%x\n", burst); -++ config |= burst << EDMAC_CONFIG_SRC_BURST_SHIFT; -++ config |= burst << EDMAC_CONFIG_DST_BURST_SHIFT; -++ if (signal >= 0) { -++ edmacv310_trace(EDMACV310_REG_TRACE_LEVEL, "edmac_dma_chan->signal = %d\n", signal); -++ config |= (unsigned int)signal << EDMAC_CXCONFIG_SIGNAL_SHIFT; -++ } -++ config |= EDMAC_CXCONFIG_DEV_MEM_TYPE << EDMAC_CXCONFIG_TSF_TYPE_SHIFT; -++ return config; -++} -++ -++struct transfer_desc *edmac_init_tsf_desc(const struct dma_chan *chan, -++ enum dma_transfer_direction direction, -++ dma_addr_t *slave_addr) -++{ -++ struct edmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -++ struct transfer_desc *tsf_desc; -++ unsigned int burst = 0; -++ unsigned int addr_width = 0; -++ unsigned int maxburst = 0; -++ tsf_desc = kzalloc(sizeof(*tsf_desc), GFP_NOWAIT); -++ if (!tsf_desc) -++ return NULL; -++ if (direction == DMA_MEM_TO_DEV) { -++ *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) { -++ *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 { -++ kfree(tsf_desc); -++ edmacv310_error("direction unsupported!\n"); -++ return NULL; -++ } -++ -++ 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); -++ -++ tsf_desc->ccfg = edmac_set_config_value(direction, addr_width, -++ burst, edmac_dma_chan->signal); -++ edmacv310_trace(EDMACV310_REG_TRACE_LEVEL, "tsf_desc->ccfg = 0x%x\n", tsf_desc->ccfg); -++ return tsf_desc; -++} -++ -++static int edmac_fill_desc(const struct edmac_sg *dsg, -++ struct transfer_desc *tsf_desc, -++ unsigned int length, unsigned int num) -++{ -++ edmac_lli *plli = NULL; -++ -++ if (num >= MAX_TSFR_LLIS) { -++ edmacv310_error("lli out of range. \n"); -++ return -ENOMEM; -++ } -++ -++ plli = (edmac_lli *)(tsf_desc->llis_vaddr); -++ (void)memset_s(&plli[num], sizeof(edmac_lli), 0x0, sizeof(*plli)); -++ -++ plli[num].src_addr = dsg->src_addr; -++ plli[num].dest_addr = dsg->dst_addr; -++ 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( -++ *plli)) & (~(EDMAC_LLI_ALIGN - 1)); -++ plli[num - 1].next_lli |= EDMAC_LLI_ENABLE; -++ } -++ return 0; -++} -++ -++static void free_dsg(struct list_head *dsg_head) -++{ -++ struct edmac_sg *dsg = NULL; -++ struct edmac_sg *_dsg = NULL; -++ -++ list_for_each_entry_safe(dsg, _dsg, dsg_head, node) { -++ list_del(&dsg->node); -++ kfree(dsg); -++ } -++} -++ -++static int edmac_add_sg(struct list_head *sg_head, -++ dma_addr_t dst, dma_addr_t src, -++ size_t len) -++{ -++ struct edmac_sg *dsg = NULL; -++ -++ if (len == 0) { -++ free_dsg(sg_head); -++ edmacv310_error("Transfer length is 0. \n"); -++ return -ENOMEM; -++ } -++ -++ dsg = (struct edmac_sg *)kzalloc(sizeof(*dsg), GFP_NOWAIT); -++ if (!dsg) { -++ free_dsg(sg_head); -++ edmacv310_error("alloc memory for dsg fail.\n"); -++ return -ENOMEM; -++ } -++ -++ list_add_tail(&dsg->node, sg_head); -++ dsg->src_addr = src; -++ dsg->dst_addr = dst; -++ dsg->len = len; -++ return 0; -++} -++ -++static int edmac_add_sg_slave(struct list_head *sg_head, -++ dma_addr_t slave_addr, dma_addr_t addr, -++ size_t length, -++ enum dma_transfer_direction direction) -++{ -++ dma_addr_t src = 0; -++ dma_addr_t dst = 0; -++ if (direction == DMA_MEM_TO_DEV) { -++ src = addr; -++ dst = slave_addr; -++ } else if (direction == DMA_DEV_TO_MEM) { -++ src = slave_addr; -++ dst = addr; -++ } else { -++ edmacv310_error("invali dma_transfer_direction.\n"); -++ return -ENOMEM; -++ } -++ return edmac_add_sg(sg_head, dst, src, length); -++} -++ -++static int edmac_fill_sg_for_slave(struct list_head *sg_head, -++ dma_addr_t slave_addr, -++ struct scatterlist *sgl, -++ unsigned int sg_len, -++ enum dma_transfer_direction direction) -++{ -++ struct scatterlist *sg = NULL; -++ int tmp, ret; -++ size_t length; -++ dma_addr_t addr; -++ if (sgl == NULL) { -++ edmacv310_error("sgl is null!\n"); -++ return -ENOMEM; -++ } -++ -++ for_each_sg(sgl, sg, sg_len, tmp) { -++ addr = sg_dma_address(sg); -++ length = sg_dma_len(sg); -++ ret = edmac_add_sg_slave(sg_head, slave_addr, addr, length, direction); -++ if (ret) -++ break; -++ } -++ return ret; -++} -++ -++static inline int edmac_fill_sg_for_m2m_copy(struct list_head *sg_head, -++ dma_addr_t dst, dma_addr_t src, -++ size_t len) -++{ -++ return edmac_add_sg(sg_head, dst, src, len); -++} -++ -++struct edmac_cyclic_args { -++ dma_addr_t slave_addr; -++ dma_addr_t buf_addr; -++ size_t buf_len; -++ size_t period_len; -++ enum dma_transfer_direction direction; -++}; -++ -++static int edmac_fill_sg_for_cyclic(struct list_head *sg_head, -++ struct edmac_cyclic_args args) -++{ -++ size_t count_in_sg = 0; -++ size_t trans_bytes; -++ int ret; -++ while (count_in_sg < args.buf_len) { -++ trans_bytes = min(args.period_len, args.buf_len - count_in_sg); -++ count_in_sg += trans_bytes; -++ ret = edmac_add_sg_slave(sg_head, args.slave_addr, args.buf_addr + count_in_sg, count_in_sg, args.direction); -++ if (ret) -++ return ret; -++ } -++ return 0; -++} -++ -++static unsigned short get_max_width(dma_addr_t ccfg) -++{ -++ unsigned short src_width = (ccfg & EDMAC_CONTROL_SRC_WIDTH_MASK) >> -++ EDMAC_CONFIG_SRC_WIDTH_SHIFT; -++ unsigned short dst_width = (ccfg & EDMAC_CONTROL_DST_WIDTH_MASK) >> -++ EDMAC_CONFIG_DST_WIDTH_SHIFT; -++ return 1 << max(src_width, dst_width); /* to byte */ -++} -++ -++static int edmac_fill_asg_lli_for_desc(struct edmac_sg *dsg, -++ struct transfer_desc *tsf_desc, -++ unsigned int *lli_count) -++{ -++ int ret; -++ unsigned short width = get_max_width(tsf_desc->ccfg); -++ -++ while (dsg->len != 0) { -++ size_t lli_len = MAX_TRANSFER_BYTES; -++ lli_len = (lli_len / width) * width; /* bus width align */ -++ lli_len = min(lli_len, dsg->len); -++ ret = edmac_fill_desc(dsg, tsf_desc, lli_len, *lli_count); -++ if (ret) -++ return ret; -++ -++ if (tsf_desc->ccfg & EDMAC_CONFIG_SRC_INC) -++ dsg->src_addr += lli_len; -++ if (tsf_desc->ccfg & EDMAC_CONFIG_DST_INC) -++ dsg->dst_addr += lli_len; -++ dsg->len -= lli_len; -++ (*lli_count)++; -++ } -++ return 0; -++} -++ -++static int edmac_fill_lli_for_desc(const struct list_head *sg_head, -++ struct transfer_desc *tsf_desc) -++{ -++ struct edmac_sg *dsg = NULL; -++ struct edmac_lli *last_plli = NULL; -++ unsigned int lli_count = 0; -++ int ret; -++ -++ list_for_each_entry(dsg, sg_head, node) { -++ ret = edmac_fill_asg_lli_for_desc(dsg, tsf_desc, &lli_count); -++ if (ret) -++ return ret; -++ } -++ -++ if (tsf_desc->cyclic) { -++ last_plli = (edmac_lli *)((uintptr_t)tsf_desc->llis_vaddr + -++ (lli_count - 1) * sizeof(*last_plli)); -++ last_plli->next_lli = tsf_desc->llis_busaddr | EDMAC_LLI_ENABLE; -++ } else { -++ last_plli = (edmac_lli *)((uintptr_t)tsf_desc->llis_vaddr + -++ (lli_count - 1) * sizeof(*last_plli)); -++ last_plli->next_lli = 0; -++ } -++ dump_lli(tsf_desc->llis_vaddr, lli_count); -++ return 0; -++} -++ -++static struct dma_async_tx_descriptor *edmac_prep_slave_sg( -++ struct dma_chan *chan, struct scatterlist *sgl, -++ unsigned int sg_len, enum dma_transfer_direction direction, -++ unsigned long flags, void *context) -++{ -++ struct edmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ struct transfer_desc *tsf_desc = NULL; -++ dma_addr_t slave_addr = 0; -++ int ret; -++ LIST_HEAD(sg_head); -++ if (sgl == NULL) { -++ edmacv310_error("sgl is null!\n"); -++ return NULL; -++ } -++ -++ tsf_desc = edmac_init_tsf_desc(chan, direction, &slave_addr); -++ if (!tsf_desc) -++ return NULL; -++ -++ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, -++ &tsf_desc->llis_busaddr); -++ if (!tsf_desc->llis_vaddr) { -++ edmacv310_error("malloc memory from pool fail !\n"); -++ goto err_alloc_lli; -++ } -++ -++ ret = edmac_fill_sg_for_slave(&sg_head, slave_addr, sgl, sg_len, direction); -++ if (ret) -++ goto err_fill_sg; -++ ret = edmac_fill_lli_for_desc(&sg_head, tsf_desc); -++ free_dsg(&sg_head); -++ if (ret) -++ goto err_fill_sg; -++ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); -++ -++err_fill_sg: -++ dma_pool_free(edmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); -++err_alloc_lli: -++ kfree(tsf_desc); -++ return NULL; -++} -++ -++static struct dma_async_tx_descriptor *edmac_prep_dma_m2m_copy( -++ struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, -++ size_t len, unsigned long flags) -++{ -++ struct edmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ struct transfer_desc *tsf_desc = NULL; -++ LIST_HEAD(sg_head); -++ u32 config = 0; -++ int ret; -++ -++ if (!len) -++ return NULL; -++ -++ tsf_desc = kzalloc(sizeof(*tsf_desc), GFP_NOWAIT); -++ if (tsf_desc == NULL) { -++ edmacv310_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) { -++ edmacv310_error("malloc memory from pool fail !\n"); -++ goto err_alloc_lli; -++ } -++ -++ 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; -++ config |= EDMAC_MEM_BIT_WIDTH << EDMAC_CONFIG_SRC_WIDTH_SHIFT; -++ config |= EDMAC_MEM_BIT_WIDTH << EDMAC_CONFIG_DST_WIDTH_SHIFT; -++ tsf_desc->ccfg = config; -++ ret = edmac_fill_sg_for_m2m_copy(&sg_head, dst, src, len); -++ if (ret) -++ goto err_fill_sg; -++ ret = edmac_fill_lli_for_desc(&sg_head, tsf_desc); -++ free_dsg(&sg_head); -++ if (ret) -++ goto err_fill_sg; -++ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); -++ -++err_fill_sg: -++ dma_pool_free(edmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); -++err_alloc_lli: -++ kfree(tsf_desc); -++ return NULL; -++} -++ -++static struct dma_async_tx_descriptor *edmac_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 edmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan); -++ struct edmacv310_driver_data *edmac = edmac_dma_chan->host; -++ struct transfer_desc *tsf_desc = NULL; -++ struct edmac_cyclic_args args = { -++ .slave_addr = 0, -++ .buf_addr = buf_addr, -++ .buf_len = buf_len, -++ .period_len = period_len, -++ .direction = direction -++ }; -++ LIST_HEAD(sg_head); -++ int ret; -++ -++ tsf_desc = edmac_init_tsf_desc(chan, direction, &(args.slave_addr)); -++ if (!tsf_desc) -++ return NULL; -++ -++ tsf_desc->llis_vaddr = dma_pool_alloc(edmac->pool, GFP_NOWAIT, -++ &tsf_desc->llis_busaddr); -++ if (!tsf_desc->llis_vaddr) { -++ edmacv310_error("malloc memory from pool fail !\n"); -++ goto err_alloc_lli; -++ } -++ -++ tsf_desc->cyclic = true; -++ ret = edmac_fill_sg_for_cyclic(&sg_head, args); -++ if (ret) -++ goto err_fill_sg; -++ ret = edmac_fill_lli_for_desc(&sg_head, tsf_desc); -++ free_dsg(&sg_head); -++ if (ret) -++ goto err_fill_sg; -++ return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags); -++ -++err_fill_sg: -++ dma_pool_free(edmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); -++err_alloc_lli: -++ kfree(tsf_desc); -++ return NULL; -++} -++ -++static void edmac_phy_reassign(struct edmacv310_phy_chan *phy_chan, -++ struct edmacv310_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(const struct edmacv310_driver_data *edmac, -++ const struct edmacv310_dma_chan *edmac_dma_chan) -++{ -++ unsigned int val; -++ struct edmacv310_phy_chan *phychan = edmac_dma_chan->phychan; -++ edmac_pause_phy_chan(edmac_dma_chan); -++ val = 0x1 << phychan->id; -++ edmacv310_writel(val, edmac->base + EDMAC_INT_TC1_RAW); -++ edmacv310_writel(val, edmac->base + EDMAC_INT_ERR1_RAW); -++ edmacv310_writel(val, edmac->base + EDMAC_INT_ERR2_RAW); -++} -++ -++void edmac_phy_free(struct edmacv310_dma_chan *chan) -++{ -++ struct edmacv310_driver_data *edmac = chan->host; -++ struct edmacv310_dma_chan *p = NULL; -++ struct edmacv310_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; -++} -++ -++bool handle_irq(const struct edmacv310_driver_data *edmac, int chan_id) -++{ -++ struct edmacv310_dma_chan *chan = NULL; -++ struct edmacv310_phy_chan *phy_chan = NULL; -++ struct transfer_desc *tsf_desc = NULL; -++ unsigned int channel_tc_status, channel_err_status[ERR_STATUS_REG_NUM]; -++ -++ phy_chan = &edmac->phy_chans[chan_id]; -++ chan = phy_chan->serving; -++ if (!chan) { -++ edmacv310_error("error interrupt on chan: %d!\n", chan_id); -++ return 0; -++ } -++ tsf_desc = chan->at; -++ -++ channel_tc_status = edmacv310_readl(edmac->base + EDMAC_INT_TC1_RAW); -++ channel_tc_status = (channel_tc_status >> chan_id) & 0x01; -++ if (channel_tc_status) -++ edmacv310_writel(channel_tc_status << chan_id, edmac->base + EDMAC_INT_TC1_RAW); -++ -++ channel_tc_status = edmacv310_readl(edmac->base + EDMAC_INT_TC2); -++ channel_tc_status = (channel_tc_status >> chan_id) & 0x01; -++ if (channel_tc_status) -++ edmacv310_writel(channel_tc_status << chan_id, edmac->base + EDMAC_INT_TC2_RAW); -++ -++ channel_err_status[0] = edmacv310_readl(edmac->base + EDMAC_INT_ERR1); -++ channel_err_status[1] = edmacv310_readl(edmac->base + EDMAC_INT_ERR2); -++ channel_err_status[2] = edmacv310_readl(edmac->base + EDMAC_INT_ERR3); -++ if ((channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) & (1 << chan_id)) { -++ edmacv310_error("Error in edmac %d!,ERR1 = 0x%x,ERR2 = 0x%x,ERR3 = 0x%x\n", -++ chan_id, channel_err_status[0], -++ channel_err_status[1], channel_err_status[2]); -++ edmacv310_writel(1 << chan_id, edmac->base + EDMAC_INT_ERR1_RAW); -++ edmacv310_writel(1 << chan_id, edmac->base + EDMAC_INT_ERR2_RAW); -++ edmacv310_writel(1 << chan_id, 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); -++ return 1; -++ } -++ 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); -++ return 1; -++} -++ -++static irqreturn_t emdacv310_irq(int irq, void *dev) -++{ -++ struct edmacv310_driver_data *edmac = (struct edmacv310_driver_data *)dev; -++ u32 mask = 0; -++ unsigned int channel_status, temp, i; -++ -++ channel_status = edmacv310_readl(edmac->base + EDMAC_INT_STAT); -++ if (!channel_status) { -++ edmacv310_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) -++ mask |= handle_irq(edmac, i) << i; -++ } -++ return mask ? IRQ_HANDLED : IRQ_NONE; -++} -++ -++static inline void edmac_dma_slave_init(struct edmacv310_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 edmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(vd->tx.chan); -++ dma_descriptor_unmap(&vd->tx); -++ dma_pool_free(edmac_dma_chan->host->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr); -++ kfree(tsf_desc); -++} -++ -++static int edmac_init_virt_channels(struct edmacv310_driver_data *edmac, -++ struct dma_device *dmadev, -++ unsigned int channels, bool slave) -++{ -++ struct edmacv310_dma_chan *chan = NULL; -++ int i; -++ INIT_LIST_HEAD(&dmadev->channels); -++ -++ for (i = 0; i < channels; i++) { -++ chan = kzalloc(sizeof(struct edmacv310_dma_chan), GFP_KERNEL); -++ if (!chan) { -++ edmacv310_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 edmacv310_dma_chan *chan = NULL; -++ struct edmacv310_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); -++ } -++} -++ -++static void edmacv310_prep_dma_device(struct platform_device *pdev, -++ struct edmacv310_driver_data *edmac) -++{ -++ 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_m2m_copy; -++ 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_prep_slave_sg; -++ edmac->slave.device_prep_dma_cyclic = edmac_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; -++} -++ -++static int edmacv310_init_chan(struct edmacv310_driver_data *edmac) -++{ -++ int i, ret; -++ edmac->phy_chans = kzalloc((edmac->channels * sizeof( -++ struct edmacv310_phy_chan)), -++ GFP_KERNEL); -++ if (!edmac->phy_chans) { -++ edmacv310_error("malloc for phy chans fail!"); -++ return -ENOMEM; -++ } -++ -++ for (i = 0; i < edmac->channels; i++) { -++ struct edmacv310_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; -++ } -++ -++ ret = edmac_init_virt_channels(edmac, &edmac->memcpy, edmac->channels, -++ false); -++ if (ret) { -++ edmacv310_error("fail to init memory virt channels!"); -++ goto free_phychans; -++ } -++ -++ ret = edmac_init_virt_channels(edmac, &edmac->slave, edmac->slave_requests, -++ true); -++ if (ret) { -++ edmacv310_error("fail to init slave virt channels!"); -++ goto free_memory_virt_channels; -++ } -++ return 0; -++ -++free_memory_virt_channels: -++ edmac_free_virt_channels(&edmac->memcpy); -++free_phychans: -++ kfree(edmac->phy_chans); -++ return -ENOMEM; -++} -++ -++static void edmacv310_free_chan(struct edmacv310_driver_data *edmac) -++{ -++ edmac_free_virt_channels(&edmac->slave); -++ edmac_free_virt_channels(&edmac->memcpy); -++ kfree(edmac->phy_chans); -++} -++ -++static void edmacv310_prep_phy_device(const struct edmacv310_driver_data *edmac) -++{ -++ clk_prepare_enable(edmac->clk); -++ clk_prepare_enable(edmac->axi_clk); -++ reset_control_deassert(edmac->rstc); -++ -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC1_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC2_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR1_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR2_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR3_RAW); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_TC1_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_TC2_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_ERR1_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_ERR2_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_ERR3_MASK); -++} -++ -++static struct edmacv310_driver_data *edmacv310_prep_edmac_device(struct platform_device *pdev) -++{ -++ int ret; -++ struct edmacv310_driver_data *edmac = NULL; -++ ssize_t trasfer_size; -++ -++ ret = dma_set_mask_and_coherent(&(pdev->dev), DMA_BIT_MASK(64)); /* 64:Addressing capability of the DMA */ -++ if (ret) -++ return NULL; -++ -++ edmac = kzalloc(sizeof(*edmac), GFP_KERNEL); -++ if (!edmac) { -++ edmacv310_error("malloc for edmac fail!"); -++ return NULL; -++ } -++ -++ edmac->dev = pdev; -++ -++ ret = get_of_probe(edmac); -++ if (ret) { -++ edmacv310_error("get dts info fail!"); -++ goto free_edmac; -++ } -++ -++ edmacv310_prep_dma_device(pdev, edmac); -++ 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) { -++ edmacv310_error("create pool fail!"); -++ goto free_edmac; -++ } -++ -++ ret = edmacv310_init_chan(edmac); -++ if (ret) -++ goto free_pool; -++ -++ return edmac; -++ -++free_pool: -++ dma_pool_destroy(edmac->pool); -++free_edmac: -++ kfree(edmac); -++ return NULL; -++} -++ -++static void free_edmac_device(struct edmacv310_driver_data *edmac) -++{ -++ edmacv310_free_chan(edmac); -++ dma_pool_destroy(edmac->pool); -++ kfree(edmac); -++} -++ -++static int __init edmacv310_probe(struct platform_device *pdev) -++{ -++ int ret; -++ struct edmacv310_driver_data *edmac = NULL; -++ -++ edmac = edmacv310_prep_edmac_device(pdev); -++ if (edmac == NULL) -++ return -ENOMEM; -++ -++ ret = request_irq(edmac->irq, emdacv310_irq, 0, DRIVER_NAME, edmac); -++ if (ret) { -++ edmacv310_error("fail to request irq"); -++ goto free_edmac; -++ } -++ edmacv310_prep_phy_device(edmac); -++ ret = dma_async_device_register(&edmac->memcpy); -++ if (ret) { -++ edmacv310_error("%s failed to register memcpy as an async device - %d\n", __func__, ret); -++ goto free_irq_res; -++ } -++ -++ ret = dma_async_device_register(&edmac->slave); -++ if (ret) { -++ edmacv310_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_irq_res: -++ free_irq(edmac->irq, edmac); -++free_edmac: -++ free_edmac_device(edmac); -++ return -ENOMEM; -++} -++ -++static int emda_remove(struct platform_device *pdev) -++{ -++ int err = 0; -++ return err; -++} -++ -++static const struct of_device_id edmacv310_match[] = { -++ { .compatible = "vendor,edmacv310" }, -++ {}, -++}; -++ -++static struct platform_driver edmacv310_driver = { -++ .remove = emda_remove, -++ .driver = { -++ .name = "edmacv310", -++ .of_match_table = edmacv310_match, -++ }, -++}; -++ -++static int __init edmacv310_init(void) -++{ -++ return platform_driver_probe(&edmacv310_driver, edmacv310_probe); -++} -++subsys_initcall(edmacv310_init); -++ -++static void __exit edmacv310_exit(void) -++{ -++ platform_driver_unregister(&edmacv310_driver); -++} -++module_exit(edmacv310_exit); -++ -++MODULE_LICENSE("GPL"); -+diff --git a/drivers/dma/edmacv310.h b/drivers/dma/edmacv310.h -+new file mode 100644 -+index 000000000..22a912a6e -+--- /dev/null -++++ b/drivers/dma/edmacv310.h -+@@ -0,0 +1,136 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __EDMACV310_H__ -++#define __EDMACV310_H__ -++ -++/* debug control */ -++#define EDMACV310_CONFIG_TRACE_LEVEL 3 -++#define EDMACV310_TRACE_LEVEL 0 -++#define EDMACV310_REG_TRACE_LEVEL 3 -++#define EDMACV310_TRACE_FMT KERN_INFO -++ -++#ifdef DEBUG_EDMAC -++#define edmacv310_trace(level, msg...) do { \ -++ if ((level) >= EDMACV310_TRACE_LEVEL) { \ -++ printk(EDMACV310_TRACE_FMT"%s:%d: ", __func__, __LINE__); \ -++ printk(msg); \ -++ printk("\n"); \ -++ } \ -++} while (0) -++ -++ -++#define edmacv310_assert(cond) do { \ -++ if (!(cond)) { \ -++ printk(KERN_ERR "Assert:edmacv310:%s:%d\n", \ -++ __func__, \ -++ __LINE__); \ -++ BUG(); \ -++ } \ -++} while (0) -++ -++#define edmacv310_error(s...) do { \ -++ printk(KERN_ERR "edmacv310:%s:%d: ", __func__, __LINE__); \ -++ printk(s); \ -++ printk("\n"); \ -++} while (0) -++ -++#else -++ -++#define edmacv310_trace(level, msg...) -++#define edmacv310_assert(level, msg...) -++#define edmacv310_error(level, msg...) -++ -++#endif -++ -++#define edmacv310_readl(addr) ((unsigned int)readl((void *)(addr))) -++ -++#define edmacv310_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 0b0 -++#define EDMAC_WIDTH_16BIT 0b1 -++#define EDMAC_WIDTH_32BIT 0b10 -++#define EDMAC_WIDTH_64BIT 0b11 -++#ifdef CONFIG_64BIT -++#define EDMAC_MEM_BIT_WIDTH EDMAC_WIDTH_64BIT -++#else -++#define EDMAC_MEM_BIT_WIDTH EDMAC_WIDTH_32BIT -++#endif -++ -++#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 -++ -++#define EDMAC_CONTROL_SRC_WIDTH_MASK GENMASK(18, 16) -++#define EDMAC_CONTROL_DST_WIDTH_MASK GENMASK(14, 12) -++#endif -+diff --git a/drivers/edmac/Kconfig b/drivers/edmac/Kconfig -+new file mode 100755 -+index 000000000..fc563ba24 -+--- /dev/null -++++ b/drivers/edmac/Kconfig -+@@ -0,0 +1,31 @@ -++# -++# Sensor device configuration -++# -++ -++if ARCH_BSP -++config EDMAC -++ tristate "Vendor EDMAC Controller support" -++ depends on !EDMACV310 -++ 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. -++ Vendor 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. -++ -++if EDMAC -++ -++config EDMAC_CHANNEL_NUM -++ int "edmac channel num" -++ default "8" -++ -++config EDMAC_INTERRUPT -++ bool "Vendor EDMAC Controller interrupt mode support" -++ depends on (ARCH_BSP && EDMAC) -++ help -++ open Vendor EDMAC Controller interrupt mode -++ -++endif -++endif -+diff --git a/drivers/edmac/Makefile b/drivers/edmac/Makefile -+new file mode 100755 -+index 000000000..2b6a64b61 -+--- /dev/null -++++ b/drivers/edmac/Makefile -+@@ -0,0 +1,6 @@ -++# -++# Makefile for the edmac drivers. -++# -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_EDMAC) += edmacv310.o -++endif -+diff --git a/drivers/edmac/edma_hi3516cv610.h b/drivers/edmac/edma_hi3516cv610.h -+new file mode 100755 -+index 000000000..63f2d210b -+--- /dev/null -++++ b/drivers/edmac/edma_hi3516cv610.h -+@@ -0,0 +1,83 @@ -++/* -++ * Copyright (c) 2017-2018 Shenshu 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 . -++ */ -++ -++#ifndef __EDMA_HI3516CV610_H__ -++#define __EDMA_HI3516CV610_H__ -++ -++#include "edmacv310.h" -++#define EDMAC_MAX_PERIPHERALS 32 -++#define EDMAC_CHANNEL_NUM 4 -++ -++#define UART2_REG_BASE 0x11042000 -++#define UART1_REG_BASE 0x11041000 -++#define UART0_REG_BASE 0x11040000 -++ -++#define UART0_DR (UART0_REG_BASE + 0x0) -++#define UART1_DR (UART1_REG_BASE + 0x0) -++#define UART2_DR (UART2_REG_BASE + 0x0) -++ -++#define I2C2_REG_BASE 0x11062000 -++#define I2C1_REG_BASE 0x11061000 -++#define I2C0_REG_BASE 0x11060000 -++ -++#define I2C0_TX_FIFO (I2C0_REG_BASE + 0x20) -++#define I2C0_RX_FIFO (I2C0_REG_BASE + 0x24) -++ -++#define I2C1_TX_FIFO (I2C1_REG_BASE + 0x20) -++#define I2C1_RX_FIFO (I2C1_REG_BASE + 0x24) -++ -++#define I2C2_TX_FIFO (I2C2_REG_BASE + 0x20) -++#define I2C2_RX_FIFO (I2C2_REG_BASE + 0x24) -++ -++#define EDMAC_TX 1 -++#define EDMAC_RX 0 -++ -++edmac_peripheral g_peripheral[EDMAC_MAX_PERIPHERALS] = { -++ {0, I2C0_RX_FIFO, DMAC_HOST0, (0x40000004), PERI_8BIT_MODE, 0}, -++ {1, I2C0_TX_FIFO, DMAC_HOST0, (0x80000004), PERI_8BIT_MODE, 0}, -++ {2, I2C1_RX_FIFO, DMAC_HOST0, (0x40000004), PERI_8BIT_MODE, 0}, -++ {3, I2C1_TX_FIFO, DMAC_HOST0, (0x80000004), PERI_8BIT_MODE, 0}, -++ {4, I2C2_RX_FIFO, DMAC_HOST0, (0x40000004), PERI_8BIT_MODE, 0}, -++ {5, I2C2_TX_FIFO, DMAC_HOST0, (0x80000004), PERI_8BIT_MODE, 0}, -++ {6, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {7, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {8, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {9, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {10, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {11, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {12, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {13, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {14, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {15, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {16, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {17, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {18, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {19, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {20, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {21, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {22, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {23, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {24, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {25, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {26, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {27, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {28, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {29, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {30, 0, DMAC_NOT_USE, 0, 0, 0}, -++ {31, 0, DMAC_NOT_USE, 0, 0, 0}, -++}; -++#endif -+diff --git a/drivers/edmac/edma_hi3519dv500.h b/drivers/edmac/edma_hi3519dv500.h -+new file mode 100755 -+index 000000000..30890a4c4 -+--- /dev/null -++++ b/drivers/edmac/edma_hi3519dv500.h -+@@ -0,0 +1,85 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __EDMA_HI3519DV500_H__ -++#define __EDMA_HI3519DV500_H__ -++ -++#include "edmacv310.h" -++#define EDMAC_MAX_PERIPHERALS 32 -++#define EDMAC_CHANNEL_NUM 8 -++ -++#define UART4_REG_BASE 0x11044000 -++#define UART3_REG_BASE 0x11043000 -++#define UART2_REG_BASE 0x11042000 -++#define UART1_REG_BASE 0x11041000 -++#define UART0_REG_BASE 0x11040000 -++ -++#define UART0_DR (UART0_REG_BASE + 0x0) -++#define UART1_DR (UART1_REG_BASE + 0x0) -++#define UART2_DR (UART2_REG_BASE + 0x0) -++#define UART3_DR (UART3_REG_BASE + 0x0) -++#define UART4_DR (UART4_REG_BASE + 0x0) -++ -++#define I2C5_REG_BASE 0x11065000 -++#define I2C4_REG_BASE 0x11064000 -++#define I2C3_REG_BASE 0x11063000 -++#define I2C2_REG_BASE 0x11062000 -++#define I2C1_REG_BASE 0x11061000 -++#define I2C0_REG_BASE 0x11060000 -++ -++#define I2C0_TX_FIFO (I2C0_REG_BASE + 0x20) -++#define I2C0_RX_FIFO (I2C0_REG_BASE + 0x24) -++ -++#define I2C1_TX_FIFO (I2C1_REG_BASE + 0x20) -++#define I2C1_RX_FIFO (I2C1_REG_BASE + 0x24) -++ -++#define I2C2_TX_FIFO (I2C2_REG_BASE + 0x20) -++#define I2C2_RX_FIFO (I2C2_REG_BASE + 0x24) -++ -++#define I2C3_TX_FIFO (I2C3_REG_BASE + 0x20) -++#define I2C3_RX_FIFO (I2C3_REG_BASE + 0x24) -++ -++#define I2C4_TX_FIFO (I2C4_REG_BASE + 0x20) -++#define I2C4_RX_FIFO (I2C4_REG_BASE + 0x24) -++ -++#define I2C5_TX_FIFO (I2C5_REG_BASE + 0x20) -++#define I2C5_RX_FIFO (I2C5_REG_BASE + 0x24) -++ -++#define I2C6_TX_FIFO (I2C6_REG_BASE + 0x20) -++#define I2C6_RX_FIFO (I2C6_REG_BASE + 0x24) -++ -++#define I2C7_TX_FIFO (I2C7_REG_BASE + 0x20) -++#define I2C7_RX_FIFO (I2C7_REG_BASE + 0x24) -++ -++#define I2C8_TX_FIFO (I2C8_REG_BASE + 0x20) -++#define I2C8_RX_FIFO (I2C8_REG_BASE + 0x24) -++ -++#define I2C9_TX_FIFO (I2C9_REG_BASE + 0x20) -++#define I2C9_RX_FIFO (I2C9_REG_BASE + 0x24) -++ -++#define I2C10_TX_FIFO (I2C10_REG_BASE + 0x20) -++#define I2C10_RX_FIFO (I2C10_REG_BASE + 0x24) -++ -++#define I2C11_TX_FIFO (I2C11_REG_BASE + 0x20) -++#define I2C11_RX_FIFO (I2C11_REG_BASE + 0x24) -++ -++ -++#define EDMAC_TX 1 -++#define EDMAC_RX 0 -++ -++edmac_peripheral g_peripheral[EDMAC_MAX_PERIPHERALS] = { -++ {0, I2C0_RX_FIFO, DMAC_HOST1, (0x40000004), PERI_8BIT_MODE, 0}, -++ {1, I2C0_TX_FIFO, DMAC_HOST1, (0x80000004), PERI_8BIT_MODE, 0}, -++ {2, I2C1_RX_FIFO, DMAC_HOST1, (0x40000004), PERI_8BIT_MODE, 0}, -++ {3, I2C1_TX_FIFO, DMAC_HOST1, (0x80000004), PERI_8BIT_MODE, 0}, -++ {4, I2C2_RX_FIFO, DMAC_HOST1, (0x40000004), PERI_8BIT_MODE, 0}, -++ {5, I2C2_TX_FIFO, DMAC_HOST1, (0x80000004), PERI_8BIT_MODE, 0}, -++ {6, I2C3_RX_FIFO, DMAC_HOST1, (0x40000004), PERI_8BIT_MODE, 0}, -++ {7, I2C3_TX_FIFO, DMAC_HOST1, (0x80000004), PERI_8BIT_MODE, 0}, -++ {8, I2C4_RX_FIFO, DMAC_HOST1, (0x40000004), PERI_8BIT_MODE, 0}, -++ {9, I2C4_TX_FIFO, DMAC_HOST1, (0x80000004), PERI_8BIT_MODE, 0}, -++ {10, I2C5_RX_FIFO, DMAC_HOST1, (0x40000004), PERI_8BIT_MODE, 0}, -++ {11, I2C5_TX_FIFO, DMAC_HOST1, (0x80000004), PERI_8BIT_MODE, 0}, -++}; -++#endif -+diff --git a/drivers/edmac/edmacv310.c b/drivers/edmac/edmacv310.c -+new file mode 100755 -+index 000000000..28ff831f9 -+--- /dev/null -++++ b/drivers/edmac/edmacv310.c -+@@ -0,0 +1,957 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "edmacv310.h" -++#include -++ -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++#include "edma_hi3519dv500.h" -++#endif -++ -++#ifdef CONFIG_ARCH_HI3516CV610_FAMILY -++#include "edma_hi3516cv610.h" -++#endif -++ -++int g_channel_status[EDMAC_CHANNEL_NUM]; -++DMAC_ISR *function[EDMAC_CHANNEL_NUM]; -++unsigned long pllihead[2] = {0, 0}; -++void __iomem *dma_regbase; -++int edmacv310_trace_level_n = EDMACV310_TRACE_LEVEL; -++ -++struct edmac_host { -++ struct platform_device *pdev; -++ void __iomem *base; -++ struct regmap *misc_regmap; -++ unsigned int misc_ctrl_base; -++ void __iomem *crg_ctrl; -++ unsigned int id; -++ struct clk *clk; -++ struct clk *axi_clk; -++ int irq; -++ struct reset_control *rstc; -++ unsigned int channels; -++ unsigned int slave_requests; -++}; -++ -++#define DRIVER_NAME "edmacv310" -++ -++int dmac_channel_allocate(void) -++{ -++ unsigned int i; -++ -++ for (i = 0; i < EDMAC_CHANNEL_NUM; i++) { -++ if (g_channel_status[i] == DMAC_CHN_VACANCY) { -++ g_channel_status[i] = DMAC_CHN_ALLOCAT; -++ return i; -++ } -++ } -++ -++ edmacv310_error("no to alloc\n"); -++ return -1; -++} -++EXPORT_SYMBOL(dmac_channel_allocate); -++ -++static void edmac_read_err_status(unsigned int *channel_err_status, -++ const unsigned int err_status_len) -++{ -++ if (err_status_len < EDMAC_ERR_REG_NUM) { -++ edmacv310_error("channel_err_status size err.\n"); -++ return; -++ } -++ channel_err_status[0] = edmacv310_readl(dma_regbase + EDMAC_INT_ERR1); -++ channel_err_status[1] = edmacv310_readl(dma_regbase + EDMAC_INT_ERR2); -++ channel_err_status[2] = edmacv310_readl(dma_regbase + EDMAC_INT_ERR3); -++} -++ -++static void edmac_err_status_filter(unsigned int *channel_err_status, -++ const unsigned int err_status_len, -++ unsigned int curr_channel) -++{ -++ if (err_status_len < EDMAC_ERR_REG_NUM) { -++ edmacv310_error("channel_err_status size err.\n"); -++ return; -++ } -++ channel_err_status[0] = (channel_err_status[0] >> curr_channel) & 0x01; -++ channel_err_status[1] = (channel_err_status[1] >> curr_channel) & 0x01; -++ channel_err_status[2] = (channel_err_status[2] >> curr_channel) & 0x01; -++} -++ -++static void edmac_clear_err_status(unsigned int curr_channel) -++{ -++ edmacv310_writel(1 << curr_channel, dma_regbase + EDMAC_INT_ERR1_RAW); -++ edmacv310_writel(1 << curr_channel, dma_regbase + EDMAC_INT_ERR2_RAW); -++ edmacv310_writel(1 << curr_channel, dma_regbase + EDMAC_INT_ERR3_RAW); -++} -++ -++/* -++ * update the state of channels -++ */ -++static int edmac_update_status(unsigned int channel) -++{ -++ unsigned int channel_tc_status; -++ unsigned int channel_err_status[EDMAC_ERR_REG_NUM]; -++ unsigned int i = channel; -++ unsigned long update_jiffies_timeout; -++ -++ update_jiffies_timeout = jiffies + EDMAC_UPDATE_TIMEOUT; -++ while (1) { -++ unsigned int channel_status; -++ channel_status = edmacv310_readl(dma_regbase + EDMAC_INT_STAT); -++ channel_status = (channel_status >> i) & 0x01; -++ if (channel_status) { -++ channel_tc_status = edmacv310_readl(dma_regbase + EDMAC_INT_TC1); -++ channel_tc_status = (channel_tc_status >> i) & 0x01; -++ if (channel_tc_status) { -++ edmacv310_writel(1 << i, dma_regbase + EDMAC_INT_TC1_RAW); -++ g_channel_status[i] = DMAC_CHN_SUCCESS; -++ break; -++ } -++ -++ channel_tc_status = edmacv310_readl(dma_regbase + EDMAC_INT_TC2); -++ channel_tc_status = (channel_tc_status >> i) & 0x01; -++ if (channel_tc_status) { -++ edmacv310_writel(1 << i, dma_regbase + EDMAC_INT_TC2_RAW); -++ g_channel_status[i] = DMAC_CHN_SUCCESS; -++ break; -++ } -++ -++ edmac_read_err_status(channel_err_status, EDMAC_ERR_REG_NUM); -++ edmac_err_status_filter(channel_err_status, EDMAC_ERR_REG_NUM, i); -++ -++ if (channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) { -++ edmacv310_error("Error in EDMAC %d finish!\n", i); -++ edmac_read_err_status(channel_err_status, EDMAC_ERR_REG_NUM); -++ edmac_clear_err_status(i); -++ g_channel_status[i] = -DMAC_CHN_ERROR; -++ break; -++ } -++ } -++ -++ if (!time_before(jiffies, update_jiffies_timeout)) { -++ edmacv310_error("Timeout in DMAC %d!\n", i); -++ g_channel_status[i] = -DMAC_CHN_TIMEOUT; -++ break; -++ } -++ } -++ return g_channel_status[i]; -++} -++ -++/* -++ * register user's function -++ */ -++int dmac_register_isr(unsigned int channel, void *pisr) -++{ -++ if (channel > EDMAC_CHANNEL_NUM - 1) { -++ edmacv310_error("invalid channel,channel=%0d\n", channel); -++ return -EINVAL; -++ } -++ -++ function[channel] = (void *)pisr; -++ -++ return 0; -++} -++EXPORT_SYMBOL(dmac_register_isr); -++ -++/* -++ * free channel -++ */ -++int dmac_channel_free(unsigned int channel) -++{ -++ if (channel < EDMAC_CHANNEL_NUM) -++ g_channel_status[channel] = DMAC_CHN_VACANCY; -++ -++ return 0; -++} -++EXPORT_SYMBOL(dmac_channel_free); -++ -++static unsigned int dmac_check_request(unsigned int peripheral_addr, -++ int direction) -++{ -++ int i; -++ -++ for (i = direction; i < EDMAC_MAX_PERIPHERALS; i += 2) { -++ if (g_peripheral[i].peri_addr == peripheral_addr) -++ return i; -++ } -++ edmacv310_error("Invalid devaddr\n"); -++ return -1; -++} -++ -++void edmac_channel_free(int channel) -++{ -++ if ((channel >= 0) && (channel < EDMAC_CHANNEL_NUM)) -++ g_channel_status[channel] = DMAC_CHN_VACANCY; -++} -++/* -++ * wait for transfer end -++ */ -++int dmac_wait(int channel) -++{ -++ int ret_result; -++ int ret = 0; -++ -++ if (channel < 0) -++ return -1; -++ -++ while (1) { -++ ret_result = edmac_update_status(channel); -++ if (ret_result == -DMAC_CHN_ERROR) { -++ edmacv310_error("Transfer Error.\n"); -++ ret = -1; -++ goto end; -++ } else if (ret_result == DMAC_NOT_FINISHED) { -++ udelay(DMAC_FINISHED_WAIT_TIME); -++ } else if (ret_result == DMAC_CHN_SUCCESS) { -++ ret = DMAC_CHN_SUCCESS; -++ goto end; -++ } else if (ret_result == DMAC_CHN_VACANCY) { -++ ret = DMAC_CHN_SUCCESS; -++ goto end; -++ } else if (ret_result == -DMAC_CHN_TIMEOUT) { -++ edmacv310_error("Timeout.\n"); -++ edmacv310_writel(EDMAC_CX_DISABLE, -++ dma_regbase + edmac_cx_config(channel)); -++ g_channel_status[channel] = DMAC_CHN_VACANCY; -++ ret = -1; -++ return ret; -++ } -++ } -++end: -++ edmacv310_writel(EDMAC_CX_DISABLE, -++ dma_regbase + edmac_cx_config(channel)); -++ edmac_channel_free(channel); -++ return ret; -++} -++EXPORT_SYMBOL(dmac_wait); -++ -++/* -++ * execute memory to peripheral dma transfer without LLI -++ */ -++int dmac_m2p_transfer(unsigned long long memaddr, unsigned int uwperipheralid, -++ unsigned int length) -++{ -++ unsigned int ulchnn; -++ unsigned int uwwidth; -++ unsigned int temp; -++ -++ ulchnn = dmac_channel_allocate(); -++ if (-1 == ulchnn) -++ return -1; -++ -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "ulchnn = %d\n", ulchnn); -++ uwwidth = g_peripheral[uwperipheralid].transfer_width; -++ if ((length >> uwwidth) >= EDMAC_TRANS_MAXSIZE) { -++ edmacv310_error("The length is more than 64k!\n"); -++ return -1; -++ } -++ -++ edmacv310_writel(memaddr & 0xffffffff, -++ dma_regbase + edmac_cx_src_addr_l(ulchnn)); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((memaddr >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_src_addr_h(ulchnn)); -++#endif -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_SRC_ADDR_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_src_addr_l(ulchnn))); -++ -++ edmacv310_writel(g_peripheral[uwperipheralid].peri_addr & 0xffffffff, -++ dma_regbase + edmac_cx_dest_addr_l(ulchnn)); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((g_peripheral[uwperipheralid].peri_addr >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_dest_addr_h(ulchnn)); -++#endif -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_DEST_ADDR_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_dest_addr_l(ulchnn))); -++ -++ edmacv310_writel(0, dma_regbase + edmac_cx_lli_l(ulchnn)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_LLI_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_lli_l(ulchnn))); -++ -++ edmacv310_writel(length, dma_regbase + edmac_cx_cnt0(ulchnn)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_CNT0 = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_cnt0(ulchnn))); -++ -++ temp = g_peripheral[uwperipheralid].transfer_cfg | (uwwidth << EDMA_SRC_WIDTH_OFFSET) | -++ (uwperipheralid << PERI_ID_OFFSET) | EDMA_CH_ENABLE; -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_CONFIG = 0x%x\n", temp); -++ edmacv310_writel(temp, dma_regbase + edmac_cx_config(ulchnn)); -++ return ulchnn; -++} -++ -++/* -++ * execute memory to peripheral dma transfer without LLI -++ */ -++int dmac_p2m_transfer(unsigned long memaddr, unsigned int uwperipheralid, -++ unsigned int length) -++{ -++ unsigned int ulchnn; -++ unsigned int uwwidth; -++ unsigned int temp; -++ -++ ulchnn = dmac_channel_allocate(); -++ if (-1 == ulchnn) -++ return -1; -++ -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "ulchnn = %d\n", ulchnn); -++ uwwidth = g_peripheral[uwperipheralid].transfer_width; -++ if ((length >> uwwidth) >= EDMAC_TRANS_MAXSIZE) { -++ edmacv310_error("The length is more than 64k!\n"); -++ return -1; -++ } -++ -++ edmacv310_writel(memaddr & 0xffffffff, -++ dma_regbase + edmac_cx_dest_addr_l(ulchnn)); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((memaddr >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_dest_addr_h(ulchnn)); -++#endif -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_DEST_ADDR_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_dest_addr_l(ulchnn))); -++ -++ edmacv310_writel(g_peripheral[uwperipheralid].peri_addr & 0xffffffff, -++ dma_regbase + edmac_cx_src_addr_l(ulchnn)); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel(0, dma_regbase + edmac_cx_src_addr_h(ulchnn)); -++#endif -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_SRC_ADDR_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_src_addr_l(ulchnn))); -++ -++ edmacv310_writel(0, dma_regbase + edmac_cx_lli_l(ulchnn)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_LLI_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_lli_l(ulchnn))); -++ -++ edmacv310_writel(length, dma_regbase + edmac_cx_cnt0(ulchnn)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_CNT0 = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_cnt0(ulchnn))); -++ -++ temp = g_peripheral[uwperipheralid].transfer_cfg | (uwwidth << EDMA_SRC_WIDTH_OFFSET) | -++ (uwperipheralid << PERI_ID_OFFSET) | EDMA_CH_ENABLE; -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_CONFIG = 0x%x\n", temp); -++ edmacv310_writel(temp, dma_regbase + edmac_cx_config(ulchnn)); -++ return ulchnn; -++} -++ -++int do_dma_m2p(unsigned long long memaddr, unsigned int peripheral_addr, -++ unsigned int length) -++{ -++ int ret; -++ int uwperipheralid; -++ -++ uwperipheralid = dmac_check_request(peripheral_addr, EDMAC_TX); -++ if (uwperipheralid < 0) { -++ edmacv310_error("m2p:Invalid devaddr\n"); -++ return -1; -++ } -++ -++ ret = dmac_m2p_transfer(memaddr, uwperipheralid, length); -++ if (ret == -1) { -++ edmacv310_error("m2p:trans err\n"); -++ return -1; -++ } -++ -++ return ret; -++} -++EXPORT_SYMBOL(do_dma_m2p); -++ -++int do_dma_p2m(unsigned long memaddr, unsigned int peripheral_addr, -++ unsigned int length) -++{ -++ int ret; -++ int uwperipheralid; -++ -++ uwperipheralid = dmac_check_request(peripheral_addr, EDMAC_RX); -++ if (uwperipheralid < 0) { -++ edmacv310_error("p2m:Invalid devaddr.\n"); -++ return -1; -++ } -++ -++ ret = dmac_p2m_transfer(memaddr, uwperipheralid, length); -++ if (ret == -1) { -++ edmacv310_error("p2m:trans err\n"); -++ return -1; -++ } -++ -++ return ret; -++} -++EXPORT_SYMBOL(do_dma_p2m); -++ -++/* -++ * buile LLI for memory to memory DMA transfer -++ */ -++int dmac_buildllim2m(const unsigned long *ppheadlli, -++ unsigned long psource, -++ unsigned long pdest, -++ unsigned int totaltransfersize, -++ unsigned int uwnumtransfers) -++{ -++ int lli_num; -++ unsigned long phy_address; -++ int j; -++ dmac_lli *plli = NULL; -++ -++ if (uwnumtransfers == 0) -++ return -EINVAL; -++ -++ lli_num = (totaltransfersize / uwnumtransfers); -++ if ((totaltransfersize % uwnumtransfers) != 0) -++ lli_num++; -++ -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "lli_num:%d\n", lli_num); -++ -++ phy_address = ppheadlli[0]; -++ plli = (dmac_lli *)ppheadlli[1]; -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "phy_address: 0x%lx\n", phy_address); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "address: 0x%p\n", plli); -++ for (j = 0; j < lli_num; j++) { -++ (void)memset_s(plli, sizeof(dmac_lli), 0x0, sizeof(dmac_lli)); -++ /* -++ * at the last transfer, chain_en should be set to 0x0; -++ * others tansfer,chain_en should be set to 0x2; -++ */ -++ plli->next_lli = (phy_address + (j + 1) * sizeof(dmac_lli)) & -++ (~(EDMAC_LLI_ALIGN - 1)); -++ if (j < lli_num - 1) { -++ plli->next_lli |= EDMAC_LLI_ENABLE; -++ plli->count = uwnumtransfers; -++ } else { -++ plli->next_lli |= EDMAC_LLI_DISABLE; -++ plli->count = totaltransfersize % uwnumtransfers; -++ } -++ -++ plli->src_addr = psource; -++ plli->dest_addr = pdest; -++ plli->config = EDMAC_CXCONFIG_M2M_LLI; -++ -++ psource += uwnumtransfers; -++ pdest += uwnumtransfers; -++ plli++; -++ } -++ -++ return 0; -++} -++EXPORT_SYMBOL(dmac_buildllim2m); -++ -++/* -++ * load configuration from LLI for memory to memory -++ */ -++int dmac_start_llim2m(unsigned int channel, const unsigned long *pfirst_lli) -++{ -++ unsigned int i = channel; -++ dmac_lli *plli; -++ -++ plli = (dmac_lli *)pfirst_lli[1]; -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "plli.src_addr: 0x%lx\n", plli->src_addr); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "plli.dst_addr: 0x%lx\n", plli->dest_addr); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "plli.next_lli: 0x%lx\n", plli->next_lli); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "plli.count: 0x%d\n", plli->count); -++ -++ edmacv310_writel(plli->dest_addr & 0xffffffff, -++ dma_regbase + edmac_cx_lli_l(i)); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((plli->dest_addr >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_lli_h(i)); -++#endif -++ edmacv310_writel(plli->count, dma_regbase + edmac_cx_cnt0(i)); -++ -++ edmacv310_writel(plli->src_addr & 0xffffffff, -++ dma_regbase + edmac_cx_src_addr_l(i)); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((plli->src_addr >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_src_addr_h(i)); -++#endif -++ edmacv310_writel(plli->dest_addr & 0xffffffff, -++ dma_regbase + edmac_cx_dest_addr_l(i)); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((plli->dest_addr >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_dest_addr_h(i)); -++#endif -++ edmacv310_writel(plli->config | EDMA_CH_ENABLE, -++ dma_regbase + edmac_cx_config(i)); -++ -++ return 0; -++} -++EXPORT_SYMBOL(dmac_start_llim2m); -++ -++/* -++ * config register for memory to memory DMA transfer without LLI -++ */ -++int dmac_start_m2m(unsigned int channel, unsigned long psource, -++ unsigned long pdest, unsigned int uwnumtransfers) -++{ -++ unsigned int i = channel; -++ -++ if (uwnumtransfers > EDMAC_TRANS_MAXSIZE || uwnumtransfers == 0) { -++ edmacv310_error("Invalidate transfer size,size=%x\n", uwnumtransfers); -++ return -EINVAL; -++ } -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "channel[%d],source=0x%lx,dest=0x%lx,length=%d\n", -++ channel, psource, pdest, uwnumtransfers); -++ -++ edmacv310_writel(psource & 0xffffffff, -++ dma_regbase + edmac_cx_src_addr_l(i)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_SRC_ADDR_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_src_addr_l(i))); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((psource >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_src_addr_h(i)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_SRC_ADDR_H = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_src_addr_h(i))); -++#endif -++ edmacv310_writel(pdest & 0xffffffff, dma_regbase + edmac_cx_dest_addr_l(i)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_DEST_ADDR_L = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_dest_addr_l(i))); -++#ifdef CONFIG_ARM64 -++ edmacv310_writel((pdest >> EDMACV310_32BIT) & 0xffffffff, -++ dma_regbase + edmac_cx_dest_addr_h(i)); -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "EDMAC_Cx_DEST_ADDR_H = 0x%x\n", -++ edmacv310_readl(dma_regbase + edmac_cx_dest_addr_h(i))); -++#endif -++ edmacv310_writel(0, dma_regbase + edmac_cx_lli_l(i)); -++ -++ edmacv310_writel(uwnumtransfers, dma_regbase + edmac_cx_cnt0(i)); -++ -++ edmacv310_writel(EDMAC_CXCONFIG_M2M | EDMA_CH_ENABLE, -++ dma_regbase + edmac_cx_config(i)); -++ -++ return 0; -++} -++EXPORT_SYMBOL(dmac_start_m2m); -++ -++/* -++ * execute memory to memory dma transfer without LLI -++ */ -++int dmac_m2m_transfer(unsigned long source, unsigned long dest, -++ unsigned int length) -++{ -++ unsigned int dma_size, dma_count, left_size; -++ int ulchnn; -++ -++ left_size = length; -++ dma_count = 0; -++ ulchnn = dmac_channel_allocate(); -++ if (ulchnn < 0) -++ return -EINVAL; -++ -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_DEBUG, "using channel[%d],source=0x%lx,dest=0x%lx,length=%d\n", -++ ulchnn, source, dest, length); -++ -++ while (left_size) { -++ if (left_size >= EDMAC_TRANS_MAXSIZE) -++ dma_size = EDMAC_TRANS_MAXSIZE; -++ else -++ dma_size = left_size; -++ if (dmac_start_m2m(ulchnn, source + dma_count * dma_size, -++ dest + dma_count * dma_size, dma_size)) { -++ edmacv310_error("dma transfer error...\n"); -++ return -1; -++ } -++ -++ if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) { -++ edmacv310_error("dma transfer error...\n"); -++ return -1; -++ } -++ left_size -= dma_size; -++ dma_count++; -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "left_size is %d.\n", left_size); -++ } -++ -++ return 0; -++} -++EXPORT_SYMBOL(dmac_m2m_transfer); -++ -++/* -++ * memory to memory dma transfer with LLI -++ * -++ * @source -++ * @dest -++ * @length -++ * */ -++int do_dma_llim2m(unsigned long source, -++ unsigned long dest, -++ unsigned long length) -++{ -++ int ret = 0; -++ int chnn; -++ -++ chnn = dmac_channel_allocate(); -++ if (chnn < 0) { -++ ret = -1; -++ goto end; -++ } -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "chnn:%d,src:%lx,dst:%lx,len:%ld.\n", chnn, source, dest, -++ length); -++ -++ if (pllihead[0] == 0) { -++ edmacv310_error("ppheadlli[0] is NULL.\n"); -++ ret = -ENOMEM; -++ goto end; -++ } -++ -++ ret = dmac_buildllim2m(pllihead, source, dest, length, EDMAC_TRANS_MAXSIZE); -++ if (ret) { -++ edmacv310_error("build lli error...\n"); -++ ret = -EIO; -++ goto end; -++ } -++ ret = dmac_start_llim2m(chnn, pllihead); -++ if (ret) { -++ edmacv310_error("start lli error...\n"); -++ ret = -EIO; -++ goto end; -++ } -++ -++end: -++ return ret; -++} -++EXPORT_SYMBOL(do_dma_llim2m); -++ -++/* -++ * alloc_dma_lli_space -++ * output: -++ * ppheadlli[0]: memory physics address -++ * ppheadlli[1]: virtual address -++ * -++ */ -++int allocate_dmalli_space(struct device *dev, unsigned long *ppheadlli, -++ unsigned int page_num) -++{ -++ dma_addr_t dma_phys; -++ void *dma_virt; -++ -++ dma_virt = dma_alloc_coherent(dev, page_num * PAGE_SIZE, -++ &dma_phys, GFP_DMA); -++ if (dma_virt == NULL) { -++ edmacv310_error("can't get dma mem from system\n"); -++ return -1; -++ } -++ -++ ppheadlli[0] = (unsigned long)(dma_phys); -++ ppheadlli[1] = (unsigned long)(dma_virt); -++ -++ if (dma_phys & (EDMAC_LLI_ALIGN - 1)) -++ return -1; -++ -++ return 0; -++} -++EXPORT_SYMBOL(allocate_dmalli_space); -++ -++static int edmac_priv_init(struct edmac_host *edmac, -++ edmac_peripheral *peripheral_info) -++{ -++ struct regmap *misc = edmac->misc_regmap; -++ int i; -++ unsigned int count = 0; -++ unsigned int offset; -++ unsigned ctrl = 0; -++ -++ for (i = 0; i < EDMAC_MAX_PERIPHERALS; i++) { -++ if (peripheral_info[i].host_sel == edmac->id) { -++ if (misc != NULL) { -++ offset = edmac->misc_ctrl_base + (count & (~0x3)); /* config misc reg for signal line */ -++ regmap_read(misc, offset, &ctrl); -++ ctrl &= ~(0x3f << ((count & 0x3) << 3)); -++ ctrl |= peripheral_info[i].peri_id << ((count & 0x3) << 3); -++ regmap_write(misc, offset, ctrl); -++ } -++ peripheral_info[i].dynamic_periphery_num = count; -++ count++; -++ } -++ } -++ -++ return 0; -++} -++ -++static int of_probe_read(struct edmac_host *edmac, struct device_node *np) -++{ -++ int ret; -++ -++ ret = of_property_read_u32(np, -++ "devid", &(edmac->id)); -++ if (ret) { -++ edmacv310_error("get edmac id fail\n"); -++ return -ENODEV; -++ } -++ -++ if (!of_find_property(np, "misc_regmap", NULL) || -++ !of_find_property(np, "misc_ctrl_base", NULL)) { -++ edmac->misc_regmap = 0; -++ } else { -++ edmac->misc_regmap = syscon_regmap_lookup_by_phandle(np, "misc_regmap"); -++ if (IS_ERR(edmac->misc_regmap)) { -++ edmacv310_error("get edmac misc fail\n"); -++ return PTR_ERR(edmac->misc_regmap); -++ } -++ -++ ret = of_property_read_u32(np, -++ "misc_ctrl_base", &(edmac->misc_ctrl_base)); -++ if (ret) { -++ edmacv310_error("get dma-misc_ctrl_base fail\n"); -++ return -ENODEV; -++ } -++ } -++ ret = of_property_read_u32(np, -++ "dma-channels", &(edmac->channels)); -++ if (ret) { -++ edmacv310_error("get dma-channels fail\n"); -++ return -ENODEV; -++ } -++ ret = of_property_read_u32(np, -++ "dma-requests", &(edmac->slave_requests)); -++ if (ret) { -++ edmacv310_error("get dma-requests fail\n"); -++ return -ENODEV; -++ } -++ edmacv310_trace(EDMACV310_TRACE_LEVEL_INFO, "dma-channels = %d, dma-requests = %d\n", -++ edmac->channels, edmac->slave_requests); -++ return 0; -++} -++ -++static int of_probe_get_resource(struct edmac_host *edmac, -++ struct platform_device *platdev) -++{ -++ struct resource *res = NULL; -++ edmac->clk = devm_clk_get(&(platdev->dev), "apb_pclk"); -++ if (IS_ERR(edmac->clk)) { -++ edmacv310_error("get edmac clk fail\n"); -++ return PTR_ERR(edmac->clk); -++ } -++ -++ edmac->axi_clk = devm_clk_get(&(platdev->dev), "axi_aclk"); -++ if (IS_ERR(edmac->axi_clk)) { -++ edmacv310_error("get edmac axi clk fail\n"); -++ return PTR_ERR(edmac->axi_clk); -++ } -++ -++ edmac->rstc = devm_reset_control_get(&(platdev->dev), "dma-reset"); -++ if (IS_ERR(edmac->rstc)) { -++ edmacv310_error("get edmac rstc fail\n"); -++ return PTR_ERR(edmac->rstc); -++ } -++ -++ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); -++ if (res == NULL) { -++ edmacv310_error("no reg resource\n"); -++ return -ENODEV; -++ } -++ -++ edmac->base = devm_ioremap_resource(&(platdev->dev), res); -++ if (IS_ERR(edmac->base)) { -++ edmacv310_error("get edmac base fail\n"); -++ return PTR_ERR(edmac->base); -++ } -++ -++ res = platform_get_resource_byname(platdev, IORESOURCE_MEM, "dma_peri_channel_req_sel"); -++ if (res != NULL) { -++ void *dma_peri_channel_req_sel = ioremap(res->start, res->end - res->start); -++ if (IS_ERR(dma_peri_channel_req_sel)) -++ return PTR_ERR(dma_peri_channel_req_sel); -++ writel(0xffffffff, dma_peri_channel_req_sel); -++ iounmap(dma_peri_channel_req_sel); -++ } -++ return 0; -++} -++ -++static int get_of_probe(struct edmac_host *edmac) -++{ -++ struct platform_device *platdev = edmac->pdev; -++ struct device_node *np = platdev->dev.of_node; -++ int ret; -++ -++ ret = of_probe_read(edmac, np); -++ if (ret) -++ return ret; -++ -++ ret = of_probe_get_resource(edmac, platdev); -++ if (ret) -++ return ret; -++ -++ edmac->irq = platform_get_irq(platdev, 0); -++ if (unlikely(edmac->irq < 0)) -++ return -ENODEV; -++ -++ edmac_priv_init(edmac, (edmac_peripheral *)&g_peripheral); -++ return 0; -++} -++ -++/* Don't need irq mode now */ -++#if defined(CONFIG_EDMAC_INTERRUPT) -++static irqreturn_t emdacv310_irq(int irq, void *dev) -++{ -++ struct edmac_host *edmac = (struct edmac_host *)dev; -++ unsigned int channel_err_status[3]; -++ unsigned int channel_tc_status, channel_status; -++ int i; -++ unsigned int mask = 0; -++ -++ channel_status = edmacv310_readl(edmac->base + EDMAC_INT_STAT); -++ if (!channel_status) { -++ edmacv310_error("channel_status = 0x%x\n", channel_status); -++ return IRQ_NONE; -++ } -++ -++ for (i = 0; i < edmac->channels; i++) { -++ channel_status = (channel_status >> i) & 0x1; -++ if (channel_status) { -++ channel_tc_status = edmacv310_readl(edmac->base + EDMAC_INT_TC1_RAW); -++ channel_tc_status = (channel_tc_status >> i) & 0x01; -++ if (channel_tc_status) -++ edmacv310_writel(channel_tc_status << i, edmac->base + EDMAC_INT_TC1_RAW); -++ -++ channel_tc_status = edmacv310_readl(edmac->base + EDMAC_INT_TC2); -++ channel_tc_status = (channel_tc_status >> i) & 0x01; -++ if (channel_tc_status) -++ edmacv310_writel(channel_tc_status << i, edmac->base + EDMAC_INT_TC2_RAW); -++ -++ channel_err_status[0] = edmacv310_readl(edmac->base + EDMAC_INT_ERR1); -++ channel_err_status[0] = (channel_err_status[0] >> i) & 0x01; -++ channel_err_status[1] = edmacv310_readl(edmac->base + EDMAC_INT_ERR2); -++ channel_err_status[1] = (channel_err_status[1] >> i) & 0x01; -++ channel_err_status[2] = edmacv310_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]) { -++ edmacv310_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]); -++ edmacv310_writel(1 << i, edmac->base + EDMAC_INT_ERR1_RAW); -++ edmacv310_writel(1 << i, edmac->base + EDMAC_INT_ERR2_RAW); -++ edmacv310_writel(1 << i, edmac->base + EDMAC_INT_ERR3_RAW); -++ } -++ if ((function[i]) != NULL) -++ function[i](i, g_channel_status[i]); -++ -++ mask |= (1 << i); -++ edmacv310_writel(EDMAC_CX_DISABLE, dma_regbase + edmac_cx_config(i)); -++ edmac_channel_free(i); -++ } -++ } -++ -++ return mask ? IRQ_HANDLED : IRQ_NONE; -++} -++#endif -++ -++static void edmac310_dev_init(const struct edmac_host *edmac) -++{ -++ clk_prepare_enable(edmac->clk); -++ clk_prepare_enable(edmac->axi_clk); -++ -++ reset_control_deassert(edmac->rstc); -++ -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC1_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_TC2_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR1_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR2_RAW); -++ edmacv310_writel(EDMAC_ALL_CHAN_CLR, edmac->base + EDMAC_INT_ERR3_RAW); -++ -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_TC1_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_TC2_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_ERR1_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_ERR2_MASK); -++ edmacv310_writel(EDMAC_INT_ENABLE_ALL_CHAN, -++ edmac->base + EDMAC_INT_ERR3_MASK); -++} -++ -++static int __init edmacv310_probe(struct platform_device *pdev) -++{ -++ int ret = 0; -++ int i = 0; -++ struct edmac_host *edmac = NULL; -++ -++ edmac = kzalloc(sizeof(*edmac), GFP_KERNEL); -++ if (!edmac) { -++ edmacv310_error("malloc for edmac fail!"); -++ ret = -ENOMEM; -++ return ret; -++ } -++ edmac->pdev = pdev; -++ -++ ret = get_of_probe(edmac); -++ if (ret) { -++ edmacv310_error("get dts info fail!"); -++ goto free_edmac; -++ } -++ -++ for (i = 0; i < EDMAC_CHANNEL_NUM; i++) -++ g_channel_status[i] = DMAC_CHN_VACANCY; -++ -++ dma_regbase = edmac->base; -++ -++ ret = allocate_dmalli_space(&(edmac->pdev->dev), pllihead, -++ EDMAC_LLI_PAGE_NUM); -++ if (ret < 0) -++ goto free_edmac; -++ -++#if defined(CONFIG_EDMAC_INTERRUPT) -++ /* register irq if necessary !*/ -++ ret = request_irq(edmac->irq, emdacv310_irq, 0, DRIVER_NAME, edmac); -++ if (ret) { -++ edmacv310_error("fail to request irq"); -++ goto free_edmac; -++ } -++#endif -++ edmac310_dev_init(edmac); -++ return 0; -++ -++free_edmac: -++ kfree(edmac); -++ -++ return ret; -++} -++ -++static int emda_remove(struct platform_device *pdev) -++{ -++ int err = 0; -++ return err; -++} -++ -++static const struct of_device_id edmacv310_match[] = { -++ { .compatible = "vendor,edmacv310_n" }, -++ {}, -++}; -++ -++static struct platform_driver edmacv310_driver = { -++ .remove = emda_remove, -++ .driver = { -++ .name = "edmacv310_n", -++ .of_match_table = edmacv310_match, -++ }, -++}; -++ -++static int __init edmacv310_init(void) -++{ -++ return platform_driver_probe(&edmacv310_driver, edmacv310_probe); -++} -++subsys_initcall(edmacv310_init); -++ -++static void __exit edmacv310_exit(void) -++{ -++ platform_driver_unregister(&edmacv310_driver); -++} -++module_exit(edmacv310_exit); -++ -++MODULE_LICENSE("GPL"); -+diff --git a/drivers/edmac/edmacv310.h b/drivers/edmac/edmacv310.h -+new file mode 100755 -+index 000000000..6275fd931 -+--- /dev/null -++++ b/drivers/edmac/edmacv310.h -+@@ -0,0 +1,175 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __EDMACV310_H__ -++#define __EDMACV310_H__ -++ -++/* debug control */ -++extern int edmacv310_trace_level_n; -++#define EDMACV310_TRACE_LEVEL 5 -++#define EDMACV310_TRACE_LEVEL_INFO 4 -++#define EDMACV310_TRACE_LEVEL_DEBUG 6 -++ -++#define EDMACV310_TRACE_FMT KERN_INFO -++ -++typedef void DMAC_ISR(unsigned int channel, int status); -++ -++#define EDMACV310_32BIT 32 -++#define EDMAC_UPDATE_TIMEOUT (30 * HZ) -++#define EDMAC_TRANS_MAXSIZE (64 * 1024 - 1) -++ -++#ifdef DEBUG_EDMAC -++ -++#define edmacv310_trace(level, msg...) do { \ -++ if ((level) >= edmacv310_trace_level_n) { \ -++ printk(EDMACV310_TRACE_FMT"%s:%d: ", __func__, __LINE__); \ -++ printk(msg); \ -++ printk("\n"); \ -++ } \ -++} while (0) -++ -++ -++#define edmacv310_assert(cond) do { \ -++ if (!(cond)) { \ -++ printk(KERN_ERR "Assert:edmacv310:%s:%d\n", \ -++ __func__, \ -++ __LINE__); \ -++ BUG(); \ -++ } \ -++} while (0) -++ -++#define edmacv310_error(s...) do { \ -++ printk(KERN_ERR "edmacv310:%s:%d: ", __func__, __LINE__); \ -++ printk(s); \ -++ printk("\n"); \ -++} while (0) -++ -++#else -++ -++#define edmacv310_trace(level, msg...) do { } while (0) -++#define edmacv310_assert(level, msg...) do { } while (0) -++#define edmacv310_error(level, msg...) do { } while (0) -++ -++#endif -++ -++#define edmacv310_readl(addr) ((unsigned int)readl((void *)(addr))) -++ -++#define edmacv310_writel(v, addr) do { writel(v, (void *)(addr)); \ -++} while (0) -++ -++ -++#define MAX_TRANSFER_BYTES 0xffff -++ -++#define EDMAC_ERR_REG_NUM 3 -++#define DMAC_FINISHED_WAIT_TIME 10 -++ -++/* 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_CXCONFIG_M2M 0xCFF33000 -++#define EDMAC_CXCONFIG_M2M_LLI 0xCFF00000 -++#define EDMAC_CXCONFIG_CHN_START 0x1 -++#define EDMAC_CX_DISABLE 0x0 -++ -++#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 -++ -++/* DMAC peripheral structure */ -++typedef struct edmac_peripheral { -++ /* peripherial ID */ -++ unsigned int peri_id; -++ /* peripheral data register address */ -++ unsigned long peri_addr; -++ /* config requset */ -++ int host_sel; -++#define DMAC_HOST0 0 -++#define DMAC_HOST1 1 -++#define DMAC_NOT_USE (-1) -++ /* default channel configuration word */ -++ unsigned int transfer_cfg; -++ /* default channel configuration word */ -++ unsigned int transfer_width; -++ unsigned int dynamic_periphery_num; -++} edmac_peripheral; -++ -++ -++#define PERI_ID_OFFSET 4 -++#define EDMA_SRC_WIDTH_OFFSET 16 -++#define EDMA_DST_WIDTH_OFFSET 12 -++#define EDMA_CH_ENABLE 1 -++ -++#define PERI_8BIT_MODE 0 -++#define PERI_16BIT_MODE 1 -++#define PERI_32BIT_MODE 2 -++#define PERI_64BIT_MODE 3 -++ -++#define EDMAC_LLI_PAGE_NUM 0x4 -++#endif -+diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -+index 1af147d8a..303e23e34 100644 -+--- a/drivers/gpio/Makefile -++++ b/drivers/gpio/Makefile -+@@ -117,6 +117,7 @@ obj-$(CONFIG_GPIO_PCH) += gpio-pch.o -+ obj-$(CONFIG_GPIO_PCIE_IDIO_24) += gpio-pcie-idio-24.o -+ obj-$(CONFIG_GPIO_PCI_IDIO_16) += gpio-pci-idio-16.o -+ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o -++obj-$(CONFIG_ARCH_BSP) += vendor/ -+ obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o -+ obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o -+ obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o -+diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c -+index f1b53dd1d..7fbfaa877 100644 -+--- a/drivers/gpio/gpio-pl061.c -++++ b/drivers/gpio/gpio-pl061.c -+@@ -24,6 +24,7 @@ -+ #include -+ #include -+ #include -++#include "vendor/vendor_gpio.h" -+ -+ #define GPIODIR 0x400 -+ #define GPIOIS 0x404 -+@@ -339,11 +340,19 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) -+ girq->parents[0] = irq; -+ girq->default_type = IRQ_TYPE_NONE; -+ girq->handler = handle_bad_irq; -+- -++#ifdef CONFIG_ARCH_BSP -++ ret = vendor_gpio_init_clk_and_base(adev, &pl061->gc, pl061->base); -++ if (ret) -++ return ret; -++#endif -+ ret = devm_gpiochip_add_data(dev, &pl061->gc, pl061); -+ if (ret) -+ return ret; -+- -++#ifdef CONFIG_ARCH_BSP -++ ret = vendor_gpio_init_irq(adev, &pl061->gc, pl061->base); -++ if (ret) -++ return ret; -++#endif -+ amba_set_drvdata(adev, pl061); -+ dev_info(dev, "PL061 GPIO chip registered\n"); -+ -+diff --git a/drivers/gpio/vendor/Makefile b/drivers/gpio/vendor/Makefile -+new file mode 100755 -+index 000000000..a46d67937 -+--- /dev/null -++++ b/drivers/gpio/vendor/Makefile -+@@ -0,0 +1 @@ -++obj-$(CONFIG_ARCH_BSP) += vendor_gpio.o -+diff --git a/drivers/gpio/vendor/vendor_gpio.c b/drivers/gpio/vendor/vendor_gpio.c -+new file mode 100755 -+index 000000000..ab8d357c2 -+--- /dev/null -++++ b/drivers/gpio/vendor/vendor_gpio.c -+@@ -0,0 +1,92 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "vendor_gpio.h" -++ -++struct gpio_vendor_irq_data { -++ void __iomem *base; -++ struct gpio_chip *gc; -++}; -++ -++irqreturn_t vendor_gpio_irq_handler(int irq, void *data) -++{ -++ unsigned long pending; -++ int offset; -++ struct gpio_vendor_irq_data *vendor_irq_data = data; -++ struct gpio_chip *gc = vendor_irq_data->gc; -++ -++ pending = readb(vendor_irq_data->base + VENDOR_GPIOMIS); -++ writeb(pending, vendor_irq_data->base + VENDOR_GPIOIC); -++ if (pending) { -++ for_each_set_bit(offset, &pending, VENDOR_GPIO_NR) -++ generic_handle_irq(irq_find_mapping(gc->irq.domain, -++ offset)); -++ } -++ -++ return IRQ_HANDLED; -++} -++ -++int vendor_gpio_init_clk_and_base(struct amba_device *adev, struct gpio_chip *gc, -++ void __iomem *base) -++{ -++ int ret, gpio_idx; -++ struct clk *clk; -++ struct device *dev = &adev->dev; -++ struct gpio_irq_chip *girq = &gc->irq; -++ -++ clk = devm_clk_get(dev, NULL); -++ if (IS_ERR(clk)) { -++ dev_warn(dev, "The GPIO clock automatic enable not support\n"); -++ } else { -++ ret = clk_prepare_enable(clk); -++ if (ret) { -++ dev_warn(dev, "The GPIO clock request failed\n"); -++ return ret; -++ } -++ } -++ -++ if (dev->of_node) { -++ gpio_idx = of_alias_get_id(dev->of_node, "gpio"); -++ if (gpio_idx < 0) -++ return -ENOMEM; -++ gc->base = gpio_idx * VENDOR_GPIO_NR; -++ } -++ -++ if (gc->base < 0) -++ gc->base = -1; -++ -++ writeb(0, base + VENDOR_GPIOIE); /* disable irqs */ -++ -++ girq->parent_handler = (irq_flow_handler_t)vendor_gpio_irq_handler; -++ devm_kfree(dev, girq->parents); -++ girq->num_parents = 0; -++ -++ return 0; -++} -++ -++int vendor_gpio_init_irq(struct amba_device *adev, struct gpio_chip *gc, -++ void __iomem *base) -++{ -++ int ret, gpio_idx; -++ struct device *dev = &adev->dev; -++ struct gpio_vendor_irq_data *vendor_irq_data = NULL; -++ -++ vendor_irq_data = devm_kzalloc(dev, sizeof(struct gpio_vendor_irq_data), GFP_KERNEL); -++ if (vendor_irq_data == NULL) -++ return -ENOMEM; -++ -++ vendor_irq_data->base = base; -++ vendor_irq_data->gc = gc; -++ -++ ret = devm_request_irq(dev, adev->irq[0], vendor_gpio_irq_handler, IRQF_SHARED, -++ dev_name(dev), vendor_irq_data); -++ if (ret) { -++ dev_info(dev, "request irq failed: %d\n", ret); -++ return ret; -++ } -++ -++ for (gpio_idx = 0; gpio_idx < gc->ngpio; gpio_idx++) -++ irq_set_parent(irq_find_mapping(gc->irq.domain, gpio_idx), adev->irq[0]); -++ -++ return 0; -++} -+diff --git a/drivers/gpio/vendor/vendor_gpio.h b/drivers/gpio/vendor/vendor_gpio.h -+new file mode 100755 -+index 000000000..119a5c6bf -+--- /dev/null -++++ b/drivers/gpio/vendor/vendor_gpio.h -+@@ -0,0 +1,27 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#ifndef __VENDOR_LINUX_GPIO_H -++#define __VENDOR_LINUX_GPIO_H -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define VENDOR_GPIO_NR 8 -++#define VENDOR_GPIOIE 0x410 -++#define VENDOR_GPIOMIS 0x418 -++#define VENDOR_GPIOIC 0x41C -++ -++int vendor_gpio_init_clk_and_base(struct amba_device *adev, struct gpio_chip *gc, -++ void __iomem *base); -++int vendor_gpio_init_irq(struct amba_device *adev, struct gpio_chip *gc, -++ void __iomem *base); -++ -++#endif /* __VENDOR_LINUX_GPIO_H */ -+diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile -+index c1d493dc9..64d70e8f8 100644 -+--- a/drivers/i2c/Makefile -++++ b/drivers/i2c/Makefile -+@@ -12,6 +12,7 @@ i2c-core-$(CONFIG_OF) += i2c-core-of.o -+ -+ obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o -+ obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o -++obj-$(CONFIG_ARCH_BSP) += vendor/ -+ obj-$(CONFIG_I2C_MUX) += i2c-mux.o -+ obj-y += algos/ busses/ muxes/ -+ obj-$(CONFIG_I2C_STUB) += i2c-stub.o -+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -+index d3f48f616..97ab0d994 100644 -+--- a/drivers/i2c/busses/Kconfig -++++ b/drivers/i2c/busses/Kconfig -+@@ -650,6 +650,17 @@ config I2C_GPIO_FAULT_INJECTOR -+ faults to an I2C bus, so another bus master can be stress-tested. -+ This is for debugging. If unsure, say 'no'. -+ -++if ARCH_BSP -++config I2C_BSP -++ tristate "Vendor I2C Controller" -++ help -++ Say Y here to include support for Vendor I2C controller in the -++ Vendor SoCs. -++ -++ This driver can also be built as a module. If so, the module -++ will be called i2c-bsp. -++endif -++ -+ config I2C_HIGHLANDER -+ tristate "Highlander FPGA SMBus interface" -+ depends on SH_HIGHLANDER || COMPILE_TEST -+@@ -1449,4 +1460,22 @@ config I2C_FSI -+ This driver can also be built as a module. If so, the module will be -+ called as i2c-fsi. -+ -++if ARCH_BSP -++config DMA_MSG_MIN_LEN -++ int "Vendor I2C support DMA minimum LEN" -++ depends on I2C_BSP -++ 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 "Vendor I2C support DMA maximum LEN" -++ depends on I2C_BSP -++ 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; -++endif # ARCH_BSP -+ endmenu -+diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -+index 280e05622..bbfaca133 100644 -+--- a/drivers/i2c/busses/Makefile -++++ b/drivers/i2c/busses/Makefile -+@@ -67,6 +67,9 @@ obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o -+ obj-$(CONFIG_I2C_EMEV2) += i2c-emev2.o -+ obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o -+ obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_I2C_BSP) += i2c-bsp.o -++endif -+ obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o -+ obj-$(CONFIG_I2C_HISI) += i2c-hisi.o -+ obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o -+diff --git a/drivers/i2c/busses/i2c-bsp.c b/drivers/i2c/busses/i2c-bsp.c -+new file mode 100755 -+index 000000000..05ba30c97 -+--- /dev/null -++++ b/drivers/i2c/busses/i2c-bsp.c -+@@ -0,0 +1,1536 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#if defined(CONFIG_EDMAC) -++#include -++#include -++ -++/* -++ * In the case of enable edmacv310_n, msg->buf must be continuous memory, for DMA processing. -++ * Mostly dma_xfer_* have to handle the uncontinuous memory. So i2c_bsp allocate -++ * continuous memory for msg->buf and use highmem_buf_list to manage msg->buf allocated by i2c_bsp. -++ */ -++struct highmem_buf_list_node { -++ __u8 *buf; -++ __u8 *highmem_buf; -++ struct i2c_msg *msg; -++ struct list_head node; -++}; -++ -++static LIST_HEAD(highmem_buf_list); -++ -++static struct highmem_buf_list_node *search_in_highmem_buf_list(struct i2c_msg *msg) -++{ -++ struct highmem_buf_list_node *highmem_buf_node = NULL; -++ struct highmem_buf_list_node *_highmem_buf_node = NULL; -++ -++ list_for_each_entry_safe(highmem_buf_node, _highmem_buf_node, &highmem_buf_list, node) { -++ if (highmem_buf_node->msg == msg) { -++ return highmem_buf_node; -++ } -++ } -++ return NULL; -++} -++#endif -++ -++#ifdef DEBUG_BSP_I2C -++#define debug_dump_i2c_msg(msg) \ -++ do { \ -++ printk("%s::%d\n", __FILE__, __LINE__); \ -++ dump_i2c_msg(msg); \ -++ } while (0) -++ -++static void dump_i2c_msg(struct i2c_msg *msg) -++{ -++ int i = 0; -++ printk("msg->addr: %u\n", (unsigned int)msg->addr); -++ printk("msg->flags:%u\n", (unsigned int)msg->flags); -++ printk("msg->len: %u\n", (unsigned int)msg->len); -++ for (; i < msg->len; i++) { -++ printk("%d %x\n", i, msg->buf[i]); -++ } -++} -++#else -++#define debug_dump_i2c_msg(msg) -++#endif -++ -++/* -++ * I2C Registers offsets -++ */ -++#define BSP_I2C_GLB 0x0 -++#define BSP_I2C_SCL_H 0x4 -++#define BSP_I2C_SCL_L 0x8 -++#define BSP_I2C_DATA1 0x10 -++#define BSP_I2C_TXF 0x20 -++#define BSP_I2C_RXF 0x24 -++#define BSP_I2C_CMD_BASE 0x30 -++#define BSP_I2C_LOOP1 0xb0 -++#define BSP_I2C_DST1 0xb4 -++#define BSP_I2C_LOOP2 0xb8 -++#define BSP_I2C_DST2 0xbc -++#define BSP_I2C_TX_WATER 0xc8 -++#define BSP_I2C_RX_WATER 0xcc -++#define BSP_I2C_CTRL1 0xd0 -++#define BSP_I2C_CTRL2 0xd4 -++#define BSP_I2C_STAT 0xd8 -++#define BSP_I2C_INTR_RAW 0xe0 -++#define BSP_I2C_INTR_EN 0xe4 -++#define BSP_I2C_INTR_STAT 0xe8 -++ -++/* -++ * I2C Global Config Register -- BSP_I2C_GLB -++ */ -++#define GLB_EN_MASK BIT(0) -++#define GLB_SDA_HOLD_MASK GENMASK(23, 8) -++#define GLB_SDA_HOLD_SHIFT (8) -++#define should_copy_to_continuous_mem(addr) true -++ -++/* -++ * I2C Timing CMD Register -- BSP_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_JMP2 0x19 -++#define CMD_UP_TXF 0x1d -++#define CMD_TX_RS 0x1e -++#define CMD_TX_P 0x1f -++ -++/* -++ * I2C Control Register 1 -- BSP_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 -- BSP_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 -- -++ * BSP_I2C_INTR_RAW, BSP_I2C_STAT, BSP_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 bsp_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; -++ int msg_num; -++ int msg_idx; -++ unsigned int msg_buf_ptr; -++ struct completion msg_complete; -++ -++ spinlock_t lock; -++ int status; -++}; -++static inline void bsp_i2c_disable(const struct bsp_i2c_dev *i2c); -++static inline void bsp_i2c_cfg_irq(const struct bsp_i2c_dev *i2c, -++ unsigned int flag); -++static inline unsigned int bsp_i2c_clr_irq(const struct bsp_i2c_dev *i2c); -++static inline void bsp_i2c_enable(const struct bsp_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 bsp_i2c_rescue(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int val; -++ unsigned int time_cnt; -++ int index; -++ -++ bsp_i2c_disable(i2c); -++ bsp_i2c_cfg_irq(i2c, 0); -++ bsp_i2c_clr_irq(i2c); -++ -++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | -++ (0x1 << FORCE_SDA_OEN_SHIFT); -++ writel(val, i2c->base + BSP_I2C_CTRL2); -++ -++ time_cnt = 0; -++ do { -++ for (index = 0; index < 9; index++) { /* Cycle ten times */ -++ val = (0x1 << GPIO_MODE_SHIFT) | 0x1; -++ writel(val, i2c->base + BSP_I2C_CTRL2); -++ -++ udelay(5); /* delay 5 us */ -++ -++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | -++ (0x1 << FORCE_SDA_OEN_SHIFT); -++ writel(val, i2c->base + BSP_I2C_CTRL2); -++ -++ udelay(5); /* delay 5 us */ -++ } -++ -++ time_cnt++; -++ if (time_cnt > I2C_WAIT_TIMEOUT) { -++ dev_err(i2c->dev, "wait Timeout!\n"); -++ goto disable_rescue; -++ } -++ -++ val = readl(i2c->base + BSP_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 + BSP_I2C_CTRL2); -++ -++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT); -++ writel(val, i2c->base + BSP_I2C_CTRL2); -++ -++ udelay(10); /* delay 10 us */ -++ -++ val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) | -++ (0x1 << FORCE_SDA_OEN_SHIFT); -++ writel(val, i2c->base + BSP_I2C_CTRL2); -++ -++disable_rescue: -++ val = (0x1 << FORCE_SCL_OEN_SHIFT) | 0x1; -++ writel(val, i2c->base + BSP_I2C_CTRL2); -++} -++ -++static inline void bsp_i2c_disable(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int val; -++ -++ val = readl(i2c->base + BSP_I2C_GLB); -++ val &= ~GLB_EN_MASK; -++ writel(val, i2c->base + BSP_I2C_GLB); -++} -++ -++static inline void bsp_i2c_enable(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int val; -++ -++ val = readl(i2c->base + BSP_I2C_GLB); -++ val |= GLB_EN_MASK; -++ writel(val, i2c->base + BSP_I2C_GLB); -++} -++ -++static inline void bsp_i2c_cfg_irq(const struct bsp_i2c_dev *i2c, -++ unsigned int flag) -++{ -++ writel(flag, i2c->base + BSP_I2C_INTR_EN); -++} -++ -++static void bsp_i2c_disable_irq(const struct bsp_i2c_dev *i2c, -++ unsigned int flag) -++{ -++ unsigned int val; -++ -++ val = readl(i2c->base + BSP_I2C_INTR_EN); -++ val &= ~flag; -++ writel(val, i2c->base + BSP_I2C_INTR_EN); -++} -++ -++static unsigned int bsp_i2c_clr_irq(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int val; -++ -++ val = readl(i2c->base + BSP_I2C_INTR_STAT); -++ writel(INTR_ALL_MASK, i2c->base + BSP_I2C_INTR_RAW); -++ -++ return val; -++} -++ -++static inline void bsp_i2c_cmdreg_set(const struct bsp_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); -++ /* Register bit width */ -++ writel(cmd, i2c->base + BSP_I2C_CMD_BASE + *offset * 4); -++ (*offset)++; -++} -++ -++/* -++ * config i2c slave addr -++ */ -++static void bsp_i2c_set_addr(const struct bsp_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; /* Shift the read flag to the left by eight bits */ -++ -++ /* 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 + BSP_I2C_DATA1); -++} -++ -++/* -++ * Start command sequence -++ */ -++static inline void bsp_i2c_start_cmd(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int val; -++ -++ val = readl(i2c->base + BSP_I2C_CTRL1); -++ val |= CTRL1_CMD_START_MASK; -++ writel(val, i2c->base + BSP_I2C_CTRL1); -++} -++ -++static int bsp_i2c_wait_rx_noempty(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int time_cnt = 0; -++ unsigned int val; -++ -++ do { -++ val = readl(i2c->base + BSP_I2C_STAT); -++ if (val & STAT_RXF_NOE_MASK) -++ return 0; -++ -++ udelay(50); /* delay 50 us */ -++ } while (time_cnt++ < I2C_WAIT_TIMEOUT); -++ -++ bsp_i2c_rescue(i2c); -++ -++ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", -++ readl(i2c->base + BSP_I2C_INTR_RAW), val); -++ return -EIO; -++} -++ -++static int bsp_i2c_wait_tx_nofull(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int time_cnt = 0; -++ unsigned int val; -++ -++ do { -++ val = readl(i2c->base + BSP_I2C_STAT); -++ if (val & STAT_TXF_NOF_MASK) -++ return 0; -++ -++ udelay(50); /* delay 50 us */ -++ } while (time_cnt++ < I2C_WAIT_TIMEOUT); -++ -++ bsp_i2c_rescue(i2c); -++ -++ dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n", -++ readl(i2c->base + BSP_I2C_INTR_RAW), val); -++ return -EIO; -++} -++ -++static int bsp_i2c_wait_idle(const struct bsp_i2c_dev *i2c) -++{ -++ unsigned int time_cnt = 0; -++ unsigned int val; -++ -++ do { -++ val = readl(i2c->base + BSP_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); /* delay 50 us */ -++ } while (time_cnt++ < I2C_WAIT_TIMEOUT); -++ -++ bsp_i2c_rescue(i2c); -++ -++ dev_err(i2c->dev, "wait idle timeout, RIS: 0x%x, SR: 0x%x\n", -++ val, readl(i2c->base + BSP_I2C_STAT)); -++ -++ return -EIO; -++} -++ -++static void bsp_i2c_set_freq(struct bsp_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("bsp_i2c_set_freq:freq can't be zero!"); -++ return; -++ } -++ /* If the frequency band is less than or equal to 100 MHz, the standard mode is used */ -++ 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 + BSP_I2C_SCL_H); -++ writel(val, i2c->base + BSP_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 + BSP_I2C_SCL_H); -++ val = ((clk_rate / 100) * 64) / freq; -++ writel(val, i2c->base + BSP_I2C_SCL_L); -++ } -++ -++ val = readl(i2c->base + BSP_I2C_GLB); -++ val &= ~GLB_SDA_HOLD_MASK; -++ val |= ((0xa << GLB_SDA_HOLD_SHIFT) & GLB_SDA_HOLD_MASK); -++ writel(val, i2c->base + BSP_I2C_GLB); -++} -++ -++/* -++ * set i2c controller TX and RX FIFO water -++ */ -++static inline void bsp_i2c_set_water(const struct bsp_i2c_dev *i2c) -++{ -++ writel(I2C_TXF_WATER, i2c->base + BSP_I2C_TX_WATER); -++ writel(I2C_RXF_WATER, i2c->base + BSP_I2C_RX_WATER); -++} -++ -++/* -++ * initialise the controller, set i2c bus interface freq -++ */ -++static void bsp_i2c_hw_init(struct bsp_i2c_dev *i2c) -++{ -++ bsp_i2c_disable(i2c); -++ bsp_i2c_disable_irq(i2c, INTR_ALL_MASK); -++ bsp_i2c_set_freq(i2c); -++ bsp_i2c_set_water(i2c); -++} -++ -++/* -++ * bsp_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 bsp_i2c_cfg_cmd(const struct bsp_i2c_dev *i2c) -++{ -++ struct i2c_msg *msg = i2c->msg; -++ int offset = 0; -++ -++ if (i2c->msg_idx == 0) -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_S, &offset); -++ else -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset); -++ -++ if (msg->flags & I2C_M_TEN) { -++ if (i2c->msg_idx == 0) { -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); -++ } else { -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); -++ } -++ } else { -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); -++ } -++ -++ if (msg->flags & I2C_M_IGNORE_NAK) -++ bsp_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); -++ else -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); -++ -++ if (msg->flags & I2C_M_RD) { -++ /* The extended address occupies two bytes */ -++ if (msg->len >= 2) { -++ writel(offset, i2c->base + BSP_I2C_DST1); -++ /* The extended address occupies two bytes */ -++ writel(msg->len - 2, i2c->base + BSP_I2C_LOOP1); -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); -++ } -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset); -++ } else { -++ writel(offset, i2c->base + BSP_I2C_DST1); -++ writel(msg->len - 1, i2c->base + BSP_I2C_LOOP1); -++ bsp_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); -++ -++ if (msg->flags & I2C_M_IGNORE_NAK) -++ bsp_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); -++ else -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); -++ -++ bsp_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__); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_P, &offset); -++ } -++ -++ bsp_i2c_cmdreg_set(i2c, CMD_EXIT, &offset); -++} -++ -++static void bsp_i2c_cfg_cmd_mul_reg(struct bsp_i2c_dev *i2c, unsigned int reg_data_width) -++{ -++ struct i2c_msg *msg = i2c->msg; -++ int offset = 0; -++ int i; -++ -++ if (i2c->msg_idx == 0) -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_S, &offset); -++ else -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset); -++ -++ if (msg->flags & I2C_M_TEN) { -++ if (i2c->msg_idx == 0) { -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); -++ } else { -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset); -++ } -++ } else { -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset); -++ } -++ -++ if (msg->flags & I2C_M_IGNORE_NAK) -++ bsp_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); -++ else -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); -++ -++ if (msg->flags & I2C_M_RD) { -++ /* The extended address occupies two bytes */ -++ if (msg->len >= 2) { -++ writel(offset, i2c->base + BSP_I2C_DST1); -++ /* The extended address occupies two bytes */ -++ writel(msg->len - 2, i2c->base + BSP_I2C_LOOP1); -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_JMP1, &offset); -++ } -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset); -++ } else { -++ for (i = 0; i < reg_data_width - 1; i++) { -++ bsp_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset); -++ } -++ bsp_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset); -++ bsp_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset); -++ } -++ -++ bsp_i2c_cmdreg_set(i2c, CMD_TX_P, &offset); -++ if (((msg->len / reg_data_width) - 1) > 0) { -++ writel(0, i2c->base + BSP_I2C_DST2); -++ writel((msg->len / reg_data_width) - 1, i2c->base + BSP_I2C_LOOP2); -++ bsp_i2c_cmdreg_set(i2c, CMD_JMP2, &offset); -++ } -++ bsp_i2c_cmdreg_set(i2c, CMD_EXIT, &offset); -++} -++ -++static inline void check_i2c_send_complete(struct bsp_i2c_dev *i2c) -++{ -++ unsigned int val; -++ val = readl(i2c->base + BSP_I2C_GLB); -++ if (val & GLB_EN_MASK) { -++ bsp_i2c_wait_idle(i2c); -++ bsp_i2c_disable(i2c); -++ } -++} -++ -++#if defined(CONFIG_EDMAC) -++int dma_to_i2c(unsigned long src, unsigned int dst, unsigned int length) -++{ -++ int chan; -++ -++ chan = do_dma_m2p(src, dst, length); -++ if (chan == -1) -++ pr_err("dma_to_i2c error\n"); -++ -++ return chan; -++} -++ -++int i2c_to_dma(unsigned int src, unsigned long dst, -++ unsigned int length) -++{ -++ int chan; -++ -++ chan = do_dma_p2m(dst, src, length); -++ if (chan == -1) -++ pr_err("dma_p2m error...\n"); -++ -++ return chan; -++} -++ -++static int bsp_i2c_do_dma_write(struct bsp_i2c_dev *i2c, -++ unsigned long dma_dst_addr) -++{ -++ int chan, val; -++ int status = 0; -++ struct i2c_msg *msg = i2c->msg; -++ -++ check_i2c_send_complete(i2c); -++ bsp_i2c_set_freq(i2c); -++ writel(0x1, i2c->base + BSP_I2C_TX_WATER); -++ bsp_i2c_enable(i2c); -++ bsp_i2c_clr_irq(i2c); -++ bsp_i2c_set_addr(i2c); -++ bsp_i2c_cfg_cmd(i2c); -++ -++ /* transmit DATA from DMAC to I2C in DMA mode */ -++ chan = dma_to_i2c(dma_dst_addr, (i2c->phybase + BSP_I2C_TXF), -++ msg->len); -++ if (chan == -1) { -++ status = -1; -++ goto fail_0; -++ } -++ -++ val = readl(i2c->base + BSP_I2C_CTRL1); -++ val &= ~CTRL1_DMA_OP_MASK; -++ val |= CTRL1_DMA_W | CTRL1_CMD_START_MASK; -++ writel(val, i2c->base + BSP_I2C_CTRL1); -++ -++ if (dmac_wait(chan) != DMAC_CHN_SUCCESS) { -++ status = -1; -++ goto fail_1; -++ } -++ -++ status = bsp_i2c_wait_idle(i2c); -++ -++fail_1: -++ dmac_channel_free((unsigned int)chan); -++fail_0: -++ bsp_i2c_disable(i2c); -++ -++ return status; -++} -++ -++static int bsp_i2c_do_dma_write_mul_reg(struct bsp_i2c_dev *i2c, -++ unsigned long dma_dst_addr, unsigned int reg_data_width) -++{ -++ int chan; -++ int val = 0; -++ struct i2c_msg *msg = i2c->msg; -++ -++ check_i2c_send_complete(i2c); -++ bsp_i2c_set_freq(i2c); -++ writel(0x1, i2c->base + BSP_I2C_TX_WATER); -++ bsp_i2c_enable(i2c); -++ bsp_i2c_clr_irq(i2c); -++ bsp_i2c_set_addr(i2c); -++ bsp_i2c_cfg_cmd_mul_reg(i2c, reg_data_width); -++ -++ /* transmit DATA from DMAC to I2C in DMA mode */ -++ chan = dma_to_i2c(dma_dst_addr, (i2c->phybase + BSP_I2C_TXF), -++ msg->len); -++ if (chan == -1) -++ return -1; -++ -++ val = readl(i2c->base + BSP_I2C_CTRL1); -++ val &= ~CTRL1_DMA_OP_MASK; -++ val |= CTRL1_DMA_W | CTRL1_CMD_START_MASK; -++ writel(val, i2c->base + BSP_I2C_CTRL1); -++ -++ return 0; -++} -++ -++static int bsp_i2c_do_dma_read(struct bsp_i2c_dev *i2c, -++ unsigned long dma_dst_addr) -++{ -++ int val, chan; -++ int status = 0; -++ struct i2c_msg *msg = i2c->msg; -++ -++ check_i2c_send_complete(i2c); -++ bsp_i2c_set_freq(i2c); -++ writel(0x0, i2c->base + BSP_I2C_RX_WATER); -++ bsp_i2c_enable(i2c); -++ bsp_i2c_clr_irq(i2c); -++ bsp_i2c_set_addr(i2c); -++ bsp_i2c_cfg_cmd(i2c); -++ -++ /* transmit DATA from I2C to DMAC in DMA mode */ -++ chan = i2c_to_dma((i2c->phybase + BSP_I2C_RXF), -++ dma_dst_addr, msg->len); -++ if (chan == -1) { -++ status = -1; -++ goto fail_0; -++ } -++ -++ val = readl(i2c->base + BSP_I2C_CTRL1); -++ val &= ~CTRL1_DMA_OP_MASK; -++ val |= CTRL1_CMD_START_MASK | CTRL1_DMA_R; -++ writel(val, i2c->base + BSP_I2C_CTRL1); -++ -++ if (dmac_wait(chan) != DMAC_CHN_SUCCESS) { -++ status = -1; -++ goto fail_1; -++ } -++ -++ status = bsp_i2c_wait_idle(i2c); -++ -++fail_1: -++ dmac_channel_free((unsigned int)chan); -++fail_0: -++ bsp_i2c_disable(i2c); -++ -++ return status; -++} -++ -++/* -++ * Before the DMA transfer, the buffer allocated in high memory is copied to contiguous memory allocated -++ * by i2c_bsp and managed by the highmem_buf_list. -++ */ -++static int copy_to_continuous_mem(struct bsp_i2c_dev *i2c) -++{ -++ int ret; -++ -++ struct highmem_buf_list_node *highmem_node = NULL; -++ if (should_copy_to_continuous_mem(i2c->msg->buf) && search_in_highmem_buf_list(i2c->msg) == NULL) { -++ highmem_node = (struct highmem_buf_list_node *)kzalloc(sizeof(*highmem_node), GFP_KERNEL | __GFP_ATOMIC); -++ if (highmem_node == NULL) { -++ dev_err(i2c->dev, "Allocate memory fail.\n"); -++ return -EINVAL; -++ } -++ -++ highmem_node->msg = i2c->msg; -++ highmem_node->highmem_buf = i2c->msg->buf; -++ i2c->msg->buf = kmalloc(i2c->msg->len, GFP_KERNEL | __GFP_ATOMIC); -++ if (i2c->msg->buf == NULL) { -++ i2c->msg->buf = highmem_node->highmem_buf; -++ kfree(highmem_node); -++ highmem_node = NULL; -++ dev_err(i2c->dev, "Allocate continuous memory fail.\n"); -++ return -EINVAL; -++ } -++ highmem_node->buf = i2c->msg->buf; -++ ret = memcpy_s(highmem_node->buf, i2c->msg->len, -++ highmem_node->highmem_buf, i2c->msg->len); -++ if (ret) { -++ dev_err(i2c->dev, "%s, memcpy_s failed!\n", __func__); -++ kfree(i2c->msg->buf); -++ i2c->msg->buf = NULL; -++ i2c->msg->buf = highmem_node->highmem_buf; -++ highmem_node->buf = NULL; -++ kfree(highmem_node); -++ highmem_node = NULL; -++ return ret; -++ } -++ list_add_tail(&highmem_node->node, &highmem_buf_list); -++ } -++ return 0; -++} -++ -++/* -++ * When the DMA transfer ends, the high memory buf is returned to the -++ * i2c->msg so that the user mode can read and release the buffer, -++ * and the contiguous memory allocated by i2c_bsp will be released. -++ */ -++static void released_contiguous_buf_from_list(struct i2c_msg *msg) -++{ -++ struct highmem_buf_list_node *highmem_node = NULL; -++ int ret; -++ -++ debug_dump_i2c_msg(msg); -++ highmem_node = search_in_highmem_buf_list(msg); -++ if (highmem_node != NULL) { -++ ret = memcpy_s(highmem_node->highmem_buf, msg->len, -++ highmem_node->buf, msg->len); -++ if (ret) { -++ printk("%s, memcpy_s failed\n", __func__); -++ return; -++ } -++ -++ list_del(&highmem_node->node); -++ kfree(highmem_node->buf); -++ msg->buf = highmem_node->highmem_buf; -++ kfree(highmem_node); -++ } -++ -++ debug_dump_i2c_msg(msg); -++} -++ -++static int bsp_i2c_dma_xfer_one_msg(struct bsp_i2c_dev *i2c) -++{ -++ unsigned int status = -EIO; -++ struct i2c_msg *msg = i2c->msg; -++ dma_addr_t dma_dst_addr; -++ -++ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", -++ __func__, __LINE__, msg->flags, msg->len); -++ -++ debug_dump_i2c_msg(msg); -++ if (copy_to_continuous_mem(i2c)) -++ return -EINVAL; -++ -++ debug_dump_i2c_msg(msg); -++ if (msg->flags & I2C_M_RD) { -++ mb(); -++ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, -++ msg->len, DMA_FROM_DEVICE); -++ status = dma_mapping_error(i2c->dev, dma_dst_addr); -++ if (status) { -++ dev_err(i2c->dev, "DMA mapping failed\n"); -++ goto out; -++ } -++ -++ status = bsp_i2c_do_dma_read(i2c, dma_dst_addr); -++ -++ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_FROM_DEVICE); -++ mb(); -++ } else { -++ mb(); -++ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, -++ msg->len, DMA_TO_DEVICE); -++ status = dma_mapping_error(i2c->dev, dma_dst_addr); -++ if (status) { -++ dev_err(i2c->dev, "DMA mapping failed\n"); -++ goto out; -++ } -++ -++ status = bsp_i2c_do_dma_write(i2c, dma_dst_addr); -++ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_TO_DEVICE); -++ mb(); -++ } -++ -++out: -++ released_contiguous_buf_from_list(i2c->msg); -++ if (!status) { -++ status = bsp_i2c_wait_idle(i2c); -++ bsp_i2c_disable(i2c); -++ } -++ -++ return status; -++} -++ -++static int bsp_i2c_dma_xfer_one_msg_mul_reg(struct bsp_i2c_dev *i2c, -++ unsigned int reg_data_width) -++{ -++ unsigned int status = -EIO; -++ struct i2c_msg *msg = i2c->msg; -++ dma_addr_t dma_dst_addr; -++ -++ dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n", -++ __func__, __LINE__, msg->flags, msg->len); -++ -++ if (copy_to_continuous_mem(i2c)) -++ return -EINVAL; -++ -++ if (msg->flags & I2C_M_RD) { -++ debug_dump_i2c_msg(i2c->msg); -++ mb(); -++ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, -++ msg->len, DMA_FROM_DEVICE); -++ status = dma_mapping_error(i2c->dev, dma_dst_addr); -++ if (status) { -++ dev_err(i2c->dev, "DMA mapping failed\n"); -++ goto out; -++ } -++ -++ status = bsp_i2c_do_dma_read(i2c, dma_dst_addr); -++ -++ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_FROM_DEVICE); -++ mb(); -++ } else { -++ mb(); -++ dma_dst_addr = dma_map_single(i2c->dev, msg->buf, -++ msg->len, DMA_TO_DEVICE); -++ status = dma_mapping_error(i2c->dev, dma_dst_addr); -++ if (status) { -++ dev_err(i2c->dev, "DMA mapping failed\n"); -++ goto out; -++ } -++ -++ status = bsp_i2c_do_dma_write_mul_reg(i2c, dma_dst_addr, reg_data_width); -++ dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_TO_DEVICE); -++ mb(); -++ debug_dump_i2c_msg(i2c->msg); -++ } -++ -++out: -++ released_contiguous_buf_from_list(i2c->msg); -++ return status; -++} -++#endif -++static int bsp_i2c_polling_xfer_one_msg(struct bsp_i2c_dev *i2c) -++{ -++ int status = -EIO; -++ 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); -++ -++ check_i2c_send_complete(i2c); -++ bsp_i2c_enable(i2c); -++ bsp_i2c_clr_irq(i2c); -++ bsp_i2c_set_addr(i2c); -++ bsp_i2c_cfg_cmd(i2c); -++ bsp_i2c_start_cmd(i2c); -++ -++ i2c->msg_buf_ptr = 0; -++ -++ if (msg->flags & I2C_M_RD) { -++ while (i2c->msg_buf_ptr < msg->len) { -++ status = bsp_i2c_wait_rx_noempty(i2c); -++ if (status) -++ goto end; -++ -++ val = readl(i2c->base + BSP_I2C_RXF); -++ msg->buf[i2c->msg_buf_ptr] = val; -++ i2c->msg_buf_ptr++; -++ } -++ } else { -++ while (i2c->msg_buf_ptr < msg->len) { -++ status = bsp_i2c_wait_tx_nofull(i2c); -++ if (status) -++ goto end; -++ -++ val = msg->buf[i2c->msg_buf_ptr]; -++ writel(val, i2c->base + BSP_I2C_TXF); -++ i2c->msg_buf_ptr++; -++ } -++ } -++ -++ status = bsp_i2c_wait_idle(i2c); -++end: -++ bsp_i2c_disable(i2c); -++ -++ return status; -++} -++ -++static int bsp_i2c_polling_xfer_one_msg_mul_reg(struct bsp_i2c_dev *i2c, -++ unsigned int reg_data_width) -++{ -++ int status = -EIO; -++ 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); -++ -++ check_i2c_send_complete(i2c); -++ bsp_i2c_enable(i2c); -++ bsp_i2c_clr_irq(i2c); -++ bsp_i2c_set_addr(i2c); -++ bsp_i2c_cfg_cmd_mul_reg(i2c, reg_data_width); -++ bsp_i2c_start_cmd(i2c); -++ -++ i2c->msg_buf_ptr = 0; -++ -++ if (msg->flags & I2C_M_RD) { -++ while (i2c->msg_buf_ptr < msg->len) { -++ status = bsp_i2c_wait_rx_noempty(i2c); -++ if (status) -++ goto end; -++ -++ val = readl(i2c->base + BSP_I2C_RXF); -++ msg->buf[i2c->msg_buf_ptr] = val; -++ i2c->msg_buf_ptr++; -++ } -++ } else { -++ while (i2c->msg_buf_ptr < msg->len) { -++ status = bsp_i2c_wait_tx_nofull(i2c); -++ if (status) -++ goto end; -++ -++ val = msg->buf[i2c->msg_buf_ptr]; -++ writel(val, i2c->base + BSP_I2C_TXF); -++ i2c->msg_buf_ptr++; -++ } -++ } -++ -++end: -++ return status; -++} -++ -++static irqreturn_t bsp_i2c_isr(int irq, void *dev_id) -++{ -++ struct bsp_i2c_dev *i2c = dev_id; -++ unsigned int irq_status; -++ struct i2c_msg *msg = i2c->msg; -++ -++ spin_lock(&i2c->lock); -++ -++ irq_status = bsp_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; -++ bsp_i2c_disable_irq(i2c, INTR_ALL_MASK); -++ -++ complete(&i2c->msg_complete); -++ goto end; -++ } -++ -++ if (msg->flags & I2C_M_RD) { -++ while ((readl(i2c->base + BSP_I2C_STAT) & STAT_RXF_NOE_MASK) -++ && (i2c->msg_buf_ptr < msg->len)) { -++ msg->buf[i2c->msg_buf_ptr] = -++ readl(i2c->base + BSP_I2C_RXF); -++ i2c->msg_buf_ptr++; -++ } -++ } else { -++ while ((readl(i2c->base + BSP_I2C_STAT) & STAT_TXF_NOF_MASK) -++ && (i2c->msg_buf_ptr < msg->len)) { -++ writel(msg->buf[i2c->msg_buf_ptr], -++ i2c->base + BSP_I2C_TXF); -++ i2c->msg_buf_ptr++; -++ } -++ } -++ -++ if (i2c->msg_buf_ptr >= msg->len) -++ bsp_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; -++ bsp_i2c_disable_irq(i2c, INTR_ALL_MASK); -++ -++ complete(&i2c->msg_complete); -++ } -++ -++end: -++ spin_unlock(&i2c->lock); -++ -++ return IRQ_HANDLED; -++} -++ -++static int bsp_i2c_interrupt_xfer_one_msg(struct bsp_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); -++ check_i2c_send_complete(i2c); -++ bsp_i2c_enable(i2c); -++ bsp_i2c_clr_irq(i2c); -++ if (msg->flags & I2C_M_RD) -++ bsp_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_TX_MASK); -++ else -++ bsp_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_RX_MASK); -++ -++ bsp_i2c_set_addr(i2c); -++ bsp_i2c_cfg_cmd(i2c); -++ bsp_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) { -++ bsp_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; -++ } -++ -++ bsp_i2c_disable(i2c); -++ -++ spin_unlock_irqrestore(&i2c->lock, flags); -++ return status; -++} -++ -++/* -++ * Master transfer function -++ */ -++static int bsp_i2c_xfer(struct i2c_adapter *adap, -++ struct i2c_msg *msgs, int num) -++{ -++ struct bsp_i2c_dev *i2c = i2c_get_adapdata(adap); -++ int status = -EINVAL; -++ unsigned long flags; -++ -++ if (msgs == NULL || (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) { -++#if defined(CONFIG_EDMAC) -++ if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) && -++ (i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN)) { -++ status = bsp_i2c_dma_xfer_one_msg(i2c); -++ if (status) -++ break; -++ } else if (i2c->irq >= 0) { -++#else -++ if (i2c->irq >= 0) { -++#endif -++ spin_unlock_irqrestore(&i2c->lock, flags); -++ status = bsp_i2c_interrupt_xfer_one_msg(i2c); -++ spin_lock_irqsave(&i2c->lock, flags); -++ if (status) -++ break; -++ } else { -++ status = bsp_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_break_polling_xfer -++ * -++ * I2c polling independent branch, Shielding interrupt interface -++ */ -++static int bsp_i2c_break_polling_xfer(const struct i2c_adapter *adap, -++ struct i2c_msg *msgs, int num) -++{ -++ struct bsp_i2c_dev *i2c = i2c_get_adapdata(adap); -++ int status = -EINVAL; -++ unsigned long flags; -++ if (msgs == NULL || (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) { -++#if defined(CONFIG_EDMAC) -++ debug_dump_i2c_msg(msgs); -++ -++ if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) && -++ (i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN)) { -++ status = bsp_i2c_dma_xfer_one_msg(i2c); -++ if (status) -++ break; -++ } -++#else -++ status = bsp_i2c_polling_xfer_one_msg(i2c); -++ if (status) -++ break; -++#endif -++ i2c->msg++; -++ i2c->msg_idx++; -++ } -++ if (!status || i2c->msg_idx > 0) -++ status = i2c->msg_idx; -++ spin_unlock_irqrestore(&i2c->lock, flags); -++ return status; -++} -++ -++static int bsp_i2c_mul_reg_xfer(struct i2c_adapter* const adap, -++ struct i2c_msg *msgs, int num, unsigned int reg_data_width) -++{ -++ struct bsp_i2c_dev *i2c = i2c_get_adapdata(adap); -++ int status = -EINVAL; -++ unsigned long flags; -++ if (msgs == NULL || (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) { -++ if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) && -++ (i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN) && (i2c->msg->flags & I2C_M_DMA)) { -++#if defined(CONFIG_EDMAC) && defined(CONFIG_EDMAC_INTERRUPT) -++ status = bsp_i2c_dma_xfer_one_msg_mul_reg(i2c, reg_data_width); -++#endif -++ if (status) -++ break; -++ } else { -++ status = bsp_i2c_polling_xfer_one_msg_mul_reg(i2c, reg_data_width); -++ 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; -++} -++/* I2C READ * -++ * 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 bsp_i2c_master_recv(const struct i2c_client* client, const char* buf, -++ int count) -++{ -++ printk("Wrong interface call" -++ "bsp_i2c_transfer is the only interface to i2c read!!!\n"); -++ -++ return -EIO; -++} -++EXPORT_SYMBOL(bsp_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 bsp_i2c_master_send(const struct i2c_client *client, -++ const char *buf, __u16 count) -++{ -++ struct i2c_adapter *adap = NULL; -++ struct i2c_msg msg; -++ int msgs_count; -++ -++ if ((client == NULL) || (buf == NULL) || (client->adapter == NULL) || -++ (count < 0)) { -++ printk(KERN_ERR "invalid args\n"); -++ return -EINVAL; -++ } -++ -++ if ((client->addr > 0x3ff) || -++ (((client->flags & I2C_M_TEN) == 0) && (client->addr > 0x7f))) { -++ printk(KERN_ERR "dev address out of range\n"); -++ return -EINVAL; -++ } -++ -++ adap = client->adapter; -++ msg.addr = client->addr; -++ msg.flags = client->flags; -++ msg.len = count; -++ -++ msg.buf = (__u8 *)buf; -++ -++ debug_dump_i2c_msg(&msg); -++ -++ msgs_count = bsp_i2c_break_polling_xfer(adap, &msg, 1); -++ -++ return (msgs_count == 1) ? count : -EIO; -++} -++EXPORT_SYMBOL(bsp_i2c_master_send); -++ -++int bsp_i2c_master_send_mul_reg(const struct i2c_client *client, -++ const char *buf, __u16 count, unsigned int reg_data_width) -++{ -++ 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) { -++ printk(KERN_ERR "buf == NULL\n"); -++ return -EINVAL; -++ } -++ msg.buf = (__u8 *)buf; -++ -++ msgs_count = bsp_i2c_mul_reg_xfer(adap, &msg, 1, reg_data_width); -++ -++ return (msgs_count == 1) ? count : -EIO; -++} -++EXPORT_SYMBOL(bsp_i2c_master_send_mul_reg); -++/** -++ * 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 bsp_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 = bsp_i2c_xfer(adap, msgs, num); -++ -++ return msgs_count; -++} -++EXPORT_SYMBOL(bsp_i2c_transfer); -++ -++static u32 bsp_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 bsp_i2c_algo = { -++ .master_xfer = bsp_i2c_xfer, -++ .functionality = bsp_i2c_func, -++}; -++ -++static int bsp_i2c_init_adap(struct i2c_adapter* const adap, struct bsp_i2c_dev* const i2c, -++ struct platform_device* const pdev) -++{ -++ int status; -++ -++ i2c_set_adapdata(adap, i2c); -++ adap->owner = THIS_MODULE; -++ strlcpy(adap->name, "bsp-i2c", sizeof(adap->name)); -++ adap->dev.parent = &pdev->dev; -++ adap->dev.of_node = pdev->dev.of_node; -++ adap->algo = &bsp_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"); -++ -++ return status; -++} -++ -++static void try_deassert_i2c_reset(const struct bsp_i2c_dev *i2c) -++{ -++ struct reset_control *i2c_rst = NULL; -++ -++ i2c_rst = devm_reset_control_get(i2c->dev, "i2c_reset"); -++ if (IS_ERR_OR_NULL(i2c_rst)) -++ return; -++ -++ /* deassert reset if "resets" property is set */ -++ dev_info(i2c->dev, "deassert reset\n"); -++ reset_control_deassert(i2c_rst); -++} -++ -++static int bsp_i2c_probe(struct platform_device *pdev) -++{ -++ int status; -++ struct bsp_i2c_dev *i2c; -++ struct i2c_adapter *adap = NULL; -++ struct resource *res = NULL; -++ -++ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); -++ if (i2c == NULL) -++ 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 == NULL) { -++ 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); -++ -++ try_deassert_i2c_reset(i2c); -++ -++ 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 */ -++ bsp_i2c_hw_init(i2c); -++ -++ i2c->irq = platform_get_irq(pdev, 0); -++ status = devm_request_irq(&pdev->dev, i2c->irq, bsp_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; -++ status = bsp_i2c_init_adap(adap, i2c, pdev); -++ if (status) -++ clk_disable_unprepare(i2c->clk); -++ -++ return status; -++} -++ -++static int bsp_i2c_remove(struct platform_device *pdev) -++{ -++ struct bsp_i2c_dev *i2c = platform_get_drvdata(pdev); -++ -++ clk_disable_unprepare(i2c->clk); -++ i2c_del_adapter(&i2c->adap); -++ -++ return 0; -++} -++ -++#ifdef CONFIG_PM_SLEEP -++static int bsp_i2c_suspend(struct device *dev) -++{ -++ struct bsp_i2c_dev *i2c = dev_get_drvdata(dev); -++ -++ i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); -++ clk_disable_unprepare(i2c->clk); -++ i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); -++ -++ return 0; -++} -++ -++static int bsp_i2c_resume(struct device *dev) -++{ -++ struct bsp_i2c_dev *i2c = dev_get_drvdata(dev); -++ -++ i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); -++ clk_prepare_enable(i2c->clk); -++ bsp_i2c_hw_init(i2c); -++ i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER); -++ -++ return 0; -++} -++#endif -++ -++static SIMPLE_DEV_PM_OPS(bsp_i2c_dev_pm, bsp_i2c_suspend, -++ bsp_i2c_resume); -++ -++static const struct of_device_id bsp_i2c_match[] = { -++ { .compatible = "vendor,i2c" }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, bsp_i2c_match); -++ -++static struct platform_driver bsp_i2c_driver = { -++ .driver = { -++ .name = "bsp-i2c", -++ .of_match_table = bsp_i2c_match, -++ .pm = &bsp_i2c_dev_pm, -++ }, -++ .probe = bsp_i2c_probe, -++ .remove = bsp_i2c_remove, -++}; -++ -++module_platform_driver(bsp_i2c_driver); -++ -++MODULE_DESCRIPTION("I2C Bus driver"); -++MODULE_LICENSE("GPL v2"); -+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c -+index dafad8919..e07a7e609 100644 -+--- a/drivers/i2c/i2c-dev.c -++++ b/drivers/i2c/i2c-dev.c -+@@ -28,6 +28,7 @@ -+ #include -+ #include -+ #include -++#include "vendor/vendor_i2c_dev.h" -+ -+ /* -+ * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a -+@@ -485,6 +486,12 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+ */ -+ client->adapter->timeout = msecs_to_jiffies(arg * 10); -+ break; -++#ifdef CONFIG_ARCH_BSP -++ case I2C_CONFIG_FLAGS: -++ return i2c_config_flags(client, arg); -++ case I2C_CONFIG_MUL_REG: -++ return i2c_config_mul_reg(client, arg); -++#endif -+ default: -+ /* NOTE: returning a fault code here could cause trouble -+ * in buggy userspace code. Some old kernel bugs returned -+diff --git a/drivers/i2c/vendor/Makefile b/drivers/i2c/vendor/Makefile -+new file mode 100755 -+index 000000000..3c19c2a0d -+--- /dev/null -++++ b/drivers/i2c/vendor/Makefile -+@@ -0,0 +1 @@ -++obj-$(CONFIG_ARCH_BSP) += vendor_i2c_dev.o -+diff --git a/drivers/i2c/vendor/vendor_i2c_dev.c b/drivers/i2c/vendor/vendor_i2c_dev.c -+new file mode 100755 -+index 000000000..f671eb674 -+--- /dev/null -++++ b/drivers/i2c/vendor/vendor_i2c_dev.c -+@@ -0,0 +1,72 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include "vendor_i2c_dev.h" -++ -++int i2c_config_flags(struct i2c_client *client, unsigned long arg) -++{ -++ if (arg & I2C_M_16BIT_REG) -++ client->flags |= I2C_M_16BIT_REG; -++ else -++ client->flags &= ~I2C_M_16BIT_REG; -++ -++ if (arg & I2C_M_16BIT_DATA) -++ client->flags |= I2C_M_16BIT_DATA; -++ else -++ client->flags &= ~I2C_M_16BIT_DATA; -++ -++ if (arg & I2C_M_DMA) -++ client->flags |= I2C_M_DMA; -++ else -++ client->flags &= ~I2C_M_DMA; -++ -++ return 0; -++} -++ -++int i2c_config_mul_reg(struct i2c_client *client, unsigned long arg) -++{ -++ int ret; -++ struct i2c_msg msg; -++ unsigned int reg_width; -++ unsigned int data_width; -++ unsigned int reg_data_width; -++ -++ if (copy_from_user(&msg, -++ (struct i2c_msg __user *)arg, -++ sizeof(msg))) -++ return -EFAULT; -++ -++ /* i2c slave dev reg width */ -++ if (client->flags & I2C_M_16BIT_REG) -++ reg_width = 2; -++ else -++ reg_width = 1; -++ -++ /* i2c send data width */ -++ if (client->flags & I2C_M_16BIT_DATA) -++ data_width = 2; -++ else -++ data_width = 1; -++ -++ reg_data_width = reg_width + data_width; -++ -++ msg.buf = memdup_user(msg.buf, msg.len); -++ -++ if (IS_ERR(msg.buf)) { -++ printk(KERN_ERR "dump user fail!!!\n"); -++ return PTR_ERR(msg.buf); -++ } -++ -++ if (msg.len == 0 || reg_data_width > msg.len || msg.len % reg_data_width != 0) { -++ printk(KERN_ERR "msg.len err!!!\n"); -++ kfree(msg.buf); -++ return -EINVAL; -++ } -++ -++ ret = bsp_i2c_master_send_mul_reg(client, msg.buf, msg.len, reg_data_width); -++ -++ kfree(msg.buf); -++ -++ return ret; -++} -+diff --git a/drivers/i2c/vendor/vendor_i2c_dev.h b/drivers/i2c/vendor/vendor_i2c_dev.h -+new file mode 100755 -+index 000000000..2997a4a1a -+--- /dev/null -++++ b/drivers/i2c/vendor/vendor_i2c_dev.h -+@@ -0,0 +1,18 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#ifndef __VENDOR_I2C_DEV_H -++#define __VENDOR_I2C_DEV_H -++ -++#include -++#include -++#include -++ -++#define I2C_CONFIG_MUL_REG 0x070c -++#define I2C_CONFIG_FLAGS 0x070d -++ -++int i2c_config_flags(struct i2c_client *client, unsigned long arg); -++ -++int i2c_config_mul_reg(struct i2c_client *client, unsigned long arg); -++ -++#endif /* __VENDOR_I2C_DEV_H */ -+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c -+index 6334f99f1..f9c5fb89a 100644 -+--- a/drivers/media/usb/uvc/uvc_driver.c -++++ b/drivers/media/usb/uvc/uvc_driver.c -+@@ -219,6 +219,13 @@ static struct uvc_format_desc uvc_fmts[] = { -+ .guid = UVC_GUID_FORMAT_HEVC, -+ .fcc = V4L2_PIX_FMT_HEVC, -+ }, -++#ifdef CONFIG_ARCH_BSP -++ { -++ .name = "H.265", -++ .guid = UVC_GUID_FORMAT_H265, -++ .fcc = V4L2_PIX_FMT_H265, -++ }, -++#endif -+ }; -+ -+ /* ------------------------------------------------------------------------ -+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h -+index c75990c09..ce82bb14c 100644 -+--- a/drivers/media/usb/uvc/uvcvideo.h -++++ b/drivers/media/usb/uvc/uvcvideo.h -+@@ -169,6 +169,11 @@ -+ { 'H', 'E', 'V', 'C', 0x00, 0x00, 0x10, 0x00, \ -+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -+ -++#ifdef CONFIG_ARCH_BSP -++#define UVC_GUID_FORMAT_H265 \ -++ { 'H', '2', '6', '5', 0x00, 0x00, 0x10, 0x00, \ -++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} -++#endif -+ -+ /* ------------------------------------------------------------------------ -+ * Driver specific constants. -+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -+index 15680c3c9..e13d00c90 100644 -+--- a/drivers/mfd/Kconfig -++++ b/drivers/mfd/Kconfig -+@@ -520,6 +520,18 @@ config MFD_HI655X_PMIC -+ help -+ Select this option to enable Hisilicon hi655x series pmic driver. -+ -++if ARCH_BSP -++config MFD_BSP_FMC -++ tristate "Vendor Flash Memory Controller" -++ depends on OF -++ select MFD_CORE -++ select REGMAP_MMIO -++ help -++ Select this option to enable the Vendor Flash Memory -++ Controller(FMC) driver. -++endif -++ -++ -+ config HTC_PASIC3 -+ tristate "HTC PASIC3 LED/DS1WM chip support" -+ select MFD_CORE -+diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -+index fb1df45a3..98d40e451 100644 -+--- a/drivers/mfd/Makefile -++++ b/drivers/mfd/Makefile -+@@ -211,6 +211,9 @@ obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o -+ obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o -+ obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o -+ obj-$(CONFIG_MFD_ATMEL_SMC) += atmel-smc.o -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_MFD_BSP_FMC) += bsp_fmc.o -++endif -+ obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o -+ obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o -+ obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o -+diff --git a/drivers/mfd/bsp_fmc.c b/drivers/mfd/bsp_fmc.c -+new file mode 100755 -+index 000000000..c7fbfc830 -+--- /dev/null -++++ b/drivers/mfd/bsp_fmc.c -+@@ -0,0 +1,123 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++unsigned char fmc_cs_user[FMC_MAX_CHIP_NUM]; -++EXPORT_SYMBOL_GPL(fmc_cs_user); -++ -++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 = "vendor,fmc-spi-nor", -++ }, -++ { -++ .name = "bsp_spi_nand", -++ .of_compatible = "vendor,fmc-spi-nand", -++ }, -++ { -++ .name = "bsp_nand", -++ .of_compatible = "vendor,fmc-nand", -++ }, -++}; -++ -++static int bsp_fmc_probe(struct platform_device *pdev) -++{ -++ struct bsp_fmc *fmc = NULL; -++ struct resource *res = NULL; -++ 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(34)); /* 34:Addressing capability of the DMA */ -++ 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 (!fmc->buffer) { -++ WARN_ON(1); -++ return -ENOMEM; -++ } -++ -++ 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 = "vendor,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("Flash Memory Controller Driver"); -+diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c -+index 4383c262b..d1986c553 100644 -+--- a/drivers/mmc/core/bus.c -++++ b/drivers/mmc/core/bus.c -+@@ -157,6 +157,10 @@ static void mmc_bus_shutdown(struct device *dev) -+ struct mmc_host *host = card->host; -+ int ret; -+ -++#ifdef CONFIG_ARCH_BSP -++ if ((host->caps & MMC_CAP_NEEDS_POLL) != 0) -++ __mmc_stop_host(host); -++#endif -+ if (dev->driver && drv->shutdown) -+ drv->shutdown(card); -+ -+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -+index d5ca59bd1..02a7a9b78 100644 -+--- a/drivers/mmc/core/core.c -++++ b/drivers/mmc/core/core.c -+@@ -45,6 +45,9 @@ -+ #include "mmc_ops.h" -+ #include "sd_ops.h" -+ #include "sdio_ops.h" -++#ifdef CONFIG_ARCH_BSP -++#include "core_complement.h" -++#endif -+ -+ /* The max erase timeout, used when host->max_busy_timeout isn't specified */ -+ #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ -+@@ -2302,9 +2305,15 @@ void mmc_rescan(struct work_struct *work) -+ mmc_bus_put(host); -+ -+ mmc_claim_host(host); -++#ifdef CONFIG_ARCH_BSP -++ mmc_set_card_status_uninit(host); -++#endif -+ if (mmc_card_is_removable(host) && host->ops->get_cd && -+ host->ops->get_cd(host) == 0) { -+ mmc_power_off(host); -++#ifdef CONFIG_ARCH_BSP -++ mmc_card_info_save(host); -++#endif -+ mmc_release_host(host); -+ goto out; -+ } -+@@ -2316,8 +2325,19 @@ void mmc_rescan(struct work_struct *work) -+ continue; -+ freq = host->f_max; -+ } -++#ifdef CONFIG_ARCH_BSP -++ if (!mmc_rescan_try_freq(host, max(freq, host->f_min))) { -++ mmc_set_card_status_init(host); -++ mmc_card_info_save(host); -++ break; -++ } else if ((i == (ARRAY_SIZE(freqs) - 1)) || -++ (freqs[i] <= host->f_min)) { -++ mmc_set_card_status_init_fail(host); -++ } -++#else -+ if (!mmc_rescan_try_freq(host, max(freq, host->f_min))) -+ break; -++#endif -+ if (freqs[i] <= host->f_min) -+ break; -+ } -+diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h -+index a6c814fdb..217a3e7b0 100644 -+--- a/drivers/mmc/core/core.h -++++ b/drivers/mmc/core/core.h -+@@ -58,6 +58,10 @@ void mmc_power_off(struct mmc_host *host); -+ void mmc_power_cycle(struct mmc_host *host, u32 ocr); -+ void mmc_set_initial_state(struct mmc_host *host); -+ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); -++#if defined(CONFIG_ARCH_BSP) && defined(CONFIG_MMC_QUICKBOOT) -++int mmc_quick_init_card(struct mmc_host *host, u32 ocr, -++ struct mmc_card *oldcard); -++#endif -+ -+ static inline void mmc_delay(unsigned int ms) -+ { -+diff --git a/drivers/mmc/core/core_complement.h b/drivers/mmc/core/core_complement.h -+new file mode 100755 -+index 000000000..d809d8027 -+--- /dev/null -++++ b/drivers/mmc/core/core_complement.h -+@@ -0,0 +1,29 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2024. All rights reserved. -++ */ -++ -++#ifndef MMC_CORE_CMPLMNT_H -++#define MMC_CORE_CMPLMNT_H -++ -++#include -++ -++inline void mmc_set_card_status_uninit(struct mmc_host *host) -++{ -++ host->card_status = MMC_CARD_UNINIT; -++} -++inline void mmc_set_card_status_init(struct mmc_host *host) -++{ -++ host->card_status = MMC_CARD_INIT; -++} -++inline void mmc_set_card_status_init_fail(struct mmc_host *host) -++{ -++ host->card_status = MMC_CARD_INIT_FAIL; -++} -++inline void mmc_card_info_save(struct mmc_host *host) -++{ -++ if (host->ops->card_info_save) -++ host->ops->card_info_save(host); -++} -++ -++#endif /* MMC_CORE_CMPLMNT_H */ -++ -+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -+index 87807ef01..54a5e4114 100644 -+--- a/drivers/mmc/core/mmc.c -++++ b/drivers/mmc/core/mmc.c -+@@ -1418,7 +1418,9 @@ static int mmc_select_hs400es(struct mmc_card *card) -+ -+ /* Set host controller to HS400 timing and frequency */ -+ mmc_set_timing(host, MMC_TIMING_MMC_HS400); -+- -++#if defined(CONFIG_ARCH_BSP) -++ mmc_set_bus_speed(card); -++#endif -+ /* Controller enable enhanced strobe function */ -+ host->ios.enhanced_strobe = true; -+ if (host->ops->hs400_enhanced_strobe) -+@@ -1527,7 +1529,12 @@ static int mmc_select_timing(struct mmc_card *card) -+ if (!mmc_can_ext_csd(card)) -+ goto bus_speed; -+ -++#ifdef CONFIG_ARCH_BSP -++ if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES && -++ card->host->caps & MMC_CAP_8_BIT_DATA) -++#else -+ if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) -++#endif -+ err = mmc_select_hs400es(card); -+ else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) -+ err = mmc_select_hs200(card); -+@@ -1566,6 +1573,298 @@ static int mmc_hs200_tuning(struct mmc_card *card) -+ return mmc_execute_tuning(card); -+ } -+ -++#if defined(CONFIG_ARCH_BSP) && defined(CONFIG_MMC_QUICKBOOT) -++#include -++#include "../../vendor/mmc/adapter/nebula_quick.h" -++static const struct mmc_bus_ops mmc_ops; -++/* -++ * Handle the detection and initialisation of a card. -++ * -++ * In the case of a resume, "oldcard" will contain the card -++ * we're trying to reinitialise. -++ */ -++int mmc_quick_init_card(struct mmc_host *host, u32 ocr, -++ struct mmc_card *oldcard) -++{ -++ struct mmc_card *card; -++ int err = 0; -++ -++ mmc_claim_host(host); -++ -++ WARN_ON(!host->claimed); -++ -++ mmc_attach_bus(host, &mmc_ops); -++ if (host->ocr_avail_mmc) -++ host->ocr_avail = host->ocr_avail_mmc; -++ -++ /* -++ * Allocate card structure. -++ */ -++ card = mmc_alloc_card(host, &mmc_type); -++ if (IS_ERR(card)) { -++ err = PTR_ERR(card); -++ goto err; -++ } -++ -++ card->ocr = mmc_select_voltage(host, ocr); -++ card->type = MMC_TYPE_MMC; -++ card->rca = 1; -++ err = memset_s(card->raw_cid, sizeof(card->raw_cid), 0x0, sizeof(card->raw_cid)); -++ if (err != 0) { -++ pr_err("memset_s cid failed\n"); -++ goto free_card; -++ } -++ -++ card->raw_cid[0] = MMC_CID_MAGIC; -++ -++ /* For quick boot, csd register can not obtain from device, -++ * should be set to init value. -++ * mmca_vsn[127:126] = 0x4; // support CSD_SPEC_VER_4 -++ * taac_ns[119:112] = 0x7F; // max -++ * taac_clks[111:104] = 0xFF; -++ * max_dtr[103:96] = 0x32; // set to 26MHz -++ * cmdclass[95:84] = 0x21B; // BASIC, BLOCK_READ, BLOCK_WRITE, ERASE, SWITCH -++ * capacity[49:47] = 0x7; // set to max, not used -++ * read_blkbits[83:80] = 0x9; // Block size is 512B -++ * read_partial[79] = 0x0; // not support -++ * write_misalign[78] = 0x0; // not support -++ * read_misalign[77] = 0x0; // not support -++ * dsr_imp[76] = 0x0; // not support -++ * capacity[73:62] = 0xFFF; // set to max, not used -++ * r2w_factor[28:26] = 0x7; -++ * write_blkbits[25:22] = 0x9; // Block size is 512B -++ * write_partial[21] = 0x0; // not support -++ */ -++ card->raw_csd[0] = 0xD0FFFF32; -++ card->raw_csd[1] = 0x435903FF; -++ card->raw_csd[2] = 0xC0038000; -++ card->raw_csd[3] = 0x1E400000; -++ -++ err = mmc_decode_csd(card); -++ if (err) { -++ pr_err("%s: decode csd failed(%d)\n", mmc_hostname(card->host), err); -++ goto free_card; -++ } -++ -++ /* Read extended CSD. */ -++ err = mmc_read_ext_csd(card); -++ if (err) { -++ pr_err("%s: read ext csd failed(%d)\n", mmc_hostname(card->host), err); -++ goto free_card; -++ } -++ -++ /* -++ * If doing byte addressing, check if required to do sector -++ * addressing. Handle the case of <2GB cards needing sector -++ * addressing. See section 8.1 JEDEC Standard JED84-A441; -++ * ocr register has bit 30 set for sector addressing. -++ */ -++ if (ocr & BIT(30)) -++ mmc_card_set_blockaddr(card); -++ -++ /* Erase size depends on CSD and Extended CSD */ -++ mmc_set_erase_size(card); -++ -++ /* Enable ERASE_GRP_DEF. This bit is lost after a reset or power off. */ -++ if (card->ext_csd.rev >= 3) { /* 3: revision */ -++ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -++ EXT_CSD_ERASE_GROUP_DEF, 1, -++ card->ext_csd.generic_cmd6_time); -++ -++ if (err && err != -EBADMSG) -++ goto free_card; -++ -++ if (err != -EBADMSG) { -++ err = 0; -++ /* -++ * Just disable enhanced area off & sz -++ * will try to enable ERASE_GROUP_DEF -++ * during next time reinit -++ */ -++ card->ext_csd.enhanced_area_offset = -EINVAL; -++ card->ext_csd.enhanced_area_size = -EINVAL; -++ } else { -++ card->ext_csd.erase_group_def = 1; -++ /* -++ * enable ERASE_GRP_DEF successfully. -++ * This will affect the erase size, so -++ * here need to reset erase size -++ */ -++ mmc_set_erase_size(card); -++ } -++ } -++ -++ /* -++ * Ensure eMMC user default partition is enabled -++ */ -++ if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { -++ card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; -++ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, -++ card->ext_csd.part_config, -++ card->ext_csd.part_time); -++ if (err && err != -EBADMSG) -++ goto free_card; -++ } -++ -++ /* -++ * Enable power_off_notification byte in the ext_csd register -++ */ -++ if (card->ext_csd.rev >= 6) { /* 6: revision */ -++ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -++ EXT_CSD_POWER_OFF_NOTIFICATION, -++ EXT_CSD_POWER_ON, -++ card->ext_csd.generic_cmd6_time); -++ if (err && err != -EBADMSG) -++ goto free_card; -++ -++ /* -++ * The err can be -EBADMSG or 0, -++ * so check for success and update the flag -++ */ -++ if (!err) -++ card->ext_csd.power_off_notification = EXT_CSD_POWER_ON; -++ } -++ -++ mmc_set_bus_speed(card); -++ -++ /* -++ * Choose the power class with selected bus interface -++ */ -++ mmc_select_powerclass(card); -++ -++ /* -++ * Enable HPI feature (if supported) -++ */ -++ if (card->ext_csd.hpi) { -++ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -++ EXT_CSD_HPI_MGMT, 1, -++ card->ext_csd.generic_cmd6_time); -++ if (err && err != -EBADMSG) -++ goto free_card; -++ if (err) { -++ pr_warn("%s: Enabling HPI failed\n", -++ mmc_hostname(card->host)); -++ card->ext_csd.hpi_en = 0; -++ err = 0; -++ } else { -++ card->ext_csd.hpi_en = 1; -++ } -++ } -++ -++ /* -++ * If cache size is higher than 0, this indicates the existence of cache -++ * and it can be turned on. Note that some eMMCs from Micron has been -++ * reported to need ~800 ms timeout, while enabling the cache after -++ * sudden power failure tests. Let's extend the timeout to a minimum of -++ * DEFAULT_CACHE_EN_TIMEOUT_MS and do it for all cards. -++ */ -++ if (card->ext_csd.cache_size > 0) { -++ unsigned int timeout_ms = MIN_CACHE_EN_TIMEOUT_MS; -++ -++ timeout_ms = max(card->ext_csd.generic_cmd6_time, timeout_ms); -++ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, -++ EXT_CSD_CACHE_CTRL, 1, timeout_ms); -++ if (err && err != -EBADMSG) -++ goto free_card; -++ -++ /* -++ * Only if no error, cache is turned on successfully. -++ */ -++ if (err) { -++ pr_warn("%s: Cache is supported, but failed to turn on (%d)\n", -++ mmc_hostname(card->host), err); -++ card->ext_csd.cache_ctrl = 0; -++ err = 0; -++ } else { -++ card->ext_csd.cache_ctrl = 1; -++ } -++ } -++ -++ /* -++ * Enable Command Queue if supported. Note that Packed Commands cannot -++ * be used with Command Queue. -++ */ -++ card->ext_csd.cmdq_en = false; -++ if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) { -++ err = mmc_cmdq_enable(card); -++ if (err && err != -EBADMSG) -++ goto free_card; -++ if (err) { -++ pr_warn("%s: Enabling CMDQ failed\n", -++ mmc_hostname(card->host)); -++ card->ext_csd.cmdq_support = false; -++ card->ext_csd.cmdq_depth = 0; -++ err = 0; -++ } -++ } -++ /* -++ * In some cases (e.g. RPMB or mmc_test), the Command Queue must be -++ * disabled for a time, so a flag is needed to indicate to re-enable the -++ * Command Queue. -++ */ -++ card->reenable_cmdq = card->ext_csd.cmdq_en; -++ -++ if (card->ext_csd.cmdq_en && !host->cqe_enabled) { -++ err = host->cqe_ops->cqe_enable(host, card); -++ if (err) { -++ pr_err("%s: Failed to enable CQE, error %d\n", -++ mmc_hostname(host), err); -++ } else { -++ host->cqe_enabled = true; -++ pr_info("%s: Command Queue Engine enabled\n", -++ mmc_hostname(host)); -++ } -++ } -++ -++ if (host->caps2 & MMC_CAP2_AVOID_3_3V && -++ host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { -++ pr_err("%s: Host failed to negotiate down from 3.3V\n", -++ mmc_hostname(host)); -++ err = -EINVAL; -++ goto free_card; -++ } -++ -++ if (!oldcard) -++ host->card = card; -++ -++ /* detect card alive */ -++ if (host->bus_ops->alive(host)) { -++ pr_info("%s: card seems dead!\n", mmc_hostname(host)); -++ err = -EINVAL; -++ goto free_card; -++ } -++ -++ mmc_release_host(host); -++ -++ err = mmc_add_card(host->card); -++ if (err) { -++ pr_err("%s: mmc add card failed.\n", mmc_hostname(host)); -++ mmc_claim_host(host); -++ goto free_card; -++ } -++ -++ return 0; -++ -++free_card: -++ if (!oldcard) -++ mmc_remove_card(card); -++ -++ host->card = NULL; -++ -++ mmc_detach_bus(host); -++ -++ /* here only set power mode to MMC_POWER_OFF */ -++ host->ios.power_mode = MMC_POWER_OFF; -++ -++ pr_err("%s: error %d whilst quick initialising MMC card\n", -++ mmc_hostname(host), err); -++err: -++ mmc_release_host(host); -++ return err; -++} -++EXPORT_SYMBOL(mmc_quick_init_card); -++#endif -++ -+ /* -+ * Handle the detection and initialisation of a card. -+ * -+@@ -1580,6 +1879,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, -+ u32 cid[4]; -+ u32 rocr; -+ -++#if defined(CONFIG_ARCH_BSP) && defined(CONFIG_MMC_QUICKBOOT) -++ /* Call here should clear sleep flag */ -++ if (mmc_is_fast_boot(mmc_priv(host))) -++ mmc_reset_init_mode(mmc_priv(host)); -++#endif -++ -+ WARN_ON(!host->claimed); -+ -+ /* Set correct bus mode for MMC before attempting init */ -+@@ -1617,6 +1922,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, -+ goto err; -+ -+ if (oldcard) { -++#if defined(CONFIG_ARCH_BSP) && defined(CONFIG_MMC_QUICKBOOT) -++ /* Fastboot emmc cid is null, next just init only */ -++ err = mmc_save_cid(host, oldcard, cid); -++ if (err != 0) { -++ pr_err("memcpy_s cid failed\n"); -++ goto err; -++ } -++#endif -+ if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { -+ pr_debug("%s: Perhaps the card was replaced\n", -+ mmc_hostname(host)); -+@@ -1910,6 +2223,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, -+ if (!oldcard) -+ host->card = card; -+ -++#if defined(CONFIG_ARCH_BSP) && defined(CONFIG_MMC_QUICKBOOT) -++ mmc_save_parameters(host); -++#endif -++ -+ return 0; -+ -+ free_card: -+diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c -+index 85c2947ed..88b33b2b1 100644 -+--- a/drivers/mmc/core/sdio.c -++++ b/drivers/mmc/core/sdio.c -+@@ -1314,3 +1314,40 @@ int mmc_attach_sdio(struct mmc_host *host) -+ return err; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++/* 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); -++ if (err) -++ goto err; -++ mmc_release_host(host); -++ return 0; -++err: -++ printk("%s: Error resetting SDIO communications: %d\n", -++ mmc_hostname(host), err); -++ mmc_release_host(host); -++ return err; -++} -++EXPORT_SYMBOL(sdio_reset_comm); -++#endif -++ -+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -+index 451c25fc2..6e0e602ef 100644 -+--- a/drivers/mmc/host/Makefile -++++ b/drivers/mmc/host/Makefile -+@@ -10,7 +10,7 @@ armmmci-$(CONFIG_MMC_STM32_SDMMC) += mmci_stm32_sdmmc.o -+ obj-$(CONFIG_MMC_PXA) += pxamci.o -+ obj-$(CONFIG_MMC_MXC) += mxcmmc.o -+ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o -+-obj-$(CONFIG_MMC_SDHCI) += sdhci.o -++obj-$(CONFIG_MMC_SDHCI) += sdhci.o sdhci_complement.o -+ obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o -+ sdhci-pci-y += sdhci-pci-core.o sdhci-pci-o2micro.o sdhci-pci-arasan.o \ -+ sdhci-pci-dwc-mshc.o sdhci-pci-gli.o -+diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c -+index 23cf7912c..f48b66927 100644 -+--- a/drivers/mmc/host/cqhci.c -++++ b/drivers/mmc/host/cqhci.c -+@@ -18,6 +18,9 @@ -+ #include -+ -+ #include "cqhci.h" -++#ifdef CONFIG_ARCH_BSP -++#include "cqhci_complement.h" -++#endif -+ -+ #define DCMD_SLOT 31 -+ #define NUM_SLOTS 32 -+@@ -46,6 +49,11 @@ static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag) -+ -+ static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag) -+ { -++#ifdef CONFIG_ARCH_BSP -++ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT) -++ return cqe_get_trans_desc_dma(cq_host, tag); -++#endif -++ -+ return cq_host->trans_desc_dma_base + -+ (cq_host->mmc->max_segs * tag * -+ cq_host->trans_desc_len); -+@@ -53,6 +61,11 @@ static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag) -+ -+ static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag) -+ { -++#ifdef CONFIG_ARCH_BSP -++ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT) -++ return cqe_get_trans_desc(cq_host, tag); -++#endif -++ -+ return cq_host->trans_desc_base + -+ (cq_host->trans_desc_len * cq_host->mmc->max_segs * tag); -+ } -+@@ -193,8 +206,12 @@ static int cqhci_host_alloc_tdl(struct cqhci_host *cq_host) -+ -+ cq_host->desc_size = cq_host->slot_sz * cq_host->num_slots; -+ -++#ifdef CONFIG_ARCH_BSP -++ cq_host->data_size = cqe_cal_data_size(cq_host); -++#else -+ cq_host->data_size = cq_host->trans_desc_len * cq_host->mmc->max_segs * -+ cq_host->mmc->cqe_qdepth; -++#endif -+ -+ pr_debug("%s: cqhci: desc_size: %zu data_sz: %zu slot-sz: %d\n", -+ mmc_hostname(cq_host->mmc), cq_host->desc_size, cq_host->data_size, -+@@ -267,6 +284,10 @@ static void __cqhci_enable(struct cqhci_host *cq_host) -+ -+ cqhci_writel(cq_host, cq_host->rca, CQHCI_SSC2); -+ -++#ifdef CONFIG_ARCH_BSP -++ cqhci_writel(cq_host, SEND_QSR_INTERVAL, CQHCI_SSC1); -++#endif -++ -+ cqhci_set_irqs(cq_host, 0); -+ -+ cqcfg |= CQHCI_ENABLE; -+@@ -276,7 +297,9 @@ static void __cqhci_enable(struct cqhci_host *cq_host) -+ if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) -+ cqhci_writel(cq_host, 0, CQHCI_CTL); -+ -++#ifndef CONFIG_ARCH_BSP -+ mmc->cqe_on = true; -++#endif -+ -+ if (cq_host->ops->enable) -+ cq_host->ops->enable(mmc); -+@@ -297,7 +320,9 @@ static void __cqhci_disable(struct cqhci_host *cq_host) -+ cqcfg &= ~CQHCI_ENABLE; -+ cqhci_writel(cq_host, cqcfg, CQHCI_CFG); -+ -++#ifndef CONFIG_ARCH_BSP -+ cq_host->mmc->cqe_on = false; -++#endif -+ -+ cq_host->activated = false; -+ } -+@@ -383,6 +408,9 @@ static void cqhci_off(struct mmc_host *mmc) -+ cq_host->ops->post_disable(mmc); -+ -+ mmc->cqe_on = false; -++#ifdef CONFIG_ARCH_BSP -++ cqhci_deactivate(mmc); -++#endif -+ } -+ -+ static void cqhci_disable(struct mmc_host *mmc) -+@@ -474,6 +502,29 @@ static void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end, -+ } -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static void _cqhci_set_tran_desc(struct cqhci_host *cq_host, u8 **desc, -++ dma_addr_t addr, int len, bool end, bool dma64, unsigned int blksz) -++{ -++ int desc_len; -++ -++ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT && -++ addr % SYNOPSYS_DMA_LIMIT + len > SYNOPSYS_DMA_LIMIT) { -++ if ((addr + (unsigned int)len) % SYNOPSYS_DMA_LIMIT < blksz) -++ BUG_ON(1); -++ -++ desc_len = (SYNOPSYS_DMA_LIMIT - addr % SYNOPSYS_DMA_LIMIT); -++ cqhci_set_tran_desc(*desc, addr, desc_len, false, dma64); -++ -++ *desc = *desc + cq_host->trans_desc_len; -++ len -= desc_len; -++ addr += desc_len; -++ } -++ -++ cqhci_set_tran_desc(*desc, addr, len, end, dma64); -++} -++#endif -++ -+ static int cqhci_prep_tran_desc(struct mmc_request *mrq, -+ struct cqhci_host *cq_host, int tag) -+ { -+@@ -500,7 +551,11 @@ static int cqhci_prep_tran_desc(struct mmc_request *mrq, -+ -+ if ((i+1) == sg_count) -+ end = true; -++#ifdef CONFIG_ARCH_BSP -++ _cqhci_set_tran_desc(cq_host, &desc, addr, len, end, dma64, data->blksz); -++#else -+ cqhci_set_tran_desc(desc, addr, len, end, dma64); -++#endif -+ desc += cq_host->trans_desc_len; -+ } -+ -+@@ -951,6 +1006,10 @@ static void cqhci_recovery_start(struct mmc_host *mmc) -+ cq_host->ops->disable(mmc, true); -+ -+ mmc->cqe_on = false; -++ -++#ifdef CONFIG_ARCH_BSP -++ cqhci_deactivate(mmc); -++#endif -+ } -+ -+ static int cqhci_error_from_flags(unsigned int flags) -+diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h -+index 89bf6adbc..b3a4ab93e 100644 -+--- a/drivers/mmc/host/cqhci.h -++++ b/drivers/mmc/host/cqhci.h -+@@ -82,6 +82,14 @@ -+ #define CQHCI_SSC1 0x40 -+ #define CQHCI_SSC1_CBC_MASK GENMASK(19, 16) -+ -++#ifdef CONFIG_ARCH_BSP -++/* -++ * Value n means CQE would send CMD13 during the transfer of data block -++ * BLOCK_CNT-n -++ */ -++#define SEND_QSR_INTERVAL 0x70001 -++#endif -++ -+ /* send status config 2 */ -+ #define CQHCI_SSC2 0x44 -+ -+@@ -138,6 +146,9 @@ -+ #define CQHCI_DAT_ADDR_LO(x) (((x) & 0xFFFFFFFF) << 32) -+ #define CQHCI_DAT_ADDR_HI(x) (((x) & 0xFFFFFFFF) << 0) -+ -++#ifdef CONFIG_ARCH_BSP -++#define SYNOPSYS_DMA_LIMIT 0x8000000 -++#endif -+ struct cqhci_host_ops; -+ struct mmc_host; -+ struct mmc_request; -+@@ -164,6 +175,9 @@ struct cqhci_host { -+ -+ u32 quirks; -+ #define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ 0x1 -++#ifdef CONFIG_ARCH_BSP -++#define CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT 0x2 -++#endif -+ -+ bool enabled; -+ bool halted; -+diff --git a/drivers/mmc/host/cqhci_complement.h b/drivers/mmc/host/cqhci_complement.h -+new file mode 100755 -+index 000000000..9dc23d5a1 -+--- /dev/null -++++ b/drivers/mmc/host/cqhci_complement.h -+@@ -0,0 +1,33 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2024. All rights reserved. -++ */ -++ -++#ifndef MMC_CQHCI_CMPLMNT_H -++#define MMC_CQHCI_CMPLMNT_H -++ -++#include "cqhci.h" -++ -++inline dma_addr_t cqe_get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag) -++{ -++ return cq_host->trans_desc_dma_base + (cq_host->mmc->max_segs * tag * -++ 2 * cq_host->trans_desc_len); /* 2 is double segs size */ -++} -++ -++inline u8 *cqe_get_trans_desc(struct cqhci_host *cq_host, u8 tag) -++{ -++ return cq_host->trans_desc_base + (cq_host->trans_desc_len * -++ cq_host->mmc->max_segs * 2 * tag); /* 2 is double segs size */ -++} -++ -++inline size_t cqe_cal_data_size(struct cqhci_host *cq_host) -++{ -++ if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT) -++ return cq_host->trans_desc_len * cq_host->mmc->max_segs * -++ 2 * cq_host->mmc->cqe_qdepth; /* 2 is double segs size */ -++ else -++ return cq_host->trans_desc_len * cq_host->mmc->max_segs * -++ cq_host->mmc->cqe_qdepth; -++} -++ -++#endif /* MMC_CQHCI_CMPLMNT_H */ -++ -+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c -+index bad01cc68..16acbd3ec 100644 -+--- a/drivers/mmc/host/sdhci.c -++++ b/drivers/mmc/host/sdhci.c -+@@ -32,6 +32,10 @@ -+ #include -+ #include -+ #include -++#ifdef CONFIG_ARCH_BSP -++#include -++#include "sdhci_complement.h" -++#endif -+ -+ #include "sdhci.h" -+ -+@@ -342,6 +346,11 @@ static void sdhci_init(struct sdhci_host *host, int soft) -+ host->reinit_uhs = true; -+ mmc->ops->set_ios(mmc, &mmc->ios); -+ } -++ -++#ifdef CONFIG_ARCH_BSP -++ if (host->ops->init) -++ host->ops->init(host); -++#endif -+ } -+ -+ static void sdhci_reinit(struct sdhci_host *host) -+@@ -1780,6 +1789,10 @@ static void sdhci_finish_command(struct sdhci_host *host) -+ } else { -+ cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE); -+ } -++ -++#ifdef CONFIG_ARCH_BSP -++ sdhci_check_card_resp(host, cmd); -++#endif -+ } -+ -+ if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd) -+@@ -2080,6 +2093,13 @@ void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode, -+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); -+ if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) -+ sdhci_runtime_pm_bus_off(host); -++#ifdef CONFIG_ARCH_BSP -++ /* -++ * Controllers need an extra 100ms delay to ensure power off -++ * completely -++ */ -++ msleep(100); -++#endif -+ } else { -+ /* -+ * Spec says that we should clear the power reg before setting -+@@ -2445,7 +2465,11 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+ } -+ -+ /* Re-enable SD Clock */ -++#ifdef CONFIG_ARCH_BSP -++ sdhci_card_clk_enable(host); -++#else -+ host->ops->set_clock(host, host->clock); -++#endif -+ } else -+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -+ -+@@ -2586,6 +2610,11 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, -+ u16 ctrl; -+ int ret; -+ -++#ifdef CONFIG_ARCH_BSP -++ if (host->ops->signal_voltage_switch) -++ return host->ops->signal_voltage_switch(host, ios); -++#endif -++ -+ /* -+ * Signal Voltage Switching is only applicable for Host Controllers -+ * v3.00 and above. -+@@ -3038,6 +3067,9 @@ static const struct mmc_host_ops sdhci_ops = { -+ .execute_tuning = sdhci_execute_tuning, -+ .card_event = sdhci_card_event, -+ .card_busy = sdhci_card_busy, -++#ifdef CONFIG_ARCH_BSP -++ .card_info_save = sdhci_card_info_save, -++#endif -+ }; -+ -+ /*****************************************************************************\ -+@@ -3159,6 +3191,12 @@ static bool sdhci_request_done(struct sdhci_host *host) -+ } -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++ if ((mrq->data != NULL) && (mrq->data->error != 0) && -++ !host->is_tuning && (host->error_count < S32_MAX)) -++ host->error_count++; -++#endif -++ -+ host->mrqs_done[i] = NULL; -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+@@ -3263,9 +3301,11 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p) -+ */ -+ if (host->pending_reset) -+ return; -++#ifndef CONFIG_ARCH_BSP -+ 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); -++#endif -+ return; -+ } -+ -+@@ -3393,10 +3433,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) -+ if (host->pending_reset) -+ return; -+ -++#ifndef CONFIG_ARCH_BSP -+ 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); -+- -++#endif -+ return; -+ } -+ -+@@ -3499,6 +3540,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) -+ do { -+ DBG("IRQ status 0x%08x\n", intmask); -+ -++#ifdef CONFIG_ARCH_BSP -++ if (((intmask & SDHCI_INT_ERROR) != 0) && !host->is_tuning && -++ (host->error_count < S32_MAX)) -++ host->error_count++; -++#endif -++ -+ if (host->ops->irq) { -+ intmask = host->ops->irq(host, intmask); -+ if (!intmask) -+@@ -3860,10 +3907,12 @@ void sdhci_cqe_enable(struct mmc_host *mmc) -+ { -+ struct sdhci_host *host = mmc_priv(mmc); -+ unsigned long flags; -++#ifndef CONFIG_ARCH_BSP -+ u8 ctrl; -+- -++#endif -+ spin_lock_irqsave(&host->lock, flags); -+ -++#ifndef CONFIG_ARCH_BSP -+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); -+ ctrl &= ~SDHCI_CTRL_DMA_MASK; -+ /* -+@@ -3881,7 +3930,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc) -+ -+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary, 512), -+ SDHCI_BLOCK_SIZE); -+- -++#endif -+ /* Set maximum timeout */ -+ sdhci_set_timeout(host, NULL); -+ -+@@ -4856,6 +4905,10 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) -+ -+ sdhci_disable_card_detection(host); -+ -++#ifdef CONFIG_ARCH_BSP -++ free_irq(host->irq, host); -++#endif -++ -+ mmc_remove_host(mmc); -+ -+ sdhci_led_unregister(host); -+@@ -4865,7 +4918,9 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) -+ -+ sdhci_writel(host, 0, SDHCI_INT_ENABLE); -+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); -++#ifndef CONFIG_ARCH_BSP -+ free_irq(host->irq, host); -++#endif -+ -+ del_timer_sync(&host->timer); -+ del_timer_sync(&host->data_timer); -+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h -+index 4db57c3a8..8deca45f1 100644 -+--- a/drivers/mmc/host/sdhci.h -++++ b/drivers/mmc/host/sdhci.h -+@@ -19,6 +19,10 @@ -+ -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#include "sdhci_complement.h" -++#endif -++ -+ /* -+ * Controller registers -+ */ -+@@ -185,7 +189,11 @@ -+ #define SDHCI_CTRL_UHS_SDR50 0x0002 -+ #define SDHCI_CTRL_UHS_SDR104 0x0003 -+ #define SDHCI_CTRL_UHS_DDR50 0x0004 -++#ifdef CONFIG_ARCH_BSP -++#define SDHCI_CTRL_HS400 0x0007 -++#else -+ #define SDHCI_CTRL_HS400 0x0005 /* Non-standard */ -++#endif -+ #define SDHCI_CTRL_VDD_180 0x0008 -+ #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 -+ #define SDHCI_CTRL_DRV_TYPE_B 0x0000 -+@@ -609,7 +617,11 @@ struct sdhci_host { -+ u32 adma_table_cnt; -+ -+ u64 data_timeout; -+- -++#ifdef CONFIG_ARCH_BSP -++ bool is_tuning; -++ unsigned int error_count; -++ struct card_info c_info; -++#endif -+ unsigned long private[] ____cacheline_aligned; -+ }; -+ -+@@ -657,6 +669,11 @@ struct sdhci_ops { -+ void (*request_done)(struct sdhci_host *host, -+ struct mmc_request *mrq); -+ void (*dump_vendor_regs)(struct sdhci_host *host); -++#ifdef CONFIG_ARCH_BSP -++ void (*init)(struct sdhci_host *host); -++ int (*signal_voltage_switch)(struct sdhci_host *host, -++ struct mmc_ios *ios); -++#endif -+ }; -+ -+ #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS -+diff --git a/drivers/mmc/host/sdhci_complement.c b/drivers/mmc/host/sdhci_complement.c -+new file mode 100755 -+index 000000000..e33a56116 -+--- /dev/null -++++ b/drivers/mmc/host/sdhci_complement.c -+@@ -0,0 +1,66 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2024. All rights reserved. -++ */ -++ -++#include -++#include -++ -++#include "sdhci_complement.h" -++#include "sdhci.h" -++ -++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; -++ int ret; -++ -++ if (card == NULL) { -++ ret = memset_s(c_info, sizeof(struct card_info), 0, sizeof(struct card_info)); -++ if (ret != EOK) -++ pr_err("memset_s c_info failed\n"); -++ 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->enhanced_strobe = mmc->ios.enhanced_strobe; -++ c_info->card_support_clock = mmc->ios.clock; -++ -++ c_info->sd_bus_speed = card->sd_bus_speed; -++ -++ ret = memcpy_s(c_info->ssr, sizeof(c_info->ssr), card->raw_ssr, 64); /* SSR length: 512bit / 8 = 64 byte */ -++ if (ret != EOK) { -++ pr_err("SD Status Reg memcpy_s failed\n"); -++ return ret; -++ } -++ -++ c_info->card_connect = CARD_CONNECT; -++out: -++ return 0; -++} -++ -++void sdhci_check_card_resp(struct sdhci_host *host, struct mmc_command *cmd) -++{ -++ 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 < S32_MAX)) { -++ host->error_count++; -++ cmd->mrq->cmd->error = -EACCES; -++ pr_err("The status of the card is abnormal, cmd->resp[0]: %x", cmd->resp[0]); -++ } -++ } -++} -++ -++void sdhci_card_clk_enable(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); -++} -++ -+diff --git a/drivers/mmc/host/sdhci_complement.h b/drivers/mmc/host/sdhci_complement.h -+new file mode 100755 -+index 000000000..64b714398 -+--- /dev/null -++++ b/drivers/mmc/host/sdhci_complement.h -+@@ -0,0 +1,40 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2024. All rights reserved. -++ */ -++ -++#ifndef MMC_SDHCI_COMPLEMENT_H -++#define MMC_SDHCI_COMPLEMENT_H -++ -++#include -++#include -++#include -++ -++#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 */ -++ -++struct card_info { -++ unsigned int card_type; -++ unsigned char timing; -++ bool enhanced_strobe; -++ 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 mmc_host; -++struct sdhci_host; -++struct mmc_command; -++int sdhci_card_info_save(struct mmc_host *mmc); -++void sdhci_check_card_resp(struct sdhci_host *host, struct mmc_command *cmd); -++void sdhci_card_clk_enable(struct sdhci_host *host); -++ -++#endif /* MMC_SDHCI_COMPLEMENT_H */ -+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile -+index 593d0593a..143cd4cef 100644 -+--- a/drivers/mtd/Makefile -++++ b/drivers/mtd/Makefile -+@@ -26,8 +26,8 @@ obj-$(CONFIG_MTD_SWAP) += mtdswap.o -+ 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/ tests/ -+ -+-obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ -+ obj-$(CONFIG_MTD_UBI) += ubi/ -+ obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ -+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig -+index 4a9aed4f0..8a6601c0c 100644 -+--- a/drivers/mtd/nand/Kconfig -++++ b/drivers/mtd/nand/Kconfig -+@@ -6,7 +6,33 @@ config MTD_NAND_CORE -+ tristate -+ -+ source "drivers/mtd/nand/onenand/Kconfig" -++if ARCH_BSP -++config MTD_SPI_NAND_BSP -++ tristate "Support for SPI NAND controller on Vendor SoCs" -++ depends on MTD_RAW_NAND -++ help -++ Enables support for the SPI NAND device drivers. -++ -++config BSP_NAND_ECC_STATUS_REPORT -++ tristate "Report the ecc status to MTD for Nand Driver" -++ depends on MTD_RAW_NAND && ARCH_BSP -++ 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 BSP_NAND_FS_MAY_NO_YAFFS2 -++ bool "Remove the restraintion of 16bit ecc type on yaffs2 to Vendor" -++ depends on MFD_BSP_FMC -++ default n -++ help -++ The ecc type: 16bit is limited by the Vendor flash memory controller, -++ as the yaffs2 tag of rootfs limits the min size of CTRL len is 28. -++endif -+ source "drivers/mtd/nand/raw/Kconfig" -++if ARCH_BSP -++source "drivers/mtd/nand/fmc100/Kconfig" -++endif -+ source "drivers/mtd/nand/spi/Kconfig" -+ -+ menu "ECC engine support" -+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile -+index 981372953..450b974b6 100644 -+--- a/drivers/mtd/nand/Makefile -++++ b/drivers/mtd/nand/Makefile -+@@ -1,6 +1,9 @@ -+ # SPDX-License-Identifier: GPL-2.0 -+ -+ nandcore-objs := core.o bbt.o -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_MTD_SPI_NAND_FMC100) += fmc100/ -++endif -+ obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o -+ -+ obj-y += onenand/ -+diff --git a/drivers/mtd/nand/fmc100/Kconfig b/drivers/mtd/nand/fmc100/Kconfig -+new file mode 100755 -+index 000000000..7e63baa3a -+--- /dev/null -++++ b/drivers/mtd/nand/fmc100/Kconfig -+@@ -0,0 +1,19 @@ -++# -++# vendor flash memory controller SPI nand device driver version 100 -++# drivers/mtd/nand/fmc100/Kconfig -++# -++ -++if ARCH_BSP -++config MTD_SPI_NAND_FMC100 -++ tristate "Vendor Flash Memory Controller v100 SPI Nand devices support" -++ depends on MFD_BSP_FMC && MTD_SPI_NAND_BSP -++ depends on ARCH_BSP -++ select MISC_FILESYSTEMS -++ select MTD_BLOCK -++ select YAFFS_FS -++ select YAFFS_YAFFS2 -++ help -++ Vendor 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. -++endif -+diff --git a/drivers/mtd/nand/fmc100/Makefile b/drivers/mtd/nand/fmc100/Makefile -+new file mode 100755 -+index 000000000..4077bb6eb -+--- /dev/null -++++ b/drivers/mtd/nand/fmc100/Makefile -+@@ -0,0 +1,29 @@ -++# -++# The Flash Memory Controller v100 Device Driver for vendor -++# -++# Copyright (c) 2016-2017 HiSilicon (Shanghai) 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/fmc100/Makefile -++# -++ -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_MTD_SPI_NAND_FMC100) += fmc100_spi_nand.o -++ -++fmc100_spi_nand-objs := fmc100_os.o fmc100.o fmc_spi_nand_ids.o fmc100_spi_general.o -++endif -+diff --git a/drivers/mtd/nand/fmc100/fmc100.c b/drivers/mtd/nand/fmc100/fmc100.c -+new file mode 100755 -+index 000000000..4c5a829e3 -+--- /dev/null -++++ b/drivers/mtd/nand/fmc100/fmc100.c -+@@ -0,0 +1,1265 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++#include -++#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(const 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 hifmc100_voltage_state_check(unsigned long *clkrate) -++{ -++ int nfc_voltage_state = NFC_3_3_STATA; -++ unsigned int value = 0; -++ void __iomem *sys_ctrl_state_reg = NULL; -++ if (clkrate == NULL) { -++ return; -++ } -++ if ((*clkrate) <= (u_long)clk_fmc_to_crg_mhz(NFC_CLK_75MHZ)) { -++ return; -++ } -++ sys_ctrl_state_reg = (void *)ioremap(SYS_CTRL_REG_BASE + SYS_CTRL_STATE_OFF, SYS_CTRL_STATE_SIZE); -++ if (sys_ctrl_state_reg == NULL) { -++ fmc_pr(PM_DBG, "|-ERR:sys state ioremap fail\n"); -++ return; -++ } -++ value = readl(sys_ctrl_state_reg); -++ if (((value >> NFC_STATE_BIT_OFF) & NFC_STATA_MASK) == NFC_1_8_STATA) { -++ nfc_voltage_state = NFC_1_8_STATA; -++ fmc_pr(PM_DBG, "|-nfc voltage is 1.8v\n"); -++ } -++ if ((nfc_voltage_state == NFC_1_8_STATA) && \ -++ (*clkrate > (u_long)clk_fmc_to_crg_mhz(NFC_CLK_75MHZ))) { -++ *clkrate = (u_long)clk_fmc_to_crg_mhz(NFC_CLK_75MHZ); -++ fmc_pr(PM_DBG, "|-nfc clk is set to 75MHZ\n"); -++ } -++ iounmap(sys_ctrl_state_reg); -++} -++ -++static void fmc100_operation_config(struct fmc_host *host, int op) -++{ -++ int ret; -++ unsigned long 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; -++ } -++ -++ hifmc100_voltage_state_check(&clkrate); -++ -++ ret = clk_set_rate(host->clk, clkrate); -++ if (WARN_ON((ret != 0))) -++ pr_err("clk_set_rate failed: %d\n", ret); -++} -++ -++static void fmc100_dma_wr_addr_config(struct fmc_host *host) -++{ -++ unsigned int reg; -++ -++#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) >> -++ FMC_DMA_BIT_SHIFT_LENTH; -++ 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) >> -++ FMC_DMA_BIT_SHIFT_LENTH; -++ 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 -++} -++ -++static void fmc100_dma_wr_op_config(struct fmc_host *host, const struct fmc_spi *spi) -++{ -++ unsigned int reg; -++ unsigned int block_num; -++ unsigned int block_num_h; -++ unsigned int page_num; -++ unsigned char pages_per_block_shift; -++ struct nand_chip *chip = host->chip; -++ -++ 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; -++ -++ fmc100_dma_wr_addr_config(host); -++ -++ 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); -++} -++ -++static void fmc100_send_cmd_write(struct fmc_host *host) -++{ -++ int ret; -++ struct fmc_spi *spi = host->spi; -++#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); -++ -++ ret = spi->driver->wait_ready(spi); -++ if (ret) { -++ db_msg("Error: %s program wait ready failed! status: %#x\n", -++ op, ret); -++ goto end; -++ } -++ -++ ret = spi->driver->write_enable(spi); -++ if (ret) { -++ db_msg("Error: %s program write enable failed! ret: %#x\n", -++ op, ret); -++ goto end; -++ } -++ -++ fmc100_dma_wr_op_config(host, spi); -++ -++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) -++{ -++ u_char status; -++ int ret; -++ unsigned char addr = STATUS_ADDR; -++ struct fmc_spi *spi = NULL; -++ -++ if (host == NULL || host->spi == NULL) { -++ db_msg("Error: host or host->spi is NULL!\n"); -++ return; -++ } -++ spi = host->spi; -++ if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) -++ addr = PROTECT_ADDR; -++ -++ ret = spi_nand_feature_op(spi, GET_OP, addr, &status); -++ if (ret) -++ return; -++ fmc_pr((ER_DBG || WR_DBG), "\t*-Get status[%#x]: %#x\n", addr, status); -++} -++ -++static void fmc100_dma_rd_addr_config(struct fmc_host *host) -++{ -++ unsigned int 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) >> -++ FMC_DMA_BIT_SHIFT_LENTH; -++ 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) >> -++ FMC_DMA_BIT_SHIFT_LENTH; -++ 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 -++} -++ -++static void fmc100_dma_rd_op_config(struct fmc_host *host, const struct fmc_spi *spi) -++{ -++ unsigned int reg; -++ unsigned int block_num; -++ unsigned int block_num_h; -++ unsigned int page_num; -++ unsigned char pages_per_block_shift; -++ struct nand_chip *chip = host->chip; -++ -++ 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) -++ 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); -++ -++ 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(RD_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg); -++ -++ fmc100_dma_rd_addr_config(host); -++ -++ 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); -++} -++ -++static void fmc100_send_cmd_read(struct fmc_host *host) -++{ -++ struct fmc_spi *spi = host->spi; -++ int ret; -++ -++#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); -++ ret = spi->driver->wait_ready(spi); -++ if (ret) { -++ db_msg("Error: %s read wait ready fail! ret: %#x\n", op, ret); -++ goto end; -++ } -++ -++ fmc100_dma_rd_op_config(host, spi); -++ -++ 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; -++ int ret; -++ -++ 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); -++ -++ ret = spi->driver->wait_ready(spi); -++ fmc_pr(ER_DBG, "\t|-Erase wait ready, ret: %#x\n", ret); -++ if (ret) { -++ db_msg("Error: Erase wait ready fail! status: %#x\n", ret); -++ goto end; -++ } -++ -++ ret = spi->driver->write_enable(spi); -++ if (ret) { -++ db_msg("Error: Erase write enable failed! ret: %#x\n", ret); -++ 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; -++ -++ if (host == NULL) { -++ db_msg("Error: host is NULL!\n"); -++ return; -++ } -++ 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 (host == NULL) { -++ db_msg("Error: host is NULL!\n"); -++ return; -++ } -++ 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 nand_chip *chip) -++{ -++ struct fmc_host *host = chip->priv; -++ unsigned char value; -++ unsigned char 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) == 0) -++ 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 void fmc100_write_buf(struct nand_chip *chip, -++ const u_char *buf, int len) -++{ -++ struct fmc_host *host = chip->priv; -++ int ret; -++ -++#ifdef FMC100_SPI_NAND_SUPPORT_REG_WRITE -++ if (buf == chip->oob_poi) -++ ret = memcpy_s((char *)host->iobase + host->pagesize, -++ FMC_MEM_LEN, buf, len); -++ else -++ ret = memcpy_s((char *)host->iobase, FMC_MEM_LEN, buf, len); -++ -++#else -++ if (buf == chip->oob_poi) -++ ret = memcpy_s((char *)(host->buffer + host->pagesize), -++ FMC_MAX_DMA_LEN, buf, len); -++ else -++ ret = memcpy_s((char *)host->buffer, FMC_MAX_DMA_LEN, buf, len); -++ -++#endif -++ if (ret) -++ printk("%s:memcpy_s failed\n", __func__); -++ -++ return; -++} -++ -++static void fmc100_read_buf(struct nand_chip *chip, u_char *buf, int len) -++{ -++ struct fmc_host *host = chip->priv; -++ int ret; -++ -++#ifdef FMC100_SPI_NAND_SUPPORT_REG_READ -++ if (buf == chip->oob_poi) -++ ret = memcpy_s(buf, MAX_OOB_LEN, (char *)host->iobase + -++ host->pagesize, len); -++ else -++ ret = memcpy_s(buf, MAX_PAGE_SIZE, (char *)host->iobase, len); -++ -++#else -++ if (buf == chip->oob_poi) -++ ret = memcpy_s(buf, MAX_OOB_LEN, (char *)host->buffer + -++ host->pagesize, len); -++ else -++ ret = memcpy_s(buf, MAX_PAGE_SIZE, (char *)host->buffer, len); -++ -++#endif -++ if (ret) { -++ printk("%s %d:memcpy_s failed\n", __func__, __LINE__); -++ return; -++ } -++ -++#ifdef CONFIG_BSP_NAND_ECC_STATUS_REPORT -++ if (buf != chip->oob_poi) { -++ u_int reg; -++ u_int ecc_step = host->pagesize >> ECC_STEP_SHIFT; -++ -++ 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 nand_chip *chip, int chipselect) -++{ -++ struct mtd_info *mtd = nand_to_mtd(chip); -++ 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; -++ } -++} -++ -++static void fmc100_ale_init(struct fmc_host *host, unsigned ctrl, unsigned int udat) -++{ -++ unsigned int addr_value = 0; -++ unsigned int addr_offset; -++ -++ if (ctrl & NAND_CTRL_CHANGE) { -++ host->addr_cycle = 0x0; -++ host->addr_value[0] = 0x0; -++ host->addr_value[1] = 0x0; -++ } -++ addr_offset = host->addr_cycle << FMC100_ADDR_CYCLE_SHIFT; -++ -++ if (host->addr_cycle >= FMC100_ADDR_CYCLE_MASK) { -++ addr_offset = (host->addr_cycle - -++ FMC100_ADDR_CYCLE_MASK) << -++ FMC100_ADDR_CYCLE_SHIFT; -++ addr_value = 1; -++ } -++ host->addr_value[addr_value] |= -++ ((udat & 0xff) << addr_offset); -++ -++ host->addr_cycle++; -++} -++ -++static void fmc100_cle_init(struct fmc_host *host, -++ unsigned ctrl, -++ unsigned int udat, -++ int *is_cache_invalid) -++{ -++ unsigned char cmd; -++ -++ 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: -++ /* dest fmcbuf just need init ID lenth */ -++ if (memset_s((u_char *)(host->iobase), FMC_MEM_LEN, -++ 0, MAX_SPI_NAND_ID_LEN)) { -++ printk("%s %d:memset_s failed\n", __func__, __LINE__); -++ break; -++ } -++ 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; -++ } -++} -++ -++static void fmc100_cmd_ctrl(struct nand_chip *chip, int dat, unsigned ctrl) -++{ -++ int is_cache_invalid = 1; -++ struct fmc_host *host = chip->priv; -++ unsigned int udat = (unsigned int)dat; -++ -++ if (ctrl & NAND_ALE) -++ fmc100_ale_init(host, ctrl, udat); -++ -++ if ((ctrl & NAND_CLE) != 0 && (ctrl & NAND_CTRL_CHANGE) != 0) -++ fmc100_cle_init(host, ctrl, udat, &is_cache_invalid); -++ -++ if ((dat == NAND_CMD_NONE) && (host->addr_cycle != 0)) { -++ 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 nand_chip *chip) -++{ -++ unsigned int reg; -++ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; -++ 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) == 0) -++ return NAND_STATUS_READY; -++ -++ cond_resched(); -++ } while ((time_after_eq(jiffies, deadline)) == 0); -++ -++ if ((chip->options & NAND_SCAN_SILENT_NODEV) == 0) -++ 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 = OOB_LENGTH_DEFAULT; -++ oobregion->offset = OOB_OFFSET_DEFAULT; -++ -++ 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 = OOB_LENGTH_DEFAULT_FREE; -++ oobregion->offset = OOB_OFFSET_DEFAULT_FREE; -++ -++ return 0; -++} -++ -++static struct mtd_ooblayout_ops fmc_ooblayout_default_ops = { -++ .ecc = fmc_ooblayout_ecc_default, -++ .free = fmc_ooblayout_free_default, -++}; -++ -++#ifdef CONFIG_BSP_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 = OOB_LENGTH_4K16BIT; -++ oobregion->offset = OOB_OFFSET_4K16BIT; -++ -++ 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 = OOB_LENGTH_4K16BIT_FREE; -++ oobregion->offset = OOB_OFFSET_4K16BIT_FREE; -++ -++ 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 = OOB_LENGTH_2K16BIT; -++ oobregion->offset = OOB_OFFSET_2K16BIT; -++ -++ 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 = OOB_LENGTH_2K16BIT_FREE; -++ oobregion->offset = OOB_OFFSET_2K16BIT_FREE; -++ -++ 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_BSP_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_BSP_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->base.memorg.bits_per_cell = 1; -++ -++ return best; -++} -++ -++static void fmc100_chip_init(struct nand_chip *chip) -++{ -++ chip->legacy.read_byte = fmc100_read_byte; -++ chip->legacy.write_buf = fmc100_write_buf; -++ chip->legacy.read_buf = fmc100_read_buf; -++ -++ chip->legacy.select_chip = fmc100_select_chip; -++ -++ chip->legacy.cmd_ctrl = fmc100_cmd_ctrl; -++ chip->legacy.dev_ready = fmc100_dev_ready; -++ -++ chip->legacy.chip_delay = FMC_CHIP_DELAY; -++ -++ chip->options = NAND_SKIP_BBTSCAN | NAND_BROKEN_XD -++ | NAND_SCAN_SILENT_NODEV; -++ -++ chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_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 = NULL; -++ struct fmc_host *host = NULL; -++ struct mtd_oob_region fmc_oobregion = {0, 0}; -++ -++ if (info == NULL || mtd == NULL || nand_dev == NULL) { -++ db_msg("set oob info err!!!\n"); -++ return; -++ } -++ -++ chip = mtd_to_nand(mtd); -++ host = chip->priv; -++ -++ 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); -++ if (info->ooblayout_ops == NULL) { -++ db_msg("Error: info->ooblayout_ops or is NULL!\n"); -++ return; -++ } -++ 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 + -++ FMC_OOB_LEN_30_EB_OFFSET); -++ -++#ifdef CONFIG_BSP_NAND_FS_MAY_NO_YAFFS2 -++ if (info->ecctype == NAND_ECC_16BIT) { -++ if (host->pagesize == _2K) { -++ /* EB bits locate in the bottom two of CTRL(6) */ -++ host->epm = (u_short *)(host->buffer + host->pagesize + -++ fmc_oobregion.offset + FMC_OOB_LEN_6_EB_OFFSET); -++ } 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 + FMC_OOB_LEN_14_EB_OFFSET); -++ } -++ } -++#endif -++} -++ -++static unsigned int fmc100_get_ecc_reg(struct fmc_host *host, -++ const struct nand_config_info *info, struct nand_dev_t *nand_dev) -++{ -++ if (info == NULL || host == NULL || nand_dev == NULL) { -++ db_msg("get ecc reg err!!!\n"); -++ return 0; -++ } -++ 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, -++ const struct nand_config_info *info) -++{ -++ if (info == NULL || host == NULL) { -++ db_msg("get page reg err!!!\n"); -++ return 0; -++ } -++ 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, -++ const struct nand_config_info *info) -++{ -++ unsigned int block_reg = 0; -++ unsigned int page_per_block; -++ struct mtd_info *mtd = NULL; -++ -++ if (info == NULL || host == NULL) { -++ db_msg("get block reg err!!!\n"); -++ return 0; -++ } -++ -++ mtd = host->mtd; -++ if (mtd == NULL) { -++ db_msg("err:mtd is NULL!!!\n"); -++ return 0; -++ } -++ 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 PAGE_PER_BLK_64: -++ block_reg = BLOCK_SIZE_64_PAGE; -++ break; -++ case PAGE_PER_BLK_128: -++ block_reg = BLOCK_SIZE_128_PAGE; -++ break; -++ case PAGE_PER_BLK_256: -++ block_reg = BLOCK_SIZE_256_PAGE; -++ break; -++ case PAGE_PER_BLK_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, -++ const 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); -++ WARN_ON(type_info == NULL); -++ if (type_info == NULL) { -++ db_msg("set config info err!!!\n"); -++ return 0; -++ } -++ -++ 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; -++} -++ -++void fmc100_spi_nand_init(struct nand_chip *chip) -++{ -++ struct fmc_host *host = NULL; -++ -++ if ((chip == NULL) || (chip->priv == NULL)) { -++ db_msg("Error: chip or chip->priv is NULL!\n"); -++ return; -++ } -++ host = chip->priv; -++ fmc_pr(BT_DBG, "\t|*-Start fmc100 SPI Nand init\n"); -++ -++ /* 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"); -++} -++#ifdef CONFIG_PM -++int fmc100_suspend(struct platform_device *pltdev, pm_message_t state) -++{ -++ 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; -++ } -++ -++ 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; -++ struct nand_memory_organization *memorg; -++ -++ memorg = nanddev_get_memorg(&chip->base); -++ -++ mutex_lock(host->lock); -++ fmc100_switch_to_spi_nand(host); -++ clk_prepare_enable(host->clk); -++ -++ for (cs = 0; cs < memorg->ntargets; cs++) -++ host->send_cmd_reset(host); -++ -++ fmc100_spi_nand_config(host); -++ -++ mutex_unlock(host->lock); -++ return 0; -++} -++#endif -+diff --git a/drivers/mtd/nand/fmc100/fmc100.h b/drivers/mtd/nand/fmc100/fmc100.h -+new file mode 100755 -+index 000000000..bd897ef41 -+--- /dev/null -++++ b/drivers/mtd/nand/fmc100/fmc100.h -+@@ -0,0 +1,371 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __FMC100_H__ -++#define __FMC100_H__ -++ -++#include -++#include -++#include -++#include "../raw/nfc_gen.h" -++ -++#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 -++/* Open it as you need #define FMC100_SPI_NAND_SUPPORT_REG_READ */ -++ -++#undef FMC100_SPI_NAND_SUPPORT_REG_WRITE -++/* Open it as you need #define FMC100_SPI_NAND_SUPPORT_REG_WRITE */ -++ -++#define WORD_READ_OFFSET_ADD_LENGTH 2 -++#define WORD_READ_START_OFFSET 2 -++ -++#define PAGE_PER_BLK_64 64 -++#define PAGE_PER_BLK_128 128 -++#define PAGE_PER_BLK_256 256 -++#define PAGE_PER_BLK_512 512 -++ -++#define OOB_LENGTH_DEFAULT 32 -++#define OOB_OFFSET_DEFAULT 32 -++#define OOB_LENGTH_DEFAULT_FREE 30 -++#define OOB_OFFSET_DEFAULT_FREE 2 -++ -++#define OOB_LENGTH_4K16BIT 14 -++#define OOB_OFFSET_4K16BIT 14 -++#define OOB_LENGTH_4K16BIT_FREE 14 -++#define OOB_OFFSET_4K16BIT_FREE 2 -++ -++#define OOB_LENGTH_2K16BIT 6 -++#define OOB_OFFSET_2K16BIT 6 -++#define OOB_LENGTH_2K16BIT_FREE 6 -++#define OOB_OFFSET_2K16BIT_FREE 2 -++ -++#ifdef CONFIG_BSP_NAND_ECC_STATUS_REPORT -++ -++#define FMC100_ECC_ERR_NUM0_BUF0 0xc0 -++ -++#define get_ecc_err_num(_i, _reg) (((_reg) >> ((_i) * 8)) & 0xff) -++#define ECC_STEP_SHIFT 10 -++#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 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 FMC100_ADDR_CYCLE_SHIFT 0x3 -++ -++#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 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 */ -++#define FMC_OOB_LEN_30_EB_OFFSET (30 - 2) -++#define FMC_OOB_LEN_6_EB_OFFSET (6 - 2) -++#define FMC_OOB_LEN_14_EB_OFFSET (14 - 2) -++ 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); -++ -++void 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); -++ -++int spi_general_wait_ready(struct fmc_spi *spi); -++int spi_general_write_enable(struct fmc_spi *spi); -++int spi_general_qe_enable(struct fmc_spi *spi); -++ -++#ifdef CONFIG_PM -++int fmc100_suspend(struct platform_device *pltdev, pm_message_t state); -++int fmc100_resume(struct platform_device *pltdev); -++void fmc100_spi_nand_config(struct fmc_host *host); -++#endif -++ -++#endif /* End of __FMC100_H__ */ -+diff --git a/drivers/mtd/nand/fmc100/fmc100_os.c b/drivers/mtd/nand/fmc100/fmc100_os.c -+new file mode 100755 -+index 000000000..a271a8952 -+--- /dev/null -++++ b/drivers/mtd/nand/fmc100/fmc100_os.c -+@@ -0,0 +1,252 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++ -++#include -++#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);/* 1000us */ -++ -++ /* Check the ID */ -++ host->offset = 0; -++ /* dest fmcbuf just need init ID lenth */ -++ if (memset_s((unsigned char *)(chip->legacy.IO_ADDR_R), FMC_MEM_LEN, 0, 0x10)) { -++ return 1; -++ } -++ -++ host->send_cmd_readid(host); -++ nand_maf_id = fmc_readb(chip->legacy.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; -++ unsigned char cs; -++ unsigned char 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 != 0) && (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_with_ids(chip, chip_num, NULL)) -++ continue; -++ -++ chip_num--; -++ } -++ -++ if (chip_num == CONFIG_SPI_NAND_MAX_CHIP_NUM) -++ result = -ENXIO; -++ else -++ result = 0; -++ -++ return result; -++} -++ -++static int spi_nand_host_parm_init(struct platform_device *pltdev, -++ struct device *dev, -++ struct fmc_host **host, -++ struct nand_chip **chip, -++ struct mtd_info **mtd) -++{ -++ int len; -++ struct bsp_fmc *fmc = dev_get_drvdata(dev->parent); -++ -++ 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)) { -++ dev_err(dev, "get host failed\n"); -++ return -ENOMEM; -++ } -++ (void)memset_s((char *)(*host), len, 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; -++ /* dest fmcbuf just need init dma_len lenth */ -++ if (memset_s((char *)(*host)->iobase, FMC_MEM_LEN, 0xff, fmc->dma_len)) { -++ dev_err(dev, "memset_s failed\n"); -++ return -1; -++ } -++ (*chip)->legacy.IO_ADDR_R = (*chip)->legacy.IO_ADDR_W = (*host)->iobase; -++ (*chip)->priv = (*host); -++ -++ return 0; -++} -++ -++static int bsp_spi_nand_probe(struct platform_device *pltdev) -++{ -++ int result; -++ 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; -++ -++ fmc_pr(BT_DBG, "\t*-Start SPI Nand flash driver probe\n"); -++ result = spi_nand_host_parm_init(pltdev, dev, &host, &chip, &mtd); -++ if (result) { -++ fmc_pr(BT_DBG, "\t*-test0\n"); -++ return result; -++ } -++ /* Set system clock */ -++ result = clk_prepare_enable(host->clk); -++ if (result) { -++ printk("\nclk prepare enable failed!"); -++ goto fail; -++ } -++ -++ fmc100_spi_nand_init(chip); -++ -++ np = of_get_next_available_child(dev->of_node, NULL); -++ if (np == NULL) { -++ printk("\nof_get_next_available_child failed!"); -++ goto fail; -++ } -++ 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) { -++ printk("\nget fmc clkrate failed"); -++ 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 == 0) { -++ fmc_pr(BT_DBG, "\t*-End driver probe !!\n"); -++ return 0; -++ } -++ -++ result = -ENODEV; -++ -++ mtd_device_unregister(mtd); -++ nand_cleanup(mtd_to_nand(mtd)); -++ -++fail: -++ clk_disable_unprepare(host->clk); -++ 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); -++ unsigned char cs; -++ -++ for (cs = 0; cs < FMC_MAX_CHIP_NUM; cs++) -++ fmc_cs_user[cs] = 0; -++ -++ if (host) { -++ if (host->clk) -++ clk_disable_unprepare(host->clk); -++ if (host->mtd) { -++ mtd_device_unregister(host->mtd); -++ nand_cleanup(mtd_to_nand(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 = "vendor,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("Vendor Flash Memory Controller V100 SPI Nand Driver"); -+diff --git a/drivers/mtd/nand/fmc100/fmc100_spi_general.c b/drivers/mtd/nand/fmc100/fmc100_spi_general.c -+new file mode 100755 -+index 000000000..15a530e58 -+--- /dev/null -++++ b/drivers/mtd/nand/fmc100/fmc100_spi_general.c -+@@ -0,0 +1,331 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++#include "fmc100.h" -++ -++static int spi_nand_feature_op_config(struct fmc_host *host, -++ u_char op, -++ const u_char *val, -++ u_char addr) -++{ -++ unsigned int reg; -++ -++ reg = fmc_cmd_cmd1((op != 0) ? 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) { -++ if (!val || !host->iobase) { -++ db_msg("Error: host->iobase is NULL !\n"); -++ return -1; -++ } -++ 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); -++ -++ return 0; -++} -++ -++static int spi_nand_get_op(struct fmc_host *host, u_char *val) -++{ -++ unsigned int reg; -++ -++ if (!val) { -++ db_msg("Error: val is NULL !\n"); -++ return -1; -++ } -++ 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 0; -++} -++ -++/* -++ Send set/get features command to SPI Nand flash -++*/ -++char spi_nand_feature_op(struct fmc_spi *spi, u_char op, u_char addr, -++ u_char *val) -++{ -++ const char *str[] = {"Get", "Set"}; -++ struct fmc_host *host = NULL; -++ int ret; -++ -++ if (!spi) { -++ db_msg("Error: spi is NULL !\n"); -++ return -1; -++ } -++ host = (struct fmc_host *)spi->host; -++ if (!host) { -++ db_msg("Error: host is NULL !\n"); -++ return -1; -++ } -++ -++ if ((op == GET_OP) && (addr == STATUS_ADDR)) { -++ ret = spi_nand_get_op(host, val); -++ return ret; -++ } -++ -++ fmc_pr(FT_DBG, "\t|||*-Start %s feature, addr[%#x]\n", str[op], addr); -++ -++ fmc100_ecc0_switch(host, ENABLE); -++ -++ ret = spi_nand_feature_op_config(host, op, val, addr); -++ if (ret) -++ return -1; -++ -++ if (op == GET_OP) { -++ if (!val || !host->iobase) { -++ db_msg("Error: val or host->iobase is NULL !\n"); -++ return -1; -++ } -++ *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 0; -++} -++ -++/* -++ Read status[C0H]:[0]bit OIP, judge whether the device is busy or not -++*/ -++int spi_general_wait_ready(struct fmc_spi *spi) -++{ -++ unsigned char status; -++ int ret; -++ unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES; -++ struct fmc_host *host = NULL; -++ -++ if (spi == NULL || spi->host == NULL) { -++ db_msg("Error: host or host->spi is NULL!\n"); -++ return -1; -++ } -++ host = (struct fmc_host *)spi->host; -++ -++ do { -++ ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, &status); -++ if (ret) -++ return -1; -++ if ((status & STATUS_OIP_MASK) == 0) { -++ if ((host->cmd_op.l_cmd == NAND_CMD_ERASE2) && -++ ((((unsigned int)status) & STATUS_E_FAIL_MASK) != 0)) -++ return status; -++ -++ if ((host->cmd_op.l_cmd == NAND_CMD_PAGEPROG) && -++ ((((unsigned int)status) & STATUS_P_FAIL_MASK) != 0)) -++ return status; -++ -++ return 0; -++ } -++ -++ cond_resched(); -++ } while (time_after_eq(jiffies, deadline) == 0); -++ -++ db_msg("Error: SPI Nand wait ready timeout, status: %#x\n", status); -++ -++ return 1; -++} -++ -++static void spi_general_write_enable_op(struct fmc_host *host) -++{ -++ unsigned int regl; -++ -++ regl = fmc_readl(host, FMC_GLOBAL_CFG); -++ fmc_pr(WE_DBG, "\t||-Get GLOBAL_CFG[%#x]%#x\n", FMC_GLOBAL_CFG, regl); -++ if (regl & FMC_GLOBAL_CFG_WP_ENABLE) { -++ regl &= ~FMC_GLOBAL_CFG_WP_ENABLE; -++ fmc_writel(host, FMC_GLOBAL_CFG, regl); -++ fmc_pr(WE_DBG, "\t||-Set GLOBAL_CFG[%#x]%#x\n", -++ FMC_GLOBAL_CFG, regl); -++ } -++ -++ regl = fmc_cmd_cmd1(SPI_CMD_WREN); -++ fmc_writel(host, FMC_CMD, regl); -++ fmc_pr(WE_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, regl); -++ -++ regl = op_cfg_fm_cs(host->cmd_op.cs) | OP_CFG_OEN_EN; -++ fmc_writel(host, FMC_OP_CFG, regl); -++ fmc_pr(WE_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, regl); -++ -++ regl = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START; -++ fmc_writel(host, FMC_OP, regl); -++ fmc_pr(WE_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, regl); -++ -++ fmc_cmd_wait_cpu_finish(host); -++} -++ -++/* -++ Send write enable cmd to SPI Nand, status[C0H]:[2]bit WEL must be set 1 -++*/ -++int spi_general_write_enable(struct fmc_spi *spi) -++{ -++ u_char reg; -++ int ret; -++ struct fmc_host *host = NULL; -++ if (spi == NULL || spi->host == NULL) { -++ db_msg("Error: host or host->spi is NULL!\n"); -++ return -1; -++ } -++ host = spi->host; -++ if (WE_DBG) -++ pr_info("\n"); -++ fmc_pr(WE_DBG, "\t|*-Start Write Enable\n"); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, ®); -++ if (ret) -++ return -1; -++ if (reg & STATUS_WEL_MASK) { -++ fmc_pr(WE_DBG, "\t||-Write Enable was opened! reg: %#x\n", -++ reg); -++ return 0; -++ } -++ -++ spi_general_write_enable_op(host); -++ -++#if WE_DBG -++ if (!spi->driver) { -++ db_msg("Error: spi->driver is NULL!\n"); -++ return -1; -++ } -++ spi->driver->wait_ready(spi); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, ®); -++ if (ret) -++ return -1; -++ 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(const 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 -++*/ -++int spi_general_qe_enable(struct fmc_spi *spi) -++{ -++ int op; -++ u_char reg; -++ int ret; -++ const char *str[] = {"Disable", "Enable"}; -++ if (!spi || !spi->host || !spi->driver) { -++ db_msg("Error: host or spi->host or spi->driver is NULL!\n"); -++ return -1; -++ } -++ 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]); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); -++ if (ret) -++ return -1; -++ 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; -++ -++ ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, ®); -++ if (ret) -++ return -1; -++ fmc_pr(QE_DBG, "\t|||-SPI Nand %s Quad\n", str[op]); -++ -++ spi->driver->wait_ready(spi); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); -++ if (ret) -++ return -1; -++ if ((reg & FEATURE_QE_ENABLE) == op) -++ fmc_pr(QE_DBG, "\t|||-SPI Nand %s Quad succeed!\n", str[op]); -++ else -++ db_msg("Error: %s Quad failed! reg: %#x\n", str[op], reg); -++ -++ fmc_pr(QE_DBG, "\t||*-End SPI Nand %s Quad.\n", str[op]); -++ -++ return op; -++} -+diff --git a/drivers/mtd/nand/fmc100/fmc_spi_nand_ids.c b/drivers/mtd/nand/fmc100/fmc_spi_nand_ids.c -+new file mode 100755 -+index 000000000..07d9a6e21 -+--- /dev/null -++++ b/drivers/mtd/nand/fmc100/fmc_spi_nand_ids.c -+@@ -0,0 +1,1639 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++#include "fmc100.h" -++ -++set_read_std(1, INFINITE, 24); -++ -++set_read_fast(1, INFINITE, 80); -++set_read_fast(1, INFINITE, 104); -++set_read_fast(1, INFINITE, 120); -++set_read_fast(1, INFINITE, 133); -++ -++set_read_dual(1, INFINITE, 80); -++set_read_dual(1, INFINITE, 104); -++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(1, INFINITE, 104); -++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, 104); -++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(1, INFINITE, 104); -++set_read_quad_addr(2, INFINITE, 104); -++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, 104); -++set_write_std(0, 256, 133); -++ -++set_write_quad(0, 256, 80); -++set_write_quad(0, 256, 104); -++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, 104); -++set_erase_sector_256k(0, _256K, 133); -++ -++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" -++ -++/****************************************************************************** -++ * We do not guarantee the compatibility of the following device models in the -++ * table.Device compatibility is based solely on the list of compatible devices -++ * in the release package. -++ ******************************************************************************/ -++static struct spi_nand_info fmc_spi_nand_flash_table[] = { -++ /* GD 3.3v GD5F1GQ5UEYIGY 1Gbit */ -++ /* name id id_len chipsize(Bytes) erasesize pagesize oobsize(Bytes) */ -++ { -++ .name = "GD5F1GQ5UEYIGY", -++ .id = {0xc8, 0x51}, -++ .id_len = 2, -++ .chipsize = _128M, -++ .erasesize = _128K, -++ .pagesize = _2K, -++ .oobsize = 128, -++ .badblock_pos = BBP_FIRST_PAGE, -++ .read = { -++ /* dummy clock:1 byte, read size:INFINITE bytes, -++ * clock frq:24MHz */ -++ &read_std(1, INFINITE, 24), -++ &read_fast(1, INFINITE, 133), -++ &read_dual(1, INFINITE, 133), -++ &read_quad(1, INFINITE, 133), -++ 0 -++ }, -++ .write = { -++ /* dummy clock:0 byte, write size:256 bytes, -++ * clock frq:80MHz */ -++ &write_std(0, 256, 133), -++ &write_quad(0, 256, 133), -++ 0 -++ }, -++ .erase = { -++ /* dummy clock:0 byte, write size:128KB, -++ * clock frq:80MHz */ -++ &erase_sector_128k(0, _128K, 133), -++ 0 -++ }, -++ .driver = &spi_driver_general, -++ }, -++ -++ /* GD 1.8v GD5F1GQ5REYIG 1Gbit */ -++ { -++ .name = "GD5F1GQ5REYIG", -++ .id = {0xc8, 0x41}, -++ .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, 24), -++ &write_quad(0, 256, 104), -++ 0 -++ }, -++ .erase = { -++ &erase_sector_128k(0, _128K, 104), -++ 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 GD5F2GQ4UB9IGR/GD5F2GQ4UBYIG 2Gbit */ -++ { -++ .name = "GD5F2GQ4UB9IGR/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 1.8v GD5F2GQ5REYIG 2Gbit */ -++ { -++ .name = "GD5F2GQ5REYIG", -++ .id = {0xc8, 0x42}, -++ .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, 104), -++ 0 -++ }, -++ .erase = { -++ &erase_sector_128k(0, _128K, 104), -++ 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 GD5F4GQ4RBYIG 4Gbit */ -++ { -++ .name = "GD5F4GQ4RBYIG", -++ .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 3.3V W25N01GVZEIG 1Gbit */ -++ { -++ .name = "W25N01GVZEIG", -++ .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 1.8V W25N01GWZEIG 1Gbit */ -++ { -++ .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, -++ }, -++ -++ /* MXIC 3.3V 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 1.8V MX35UF1G14AC 1Gbit */ -++ { -++ .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 3.3V 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 1.8V MX35UF2G14AC 2Gbit */ -++ { -++ .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, -++ }, -++ -++ /* TOSHIBA 3.3V TC58CVG0S3HQAIE/TC58CVG0S3HRAIF 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 3.3V TC58CVG0S3HRAIJ 1bit */ -++ { -++ .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 1.8V TC58CYG0S3HRAIG 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 1.8V TC58CYG0S3HRAIJ 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 3.3V TC58CVG1S3HQAIE/TC58CVG1S3HRAIF/TC58CVG1S3HRAIG 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 3.3V 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 1.8V TC58CYG1S3HRAIG 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 1.8V TC58CYG1S3HRAIJ 1.8V 2Gbit */ -++ { -++ .name = "TC58CYG1S3HRAIJ", -++ .id = {0x98, 0xdb, 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 3.3V TC58CVG2S0HQAIE/TC58CVG2S0HRAIF 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 3.3V 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 1.8V TC58CYG2S0HRAIG 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 1.8V TH58CYG2S0HRAIJ 4Gbit */ -++ { -++ .name = "TH58CYG2S0HRAIJ", -++ .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, -++ }, -++ -++ /* 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, -++ }, -++ -++ /* Dosilicon 3.3V DS35Q1GB-IB 1Gbit */ -++ { -++ .name = "DS35Q1GB-IB", -++ .id = {0xe5, 0xf1}, -++ .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, 80), -++ &write_quad(0, 256, 104), -++ 0 -++ }, -++ .erase = { -++ &erase_sector_128k(0, _128K, 104), -++ 0 -++ }, -++ .driver = &spi_driver_general, -++ }, -++ -++ /* Dosilicon 3.3V DS35Q12C-1B 512Mbit */ -++ { -++ .name = "DS35Q12C-1D", -++ .id = {0xe5, 0x75}, -++ .id_len = 2, -++ .chipsize = _64M, -++ .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, 80), -++ &write_quad(0, 256, 104), -++ 0 -++ }, -++ .erase = { -++ &erase_sector_128k(0, _128K, 104), -++ 0 -++ }, -++ .driver = &spi_driver_general, -++ }, -++ -++ /* XTX 3.3V XT26G01BWSEGA 1Gbit */ -++ { -++ .name = "XT26G01BWSEGA", -++ .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, -++ }, -++ -++ /* Dosilicon 3.3V DS35Q4GA-IB 1Gb */ -++ { -++ .name = "DS35Q4GA-IB", -++ .id = {0xe5, 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, 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, -++ }, -++ -++ /* 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-DND-U-G 1Gbit */ -++ { -++ .name = "FM25S01A-DND-U-G", -++ .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), /* 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, -++ }, -++ -++ { .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; -++ int ret; -++ -++ for (fitspiop = spiop = ((rw_type == RW_OP_WRITE) ? spiinfo->write : spiinfo->read); -++ (*spiop) && ix < MAX_SPI_OP; spiop++, ix++) { -++ if (((((unsigned int)(*spiop)->iftype) & iftype) != 0) -++ && ((*spiop)->dummy <= max_dummy) -++ && (*fitspiop)->iftype < (*spiop)->iftype) -++ fitspiop = spiop; -++ } -++ ret = memcpy_s(spiop_rw, sizeof(struct spi_op), (*fitspiop), -++ sizeof(struct spi_op)); -++ if (ret) -++ printk("%s: memcpy_s failed\n", __func__); -++} -++ -++ -++static void fmc100_spi_nand_get_erase(const struct spi_nand_info *spiinfo, -++ struct spi_op *spiop_erase) -++{ -++ int ix; -++ int ret; -++ -++ 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) { -++ ret = memcpy_s(&spiop_erase[ix], sizeof(struct spi_op), -++ spiinfo->erase[ix], sizeof(struct spi_op)); -++ if (ret) -++ printk("%s:memcpy_s failed\n", __func__); -++ 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) { /* 2 is row1 of iftype_write[] */ -++ 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) { /* 2 is row1 of iftype_read[] */ -++ 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_nand_op_cmd_init(struct spi_nand_info *spi_dev, -++ struct fmc_spi *spi) -++{ -++ 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); -++} -++ -++ -++static int fmc100_spi_nand_dis_wr_protect(struct fmc_spi *spi, u_char *reg) -++{ -++ int ret; -++ -++ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, reg); -++ if (ret) -++ return ret; -++ fmc_pr(BT_DBG, "\t||-Get protect status[%#x]: %#x\n", PROTECT_ADDR, -++ *reg); -++ if (any_bp_enable(*reg)) { -++ *reg &= ~ALL_BP_MASK; -++ ret = spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, reg); -++ if (ret) -++ return ret; -++ fmc_pr(BT_DBG, "\t||-Set [%#x]FT %#x\n", PROTECT_ADDR, *reg); -++ -++ spi->driver->wait_ready(spi); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, reg); -++ if (ret) -++ return ret; -++ 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"); -++ } -++ return ret; -++} -++ -++static int fmc100_spi_nand_dis_chip_inner_ecc(struct fmc_spi *spi, u_char *reg) -++{ -++ int ret; -++ -++ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, reg); -++ if (ret) -++ return ret; -++ fmc_pr(BT_DBG, "\t||-Get feature status[%#x]: %#x\n", FEATURE_ADDR, -++ *reg); -++ if (*reg & FEATURE_ECC_ENABLE) { -++ *reg &= ~FEATURE_ECC_ENABLE; -++ ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, reg); -++ if (ret) -++ return ret; -++ fmc_pr(BT_DBG, "\t||-Set [%#x]FT: %#x\n", FEATURE_ADDR, *reg); -++ -++ spi->driver->wait_ready(spi); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, reg); -++ if (ret) -++ return ret; -++ 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"); -++ } -++ return ret; -++} -++ -++static void fmc100_spi_ids_probe(struct mtd_info *mtd, -++ struct spi_nand_info *spi_dev) -++{ -++ u_char reg; -++ int ret; -++ struct nand_chip *chip = NULL; -++ struct fmc_host *host = NULL; -++ struct fmc_spi *spi = NULL; -++ -++ if (mtd == NULL || spi_dev == NULL) { -++ db_msg("Error: mtd or spi_dev is NULL!\n"); -++ return; -++ } -++ chip = mtd_to_nand(mtd); -++ if (chip == NULL || chip->priv == NULL) { -++ db_msg("Error: chip is NULL!\n"); -++ return; -++ } -++ host = chip->priv; -++ if (host->spi == NULL) { -++ db_msg("Error: host->spi is NULL!\n"); -++ return; -++ } -++ 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; -++ if (!spi->driver) { -++ db_msg("Error: host->driver is NULL!\n"); -++ return; -++ } -++ -++ fmc100_spi_nand_op_cmd_init(spi_dev, spi); -++ -++ if (spi->driver->qe_enable) -++ spi->driver->qe_enable(spi); -++ -++ /* Disable write protection */ -++ ret = fmc100_spi_nand_dis_wr_protect(spi, ®); -++ if (ret) -++ return; -++ -++ /* Disable chip internal ECC */ -++ ret = fmc100_spi_nand_dis_chip_inner_ecc(spi, ®); -++ if (ret) -++ return; -++ -++ 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; -++ int len; -++ char buffer[BUFF_LEN]; -++ 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; -++ int ret; -++ -++ fmc_pr(BT_DBG, "\t*-Start find SPI Nand flash\n"); -++ -++ len = sprintf_s(buffer, BUFF_LEN, "SPI Nand(cs %d) ID: %#x %#x", -++ host->cmd_op.cs, id[0], id[1]); -++ if (len < 0) -++ printk("%s, line: %d, sprintf_s failed\n", __func__, __LINE__); -++ -++ for (; spi_dev->id_len; spi_dev++) { -++ unsigned long long tmp; -++ if (memcmp(id, spi_dev->id, spi_dev->id_len)) -++ continue; -++ -++ for (ix = 2; ix < spi_dev->id_len; ix++) { /* star from id[2] */ -++ if ((spi_dev->id_len <= MAX_SPI_NAND_ID_LEN)) { -++ len += sprintf_s(buffer + len, BUFF_LEN - len, " %#x", -++ id[ix]); -++ if (len < 0) -++ printk("%s,line: %d, sprintf_s failed\n", -++ __func__, __LINE__); -++ } -++ } -++ 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; -++ ret = memcpy_s(type->id, MAX_SPI_NAND_ID_LEN, spi_dev->id, -++ spi_dev->id_len); -++ if (ret) { -++ printk("%s: memcpy_s failed\n", __func__); -++ return NULL; -++ } -++ type->pagesize = spi_dev->pagesize; -++ type->chipsize = (unsigned int)(spi_dev->chipsize >> -++ 20); /* 1M unit shift right 20 bit */ -++ 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->base.memorg.pagesize = spi_dev->pagesize; -++ chip->base.memorg.pages_per_eraseblock = spi_dev->erasesize / spi_dev->pagesize; -++ -++ tmp = spi_dev->chipsize; -++ do_div(tmp, spi_dev->erasesize); -++ chip->base.memorg.eraseblocks_per_lun = tmp; -++ -++ chip->base.memorg.oobsize = spi_dev->oobsize; -++ -++ 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 -++ -++ -++static int fmc100_spi_nand_dis_wp(struct fmc_spi *spi, u_char *reg) -++{ -++ int ret; -++ -++ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, reg); -++ if (ret) -++ return ret; -++ fmc_pr(PM_DBG, "\t|-Get protect status[%#x]: %#x\n", PROTECT_ADDR, -++ *reg); -++ if (any_bp_enable(*reg)) { -++ *reg &= ~ALL_BP_MASK; -++ ret = spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, reg); -++ if (ret) -++ return ret; -++ fmc_pr(PM_DBG, "\t|-Set [%#x]FT %#x\n", PROTECT_ADDR, *reg); -++ -++ spi->driver->wait_ready(spi); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, reg); -++ if (ret) -++ return ret; -++ 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"); -++ } -++ return ret; -++} -++ -++void fmc100_spi_nand_config(struct fmc_host *host) -++{ -++ u_char reg; -++ int ret; -++ struct fmc_spi *spi = NULL; -++ static const char *str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"}; -++ -++ if ((host == NULL) || (host->spi == NULL)) { -++ db_msg("Error: host or host->spi is NULL!\n"); -++ return; -++ } -++ spi = host->spi; -++ /* 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 */ -++ ret = fmc100_spi_nand_dis_wp(spi, ®); -++ if (ret) -++ return; -++ /* Disable chip internal ECC */ -++ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); -++ if (ret) -++ return; -++ fmc_pr(PM_DBG, "\t|-Get feature status[%#x]: %#x\n", FEATURE_ADDR, -++ reg); -++ if (reg & FEATURE_ECC_ENABLE) { -++ reg &= ~FEATURE_ECC_ENABLE; -++ ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, ®); -++ if (ret) -++ return; -++ fmc_pr(PM_DBG, "\t|-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg); -++ -++ spi->driver->wait_ready(spi); -++ -++ ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, ®); -++ if (ret) -++ return; -++ fmc_pr(PM_DBG, "\t|-Check internal ECC disable result: %#x\n", -++ reg); -++ if (reg & FEATURE_ECC_ENABLE) -++ db_msg("Error: Chip internal ECC disable failed!\n"); -++ } -++} -++ -++#endif /* CONFIG_PM */ -+diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile -+index 2930f5b90..32f0f4701 100644 -+--- a/drivers/mtd/nand/raw/Makefile -++++ b/drivers/mtd/nand/raw/Makefile -+@@ -59,7 +59,10 @@ obj-$(CONFIG_MTD_NAND_MESON) += meson_nand.o -+ obj-$(CONFIG_MTD_NAND_CADENCE) += cadence-nand-controller.o -+ obj-$(CONFIG_MTD_NAND_ARASAN) += arasan-nand-controller.o -+ -+-nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o -++nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o -++ifdef CONFIG_ARCH_BSP -++nand-objs += nfc_gen.o nfc_spl_ids.o match_table.o -++endif -+ nand-objs += nand_onfi.o -+ nand-objs += nand_jedec.o -+ nand-objs += nand_amd.o -+diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h -+index 012876e14..91e04eb14 100644 -+--- a/drivers/mtd/nand/raw/internals.h -++++ b/drivers/mtd/nand/raw/internals.h -+@@ -34,6 +34,16 @@ -+ #define NAND_MFR_TOSHIBA 0x98 -+ #define NAND_MFR_WINBOND 0xef -+ -++#ifdef CONFIG_ARCH_BSP -++#define NAND_MFR_MXIC 0xc2 -++#define NAND_MFR_ALL_FLASH 0xc1 -++#define NAND_MFR_PARAGON 0xa1 -++#define NAND_MFR_GD_ESMT 0xc8 -++#define NAND_MFR_HEYANGTEK 0xc9 -++#define NAND_MFR_DOSILICON 0xe5 -++#define NAND_MFR_FIDELIX 0xf8 -++#endif -++ -+ /** -+ * struct nand_manufacturer_ops - NAND Manufacturer operations -+ * @detect: detect the NAND memory organization and capabilities -+diff --git a/drivers/mtd/nand/raw/match_table.c b/drivers/mtd/nand/raw/match_table.c -+new file mode 100755 -+index 000000000..38e923dc6 -+--- /dev/null -++++ b/drivers/mtd/nand/raw/match_table.c -+@@ -0,0 +1,98 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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) == 0) { -++ 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) == 0) { -++ return table->type; -++ } -++ table++; -++ } -++ return def; -++} -++ -++void *match_type_to_data(struct match_t *table, int nr_table, int type, -++ void *def) -++{ -++ while (nr_table-- > 0) { -++ if (table->type == type) { -++ return table->data; -++ } -++ table++; -++ } -++ return def; -++} -+diff --git a/drivers/mtd/nand/raw/match_table.h b/drivers/mtd/nand/raw/match_table.h -+new file mode 100755 -+index 000000000..bb96a42bd -+--- /dev/null -++++ b/drivers/mtd/nand/raw/match_table.h -+@@ -0,0 +1,48 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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, -++ void *def); -++ -++#endif /* End of __MATCH_TABLE_H__ */ -+diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c -+index c41c0ff61..62ecd8116 100644 -+--- a/drivers/mtd/nand/raw/nand_base.c -++++ b/drivers/mtd/nand/raw/nand_base.c -+@@ -42,6 +42,7 @@ -+ #include -+ #include -+ #include -++#include "nfc_gen.h" -+ #include -+ -+ #include "internals.h" -+@@ -3967,6 +3968,10 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to, -+ int ret; -+ int oob_required = oob ? 1 : 0; -+ -++#ifdef CONFIG_ARCH_BSP -++ oob_required = 1; -++#endif -++ -+ ops->retlen = 0; -+ if (!writelen) -+ return 0; -+@@ -4746,6 +4751,29 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) -+ /* Try to identify manufacturer */ -+ manufacturer_desc = nand_get_manufacturer_desc(maf_id); -+ chip->manufacturer.desc = manufacturer_desc; -++#ifdef CONFIG_ARCH_BSP -++ -++#ifndef CONFIG_MTD_SPI_NAND_BSP -++ /* Parallel Nand Flash */ -++ -++ /* The 3rd id byte holds MLC / multichip data */ -++ chip->base.memorg.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_BSP -++ else { -++ pr_info("This device[%02x,%02x] cannot found in spi nand id table!!\n", -++ maf_id, dev_id); -++ return -ENODEV; -++ } -++#endif -++ -++#endif /* endif CONFIG_ARCH_BSP */ -+ -+ if (!type) -+ type = nand_flash_ids; -+@@ -4811,12 +4839,21 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) -+ memorg->pages_per_eraseblock); -+ -+ ident_done: -++#ifdef CONFIG_ARCH_BSP -++ nfc_nand_param_adjust(mtd, chip); -++ chip->parameters.model = kstrdup(type->name, GFP_KERNEL); -++ if (!chip->parameters.model) -++ return -ENOMEM; -++#endif -+ if (!mtd->name) -+ mtd->name = chip->parameters.model; -+ -+ if (chip->options & NAND_BUSWIDTH_AUTO) { -+ WARN_ON(busw & NAND_BUSWIDTH_16); -+ nand_set_defaults(chip); -++#ifdef CONFIG_ARCH_BSP -++ printk("NAND_BUSWIDTH_AUTO,line:%d",__LINE__); -++#endif -+ } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { -+ /* -+ * Check, if buswidth is correct. Hardware drivers should set -+@@ -4864,6 +4901,11 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) -+ pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", -+ (int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", -+ mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); -++ -++#ifdef CONFIG_ARCH_BSP -++ /* Print ecc type and ecc mode about vendor flash controller */ -++ nfc_show_info(mtd, nand_manufacturer_name(manufacturer_desc), type->name); -++#endif -+ return 0; -+ -+ free_detect_allocation: -+diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c -+index b9945791a..9985a9c91 100644 -+--- a/drivers/mtd/nand/raw/nand_ids.c -++++ b/drivers/mtd/nand/raw/nand_ids.c -+@@ -185,6 +185,15 @@ static const struct nand_manufacturer_desc nand_manufacturer_descs[] = { -+ {NAND_MFR_STMICRO, "ST Micro"}, -+ {NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops}, -+ {NAND_MFR_WINBOND, "Winbond"}, -++#ifdef CONFIG_ARCH_BSP -++ {NAND_MFR_MXIC, "MXIC"}, -++ {NAND_MFR_ALL_FLASH, "All-flash"}, -++ {NAND_MFR_PARAGON, "Paragon"}, -++ {NAND_MFR_HEYANGTEK, "HeYangTek"}, -++ {NAND_MFR_DOSILICON, "Dosilicon"}, -++ {NAND_MFR_FIDELIX, "Fidelix/Dosi"}, /* Fidelix was purchased by Dosilicon */ -++ {0x0, "Unknown"} -++#endif -+ }; -+ -+ /** -+diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c -+index 1472f925f..f90b37d62 100644 -+--- a/drivers/mtd/nand/raw/nand_macronix.c -++++ b/drivers/mtd/nand/raw/nand_macronix.c -+@@ -36,6 +36,7 @@ struct nand_onfi_vendor_macronix { -+ u8 reliability_func; -+ } __packed; -+ -++#ifndef CONFIG_ARCH_BSP -+ static int macronix_nand_setup_read_retry(struct nand_chip *chip, int mode) -+ { -+ u8 feature[ONFI_SUBFEATURE_PARAM_LEN]; -+@@ -139,6 +140,7 @@ static void macronix_nand_onfi_init(struct nand_chip *chip) -+ ONFI_FEATURE_ADDR_READ_RETRY, 1); -+ } -+ } -++#endif -+ -+ /* -+ * Macronix AC series does not support using SET/GET_FEATURES to change -+@@ -185,6 +187,8 @@ static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) -+ * disabled. Lock/unlock protection area can be partition according to -+ * protection bits, i.e. upper 1/2 locked, upper 1/4 locked and so on. -+ */ -++ -++#ifndef CONFIG_ARCH_BSP -+ static int mxic_nand_lock(struct nand_chip *chip, loff_t ofs, uint64_t len) -+ { -+ u8 feature[ONFI_SUBFEATURE_PARAM_LEN]; -+@@ -315,17 +319,20 @@ static void macronix_nand_deep_power_down_support(struct nand_chip *chip) -+ chip->ops.suspend = mxic_nand_suspend; -+ chip->ops.resume = mxic_nand_resume; -+ } -++#endif -+ -+ static int macronix_nand_init(struct nand_chip *chip) -+ { -++ -+ if (nand_is_slc(chip)) -+ chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; -+ -+ macronix_nand_fix_broken_get_timings(chip); -++#ifndef CONFIG_ARCH_BSP -+ macronix_nand_onfi_init(chip); -+ macronix_nand_block_protection_support(chip); -+ macronix_nand_deep_power_down_support(chip); -+- -++#endif -+ return 0; -+ } -+ -+diff --git a/drivers/mtd/nand/raw/nfc_gen.c b/drivers/mtd/nand/raw/nfc_gen.c -+new file mode 100755 -+index 000000000..6d6421c18 -+--- /dev/null -++++ b/drivers/mtd/nand/raw/nfc_gen.c -+@@ -0,0 +1,214 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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; -++EXPORT_SYMBOL_GPL(get_spi_nand_flash_type_hook); -++ -++static struct match_t match_ecc[] = { -++ MATCH_SET_TYPE_DATA(NAND_ECC_NONE_0, "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"); -++} -++EXPORT_SYMBOL_GPL(nand_ecc_name); -++ -++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[(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"); -++} -++EXPORT_SYMBOL_GPL(nand_page_name); -++ -++char *get_pagesize_str(enum page_type pagetype) -++{ -++ static char *pagesize_str[] = { -++ "512", "2K", "4K", "8K", "16K", "unknown", -++ "unknown", "unknown" -++ }; -++ return pagesize_str[(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[(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); -++} -++ -++static int __init dbgfs_options_setup(char *s) -++{ -++ char *nand_dbgfs_options; -++ -++ nand_dbgfs_options = s; -++ return 1; -++} -++__setup("nanddbgfs=", dbgfs_options_setup); -++ -++int get_bits(unsigned int n) -++{ -++ int loop; -++ int ret = 0; -++ -++ if (n == 0) -++ 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_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); -++} -++EXPORT_SYMBOL_GPL(match_page_type_to_reg); -++ -++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); -++} -++EXPORT_SYMBOL_GPL(match_ecc_type_to_reg); -++ -++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); -++} -++EXPORT_SYMBOL_GPL(match_page_type_to_size); -+diff --git a/drivers/mtd/nand/raw/nfc_gen.h b/drivers/mtd/nand/raw/nfc_gen.h -+new file mode 100755 -+index 000000000..925186e7c -+--- /dev/null -++++ b/drivers/mtd/nand/raw/nfc_gen.h -+@@ -0,0 +1,265 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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 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[NAND_MAX_ID_LEN]; -++ 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, const char *vendor, 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 unsigned char match_page_reg_to_type(unsigned char reg); -++ -++extern unsigned char match_page_type_to_reg(unsigned char type); -++ -++extern const char *match_page_type_to_str(unsigned char type); -++ -++extern unsigned char match_ecc_reg_to_type(unsigned char reg); -++ -++extern unsigned char match_ecc_type_to_reg(unsigned char type); -++ -++extern const char *match_ecc_type_to_str(unsigned char type); -++ -++extern unsigned char match_page_size_to_type(unsigned int size); -++ -++extern unsigned int match_page_type_to_size(unsigned char type); -++ -++const char *nand_ecc_name(int type); -++ -++#endif /* End of __NFC_GEN_H__ */ -+diff --git a/drivers/mtd/nand/raw/nfc_spl_ids.c b/drivers/mtd/nand/raw/nfc_spl_ids.c -+new file mode 100755 -+index 000000000..a15e8e6b8 -+--- /dev/null -++++ b/drivers/mtd/nand/raw/nfc_spl_ids.c -+@@ -0,0 +1,963 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#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, -++ }, -++ { -++ .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; -++EXPORT_SYMBOL_GPL(nfc_param_adjust); -++ -++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; -++ int ret; -++ -++ (void)memset_s(nand_dev, sizeof(struct nand_dev_t), 0, -++ sizeof(struct nand_dev_t)); -++ ret = memcpy_s(nand_dev->ids, NAND_MAX_ID_LEN, id_data, NAND_MAX_ID_LEN); -++ if (ret) { -++ printk("%s:memcpy_s failed!\n", __func__); -++ return NULL; -++ } -++ -++ if (!nfc_nand_probe(mtd, chip, nand_dev)) -++ return NULL; -++ -++ type = &nand_dev->flash_dev; -++ -++ if (!mtd->name) -++ mtd->name = type->name; -++ -++ 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 == 0) -++ nand_dev->oobsize = mtd->oobsize; -++ -++ if (nfc_param_adjust) -++ nfc_param_adjust(mtd, chip, nand_dev); -++} -++ -++ -++void nfc_show_info(struct mtd_info *mtd, const char *vendor, char *chipname) -++{ -++ struct nand_dev_t *nand_dev = &__nand_dev; -++ -++ 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) -++{ -++} -+diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile -+index 653923896..6915b062a 100644 -+--- a/drivers/mtd/spi-nor/Makefile -++++ b/drivers/mtd/spi-nor/Makefile -+@@ -17,6 +17,7 @@ spi-nor-objs += sst.o -+ spi-nor-objs += winbond.o -+ spi-nor-objs += xilinx.o -+ spi-nor-objs += xmc.o -++spi-nor-objs += bsp-generic.o -+ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o -+ -+ obj-$(CONFIG_MTD_SPI_NOR) += controllers/ -+diff --git a/drivers/mtd/spi-nor/bsp-generic.c b/drivers/mtd/spi-nor/bsp-generic.c -+new file mode 100755 -+index 000000000..09feee230 -+--- /dev/null -++++ b/drivers/mtd/spi-nor/bsp-generic.c -+@@ -0,0 +1,149 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++ -++#include "core.h" -++ -++static void gd25q256_default_init(struct spi_nor *nor) -++{ -++ /* -++ * Some manufacturer like GigaDevice may use different -++ * bit to set QE on different memories, so the MFR can't -++ * indicate the quad_enable method for this case, we need -++ * to set it in the default_init fixup hook. -++ */ -++ nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; -++} -++ -++static struct spi_nor_fixups gd25q256_fixups = { -++ .default_init = gd25q256_default_init, -++}; -++ -++static void macronix_default_init(struct spi_nor *nor) -++{ -++ nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; -++ nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; -++} -++ -++static const struct spi_nor_fixups macronix_fixups = { -++ .default_init = macronix_default_init, -++}; -++ -++static const struct flash_info general_parts[] = { -++ /* XTX */ -++ { "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) }, -++ { "xt25f32b", INFO(0x0b4016, 0, 64 * 1024, 256, -++ SPI_NOR_QUAD_READ) PARAMS(xtx), CLK_MHZ_2X(100) }, -++ /* FM */ -++ { "fm25q64", INFO(0xa14017, 0, 64 * 1024, 128, -++ SPI_NOR_QUAD_READ) PARAMS(spansion), CLK_MHZ_2X(80) }, -++ { "fm25q64a", INFO(0xa14018, 0, 64 * 1024, 256, -++ SPI_NOR_QUAD_READ) PARAMS(spansion), CLK_MHZ_2X(80) }, -++ /* EON */ -++ { "en25qh64a", INFO(0x1c7017, 0, 64 * 1024, 128, -++ SPI_NOR_QUAD_READ) PARAMS(eon), CLK_MHZ_2X(104) }, -++ /* GD */ -++ { "gd25lq32", INFO(0xc86016, 0, 64 * 1024, 64, -++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, -++ { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512, -++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -++ SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | -++ SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6) -++ .fixups = &gd25q256_fixups }, -++ { "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) }, -++ /* GigaDevice 1.8V */ -++ { "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) }, -++ /* macronix */ -++ { "mx25l6436f", INFO(0xc22017, 0, 64 * 1024, 128, -++ SPI_NOR_QUAD_READ) PARAMS(mxic), CLK_MHZ_2X(133) -++ .fixups = ¯onix_fixups }, -++ -++ { "mx25l25635f", INFO(0xc22019, 0, 64 * 1024, 512, -++ SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) PARAMS(mxic), CLK_MHZ_2X(84) -++ .fixups = ¯onix_fixups}, -++ { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, -++ SECT_4K | SPI_NOR_DUAL_READ) CLK_MHZ_2X(80) -++ .fixups = ¯onix_fixups }, -++ { "mx25v1635f", INFO(0xc22315, 0, 64 * 1024, 32, -++ SPI_NOR_QUAD_READ) PARAMS(mxic), CLK_MHZ_2X(80) -++ .fixups = ¯onix_fixups}, -++ /* Macronix/MXIC 1.8V */ -++ { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, -++ SECT_4K | SPI_NOR_QUAD_READ) PARAMS(mxic), CLK_MHZ_2X(84) -++ .fixups = ¯onix_fixups}, -++ { "mx25u12835f/mx25u12832f", INFO(0xc22538, 0, 64 * 1024, 256, -++ SPI_NOR_QUAD_READ) PARAMS(mxic), CLK_MHZ_2X(84) -++ .fixups = ¯onix_fixups}, -++ { "mx66l51235l/mx25l51245g", INFO(0xc2201a, 0, 64 * 1024, 1024, -++ SPI_NOR_QUAD_READ) PARAMS(mxic), CLK_MHZ_2X(133) -++ .fixups = ¯onix_fixups}, -++ /* Winbond */ -++ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, -++ SECT_4K | SPI_NOR_QUAD_READ) PARAMS(winbond), CLK_MHZ_2X(80) }, -++ { "w25q64fv(spi)/w25q64jv_iq", INFO(0xef4017, 0, 64 * 1024, 128, -++ SECT_4K | SPI_NOR_QUAD_READ) PARAMS(winbond), CLK_MHZ_2X(80) }, -++ { "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) }, -++ { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, -++ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) -++ PARAMS(winbond), CLK_MHZ_2X(80) }, -++ { "w25q01jvzeiq", INFO(0xef4021, 0, 64 * 1024, 2048, -++ SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) -++ PARAMS(winbond), CLK_MHZ_2X(90) }, -++ /* 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) }, -++ /* 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) }, -++ { "xm25qh64c", INFO(0x204017, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ) -++ PARAMS(xmc), CLK_MHZ_2X(104) }, -++ { "xm25qh128c", INFO(0x204018, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) -++ PARAMS(xmc), CLK_MHZ_2X(104) }, -++}; -++ -++static void spinor_default_init(struct spi_nor *nor) -++{ -++} -++ -++static const struct spi_nor_fixups general_fixups = { -++ .default_init = spinor_default_init, -++}; -++ -++const struct spi_nor_manufacturer spi_nor_general = { -++ .name = "general", -++ .parts = general_parts, -++ .nparts = ARRAY_SIZE(general_parts), -++ .fixups = &general_fixups, -++}; -+diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig -+index 5c0e0ec2e..b26962ef8 100644 -+--- a/drivers/mtd/spi-nor/controllers/Kconfig -++++ b/drivers/mtd/spi-nor/controllers/Kconfig -+@@ -16,6 +16,15 @@ config SPI_HISI_SFC -+ help -+ This enables support for HiSilicon FMC SPI NOR flash controller. -+ -++if ARCH_BSP -++config SPI_BSP_SFC -++ tristate "Vendor FMCV100 SPI-NOR Flash Controller(SFC)" -++ depends on HAS_IOMEM && HAS_DMA -++ help -++ This enables support for vendor flash memory contrller ver100 -++ (FMCV100)- SPI-NOR flash controller. -++endif -++ -+ config SPI_NXP_SPIFI -+ tristate "NXP SPI Flash Interface (SPIFI)" -+ depends on OF && (ARCH_LPC18XX || COMPILE_TEST) -+@@ -62,3 +71,33 @@ config SPI_INTEL_SPI_PLATFORM -+ -+ To compile this driver as a module, choose M here: the module -+ will be called intel-spi-platform. -++ -++if ARCH_BSP -++config MTD_SPI_IDS -++ bool "SPI Flash Timing Cycles Probe Function" -++ default n -++ help -++ This option enables sfc300/sfc350 used spi flash timing cylces -++ probe function. -++ If your use sfc300 and sfc350, this function should be select. -++ -++config CLOSE_SPI_8PIN_4IO -++ bool "Close SPI device Quad SPI mode for some 8PIN chip" -++ default y if ARCH_BSP -++ 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 BSP_SPI_BLOCK_PROTECT -++ bool "Vendor Spi Nor Device BP(Block Protect) Support" -++ depends on SPI_BSP_SFC -++ default y if SPI_BSP_SFC -++ help -++ 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. -++endif # ARCH_BSP -+diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile -+index e7abba491..23c19956c 100644 -+--- a/drivers/mtd/spi-nor/controllers/Makefile -++++ b/drivers/mtd/spi-nor/controllers/Makefile -+@@ -5,3 +5,6 @@ obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o -+ obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o -+ obj-$(CONFIG_SPI_INTEL_SPI_PCI) += intel-spi-pci.o -+ obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM) += intel-spi-platform.o -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_SPI_BSP_SFC) += bsp-sfc.o -++endif -+diff --git a/drivers/mtd/spi-nor/controllers/bsp-sfc.c b/drivers/mtd/spi-nor/controllers/bsp-sfc.c -+new file mode 100755 -+index 000000000..96733b13b -+--- /dev/null -++++ b/drivers/mtd/spi-nor/controllers/bsp-sfc.c -+@@ -0,0 +1,796 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#ifdef CONFIG_ARCH_BSP -++#include -++#include -++#include "../../mtdcore.h" -++#endif /* CONFIG_ARCH_BSP */ -++ -++#ifndef CONFIG_ARCH_BSP -++/* Hardware register offsets and field definitions */ -++#define FMC_CFG 0x00 -++#define FMC_CFG_OP_MODE_MASK BIT_MASK(0) -++#define FMC_CFG_OP_MODE_BOOT 0 -++#define FMC_CFG_OP_MODE_NORMAL 1 -++#define fmc_cfg_ecc_type(type) (((type) & 0x3) << 1) -++#define FMC_CFG_FLASH_SEL_MASK 0x6 -++#define mfc_ecc_type(type) (((type) & 0x7) << 5) -++#define FMC_ECC_TYPE_MASK GENMASK(7, 5) -++#define SPI_NOR_ADDR_MODE_MASK BIT_MASK(10) -++#define SPI_NOR_ADDR_MODE_3BYTES (0x0 << 10) -++#define SPI_NOR_ADDR_MODE_4BYTES (0x1 << 10) -++#define FMC_GLOBAL_CFG 0x04 -++#define FMC_GLOBAL_CFG_WP_ENABLE BIT(6) -++#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_INT 0x18 -++#define FMC_INT_OP_DONE BIT(0) -++#define FMC_INT_CLR 0x20 -++#define FMC_CMD 0x24 -++#define fmc_cmd_cmd1(cmd) ((cmd) & 0xff) -++#define FMC_ADDRL 0x2c -++#define FMC_OP_CFG 0x30 -++#define op_cfg_fm_cs(cs) ((cs) << 11) -++#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 FMC_DATA_NUM 0x38 -++#define fmc_data_num_cnt(cnt) ((cnt) & GENMASK(13, 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_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) & GENMASK(27, 0)) -++#define FMC_DMA_SADDR_D0 0x4c -++#define FMC_DMA_MAX_LEN (4096) -++#define FMC_DMA_MASK (FMC_DMA_MAX_LEN - 1) -++#define FMC_OP_DMA 0x68 -++#define op_ctrl_rd_opcode(code) (((code) & 0xff) << 16) -++#define op_ctrl_wr_opcode(code) (((code) & 0xff) << 8) -++#define op_ctrl_rw_op(op) ((op) << 1) -++#define OP_CTRL_DMA_OP_READY BIT(0) -++#define FMC_OP_READ 0x0 -++#define FMC_OP_WRITE 0x1 -++#define FMC_WAIT_TIMEOUT 1000000 -++ -++enum fmc_iftype { -++ IF_TYPE_STD, -++ IF_TYPE_DUAL, -++ IF_TYPE_DIO, -++ IF_TYPE_QUAD, -++ IF_TYPE_QIO, -++}; -++#endif /* CONFIG_ARCH_BSP */ -++ -++struct fmc_priv { -++ u32 chipselect; -++ u32 clkrate; -++ struct fmc_host *host; -++}; -++ -++#ifndef CONFIG_ARCH_BSP -++#define FMC_MAX_CHIP_NUM 2 -++#endif /* CONFIG_ARCH_BSP */ -++struct fmc_host { -++ struct device *dev; -++#ifdef CONFIG_ARCH_BSP -++ struct mutex *lock; -++#else -++ struct mutex lock; -++#endif /* CONFIG_ARCH_BSP */ -++ -++ void __iomem *regbase; -++ void __iomem *iobase; -++ struct clk *clk; -++ void *buffer; -++ dma_addr_t dma_buffer; -++ -++ struct spi_nor *nor[FMC_MAX_CHIP_NUM]; -++ u32 num_chip; -++#ifdef CONFIG_ARCH_BSP -++ struct fmc_priv priv[FMC_MAX_CHIP_NUM]; -++ unsigned int dma_len; -++#endif /* CONFIG_ARCH_BSP */ -++}; -++ -++static inline int bsp_spi_nor_wait_op_finish(const struct fmc_host *host) -++{ -++ u32 reg; -++ -++ if (!host) -++ return -1; -++ -++ return readl_poll_timeout(host->regbase + FMC_INT, reg, -++ (reg & FMC_INT_OP_DONE), 0, FMC_WAIT_TIMEOUT); -++} -++ -++static u8 bsp_spi_nor_get_if_type(enum spi_nor_protocol proto) -++{ -++ enum fmc_iftype if_type; -++ -++ switch (proto) { -++ 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 (u8)if_type; -++} -++ -++#ifdef CONFIG_ARCH_BSP -++static void spi_nor_switch_spi_type(struct fmc_host *host) -++{ -++ unsigned int reg; -++ -++ reg = readl(host->regbase + FMC_CFG); -++ reg &= ~FLASH_TYPE_SEL_MASK; -++ reg |= fmc_cfg_ecc_type(0); -++ writel(reg, host->regbase + FMC_CFG); -++} -++#endif /* CONFIG_ARCH_BSP */ -++ -++static void bsp_spi_nor_init(struct fmc_host *host) -++{ -++ u32 reg; -++ -++#ifdef CONFIG_ARCH_BSP -++ /* switch the flash type to spi nor */ -++ spi_nor_switch_spi_type(host); -++ -++ /* set the boot mode to normal */ -++ reg = readl(host->regbase + FMC_CFG); -++ if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) { -++ reg |= fmc_cfg_op_mode(FMC_CFG_OP_MODE_NORMAL); -++ writel(reg, host->regbase + FMC_CFG); -++ } -++ -++ /* hold on STR mode */ -++ reg = readl(host->regbase + FMC_GLOBAL_CFG); -++ reg &= (~FMC_GLOBAL_CFG_DTR_MODE); -++ writel(reg, host->regbase + FMC_GLOBAL_CFG); -++#endif /* CONFIG_ARCH_BSP */ -++ -++ /* set timming */ -++ reg = timing_cfg_tcsh(CS_HOLD_TIME) | -++ timing_cfg_tcss(CS_SETUP_TIME) | -++ timing_cfg_tshsl(CS_DESELECT_TIME); -++ writel(reg, host->regbase + FMC_SPI_TIMING_CFG); -++} -++ -++static int bsp_spi_nor_prep(struct spi_nor *nor) -++{ -++ struct fmc_priv *priv = nor->priv; -++ struct fmc_host *host = priv->host; -++ int ret; -++#ifdef CONFIG_ARCH_BSP -++ u32 clkrate; -++ -++ mutex_lock(&fmc_switch_mutex); -++ mutex_lock(host->lock); -++ -++ clkrate = min_t(u32, priv->clkrate, nor->clkrate); -++ ret = clk_set_rate(host->clk, clkrate); -++#else -++ mutex_lock(&host->lock); -++ -++ ret = clk_set_rate(host->clk, priv->clkrate); -++#endif /* CONFIG_ARCH_BSP */ -++ if (ret) -++ goto out; -++ -++ ret = clk_prepare_enable(host->clk); -++ if (ret) -++ goto out; -++ -++#ifdef CONFIG_ARCH_BSP -++ spi_nor_switch_spi_type(host); -++#endif /* CONFIG_ARCH_BSP */ -++ -++ return 0; -++ -++out: -++#ifdef CONFIG_ARCH_BSP -++ mutex_unlock(host->lock); -++#else -++ mutex_unlock(&host->lock); -++#endif /* CONFIG_ARCH_BSP */ -++ return ret; -++} -++ -++static void bsp_spi_nor_unprep(struct spi_nor *nor) -++{ -++ struct fmc_priv *priv = nor->priv; -++ struct fmc_host *host = priv->host; -++ -++ clk_disable_unprepare(host->clk); -++#ifdef CONFIG_ARCH_BSP -++ mutex_unlock(host->lock); -++ mutex_unlock(&fmc_switch_mutex); -++#else -++ mutex_unlock(&host->lock); -++#endif /* CONFIG_ARCH_BSP */ -++} -++ -++static int bsp_spi_nor_op_reg(struct spi_nor *nor, -++ u8 opcode, size_t len, u8 optype) -++{ -++ struct fmc_priv *priv = nor->priv; -++ struct fmc_host *host = priv->host; -++ u32 reg; -++ -++ reg = fmc_cmd_cmd1(opcode); -++ writel(reg, host->regbase + FMC_CMD); -++ -++ reg = fmc_data_num_cnt((unsigned int)len); -++ writel(reg, host->regbase + FMC_DATA_NUM); -++ -++#ifdef CONFIG_ARCH_BSP -++ reg = op_cfg_fm_cs(priv->chipselect) | OP_CFG_OEN_EN; -++#else -++ reg = op_cfg_fm_cs(priv->chipselect); -++#endif /* CONFIG_ARCH_BSP */ -++ writel(reg, host->regbase + FMC_OP_CFG); -++ -++ writel(0xff, host->regbase + FMC_INT_CLR); -++ reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START | optype; -++ writel(reg, host->regbase + FMC_OP); -++ -++ return bsp_spi_nor_wait_op_finish(host); -++} -++ -++static int bsp_spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, -++ size_t 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, -++ const u8 *buf, size_t 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; -++ u32 reg; -++ -++ reg = readl(host->regbase + 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; -++ writel(reg, host->regbase + FMC_CFG); -++ -++ writel(start_off, host->regbase + FMC_ADDRL); -++ -++#ifdef CONFIG_ARCH_BSP -++ reg = (unsigned int)dma_buf; -++ writel(reg, host->regbase + FMC_DMA_SADDR_D0); -++ -++#ifdef CONFIG_64BIT -++ reg = (dma_buf & FMC_DMA_SADDRH_MASK) >> 32; -++ writel(reg, host->regbase + FMC_DMA_SADDRH_D0); -++#endif -++#else -++ writel(dma_buf, host->regbase + FMC_DMA_SADDR_D0); -++#endif /* CONFIG_ARCH_BSP */ -++ -++ writel(fmc_dma_len_set(len), host->regbase + FMC_DMA_LEN); -++ -++ reg = op_cfg_fm_cs(priv->chipselect); -++ if (op_type == FMC_OP_READ) -++ if_type = bsp_spi_nor_get_if_type(nor->read_proto); -++ else -++ if_type = bsp_spi_nor_get_if_type(nor->write_proto); -++ reg |= op_cfg_mem_if_type(if_type); -++ if (op_type == FMC_OP_READ) -++ reg |= op_cfg_dummy_num(nor->read_dummy >> 3); -++ -++#ifdef CONFIG_ARCH_BSP -++ reg |= OP_CFG_OEN_EN; -++#endif /* CONFIG_ARCH_BSP */ -++ -++ writel(reg, host->regbase + FMC_OP_CFG); -++ -++ writel(0xff, host->regbase + FMC_INT_CLR); -++ 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); -++ writel(reg, host->regbase + FMC_OP_DMA); -++ -++ return bsp_spi_nor_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; -++ -++#ifdef CONFIG_ARCH_BSP -++ for (offset = 0; offset < len; offset += host->dma_len) { -++ size_t trans = min_t(size_t, host->dma_len, len - offset); -++#else -++ for (offset = 0; offset < len; offset += FMC_DMA_MAX_LEN) { -++ size_t trans = min_t(size_t, FMC_DMA_MAX_LEN, len - offset); -++#endif /* CONFIG_ARCH_BSP */ -++ -++ 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; -++ } -++ -++ ret = memcpy_s(read_buf + offset, trans, host->buffer, trans); -++ if (ret) { -++ printk("%s:memcpy_s failed\n", __func__); -++ return ret; -++ } -++ } -++ -++ 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; -++ -++#ifdef CONFIG_ARCH_BSP -++ for (offset = 0; offset < len; offset += host->dma_len) { -++ size_t trans = min_t(size_t, host->dma_len, len - offset); -++#else -++ for (offset = 0; offset < len; offset += FMC_DMA_MAX_LEN) { -++ size_t trans = min_t(size_t, FMC_DMA_MAX_LEN, len - offset); -++#endif /* CONFIG_ARCH_BSP */ -++ -++ ret = memcpy_s(host->buffer, trans, write_buf + offset, trans); -++ if (ret) { -++ printk("%s,memcpy_s failed\n", __func__); -++ return ret; -++ } -++ -++ 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. -++ */ -++#ifdef CONFIG_ARCH_BSP -++static int bsp_snor_device_register(struct mtd_info *mtd) -++{ -++ int ret; -++ -++ /* -++ * We do not add the whole spi flash as a mtdblock device, -++ * To avoid the number of nand partition +1. -++ */ -++ INIT_LIST_HEAD(&mtd->partitions); -++ ret = parse_mtd_partitions(mtd, NULL, NULL); -++ -++ return ret; -++} -++#endif /* CONFIG_ARCH_BSP */ -++ -++static const struct spi_nor_controller_ops bsp_controller_ops = { -++ .prepare = bsp_spi_nor_prep, -++ .unprepare = bsp_spi_nor_unprep, -++ .read_reg = bsp_spi_nor_read_reg, -++ .write_reg = bsp_spi_nor_write_reg, -++ .read = bsp_spi_nor_read, -++ .write = bsp_spi_nor_write, -++}; -++ -++/** -++ * 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 spi_nor_hwcaps hwcaps = { -++ .mask = SNOR_HWCAPS_READ | -++ SNOR_HWCAPS_READ_FAST | -++ SNOR_HWCAPS_READ_1_1_2 | -++#ifdef CONFIG_ARCH_BSP -++ SNOR_HWCAPS_READ_1_2_2 | -++#else -++ -++ SNOR_HWCAPS_READ_1_1_4 | -++#endif -++ SNOR_HWCAPS_PP, -++ }; -++ struct device *dev = NULL; -++ struct spi_nor *nor = NULL; -++ struct fmc_priv *priv = NULL; -++ struct mtd_info *mtd = NULL; -++ int ret; -++ -++ if (!host || !host->dev) -++ return -ENXIO; -++ -++ dev = host->dev; -++ 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 %pOF\n", -++ np); -++ return ret; -++ } -++ -++#ifdef CONFIG_ARCH_BSP -++ 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; -++ } -++#endif /* CONFIG_ARCH_BSP */ -++ -++ ret = of_property_read_u32(np, "spi-max-frequency", -++ &priv->clkrate); -++ if (ret) { -++ dev_err(dev, "There's no spi-max-frequency property for %pOF\n", -++ np); -++ return ret; -++ } -++ priv->host = host; -++ nor->priv = priv; -++ nor->controller_ops = &bsp_controller_ops; -++ -++#ifndef CONFIG_CLOSE_SPI_8PIN_4IO -++ hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4 | -++ SNOR_HWCAPS_READ_1_4_4 | -++ SNOR_HWCAPS_PP_1_1_4 | -++ SNOR_HWCAPS_PP_1_4_4; -++#endif -++ -++ ret = spi_nor_scan(nor, NULL, &hwcaps); -++ if (ret) -++ return ret; -++ -++ mtd = &nor->mtd; -++ mtd->name = np->name; -++#ifdef CONFIG_ARCH_BSP -++ ret = bsp_snor_device_register(mtd); -++ if (ret < 0) -++ return ret; -++ /* current chipselect has scanned, to detect next chipselect */ -++ fmc_cs_user[host->num_chip]++; -++#else -++ ret = mtd_device_register(mtd, NULL, 0); -++ if (ret) -++ return ret; -++ host->num_chip++; -++#endif /* CONFIG_ARCH_BSP */ -++ -++ 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; -++ int ret; -++ -++ for_each_available_child_of_node(dev->of_node, np) { -++#ifdef CONFIG_ARCH_BSP -++ if (host->num_chip == FMC_MAX_CHIP_NUM) { -++ dev_warn(dev, "Flash device number exceeds the maximum chipselect number\n"); -++ break; -++ } -++ if (fmc_cs_user[host->num_chip]) { -++ dev_warn(dev, "Current CS(%d) is occupied.\n", -++ host->num_chip); -++ continue; -++ } -++#endif /* CONFIG_ARCH_BSP */ -++ ret = bsp_spi_nor_register(np, host); -++ if (ret) -++ goto fail; -++ -++#ifdef CONFIG_ARCH_BSP -++ host->num_chip++; -++#endif /* CONFIG_ARCH_BSP */ -++ } -++ -++ return 0; -++ -++fail: -++ bsp_spi_nor_unregister_all(host); -++ return ret; -++} -++ -++#ifdef CONFIG_ARCH_BSP -++static int bsp_init_host(struct platform_device *pdev, struct fmc_host *host) -++{ -++ struct device *dev = &pdev->dev; -++ struct bsp_fmc *fmc = dev_get_drvdata(dev->parent); -++ -++ if (!fmc) { -++ dev_err(&pdev->dev, "get mfd fmc devices failed\n"); -++ return -ENXIO; -++ } -++ -++ 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; -++ -++ return 0; -++} -++#endif /* CONFIG_ARCH_BSP */ -++ -++static int bsp_spi_nor_probe(struct platform_device *pdev) -++{ -++ struct device *dev = &pdev->dev; -++#ifndef CONFIG_ARCH_BSP -++ struct resource *res; -++#endif /* CONFIG_ARCH_BSP */ -++ struct fmc_host *host; -++ int ret; -++ -++ host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); -++ if (!host) -++ return -ENOMEM; -++ -++ platform_set_drvdata(pdev, host); -++ host->dev = dev; -++ -++#ifdef CONFIG_ARCH_BSP -++ ret = bsp_init_host(pdev, host); -++ if (ret) { -++ return ret; -++ } -++#else -++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control"); -++ host->regbase = devm_ioremap_resource(dev, res); -++ if (IS_ERR(host->regbase)) -++ return PTR_ERR(host->regbase); -++ -++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); -++ host->iobase = devm_ioremap_resource(dev, res); -++ if (IS_ERR(host->iobase)) -++ return PTR_ERR(host->iobase); -++ -++ host->clk = devm_clk_get(dev, NULL); -++ if (IS_ERR(host->clk)) -++ return PTR_ERR(host->clk); -++ -++ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); /* 32:Addressing capability of the DMA */ -++ if (ret) { -++ dev_warn(dev, "Unable to set dma mask\n"); -++ return ret; -++ } -++ -++ host->buffer = dmam_alloc_coherent(dev, FMC_DMA_MAX_LEN, -++ &host->dma_buffer, GFP_KERNEL); -++ if (!host->buffer) -++ return -ENOMEM; -++#endif /* CONFIG_ARCH_BSP */ -++ -++ ret = clk_prepare_enable(host->clk); -++ if (ret) -++ return ret; -++ -++#ifndef CONFIG_ARCH_BSP -++ mutex_init(&host->lock); -++#endif /* CONFIG_ARCH_BSP */ -++ bsp_spi_nor_init(host); -++ ret = bsp_spi_nor_register_all(host); -++ if (ret) { -++#ifdef CONFIG_ARCH_BSP -++ dev_warn(dev, "spi nor register fail!\n"); -++#else -++ mutex_destroy(&host->lock); -++#endif /* CONFIG_ARCH_BSP */ -++ 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); -++ unsigned char cs; -++ -++ for (cs = 0; cs < FMC_MAX_CHIP_NUM; cs++) -++ fmc_cs_user[cs] = 0; -++ -++ if (host && host->clk) { -++ bsp_spi_nor_unregister_all(host); -++#ifndef CONFIG_ARCH_BSP -++ mutex_destroy(&host->lock); -++#endif /* CONFIG_ARCH_BSP */ -++ clk_disable_unprepare(host->clk); -++ } -++ -++ return 0; -++} -++ -++#ifdef CONFIG_ARCH_BSP -++ -++static void bsp_spi_nor_driver_shutdown(struct platform_device *pdev) -++{ -++ int i; -++ struct fmc_host *host = platform_get_drvdata(pdev); -++ -++ if (!host || !host->clk) -++ 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 || !host->clk) -++ 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 || !host->clk) -++ 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++) -++ bsp_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 */ -++#endif /* CONFIG_ARCH_BSP */ -++ -++static const struct of_device_id bsp_spi_nor_dt_ids[] = { -++ { .compatible = "vendor,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, -++#ifdef CONFIG_ARCH_BSP -++ .shutdown = bsp_spi_nor_driver_shutdown, -++#ifdef CONFIG_PM -++ .suspend = bsp_spi_nor_driver_suspend, -++ .resume = bsp_spi_nor_driver_resume, -++#endif -++#endif /* CONFIG_ARCH_BSP */ -++}; -++module_platform_driver(bsp_spi_nor_driver); -++ -++MODULE_LICENSE("GPL v2"); -++MODULE_DESCRIPTION("SPI Nor Flash Controller Driver"); -+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c -+index 09e112f37..016d48b85 100644 -+--- a/drivers/mtd/spi-nor/core.c -++++ b/drivers/mtd/spi-nor/core.c -+@@ -21,6 +21,9 @@ -+ #include -+ #include -+ #include -++#ifdef CONFIG_ARCH_BSP -++#include "linux/securec.h" -++#endif -+ -+ #include "core.h" -+ -+@@ -1486,6 +1489,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) -+ if (ret) -+ return ret; -+ -++#ifdef CONFIG_BSP_SPI_BLOCK_PROTECT -++ if ((nor->level) && (addr < nor->end_addr)) { -++ dev_err(nor->dev, "Error: The erase area was locked\n"); -++ spi_nor_unlock_and_unprep(nor); -++ return -EINVAL; -++ } -++#endif -+ /* whole-chip erase? */ -+ if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { -+ unsigned long timeout; -+@@ -1898,8 +1908,12 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -+ ret = spi_nor_lock_and_prep(nor); -+ if (ret) -+ return ret; -+- -++#ifdef CONFIG_ARCH_BSP -++ if (nor->params->locking_ops->unlock) -++ ret = nor->params->locking_ops->unlock(nor, ofs, len); -++#else -+ ret = nor->params->locking_ops->unlock(nor, ofs, len); -++#endif -+ -+ spi_nor_unlock_and_unprep(nor); -+ return ret; -+@@ -2021,6 +2035,9 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor) -+ } -+ -+ static const struct spi_nor_manufacturer *manufacturers[] = { -++#ifdef CONFIG_ARCH_BSP -++ &spi_nor_general, -++#endif -+ &spi_nor_atmel, -+ &spi_nor_catalyst, -+ &spi_nor_eon, -+@@ -2078,6 +2095,13 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) -+ dev_dbg(nor->dev, "error %d reading JEDEC ID\n", ret); -+ return ERR_PTR(ret); -+ } -++#ifdef CONFIG_ARCH_BSP -++ if ((id[0] == 0xff) || (id[0] == 0x00)) { -++ dev_err(nor->dev, "unrecognized Manufacturer ID\n"); -++ return ERR_PTR(-ENODEV); -++ } -++ printk("cmd read ID 0x%x 0x%x 0x%x\n", id[0], id[1], id[2]); -++#endif /* CONFIG_ARCH_BSP */ -+ -+ for (i = 0; i < ARRAY_SIZE(manufacturers); i++) { -+ info = spi_nor_search_part_by_id(manufacturers[i]->parts, -+@@ -2150,6 +2174,13 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, -+ ret = spi_nor_lock_and_prep(nor); -+ if (ret) -+ return ret; -++#ifdef CONFIG_BSP_SPI_BLOCK_PROTECT -++ if (nor->level && (to < nor->end_addr)) { -++ dev_err(nor->dev, "Error: The DMA write area was locked\n"); -++ spi_nor_unlock_and_unprep(nor); -++ return -EINVAL; -++ } -++#endif -+ -+ for (i = 0; i < len; ) { -+ ssize_t written; -+@@ -2197,6 +2228,250 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, -+ return ret; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_BSP_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; -++ unsigned char mfr_id; -++ -++ 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; -++ -++ mfr_id = JEDEC_MFR(info); -++ /* MFR_MACRONIX special chipsize process */ -++ if (mfr_id == 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) { /* general case */ -++ nor->end_addr = chipsize >> (lock_level_max - nor->level); -++ return; -++ } -++ } -++ -++ switch (mfr_id) { -++ case SNOR_MFR_MACRONIX: -++ 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->controller_ops->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) { -++ /* 9-15:(256 blocks, protected all) */ -++ nor->lock_level_max = LOCK_LEVEL_MAX(bp_num) - 5; /* level 10 = 16 - 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_BSP_SPI_BLOCK_PROTECT */ -++ -++static int spi_nor_sr3_to_reset(struct spi_nor *nor) -++{ -++ int ret; -++ unsigned char val; -++ -++ ret = nor->controller_ops->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->controller_ops->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_clear_dtr_mode(struct spi_nor *nor, const struct flash_info *info) -++{ -++ int ret = 0; -++ unsigned char cval = 0; -++ unsigned char val = 0; -++ -++ if (JEDEC_MFR(info) == SNOR_MFR_MACRONIX) { -++ ret = spi_nor_read_sr(nor, &val); -++ if (ret) -++ return ret; -++ if (val < 0) -++ return val; -++ -++ /* read Configuration Register for macronix's spi nor flash */ -++ ret = nor->controller_ops->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) { -++ ret = spi_nor_write_enable(nor); -++ if (ret) -++ return ret; -++ nor->bouncebuf[0] = val; -++ nor->bouncebuf[1] = (cval & (~CR_DUMMY_CYCLE)); -++ ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR, nor->bouncebuf, 2); /* 2:bit */ -++ } -++ } -++ -++ return ret; -++} -++ -++int spi_nor_dtrclear_pinreset(struct spi_nor *nor, const struct flash_info *info, const struct spi_nor_hwcaps *hwcaps) -++{ -++ int ret; -++ -++ ret = spi_nor_clear_dtr_mode(nor, info); -++ if (ret) { -++ dev_err(nor->dev, "Clear Dtr Mode Fail.\n"); -++ return ret; -++ } -++ -++ if (!(hwcaps->mask & (SNOR_HWCAPS_READ_1_1_4 | SNOR_HWCAPS_READ_1_4_4))) { -++ ret = spi_nor_reset_pin_enable(nor, info); -++ if (ret) { -++ dev_err(nor->dev, "Enable RESET# Fail.\n"); -++ return ret; -++ } -++ } -++ return 0; -++} -++#endif /* CONFIG_ARCH_BSP */ -++ -+ static int spi_nor_check(struct spi_nor *nor) -+ { -+ if (!nor->dev || -+@@ -3088,6 +3363,109 @@ static int spi_nor_set_addr_width(struct spi_nor *nor) -+ return 0; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++ -++static int bsp_spi_nor_init_params(struct spi_nor *nor) -++{ -++ errno_t err = -1; -++ -++ nor->params = devm_kzalloc(nor->dev, sizeof(*nor->params), GFP_KERNEL); -++ if (!nor->params) -++ return -ENOMEM; -++ -++ err = memcpy_s(nor->params, sizeof(struct spi_nor_flash_parameter), -++ nor->info->params, sizeof(*nor->params)); -++ if (err != EOK) { -++ devm_kfree(nor->dev, nor->params); -++ dev_dbg(nor->dev, "nor params memory copy fail\n"); -++ return err; -++ } -++ -++ spi_nor_info_init_params(nor); -++ -++ spi_nor_manufacturer_init_params(nor); -++ -++ spi_nor_late_init_params(nor); -++ -++ return 0; -++} -++ -++void spi_nor_driver_shutdown(struct spi_nor *nor) -++{ -++ /* disable 4-byte addressing if the device exceeds 16MiB */ -++ if (nor->addr_width == 4) -++ nor->params->set_4byte_addr_mode(nor, false); -++ -++ return; -++} -++EXPORT_SYMBOL_GPL(spi_nor_driver_shutdown); -++ -++#ifdef CONFIG_PM -++int spi_nor_suspend(struct spi_nor *nor, pm_message_t state) -++{ -++ return spi_nor_wait_till_ready(nor); -++} -++EXPORT_SYMBOL_GPL(spi_nor_suspend); -++ -++int bsp_spi_nor_resume(struct spi_nor *nor) -++{ -++ int ret; -++ const struct flash_info *info = NULL; -++ -++ struct spi_nor_hwcaps hwcaps = { -++ .mask = SNOR_HWCAPS_READ | -++ SNOR_HWCAPS_READ_FAST | -++ SNOR_HWCAPS_READ_1_1_2 | -++#ifdef CONFIG_ARCH_BSP -++ SNOR_HWCAPS_READ_1_2_2 | -++#else -++ -++ SNOR_HWCAPS_READ_1_1_4 | -++#endif -++ SNOR_HWCAPS_PP, -++ }; -++#ifndef CONFIG_CLOSE_SPI_8PIN_4IO -++ hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4 | -++ SNOR_HWCAPS_READ_1_4_4 | -++ SNOR_HWCAPS_PP_1_1_4 | -++ SNOR_HWCAPS_PP_1_4_4; -++#endif -++ -++ if (!info) -++ info = spi_nor_read_id(nor); -++ -++ /* Quad mode takes precedence over fast/normal */ -++#ifdef CONFIG_ARCH_BSP -++ if (info->params) { -++ bsp_spi_nor_init_params(nor); -++ } else -++#endif /* CONFIG_ARCH_BSP */ -++ { -++ ret = spi_nor_init_params(nor); -++ if (ret) -++ return ret; -++ } -++ ret = spi_nor_setup(nor, &hwcaps); -++ if (ret) -++ return ret; -++#ifdef CONFIG_ARCH_BSP -++ ret = spi_nor_dtrclear_pinreset(nor, info, &hwcaps); -++ if (ret) { -++ dev_err(nor->dev, "Clear Dtr Mode or Enable RESET Fail.\n"); -++ return ret; -++ } -++#endif -++ /* enable 4-byte addressing if the device exceeds 16MiB */ -++ if (nor->addr_width == 4 && JEDEC_MFR(info) != SNOR_MFR_SPANSION) { -++ nor->params->set_4byte_addr_mode(nor, true); -++ } -++ -++ return 0; -++} -++EXPORT_SYMBOL_GPL(bsp_spi_nor_resume); -++#endif /* End of CONFIG_PM */ -++#endif /* CONFIG_ARCH_BSP */ -++ -+ static void spi_nor_debugfs_init(struct spi_nor *nor, -+ const struct flash_info *info) -+ { -+@@ -3106,8 +3484,15 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor, -+ if (name) -+ info = spi_nor_match_id(nor, name); -+ /* Try to auto-detect if chip name wasn't specified or not found */ -++#ifdef CONFIG_ARCH_BSP -++ if (!info) { -++ dev_info(nor->dev, "SPI Nor ID Table Version %s\n", SPI_NOR_IDS_VER); -++ info = spi_nor_read_id(nor); -++ } -++#else -+ if (!info) -+ info = spi_nor_read_id(nor); -++#endif -+ if (IS_ERR_OR_NULL(info)) -+ return ERR_PTR(-ENOENT); -+ -+@@ -3193,11 +3578,22 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, -+ nor->flags |= SNOR_F_HAS_LOCK; -+ -+ mtd->_write = spi_nor_write; -+- -++#ifdef CONFIG_BSP_SPI_BLOCK_PROTECT -++ /* NOR block protection support */ -++ bsp_get_spi_lock_info(nor, info); -++#endif /* CONFIG_BSP_SPI_BLOCK_PROTECT */ -+ /* Init flash parameters based on flash_info struct and SFDP */ -+- ret = spi_nor_init_params(nor); -+- if (ret) -+- return ret; -++#ifdef CONFIG_ARCH_BSP -++ if (info->params) { -++ bsp_spi_nor_init_params(nor); -++ } else -++#endif /* CONFIG_ARCH_BSP */ -++ { -++ ret = spi_nor_init_params(nor); -++ if (ret) { -++ return ret; -++ } -++ } -+ -+ if (!mtd->name) -+ mtd->name = dev_name(dev); -+@@ -3206,6 +3602,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, -+ mtd->writesize = 1; -+ mtd->flags = MTD_CAP_NORFLASH; -+ mtd->size = nor->params->size; -++#ifdef CONFIG_ARCH_BSP -++ mtd->erasesize = info->sector_size; -++#endif -+ mtd->_erase = spi_nor_erase; -+ mtd->_read = spi_nor_read; -+ mtd->_resume = spi_nor_resume; -+@@ -3257,12 +3656,28 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, -+ if (ret) -+ return ret; -+ -++#ifdef CONFIG_ARCH_BSP -++ ret = spi_nor_dtrclear_pinreset(nor, info, hwcaps); -++ if (ret) { -++ dev_err(nor->dev, "Clear Dtr Mode or Enable RESET Fail.\n"); -++ return ret; -++ } -++#endif -+ if (info->flags & SPI_NOR_4B_OPCODES) -+ nor->flags |= SNOR_F_4B_OPCODES; -+ -+ ret = spi_nor_set_addr_width(nor); -+ if (ret) -+ return ret; -++#ifdef CONFIG_ARCH_BSP -++ /* choose the suitable clockrate */ -++ if ((info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) /* device supports dual or quad */ -++ && (hwcaps->mask & (~SNOR_HWCAPS_READ)) /* controller supports fast mode */ -++ && info->clkrate) -++ nor->clkrate = info->clkrate; -++ else -++ nor->clkrate = 24000000; -++#endif /* CONFIG_ARCH_BSP */ -+ -+ /* Send all the required SPI flash commands to initialize device */ -+ ret = spi_nor_init(nor); -+diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h -+index 788775bb6..b689de9ba 100644 -+--- a/drivers/mtd/spi-nor/core.h -++++ b/drivers/mtd/spi-nor/core.h -+@@ -312,10 +312,233 @@ struct flash_info { -+ * Must be used with SPI_NOR_4BIT_BP. -+ */ -+ -++#ifdef CONFIG_ARCH_BSP -++ const struct spi_nor_flash_parameter *params; -++ u32 clkrate; -++#endif /* CONFIG_ARCH_BSP */ -+ /* Part specific fixup hooks. */ -+ const struct spi_nor_fixups *fixups; -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++#define JEDEC_MFR(info) ((info)->id[0]) -++ -++#define SNOR_RD_MODES \ -++ (SNOR_HWCAPS_READ | \ -++ SNOR_HWCAPS_READ_FAST | \ -++ SNOR_HWCAPS_READ_1_1_2 | \ -++ SNOR_HWCAPS_READ_1_2_2 | \ -++ SNOR_HWCAPS_READ_1_1_4 | \ -++ SNOR_HWCAPS_READ_1_4_4) -++ -++#define SNOR_WR_MODES \ -++ (SNOR_HWCAPS_PP | \ -++ SNOR_HWCAPS_PP_1_1_4) -++ -++#define SNOR_EON_RD_MODES \ -++ (SNOR_HWCAPS_READ | \ -++ SNOR_HWCAPS_READ_FAST | \ -++ SNOR_HWCAPS_READ_1_1_2 | \ -++ SNOR_HWCAPS_READ_1_2_2) -++ -++#define SNOR_EON_WR_MODES \ -++ (SNOR_HWCAPS_PP) -++ -++#define SNOR_PARAGON_WR_MODES \ -++ (SNOR_HWCAPS_PP) -++ -++#define SNOR_MXIC_WR_MODES \ -++ (SNOR_HWCAPS_PP | \ -++ SNOR_HWCAPS_PP_1_4_4) -++ -++static const struct spi_nor_flash_parameter eon_params = { -++ .hwcaps.mask = SNOR_EON_RD_MODES | SNOR_EON_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ -++}; -++ -++static const struct spi_nor_flash_parameter esmt_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++}; -++ -++ -++static const struct spi_nor_flash_parameter paragon_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_PARAGON_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ -++}; -++ -++static const struct spi_nor_flash_parameter gd_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++}; -++ -++static const struct spi_nor_flash_parameter winbond_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(8, 0, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++}; -++ -++static const struct spi_nor_flash_parameter spansion_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++}; -++ -++ -++static const struct spi_nor_flash_parameter mxic_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_MXIC_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(8, 16, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_4_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_4_4, SNOR_PROTO_1_4_4), -++ -++}; -++ -++static const struct spi_nor_flash_parameter xmc_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++}; -++ -++static const struct spi_nor_flash_parameter micron_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(8, 8, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(0, 40, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++}; -++ -++static const struct spi_nor_flash_parameter micron_4k_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(1, 7, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(1, 9, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++}; -++ -++static const struct spi_nor_flash_parameter xtx_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ] = SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4] = SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4] = SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++}; -++ -++static const struct spi_nor_flash_parameter puya_params = { -++ .hwcaps.mask = SNOR_RD_MODES | SNOR_WR_MODES, -++ -++ .reads[SNOR_CMD_READ]= SNOR_OP_READ(0, 0, SPINOR_OP_READ, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_FAST]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_FAST, SNOR_PROTO_1_1_1), -++ .reads[SNOR_CMD_READ_1_1_2]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_2, SNOR_PROTO_1_1_2), -++ .reads[SNOR_CMD_READ_1_2_2]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_2_2, SNOR_PROTO_1_2_2), -++ .reads[SNOR_CMD_READ_1_1_4]= SNOR_OP_READ(0, 8, SPINOR_OP_READ_1_1_4, SNOR_PROTO_1_1_4), -++ .reads[SNOR_CMD_READ_1_4_4]= SNOR_OP_READ(0, 24, SPINOR_OP_READ_1_4_4, SNOR_PROTO_1_4_4), -++ -++ .page_programs[SNOR_CMD_PP] = SNOR_OP_PROGRAMS(SPINOR_OP_PP, SNOR_PROTO_1_1_1), -++ .page_programs[SNOR_CMD_PP_1_1_4] = SNOR_OP_PROGRAMS(SPINOR_OP_PP_1_1_4, SNOR_PROTO_1_1_4), -++ -++ //.quad_enable = puya_quad_enable, -++}; -++ -++#define PARAMS(_name) .params = &_name##_params -++ -++/* 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), -++#define SPI_NOR_IDS_VER "1.2" -++#endif /* CONFIG_ARCH_BSP */ -++ -+ /* Used when the "_ext_id" is two bytes at most */ -+ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ -+ .id = { \ -+@@ -398,6 +621,7 @@ extern const struct spi_nor_manufacturer spi_nor_sst; -+ extern const struct spi_nor_manufacturer spi_nor_winbond; -+ extern const struct spi_nor_manufacturer spi_nor_xilinx; -+ extern const struct spi_nor_manufacturer spi_nor_xmc; -++extern const struct spi_nor_manufacturer spi_nor_general; -+ -+ int spi_nor_write_enable(struct spi_nor *nor); -+ int spi_nor_write_disable(struct spi_nor *nor); -+diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig -+index 19059df86..a53a2651d 100644 -+--- a/drivers/net/ethernet/Kconfig -++++ b/drivers/net/ethernet/Kconfig -+@@ -85,6 +85,9 @@ source "drivers/net/ethernet/ibm/Kconfig" -+ source "drivers/net/ethernet/intel/Kconfig" -+ source "drivers/net/ethernet/mucse/Kconfig" -+ source "drivers/net/ethernet/xscale/Kconfig" -++if ARCH_BSP -++source "drivers/net/ethernet/vendor/Kconfig" -++endif -+ source "drivers/net/ethernet/netswift/Kconfig" -+ -+ config JME -+diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile -+index c824e6f78..d5e366866 100644 -+--- a/drivers/net/ethernet/Makefile -++++ b/drivers/net/ethernet/Makefile -+@@ -42,6 +42,9 @@ obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/ -+ obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/ -+ obj-$(CONFIG_NET_VENDOR_GOOGLE) += google/ -+ obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/ -++ifneq ($(CONFIG_ARCH_BSP), ) -++obj-$(CONFIG_NET_VENDOR_VENDOR) += vendor/ -++endif -+ obj-$(CONFIG_NET_VENDOR_HUAWEI) += huawei/ -+ obj-$(CONFIG_NET_VENDOR_IBM) += ibm/ -+ obj-$(CONFIG_NET_VENDOR_INTEL) += intel/ -+diff --git a/drivers/net/ethernet/vendor/Kconfig b/drivers/net/ethernet/vendor/Kconfig -+new file mode 100755 -+index 000000000..0c0922aee -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/Kconfig -+@@ -0,0 +1,33 @@ -++# -++# VENDOR device configuration -++# -++ -++config NET_VENDOR_VENDOR -++ bool "Vendor devices" -++ default y -++ depends on OF || ACPI -++ 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 Vendor devices. If you say Y, you will be asked -++ for your specific card in the following questions. -++ -++if NET_VENDOR_VENDOR -++ -++config VENDOR_FEMAC -++ tristate "Vendor Fast Ethernet MAC device support" -++ depends on HAS_IOMEM -++ select PHYLIB -++ select RESET_CONTROLLER -++ help -++ This selects the Vendor 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). -++ -++source "drivers/net/ethernet/vendor/gmac/Kconfig" -++endif # NET_VENDOR_VENDOR -+diff --git a/drivers/net/ethernet/vendor/Makefile b/drivers/net/ethernet/vendor/Makefile -+new file mode 100755 -+index 000000000..00c1e6e08 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/Makefile -+@@ -0,0 +1,7 @@ -++# SPDX-License-Identifier: GPL-2.0 -++# -++# Makefile for the VENDOR network device drivers. -++# -++ -++obj-$(CONFIG_ETH_GMAC) += gmac/ -++obj-$(CONFIG_VENDOR_FEMAC) += eth/ -+diff --git a/drivers/net/ethernet/vendor/eth/Kconfig b/drivers/net/ethernet/vendor/eth/Kconfig -+new file mode 100755 -+index 000000000..e4ae21998 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/Kconfig -+@@ -0,0 +1,19 @@ -++# -++# hleth family network device configuration -++# -++ -++menuconfig FEMAC -++ tristate "hleth(switch fabric) family network device support" -++ select PHYLIB -++ help -++ This selects the hleth family network device. -++ -++if FEMAC -++ -++config HLETH_MAX_RX_POOLS -++ int "hleth max rx pool size" -++ default "1024" -++ help -++ hleth max static rx pool size. -++ -++endif -+diff --git a/drivers/net/ethernet/vendor/eth/Makefile b/drivers/net/ethernet/vendor/eth/Makefile -+new file mode 100755 -+index 000000000..6011503cd -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/Makefile -+@@ -0,0 +1,12 @@ -++# -++# Makefile for the huanglong hleth device drivers. -++# -++ -++ccflags-y += -I$(srctree)/include/linux/ -++KBUILD_CFLAGS += -Werror -++ifeq ($(CONFIG_SOCT_DRV_BUILD_KO),y) -++obj-m += hl_eth.o -++else -++obj-y += hl_eth.o -++endif -++hl_eth-objs := mdio.o hleth.o phy.o autoeee.o -+diff --git a/drivers/net/ethernet/vendor/eth/autoeee.c b/drivers/net/ethernet/vendor/eth/autoeee.c -+new file mode 100755 -+index 000000000..4c1f99251 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/autoeee.c -+@@ -0,0 +1,225 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Autoeee phy settings. -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++#include -++#include "huanglong_phy.h" -++#include "hleth.h" -++ -++/*----------------------------Macro definition-------------------------------*/ -++#define NO_EEE 0 -++#define MAC_EEE 1 -++#define PHY_EEE 2 -++#define PARTNER_EEE 2 -++ -++#define debug(fmt...) -++struct phy_info { -++ char *name; -++ int phy_id; -++ char eee_available;/* eee support by this phy */ -++ int (*eee_init)(struct phy_device *phy_dev); -++}; -++ -++/* GMAC register definition */ -++#define EEE_ENABLE 0x488 -++#define BIT_EEE_ENABLE (1U << 0) -++#define EEE_TIMER 0x48C -++#define EEE_LINK_STATUS 0x490 -++#define BIT_PHY_LINK_STATUS (1U << 0) -++#define EEE_TIME_CLK_CNT 0x494 -++ -++/* ----------------------------phy register-------------------------------*/ -++/* MMD: MDIO Manageable Device */ -++#define MACR 0x0D -++#define MAADR 0x0E -++#define EEE_DEV 0x3 -++#define EEE_CAPABILITY 0x14 -++#define EEELPAR_DEV 0x7 -++#define EEELPAR 0x3D /* EEE link partner ability register */ -++#define EEE_ADVERTISE 0x3c -++#define LP_1000BASE_EEE (1U << 2) -++#define LP_100BASE_EEE (1U << 1) -++ -++static struct phy_info phy_info_table[]; -++ -++static struct phy_info *phy_search_ids(int phy_id) -++{ -++ int i; -++ struct phy_info *fit_info = NULL; -++ -++ for (i = 0; phy_info_table[i].name != NULL; i++) { -++ if (phy_id == phy_info_table[i].phy_id) -++ fit_info = &phy_info_table[i]; -++ } -++ -++ return fit_info; -++} -++ -++static inline int phy_mmd_read(struct phy_device *phy_dev, -++ u32 mmd_device, u32 regnum) -++{ -++ phy_write(phy_dev, MACR, mmd_device);/* function = 00 address */ -++ phy_write(phy_dev, MAADR, regnum); -++ phy_write(phy_dev, MACR, 0x4000 | mmd_device);/* function = 01 data */ -++ -++ return phy_read(phy_dev, MAADR); -++} -++ -++static inline int phy_mmd_write(struct phy_device *phy_dev, -++ u32 mmd_device, u32 regnum, u16 val) -++{ -++ phy_write(phy_dev, MACR, mmd_device);/* function = 00 address */ -++ phy_write(phy_dev, MAADR, regnum); -++ phy_write(phy_dev, MACR, 0x4000 | mmd_device);/* function = 01 data */ -++ -++ return phy_write(phy_dev, MAADR, val); -++} -++ -++static int smsc_lan8740_init(struct phy_device *phy_dev) -++{ -++ static int first_time; -++ int v, eee_type = 0; -++ /* Realtek LAN 8740 start to enable eee */ -++ int eee_lan; -++ -++ if (first_time == 0) { -++ eee_lan = phy_read(phy_dev, 0x10); -++ eee_lan |= 0x4; -++ phy_write(phy_dev, 0x10, eee_lan); -++ eee_lan = phy_read(phy_dev, 0x10); -++ debug("eee enable bit[45?] :%x\n", eee_lan); -++ /* auto negotiate after enable eee */ -++ eee_lan = phy_read(phy_dev, 0x0); -++ eee_lan |= 0x200; -++ phy_write(phy_dev, 0x0, eee_lan); -++ first_time = 1; -++ } -++ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); -++ debug("EEELPAR = 0x%x\n", v); -++ -++ if (v & LP_100BASE_EEE) -++ eee_type |= HLETH_P_MAC_PORTSET_SPD_100M; -++ -++ return eee_type; -++} -++ -++static int rtl8211eg_init(struct phy_device *phy_dev) -++{ -++ int eee_type = 0, v; -++ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); -++ debug("EEELPAR = 0x%x\n", v); -++ -++ if (v & LP_100BASE_EEE) -++ eee_type |= HLETH_P_MAC_PORTSET_SPD_100M; -++ -++ return eee_type; -++} -++ -++static int festa_eee_init(struct phy_device *phy_dev) -++{ -++ static int first_time_init; -++ int v, eee_type = 0; -++ -++ if (first_time_init == 0) { -++ /* EEE_CAPABILITY register: support 100M-BaseT */ -++ v = phy_mmd_read(phy_dev, EEE_DEV, EEE_CAPABILITY); -++ phy_mmd_write(phy_dev, EEE_DEV, EEE_CAPABILITY, v | (1<<1)); -++ -++ /* EEE_ADVERTISEMENT register: advertising 100M-BaseT */ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEE_ADVERTISE); -++ phy_mmd_write(phy_dev, EEELPAR_DEV, EEE_ADVERTISE, v | (1<<1)); -++ -++ v = phy_read(phy_dev, MII_BMCR); -++ v |= (BMCR_ANENABLE | BMCR_ANRESTART); -++ phy_write(phy_dev, MII_BMCR, v);/* auto-neg restart */ -++ -++ first_time_init = 1; -++ } -++ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); -++ debug("EEELPAR = 0x%x\n", v); -++ -++ if (v & LP_100BASE_EEE) -++ eee_type |= HLETH_P_MAC_PORTSET_SPD_100M; -++ -++ return eee_type; -++} -++ -++static struct phy_info phy_info_table[] = { -++ /* phy_name phy_id eee_available phy_driver */ -++ /* SMSC */ -++ {"SMSC LAN8740", 0x0007c110, MAC_EEE, &smsc_lan8740_init}, -++ /* Realtek */ -++ {"Realtek 8211EG", 0x001cc915, PHY_EEE, &rtl8211eg_init}, -++ {"Festa V220", HUANGLONG_PHY_ID_FESTAV220, MAC_EEE, &festa_eee_init}, -++ {"Festa V212", HUANGLONG_PHY_ID_FESTAV212, MAC_EEE, &festa_eee_init}, -++ {0, 0, 0, 0}, -++}; -++ -++void hleth_autoeee_init(struct hleth_netdev_priv *priv, int link_stat) -++{ -++ int phy_id = priv->phy->phy_id; -++ int eee_available, lp_eee_capable; -++ unsigned int v; -++ struct phy_info *phy_info = NULL; -++ -++ if (priv->eee_init != NULL) -++ goto eee_init; -++ -++ phy_info = phy_search_ids(phy_id); -++ if (phy_info != NULL) { -++ eee_available = phy_info->eee_available; -++ debug("fit phy_id:0x%x, phy_name:%s, eee:%d\n", -++ phy_info->phy_id, phy_info->name, eee_available); -++ -++ if (eee_available == 0) -++ goto not_support; -++ -++ if (eee_available == PHY_EEE) { -++ debug("enter phy-EEE mode\n"); -++ v = readl(priv->port_base + EEE_ENABLE); -++ v &= ~BIT_EEE_ENABLE;/* disable auto-EEE */ -++ writel(v, priv->port_base + EEE_ENABLE); -++ return; -++ } -++ -++ priv->eee_init = phy_info->eee_init; -++eee_init: -++ lp_eee_capable = priv->eee_init(priv->phy); -++ if (link_stat & HLETH_P_MAC_PORTSET_LINKED) { -++ if (lp_eee_capable & link_stat) { -++ /* EEE_1us: 0x7c for 125M */ -++ writel(0x7c, priv->port_base + EEE_TIME_CLK_CNT); -++ writel(0x4002710, priv->port_base + EEE_TIMER); -++ -++ v = readl(priv->port_base + EEE_LINK_STATUS); -++ v |= 0x3 << 1;/* auto EEE and ... */ -++ v |= BIT_PHY_LINK_STATUS;/* phy linkup */ -++ writel(v, priv->port_base + EEE_LINK_STATUS); -++ -++ v = readl(priv->port_base + EEE_ENABLE); -++ v |= BIT_EEE_ENABLE;/* enable EEE */ -++ writel(v, priv->port_base + EEE_ENABLE); -++ -++ debug("enter auto-EEE mode\n"); -++ } else { -++ debug("link partner not support EEE\n"); -++ }; -++ } else { -++ v = readl(priv->port_base + EEE_LINK_STATUS); -++ v &= ~(BIT_PHY_LINK_STATUS);/* phy linkdown */ -++ writel(v, priv->port_base + EEE_LINK_STATUS); -++ } -++ return; -++ } -++ -++not_support: -++ priv->eee_init = NULL; -++ debug("non-EEE mode\n"); -++} -++ -+diff --git a/drivers/net/ethernet/vendor/eth/driver_obj.mk b/drivers/net/ethernet/vendor/eth/driver_obj.mk -+new file mode 100755 -+index 000000000..7f50fbef3 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/driver_obj.mk -+@@ -0,0 +1,3 @@ -++obj-$(CONFIG_FEPHY) += huanglong/netphy/ -++obj-$(CONFIG_FEMAC) += huanglong/eth/ -++ -+diff --git a/drivers/net/ethernet/vendor/eth/festa.h b/drivers/net/ethernet/vendor/eth/festa.h -+new file mode 100755 -+index 000000000..6d4893f0f -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/festa.h -+@@ -0,0 +1,534 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Festa parameters. -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++0x33f9, 0xbd, -++0x33fa, 0x34, -++0x33fb, 0x00, -++0x33fc, 0x39, -++0x3400, 0x39, -++0x3401, 0xCC, -++0x3402, 0x17, -++0x3403, 0x01, -++0x3404, 0xFD, -++0x3405, 0xFF, -++0x3406, 0xF2, -++0x3407, 0x4F, -++0x3408, 0xFD, -++0x3409, 0xFF, -++0x340A, 0xF0, -++0x340B, 0xF6, -++0x340C, 0x36, -++0x340D, 0x08, -++0x340E, 0x26, -++0x340F, 0x05, -++0x3410, 0xC6, -++0x3411, 0x01, -++0x3412, 0xF7, -++0x3413, 0x36, -++0x3414, 0x08, -++0x3415, 0xF6, -++0x3416, 0x08, -++0x3417, 0x00, -++0x3418, 0xF7, -++0x3419, 0x36, -++0x341A, 0x09, -++0x341B, 0xC6, -++0x341C, 0x01, -++0x341D, 0xF7, -++0x341E, 0x08, -++0x341F, 0x00, -++0x3420, 0x20, -++0x3421, 0x1B, -++0x3422, 0xCC, -++0x3423, 0x35, -++0x3424, 0x9F, -++0x3425, 0x1A, -++0x3426, 0xB3, -++0x3427, 0x00, -++0x3428, 0xEE, -++0x3429, 0x27, -++0x342A, 0x0F, -++0x342B, 0xFD, -++0x342C, 0x00, -++0x342D, 0xEE, -++0x342E, 0x7F, -++0x342F, 0x01, -++0x3430, 0xDB, -++0x3431, 0x7F, -++0x3432, 0x01, -++0x3433, 0xCD, -++0x3434, 0xCC, -++0x3435, 0x34, -++0x3436, 0x4B, -++0x3437, 0xFD, -++0x3438, 0x00, -++0x3439, 0xCC, -++0x343A, 0x78, -++0x343B, 0x08, -++0x343C, 0x00, -++0x343D, 0xF6, -++0x343E, 0x08, -++0x343F, 0x00, -++0x3440, 0xC1, -++0x3441, 0x02, -++0x3442, 0x26, -++0x3443, 0xDE, -++0x3444, 0xF6, -++0x3445, 0x36, -++0x3446, 0x09, -++0x3447, 0xF7, -++0x3448, 0x08, -++0x3449, 0x00, -++0x344A, 0x39, -++0x344B, 0xBD, -++0x344C, 0xF7, -++0x344D, 0xFA, -++0x344E, 0x08, -++0x344F, 0xCC, -++0x3450, 0x20, -++0x3451, 0xA1, -++0x3452, 0xED, -++0x3453, 0x05, -++0x3454, 0xC6, -++0x3455, 0xA4, -++0x3456, 0xED, -++0x3457, 0x03, -++0x3458, 0xBD, -++0x3459, 0x8B, -++0x345A, 0x82, -++0x345B, 0xE7, -++0x345C, 0x07, -++0x345D, 0xC0, -++0x345E, 0x02, -++0x345F, 0x27, -++0x3460, 0x11, -++0x3461, 0x5A, -++0x3462, 0x27, -++0x3463, 0x0E, -++0x3464, 0x5A, -++0x3465, 0x27, -++0x3466, 0x39, -++0x3467, 0x5A, -++0x3468, 0x27, -++0x3469, 0x36, -++0x346A, 0x5A, -++0x346B, 0x27, -++0x346C, 0x51, -++0x346D, 0x5A, -++0x346E, 0x27, -++0x346F, 0x4E, -++0x3470, 0x20, -++0x3471, 0x6D, -++0x3472, 0x18, -++0x3473, 0xFE, -++0x3474, 0x30, -++0x3475, 0x1E, -++0x3476, 0xF6, -++0x3477, 0x30, -++0x3478, 0x22, -++0x3479, 0x18, -++0x347A, 0x3A, -++0x347B, 0x18, -++0x347C, 0xE6, -++0x347D, 0x00, -++0x347E, 0x58, -++0x347F, 0x58, -++0x3480, 0xE7, -++0x3481, 0x02, -++0x3482, 0x1A, -++0x3483, 0xEE, -++0x3484, 0x05, -++0x3485, 0x18, -++0x3486, 0xE6, -++0x3487, 0x00, -++0x3488, 0xC4, -++0x3489, 0x03, -++0x348A, 0xEA, -++0x348B, 0x02, -++0x348C, 0x18, -++0x348D, 0xE7, -++0x348E, 0x00, -++0x348F, 0x1A, -++0x3490, 0xEE, -++0x3491, 0x03, -++0x3492, 0x18, -++0x3493, 0xE6, -++0x3494, 0x00, -++0x3495, 0xC4, -++0x3496, 0x1F, -++0x3497, 0xCA, -++0x3498, 0xC0, -++0x3499, 0x18, -++0x349A, 0xE7, -++0x349B, 0x00, -++0x349C, 0xC6, -++0x349D, 0x09, -++0x349E, 0x20, -++0x349F, 0x3A, -++0x34A0, 0x1A, -++0x34A1, 0xEE, -++0x34A2, 0x05, -++0x34A3, 0x18, -++0x34A4, 0xE6, -++0x34A5, 0x00, -++0x34A6, 0xC4, -++0x34A7, 0x03, -++0x34A8, 0xCA, -++0x34A9, 0x5C, -++0x34AA, 0x18, -++0x34AB, 0xE7, -++0x34AC, 0x00, -++0x34AD, 0x1A, -++0x34AE, 0xEE, -++0x34AF, 0x03, -++0x34B0, 0x18, -++0x34B1, 0xE6, -++0x34B2, 0x00, -++0x34B3, 0xC4, -++0x34B4, 0x1F, -++0x34B5, 0xCA, -++0x34B6, 0x20, -++0x34B7, 0x18, -++0x34B8, 0xE7, -++0x34B9, 0x00, -++0x34BA, 0xC6, -++0x34BB, 0x74, -++0x34BC, 0x20, -++0x34BD, 0x1C, -++0x34BE, 0x1A, -++0x34BF, 0xEE, -++0x34C0, 0x05, -++0x34C1, 0x18, -++0x34C2, 0xE6, -++0x34C3, 0x00, -++0x34C4, 0xC4, -++0x34C5, 0x03, -++0x34C6, 0xCA, -++0x34C7, 0x48, -++0x34C8, 0x18, -++0x34C9, 0xE7, -++0x34CA, 0x00, -++0x34CB, 0x1A, -++0x34CC, 0xEE, -++0x34CD, 0x03, -++0x34CE, 0x18, -++0x34CF, 0xE6, -++0x34D0, 0x00, -++0x34D1, 0xC4, -++0x34D2, 0x1F, -++0x34D3, 0xCA, -++0x34D4, 0x20, -++0x34D5, 0x18, -++0x34D6, 0xE7, -++0x34D7, 0x00, -++0x34D8, 0xC6, -++0x34D9, 0x52, -++0x34DA, 0x18, -++0x34DB, 0x08, -++0x34DC, 0x18, -++0x34DD, 0xE7, -++0x34DE, 0x00, -++0x34DF, 0xAE, -++0x34E0, 0x00, -++0x34E1, 0x38, -++0x34E2, 0x39, -++0x34E3, 0x3C, -++0x34E4, 0x37, -++0x34E5, 0x36, -++0x34E6, 0x30, -++0x34E7, 0x1A, -++0x34E8, 0xEE, -++0x34E9, 0x00, -++0x34EA, 0x18, -++0x34EB, 0xE6, -++0x34EC, 0x00, -++0x34ED, 0x26, -++0x34EE, 0x52, -++0x34EF, 0xF6, -++0x34F0, 0x00, -++0x34F1, 0x5C, -++0x34F2, 0xC5, -++0x34F3, 0x04, -++0x34F4, 0x27, -++0x34F5, 0x06, -++0x34F6, 0xCC, -++0x34F7, 0x35, -++0x34F8, 0xFC, -++0x34F9, 0xBD, -++0x34FA, 0xF1, -++0x34FB, 0xC8, -++0x34FC, 0xC6, -++0x34FD, 0x52, -++0x34FE, 0xBD, -++0x34FF, 0xDD, -++0x3500, 0x68, -++0x3501, 0x5D, -++0x3502, 0x27, -++0x3503, 0x03, -++0x3504, 0xBD, -++0x3505, 0xC0, -++0x3506, 0x17, -++0x3507, 0xF6, -++0x3508, 0x00, -++0x3509, 0x46, -++0x350A, 0xC5, -++0x350B, 0x0C, -++0x350C, 0x26, -++0x350D, 0x0A, -++0x350E, 0x1A, -++0x350F, 0xEE, -++0x3510, 0x00, -++0x3511, 0x18, -++0x3512, 0x6F, -++0x3513, 0x00, -++0x3514, 0xC6, -++0x3515, 0x07, -++0x3516, 0x20, -++0x3517, 0x26, -++0x3518, 0xFC, -++0x3519, 0x30, -++0x351A, 0x0C, -++0x351B, 0xBD, -++0x351C, 0x92, -++0x351D, 0x8B, -++0x351E, 0xBD, -++0x351F, 0x9D, -++0x3520, 0xAC, -++0x3521, 0xF6, -++0x3522, 0x31, -++0x3523, 0x52, -++0x3524, 0x27, -++0x3525, 0x04, -++0x3526, 0xC6, -++0x3527, 0x01, -++0x3528, 0x20, -++0x3529, 0x02, -++0x352A, 0xC6, -++0x352B, 0x02, -++0x352C, 0x37, -++0x352D, 0xC6, -++0x352E, 0x51, -++0x352F, 0xBD, -++0x3530, 0xDC, -++0x3531, 0xC8, -++0x3532, 0x31, -++0x3533, 0x7F, -++0x3534, 0x02, -++0x3535, 0x23, -++0x3536, 0xC6, -++0x3537, 0x02, -++0x3538, 0x1A, -++0x3539, 0xEE, -++0x353A, 0x00, -++0x353B, 0x18, -++0x353C, 0xE7, -++0x353D, 0x00, -++0x353E, 0x38, -++0x353F, 0x38, -++0x3540, 0x39, -++0x3541, 0xC6, -++0x3542, 0x52, -++0x3543, 0xBD, -++0x3544, 0xDD, -++0x3545, 0x68, -++0x3546, 0x5D, -++0x3547, 0x27, -++0x3548, 0x03, -++0x3549, 0xBD, -++0x354A, 0xC0, -++0x354B, 0x17, -++0x354C, 0xF6, -++0x354D, 0x00, -++0x354E, 0x46, -++0x354F, 0xC5, -++0x3550, 0x0C, -++0x3551, 0x26, -++0x3552, 0x0A, -++0x3553, 0x1A, -++0x3554, 0xEE, -++0x3555, 0x00, -++0x3556, 0x18, -++0x3557, 0x6F, -++0x3558, 0x00, -++0x3559, 0xC6, -++0x355A, 0x07, -++0x355B, 0x20, -++0x355C, 0xE1, -++0x355D, 0xC6, -++0x355E, 0x51, -++0x355F, 0xBD, -++0x3560, 0xDD, -++0x3561, 0x68, -++0x3562, 0x5D, -++0x3563, 0x26, -++0x3564, 0x04, -++0x3565, 0xC6, -++0x3566, 0x02, -++0x3567, 0x20, -++0x3568, 0xD5, -++0x3569, 0xF6, -++0x356A, 0x31, -++0x356B, 0x52, -++0x356C, 0x26, -++0x356D, 0x27, -++0x356E, 0xF6, -++0x356F, 0x00, -++0x3570, 0x41, -++0x3571, 0xC5, -++0x3572, 0x10, -++0x3573, 0x26, -++0x3574, 0x20, -++0x3575, 0xF6, -++0x3576, 0x02, -++0x3577, 0x23, -++0x3578, 0xC1, -++0x3579, 0x02, -++0x357A, 0x24, -++0x357B, 0x19, -++0x357C, 0x18, -++0x357D, 0xFE, -++0x357E, 0x02, -++0x357F, 0x24, -++0x3580, 0x18, -++0x3581, 0xAD, -++0x3582, 0x00, -++0x3583, 0xF6, -++0x3584, 0x02, -++0x3585, 0x22, -++0x3586, 0x27, -++0x3587, 0x0D, -++0x3588, 0xC6, -++0x3589, 0x02, -++0x358A, 0x37, -++0x358B, 0xC6, -++0x358C, 0x51, -++0x358D, 0xBD, -++0x358E, 0xDC, -++0x358F, 0xC8, -++0x3590, 0x31, -++0x3591, 0xC6, -++0x3592, 0x02, -++0x3593, 0x20, -++0x3594, 0xA9, -++0x3595, 0x1A, -++0x3596, 0xEE, -++0x3597, 0x00, -++0x3598, 0x18, -++0x3599, 0x6F, -++0x359A, 0x00, -++0x359B, 0xC6, -++0x359C, 0x03, -++0x359D, 0x20, -++0x359E, 0x9F, -++0x359F, 0xF6, -++0x35A0, 0x01, -++0x35A1, 0xDB, -++0x35A2, 0xC1, -++0x35A3, 0x08, -++0x35A4, 0x24, -++0x35A5, 0x55, -++0x35A6, 0xBD, -++0x35A7, 0xF8, -++0x35A8, 0x51, -++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, 0xCD, -++0x35BD, 0xBD, -++0x35BE, 0xC0, -++0x35BF, 0xBF, -++0x35C0, 0x20, -++0x35C1, 0x36, -++0x35C2, 0xCC, -++0x35C3, 0x01, -++0x35C4, 0xCD, -++0x35C5, 0xBD, -++0x35C6, 0xC1, -++0x35C7, 0x59, -++0x35C8, 0x20, -++0x35C9, 0x2E, -++0x35CA, 0xCC, -++0x35CB, 0x01, -++0x35CC, 0xCD, -++0x35CD, 0xBD, -++0x35CE, 0x34, -++0x35CF, 0xE3, -++0x35D0, 0x20, -++0x35D1, 0x26, -++0x35D2, 0xCC, -++0x35D3, 0x01, -++0x35D4, 0xCD, -++0x35D5, 0xBD, -++0x35D6, 0xC3, -++0x35D7, 0xC1, -++0x35D8, 0x20, -++0x35D9, 0x1E, -++0x35DA, 0xCC, -++0x35DB, 0x01, -++0x35DC, 0xCD, -++0x35DD, 0xBD, -++0x35DE, 0xC4, -++0x35DF, 0x69, -++0x35E0, 0x20, -++0x35E1, 0x16, -++0x35E2, 0xCC, -++0x35E3, 0x01, -++0x35E4, 0xCD, -++0x35E5, 0xBD, -++0x35E6, 0xC5, -++0x35E7, 0x3B, -++0x35E8, 0x20, -++0x35E9, 0x0E, -++0x35EA, 0xCC, -++0x35EB, 0x01, -++0x35EC, 0xCD, -++0x35ED, 0xBD, -++0x35EE, 0xC6, -++0x35EF, 0x77, -++0x35F0, 0x20, -++0x35F1, 0x06, -++0x35F2, 0xCC, -++0x35F3, 0x01, -++0x35F4, 0xCD, -++0x35F5, 0xBD, -++0x35F6, 0xC8, -++0x35F7, 0x5F, -++0x35F8, 0xF7, -++0x35F9, 0x01, -++0x35FA, 0xDB, -++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, 0x00, -++0x3400, 0x01, -++0x33f8, 0x01 -+\ No newline at end of file -+diff --git a/drivers/net/ethernet/vendor/eth/hleth.c b/drivers/net/ethernet/vendor/eth/hleth.c -+new file mode 100755 -+index 000000000..e8d70d94d -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/hleth.c -+@@ -0,0 +1,2503 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Main driver functions. -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "mdio.h" -++#include "hleth_dbg.h" -++#include "hleth.h" -++ -++/* default: softirq recv packets, disable hardirq recv */ -++ -++/* default, eth enable */ -++static bool hleth_disable; -++ -++static void hleth_tx_timeout_task(struct work_struct *ws); -++ -++#ifdef MODULE -++module_param(hleth_disable, bool, 0); -++#else -++static int __init hleth_noeth(char *str) -++{ -++ hleth_disable = true; -++ -++ return 0; -++} -++ -++early_param("noeth", hleth_noeth); -++#endif -++ -++#include "pm.c" -++ -++static int hleth_hw_set_macaddress(const struct hleth_netdev_priv *priv, -++ const unsigned char *mac) -++{ -++ u32 reg; -++ -++ if (priv->port == HLETH_PORT_1) { -++ reg = hleth_readl(priv->glb_base, HLETH_GLB_DN_HOSTMAC_ENA); -++ reg |= HLETH_GLB_DN_HOSTMAC_ENA_BIT; -++ hleth_writel(priv->glb_base, reg, HLETH_GLB_DN_HOSTMAC_ENA); -++ } -++ -++ reg = mac[1] | (mac[0] << 8); /* 8:left shift val */ -++ if (priv->port == HLETH_PORT_0) -++ hleth_writel(priv->glb_base, reg, HLETH_GLB_HOSTMAC_H16); -++ else -++ hleth_writel(priv->glb_base, reg, HLETH_GLB_DN_HOSTMAC_H16); -++ -++ reg = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24); /* 2,3,4,5,8,16,24:left shift val */ -++ if (priv->port == HLETH_PORT_0) -++ hleth_writel(priv->glb_base, reg, HLETH_GLB_HOSTMAC_L32); -++ else -++ hleth_writel(priv->glb_base, reg, HLETH_GLB_DN_HOSTMAC_L32); -++ -++ return 0; -++} -++ -++static void hleth_irq_enable(struct hleth_netdev_priv *priv, int irqs) -++{ -++ u32 val; -++ -++ local_lock(priv); -++ val = hleth_readl(priv->glb_base, HLETH_GLB_IRQ_ENA); -++ hleth_writel(priv->glb_base, val | (u32)irqs, HLETH_GLB_IRQ_ENA); -++ local_unlock(priv); -++} -++ -++static void hleth_irq_disable(struct hleth_netdev_priv *priv, int irqs) -++{ -++ u32 val; -++ -++ local_lock(priv); -++ val = hleth_readl(priv->glb_base, HLETH_GLB_IRQ_ENA); -++ hleth_writel(priv->glb_base, val & (u32)(~irqs), HLETH_GLB_IRQ_ENA); -++ local_unlock(priv); -++} -++ -++static void hleth_clear_irqstatus(struct hleth_netdev_priv *priv, int irqs) -++{ -++ local_lock(priv); -++ hleth_writel(priv->glb_base, irqs, HLETH_GLB_IRQ_RAW); -++ local_unlock(priv); -++} -++ -++static int hleth_port_reset(const struct hleth_netdev_priv *priv) -++{ -++ struct hleth_platdrv_data *pdata = dev_get_drvdata(priv->dev); -++ u32 rst_bit = 0; -++ u32 val; -++ -++ if (pdata->hleth_real_port_cnt == 1) { -++ rst_bit = HLETH_GLB_SOFT_RESET_ALL; -++ } else { -++ if (priv->port == HLETH_PORT_0) { -++ rst_bit |= HLETH_GLB_SOFT_RESET_P0; -++ } else if (priv->port == HLETH_PORT_1) { -++ rst_bit |= HLETH_GLB_SOFT_RESET_P1; -++ } -++ } -++ -++ val = hleth_readl(priv->glb_base, HLETH_GLB_SOFT_RESET); -++ -++ val |= rst_bit; -++ hleth_writel(priv->glb_base, val, HLETH_GLB_SOFT_RESET); -++ usleep_range(1000, 10000); /* 1000,10000:delay zone */ -++ val &= ~rst_bit; -++ hleth_writel(priv->glb_base, val, HLETH_GLB_SOFT_RESET); -++ usleep_range(1000, 10000); /* 1000,10000:delay zone */ -++ val |= rst_bit; -++ hleth_writel(priv->glb_base, val, HLETH_GLB_SOFT_RESET); -++ usleep_range(1000, 10000); /* 1000,10000:delay zone */ -++ val &= ~rst_bit; -++ hleth_writel(priv->glb_base, val, HLETH_GLB_SOFT_RESET); -++ -++ return 0; -++} -++ -++static void hleth_set_flow_ctrl(struct hleth_netdev_priv *priv, bool enable) -++{ -++ unsigned int pause_en; -++ unsigned int tx_flow_ctrl; -++ -++ tx_flow_ctrl = hleth_readl(priv->port_base, HLETH_P_GLB_FC_LEVEL); -++ tx_flow_ctrl &= ~HLETH_P_GLB_FC_DEACTIVE_THR_MASK; -++ tx_flow_ctrl |= priv->tx_pause_deactive_thresh; -++ tx_flow_ctrl &= ~HLETH_P_GLB_FC_ACTIVE_THR_MASK; -++ tx_flow_ctrl |= priv->tx_pause_active_thresh << BITS_FC_ACTIVE_THR_OFFSET; -++ -++ pause_en = hleth_readl(priv->port_base, HLETH_P_MAC_SET); -++ -++ if (priv->tx_pause_en && enable) { -++ tx_flow_ctrl |= BIT_FC_EN; -++ pause_en |= BIT_PAUSE_EN; -++ } else { -++ tx_flow_ctrl &= ~BIT_FC_EN; -++ pause_en &= ~BIT_PAUSE_EN; -++ } -++ -++ hleth_writel(priv->port_base, tx_flow_ctrl, HLETH_P_GLB_FC_LEVEL); -++ -++ hleth_writel(priv->port_base, pause_en, HLETH_P_MAC_SET); -++} -++ -++static void hleth_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ -++ pause->autoneg = dev->phydev->autoneg; -++ pause->rx_pause = 1; -++ if (priv->tx_pause_en) -++ pause->tx_pause = 1; -++} -++ -++static int hleth_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ struct phy_device *phy = NULL; -++ -++ phy = dev->phydev; -++ if (pause->tx_pause != priv->tx_pause_en) { -++ priv->tx_pause_en = pause->tx_pause; -++ hleth_set_flow_ctrl(priv, priv->tx_pause_en); -++ -++ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phy->advertising); -++ if (priv->tx_pause_en) -++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phy->advertising); -++ if ((phy->autoneg != 0) && netif_running(dev)) { -++ return phy_start_aneg(phy); -++ } -++ } -++ -++ return 0; -++} -++ -++static void hleth_port_init(struct hleth_netdev_priv *priv) -++{ -++ u32 val; -++ unsigned long phy_intf = (priv->phy_mode == PHY_INTERFACE_MODE_MII ? -++ HLETH_P_MAC_PORTSEL_MII : HLETH_P_MAC_PORTSEL_RMII); -++ -++ /* set little endian */ -++ val = hleth_readl(priv->glb_base, HLETH_GLB_ENDIAN_MOD); -++ val |= HLETH_GLB_ENDIAN_MOD_IN; -++ val |= HLETH_GLB_ENDIAN_MOD_OUT; -++ hleth_writel(priv->glb_base, val, HLETH_GLB_ENDIAN_MOD); -++ -++ /* set stat ctrl to cpuset, and MII or RMII mode */ -++ hleth_writel(priv->port_base, phy_intf | HLETH_P_MAC_PORTSEL_STAT_CPU, -++ HLETH_P_MAC_PORTSEL); -++ -++ /* clear all interrupt status */ -++ hleth_clear_irqstatus(priv, ud_bit_name(HLETH_GLB_IRQ_ENA_BIT)); -++ -++ /* disable interrupts */ -++ hleth_irq_disable(priv, ud_bit_name(HLETH_GLB_IRQ_ENA_BIT) | -++ ud_bit_name(HLETH_GLB_IRQ_ENA_IEN)); -++ -++ if (has_tso_cap(priv->hw_cap)) { -++ /* enable TSO debug for error handle */ -++ val = readl(priv->port_base + HLETH_P_TSO_DBG_EN); -++ val |= BITS_TSO_DBG_EN; -++ writel(val, priv->port_base + HLETH_P_TSO_DBG_EN); -++ } -++ -++ /* disable vlan, enable UpEther<->CPU */ -++ val = hleth_readl(priv->glb_base, HLETH_GLB_FWCTRL); -++ val &= ~HLETH_GLB_FWCTRL_VLAN_ENABLE; -++ val |= ud_bit_name(HLETH_GLB_FWCTRL_FW2CPU_ENA); -++ val &= ~(ud_bit_name(HLETH_GLB_FWCTRL_FWALL2CPU)); -++ hleth_writel(priv->glb_base, val, HLETH_GLB_FWCTRL); -++ val = hleth_readl(priv->glb_base, HLETH_GLB_MACTCTRL); -++ val |= ud_bit_name(HLETH_GLB_MACTCTRL_BROAD2CPU); -++ val |= ud_bit_name(HLETH_GLB_MACTCTRL_MACT_ENA); -++ hleth_writel(priv->glb_base, val, HLETH_GLB_MACTCTRL); -++ -++ /* set pre count limit */ -++ val = hleth_readl(priv->port_base, HLETH_P_MAC_TX_IPGCTRL); -++ val &= ~HLETH_P_MAC_TX_IPGCTRL_PRE_CNT_LMT_MSK; -++ val |= 0; -++ hleth_writel(priv->port_base, val, HLETH_P_MAC_TX_IPGCTRL); -++ -++ /* set max receive length */ -++ val = hleth_readl(priv->port_base, HLETH_P_MAC_SET); -++ val &= ~HLETH_P_MAC_SET_LEN_MAX_MSK; -++ val |= hleth_p_mac_set_len_max(HLETH_MAX_RCV_LEN); -++ hleth_writel(priv->port_base, val, HLETH_P_MAC_SET); -++ -++ /* config Rx Checksum Offload, -++ * disable TCP/UDP payload checksum bad drop -++ */ -++ val = hleth_readl(priv->port_base, HLETH_P_RX_COE_CTRL); -++ val &= ~BIT_COE_PAYLOAD_DROP; -++ hleth_writel(priv->port_base, val, HLETH_P_RX_COE_CTRL); -++ -++ hleth_set_flow_ctrl(priv, priv->tx_pause_en); -++} -++ -++static void hleth_set_hwq_depth(const struct hleth_netdev_priv *priv) -++{ -++ u32 val; -++ -++ val = hleth_readl(priv->port_base, HLETH_P_GLB_QLEN_SET); -++ val &= ~HLETH_P_GLB_QLEN_SET_TXQ_DEP_MSK; -++ val |= hleth_p_glb_qlen_set_txq_dep((unsigned int)(priv->depth.hw_xmitq)); -++ val &= ~HLETH_P_GLB_QLEN_SET_RXQ_DEP_MSK; -++ val |= hleth_p_glb_qlen_set_rxq_dep((unsigned int)(HLETH_MAX_QUEUE_DEPTH - -++ priv->depth.hw_xmitq)); -++ hleth_writel(priv->port_base, val, HLETH_P_GLB_QLEN_SET); -++} -++ -++static inline unsigned int hleth_hw_xmitq_ready(const struct hleth_netdev_priv *priv) -++{ -++ unsigned int ret; -++ -++ if (priv == NULL) -++ return 0; -++ -++ ret = hleth_readl(priv->port_base, HLETH_P_GLB_RO_QUEUE_STAT); -++ ret &= HLETH_P_GLB_RO_QUEUE_STAT_XMITQ_RDY_MSK; -++ -++ return ret; -++} -++ -++static void hleth_tx_sg_dma_unmap(struct hleth_netdev_priv *priv, -++ struct sk_buff *skb, unsigned int pos) -++{ -++ struct sg_desc *desc_cur; -++ dma_addr_t addr; -++ u32 len; -++ int i; -++ -++ desc_cur = priv->sg_desc_queue.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 hleth_tx_dma_unmap(struct hleth_netdev_priv *priv, -++ struct sk_buff *skb, unsigned int pos) -++{ -++ dma_addr_t dma_addr; -++ -++ if (!(skb_is_gso(skb) || (skb_shinfo(skb)->nr_frags != 0))) { -++ dma_addr = priv->txq.dma_phys[pos]; -++ dma_unmap_single(priv->dev, dma_addr, skb->len, DMA_TO_DEVICE); -++ } else { -++ hleth_tx_sg_dma_unmap(priv, skb, pos); -++ } -++} -++ -++static int hleth_xmit_release_skb(struct hleth_netdev_priv *priv) -++{ -++ struct hleth_queue *txq = &priv->txq; -++ u32 val; -++ int ret = 0; -++ struct sk_buff *skb = NULL; -++ u32 tx_comp = 0; -++ struct net_device *ndev = priv->ndev; -++ -++ local_lock(priv); -++ -++ val = hleth_readl(priv->port_base, HLETH_P_GLB_RO_QUEUE_STAT) & -++ HLETH_P_GLB_RO_QUEUE_STAT_XMITQ_CNT_INUSE_MSK; -++ while (val < priv->tx_fifo_used_cnt) { -++ skb = txq->skb[txq->tail]; -++ -++ if (skb == NULL) { -++ pr_err("hw_xmitq_cnt_inuse=%d, tx_fifo_used_cnt=%d\n", -++ val, priv->tx_fifo_used_cnt); -++ ret = -1; -++ goto error_exit; -++ } -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_dec(&priv->tx_skb_occupied); -++ atomic_sub(skb->truesize, &priv->tx_skb_mem_occupied); -++#endif -++ hleth_tx_dma_unmap(priv, skb, txq->tail); -++ dev_kfree_skb_any(skb); -++ -++ priv->tx_fifo_used_cnt--; -++ tx_comp++; -++ -++ val = hleth_readl(priv->port_base, HLETH_P_GLB_RO_QUEUE_STAT) & -++ HLETH_P_GLB_RO_QUEUE_STAT_XMITQ_CNT_INUSE_MSK; -++ txq->skb[txq->tail] = NULL; -++ txq->tail = (txq->tail + 1) % txq->num; -++ } -++ -++ if (tx_comp) -++ netif_wake_queue(ndev); -++ -++error_exit: -++ local_unlock(priv); -++ return ret; -++} -++ -++#ifdef CONFIG_HLETH_MAX_RX_POOLS -++static __maybe_unused struct sk_buff *hleth_platdev_alloc_skb(struct hleth_netdev_priv *priv) -++{ -++ struct sk_buff *skb; -++ int i; -++ int ret; -++ -++ skb = priv->rx_pool.sk_pool[priv->rx_pool.next_free_skb++]; -++ -++ if (priv->rx_pool.next_free_skb == CONFIG_HLETH_MAX_RX_POOLS) -++ priv->rx_pool.next_free_skb = 0; -++ -++ /* current skb is used by kernel or other process,find another skb */ -++ if (skb_shared(skb) || (atomic_read(&(skb_shinfo(skb)->dataref)) > 1)) { -++ for (i = 0; i < CONFIG_HLETH_MAX_RX_POOLS; i++) { -++ skb = priv->rx_pool.sk_pool[priv-> -++ rx_pool.next_free_skb++]; -++ if (priv->rx_pool.next_free_skb == -++ CONFIG_HLETH_MAX_RX_POOLS) -++ priv->rx_pool.next_free_skb = 0; -++ -++ if ((skb_shared(skb) == 0) && -++ (atomic_read(&(skb_shinfo(skb)->dataref)) <= 1)) -++ break; -++ } -++ -++ if (i == CONFIG_HLETH_MAX_RX_POOLS) { -++ priv->stat.rx_pool_dry_times++; -++ pr_debug("%ld: no free skb\n", -++ priv->stat.rx_pool_dry_times); -++ skb = netdev_alloc_skb_ip_align(priv->ndev, SKB_SIZE); -++ return skb; -++ } -++ } -++ ret = memset_s(skb, sizeof(struct sk_buff), 0, offsetof(struct sk_buff, tail)); -++ if (ret != EOK) { -++ pr_err("memset skb error ret=%d\n", ret); -++ return NULL; -++ } -++ -++ skb->data = skb->head; -++ skb_reset_tail_pointer(skb); -++ WARN(skb->end != (skb->tail + SKB_DATA_ALIGN(SKB_SIZE + NET_IP_ALIGN + NET_SKB_PAD)), -++ "head=%p, tail=%x, end=%x\n", skb->head, (unsigned int)skb->tail, -++ (unsigned int)skb->end); -++ skb->end = skb->tail + SKB_DATA_ALIGN(SKB_SIZE + NET_IP_ALIGN + NET_SKB_PAD); -++ -++ skb_reserve(skb, NET_IP_ALIGN + NET_SKB_PAD); -++ skb->len = 0; -++ skb->data_len = 0; -++ skb->cloned = 0; -++ skb->dev = priv->ndev; -++ atomic_inc(&skb->users.refs); -++ return skb; -++} -++#endif -++ -++static int hleth_feed_hw(struct hleth_netdev_priv *priv) -++{ -++ struct hleth_queue *rxq = &priv->rxq; -++ struct sk_buff *skb = NULL; -++ dma_addr_t addr; -++ int cnt = 0; -++ u32 rx_head_len; -++ u32 pos; -++ -++ /* if skb occupied too much, then do not alloc any more. */ -++ rx_head_len = skb_queue_len(&priv->rx_head); -++ if (rx_head_len > HLETH_MAX_RX_HEAD_LEN) -++ return 0; -++ -++ local_lock(priv); -++ -++ pos = rxq->head; -++ while ((unsigned int)hleth_readl(priv->port_base, HLETH_P_GLB_RO_QUEUE_STAT) & -++ HLETH_P_GLB_RO_QUEUE_STAT_RECVQ_RDY_MSK) { -++ if (unlikely(CIRC_SPACE(pos, rxq->tail, (unsigned int)rxq->num) == 0)) -++ break; -++ if (unlikely(rxq->skb[pos])) { -++ netdev_err(priv->ndev, "err skb[%d]=%p\n", -++ pos, rxq->skb[pos]); -++ break; -++ } -++ -++ skb = netdev_alloc_skb_ip_align(priv->ndev, HLETH_MAX_FRAME_SIZE); -++ if (skb == NULL) -++ break; -++ -++ addr = dma_map_single(priv->dev, skb->data, HLETH_MAX_FRAME_SIZE, -++ 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; -++ -++ hleth_writel(priv->port_base, addr, HLETH_P_GLB_IQ_ADDR); -++ pos = (pos + 1) % rxq->num; -++ cnt++; -++ -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_inc(&priv->rx_skb_occupied); -++ atomic_add(skb->truesize, &priv->rx_skb_mem_occupied); -++#endif -++ } -++ rxq->head = pos; -++ -++ local_unlock(priv); -++ return cnt; -++} -++ -++static int hleth_skb_rxcsum(struct hleth_netdev_priv *priv, struct sk_buff *skb, -++ u32 rx_pkt_info) -++{ -++ struct net_device *dev = priv->ndev; -++ 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 != 0) && (payload_csum_done != 0)) { -++ if (unlikely(hdr_csum_err != 0)) { -++ dev->stats.rx_errors++; -++ dev->stats.rx_crc_errors++; -++ dev_kfree_skb_any(skb); -++ return -1; -++ } else if (payload_csum_err == 0) { -++ skb->ip_summed = CHECKSUM_UNNECESSARY; -++ } -++ } -++ } -++ return 0; -++} -++ -++static int hleth_recv_budget(struct hleth_netdev_priv *priv) -++{ -++ struct hleth_queue *rxq = &priv->rxq; -++ struct sk_buff *skb = NULL; -++ dma_addr_t addr; -++ u32 pos; -++ u32 rlen; -++ int cnt = 0; -++ -++ local_lock(priv); -++ -++ pos = rxq->tail; -++ while ((hleth_readl(priv->glb_base, HLETH_GLB_IRQ_RAW) & -++ (ud_bit_name(HLETH_GLB_IRQ_INT_RX_RDY)))) { -++ rlen = hleth_readl(priv->port_base, HLETH_P_GLB_RO_IQFRM_DES); -++ -++ /* hw set rx pkg finish */ -++ hleth_writel(priv->glb_base, -++ ud_bit_name(HLETH_GLB_IRQ_INT_RX_RDY), -++ HLETH_GLB_IRQ_RAW); -++ -++ skb = rxq->skb[pos]; -++ -++ if (skb == NULL) { -++ pr_err("chip told us to receive pkg," -++ "but no more can be received!\n"); -++ break; -++ } -++ rxq->skb[pos] = NULL; -++ -++ addr = rxq->dma_phys[pos]; -++ dma_unmap_single(priv->dev, addr, HLETH_MAX_FRAME_SIZE, -++ DMA_FROM_DEVICE); -++ -++ if (hleth_skb_rxcsum(priv, skb, rlen) < 0) -++ goto next; -++ rlen &= HLETH_P_GLB_RO_IQFRM_DES_FDIN_LEN_MSK; -++ rlen -= ETH_FCS_LEN; /* remove FCS 4Bytes */ -++ skb_put(skb, rlen); -++ -++ skb_queue_tail(&priv->rx_head, skb); -++next: -++ pos = (pos + 1) % rxq->num; -++ cnt++; -++ } -++ rxq->tail = pos; -++ -++ local_unlock(priv); -++ -++ /* fill hardware receive queue again */ -++ hleth_feed_hw(priv); -++ -++ return cnt; -++} -++ -++static void hleth_adjust_link(struct net_device *dev) -++{ -++ int stat = 0; -++ bool fc_enable = false; -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ -++ stat |= (priv->phy->link) ? HLETH_P_MAC_PORTSET_LINKED : 0; -++ stat |= (priv->phy->duplex == DUPLEX_FULL) ? -++ HLETH_P_MAC_PORTSET_DUP_FULL : 0; -++ stat |= (priv->phy->speed == SPEED_100) ? -++ HLETH_P_MAC_PORTSET_SPD_100M : 0; -++ -++ /* The following expression -++ * "(stat | priv->link_stat) & HLETH_P_MAC_PORTSET_LINKED" -++ * means we only consider three link status change as valid: -++ * 1) down -> up; -++ * 2) up -> down; -++ * 3) up -> up; (maybe the link speed and duplex changed) -++ * We will ignore the "down -> down" condition. -++ */ -++ if ((stat != priv->link_stat) && -++ ((((unsigned int)stat | (unsigned int)priv->link_stat) & HLETH_P_MAC_PORTSET_LINKED) != 0)) { -++ hleth_writel(priv->port_base, stat, HLETH_P_MAC_PORTSET); -++ phy_print_status(priv->phy); -++ priv->link_stat = stat; -++ -++ if (priv->phy->pause != 0) -++ fc_enable = true; -++ hleth_set_flow_ctrl(priv, fc_enable); -++ if (priv->autoeee_enabled) -++ hleth_autoeee_init(priv, stat); -++ } -++} -++ -++#ifdef CONFIG_HLETH_MAX_RX_POOLS -++static int hleth_init_skb_buffers(struct hleth_netdev_priv *priv) -++{ -++ int i; -++ struct sk_buff *skb; -++ -++ for (i = 0; i < CONFIG_HLETH_MAX_RX_POOLS; i++) { -++ skb = netdev_alloc_skb_ip_align(priv->ndev, SKB_SIZE); -++ if (!skb) -++ break; -++ priv->rx_pool.sk_pool[i] = skb; -++ } -++ -++ if (i < CONFIG_HLETH_MAX_RX_POOLS) { -++ pr_err("no mem\n"); -++ for (i--; i > 0; i--) -++ dev_kfree_skb_any(priv->rx_pool.sk_pool[i]); -++ return -ENOMEM; -++ } -++ -++ priv->rx_pool.next_free_skb = 0; -++ priv->stat.rx_pool_dry_times = 0; -++ return 0; -++} -++ -++static void hleth_destroy_skb_buffers(struct hleth_netdev_priv *priv) -++{ -++ int i; -++ -++ for (i = 0; i < CONFIG_HLETH_MAX_RX_POOLS; i++) -++ dev_kfree_skb_any(priv->rx_pool.sk_pool[i]); -++ -++ priv->rx_pool.next_free_skb = 0; -++ priv->stat.rx_pool_dry_times = 0; -++} -++#endif -++ -++static void hleth_net_isr_proc(struct net_device *ndev, int ints) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(ndev); -++ -++ if ((((unsigned int)ints & ud_bit_name(HLETH_GLB_IRQ_INT_MULTI_RXRDY)) != 0) || -++ (((unsigned int)ints & ud_bit_name(HLETH_GLB_IRQ_INT_TXQUE_RDY))!= 0)) { -++ hleth_clear_irqstatus(priv, ud_bit_name(HLETH_GLB_IRQ_INT_TXQUE_RDY)); -++#ifdef FEMAC_RX_REFILL_IN_IRQ -++ hleth_recv_budget(priv); -++#else -++ hleth_irq_disable(priv, -++ ud_bit_name(HLETH_GLB_IRQ_INT_MULTI_RXRDY)); -++ hleth_irq_disable(priv, -++ ud_bit_name(HLETH_GLB_IRQ_INT_TXQUE_RDY)); -++#endif -++ napi_schedule(&priv->napi); -++ } -++} -++ -++static void hleth_get_tso_err_info(struct hleth_netdev_priv *priv) -++{ -++ unsigned int reg_addr, reg_tx_info, reg_tx_err; -++ unsigned int sg_index; -++ struct sg_desc *sg_desc = NULL; -++ int *sg_word = NULL; -++ int i; -++ -++ reg_addr = readl(priv->port_base + HLETH_P_TSO_DBG_ADDR); -++ reg_tx_info = readl(priv->port_base + HLETH_P_TSO_DBG_TX_INFO); -++ reg_tx_err = readl(priv->port_base + HLETH_P_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->sg_desc_queue.dma_phys) / sizeof(struct sg_desc); -++ sg_desc = priv->sg_desc_queue.desc + sg_index; -++ sg_word = (int *)sg_desc; -++ for (i = 0; i < sizeof(struct sg_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 */ -++ hleth_irq_disable(priv, ud_bit_name(HLETH_GLB_IRQ_INT_TX_ERR)); -++ /* -++ * If we need allow netcard transmit packet again. -++ * we should readl TSO_DBG_STATE and enable irq. -++ */ -++} -++ -++static irqreturn_t hleth_net_isr(int irq, void *dev_id) -++{ -++ unsigned int ints; -++ struct net_device *dev = (struct net_device *)dev_id; -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ -++ /* mask the all interrupt */ -++ hleth_irq_disable(priv, HLETH_GLB_IRQ_ENA_IEN_A); -++ ints = hleth_readl(priv->glb_base, HLETH_GLB_IRQ_STAT); -++ if ((priv->port == HLETH_PORT_0) && -++ likely((ints & HLETH_GLB_IRQ_ENA_BIT_U) != 0)) { -++ hleth_net_isr_proc(dev, (ints & HLETH_GLB_IRQ_ENA_BIT_U)); -++ hleth_clear_irqstatus(priv, (ints & HLETH_GLB_IRQ_ENA_BIT_U)); -++ ints &= ~HLETH_GLB_IRQ_ENA_BIT_U; -++ } -++ -++ if ((priv->port == HLETH_PORT_1) && -++ likely((ints & HLETH_GLB_IRQ_ENA_BIT_D) != 0)) { -++ hleth_net_isr_proc(dev, (ints & HLETH_GLB_IRQ_ENA_BIT_D)); -++ hleth_clear_irqstatus(priv, (ints & HLETH_GLB_IRQ_ENA_BIT_D)); -++ ints &= ~HLETH_GLB_IRQ_ENA_BIT_D; -++ } -++ -++ if ((has_tso_cap(priv->hw_cap) != 0) && unlikely((ints & ud_bit_name(HLETH_GLB_IRQ_INT_TX_ERR)) != 0)) -++ hleth_get_tso_err_info(priv); -++ -++ /* unmask the all interrupt */ -++ hleth_irq_enable(priv, HLETH_GLB_IRQ_ENA_IEN_A); -++ -++ return IRQ_HANDLED; -++} -++ -++static void hleth_monitor_func(struct timer_list *t) -++{ -++ struct hleth_netdev_priv *priv = from_timer(priv, t, monitor); -++ -++ if (priv == NULL || !netif_running(priv->ndev)) { -++ pr_debug("network driver is stopped.\n"); -++ return; -++ } -++ -++ hleth_feed_hw(priv); -++ hleth_xmit_release_skb(priv); -++ -++ priv->monitor.expires = -++ jiffies + msecs_to_jiffies(HLETH_MONITOR_TIMER); -++ add_timer(&priv->monitor); -++} -++ -++static int hleth_net_open(struct net_device *dev) -++{ -++ int ret = 0; -++ struct cpumask cpumask; -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ -++ ret = request_irq(dev->irq, hleth_net_isr, IRQF_SHARED, -++ dev->name, dev); -++ if (ret) { -++ pr_err("request_irq %d failed!\n", dev->irq); -++ return ret; -++ } -++ -++ /* set irq affinity */ -++ if ((num_online_cpus() > 1) && (cpu_online(HLETH_IRQ_AFFINITY_CPU) != 0)) { -++ cpumask_clear(&cpumask); -++ cpumask_set_cpu(HLETH_IRQ_AFFINITY_CPU, &cpumask); -++ irq_set_affinity(dev->irq, &cpumask); -++ } -++ -++ if (!is_valid_ether_addr(dev->dev_addr)) -++ random_ether_addr(dev->dev_addr); -++ -++ hleth_hw_set_macaddress(priv, dev->dev_addr); -++ -++ /* setup hardware */ -++ hleth_set_hwq_depth(priv); -++ hleth_clear_irqstatus(priv, ud_bit_name(HLETH_GLB_IRQ_ENA_BIT)); -++ -++ netif_carrier_off(dev); -++ hleth_feed_hw(priv); -++ -++ netif_wake_queue(dev); -++ napi_enable(&priv->napi); -++ -++ priv->link_stat = 0; -++ if (priv->phy != NULL) -++ phy_start(priv->phy); -++ -++ hleth_irq_enable(priv, ud_bit_name(HLETH_GLB_IRQ_INT_MULTI_RXRDY) | -++ ud_bit_name(HLETH_GLB_IRQ_ENA_IEN) | -++ HLETH_GLB_IRQ_ENA_IEN_A); -++ if (has_tso_cap(priv->hw_cap)) -++ hleth_irq_enable(priv, ud_bit_name(HLETH_GLB_IRQ_INT_TX_ERR)); -++ -++ priv->monitor.expires = -++ jiffies + msecs_to_jiffies(HLETH_MONITOR_TIMER); -++ add_timer(&priv->monitor); -++ -++ return 0; -++} -++ -++static void hleth_free_skb_rings(struct hleth_netdev_priv *priv); -++ -++static int hleth_net_close(struct net_device *dev) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ struct sk_buff *skb = NULL; -++ -++ hleth_irq_disable(priv, ud_bit_name(HLETH_GLB_IRQ_INT_MULTI_RXRDY)); -++ napi_disable(&priv->napi); -++ netif_stop_queue(dev); -++ if (priv->phy != NULL) -++ phy_stop(priv->phy); -++ -++ del_timer_sync(&priv->monitor); -++ -++ /* reset and init port */ -++ hleth_port_reset(priv); -++ -++ while ((skb = skb_dequeue(&priv->rx_head)) != NULL) { -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_dec(&priv->rx_skb_occupied); -++ atomic_sub(skb->truesize, &priv->rx_skb_mem_occupied); -++#endif -++ kfree_skb(skb); -++ } -++ -++ hleth_free_skb_rings(priv); -++ -++ free_irq(dev->irq, dev); -++ return 0; -++} -++ -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) -++static void hleth_net_timeout(struct net_device *dev, unsigned int txqueue) -++#else -++static void hleth_net_timeout(struct net_device *dev) -++#endif -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ -++ pr_err("tx timeout\n"); -++ schedule_work(&priv->tx_timeout_task); -++} -++ -++static void hleth_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 hleth_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 hleth_skb_is_ipv6(struct sk_buff *skb) -++{ -++ return (hleth_get_l3_proto(skb) == htons(ETH_P_IPV6)); -++} -++ -++static int hleth_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) != 0)) -++ return -EINVAL; -++ } -++ -++ return 0; -++} -++ -++static int hleth_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 (hleth_skb_is_ipv6(skb)) -++ return hleth_check_hw_capability_for_ipv6(skb); -++ -++ return 0; -++} -++ -++static unsigned int hleth_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)) { -++ hleth_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; -++} -++ -++static u32 hleth_get_pkt_info(struct sk_buff *skb) -++{ -++ __be16 l3_proto; -++ unsigned int l4_proto = IPPROTO_MAX; -++ bool do_txcsum = false; -++ int max_data_len; -++ unsigned int max_mss = ETH_DATA_LEN; -++ u32 pkt_info = 0; -++ -++ if (skb == NULL) -++ return 0; -++ -++ max_data_len = skb->len - ETH_HLEN; -++ -++ 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 |= hleth_get_pkt_info_gso(skb, do_txcsum, max_mss, l4_proto); -++ -++ return pkt_info; -++} -++ -++static netdev_tx_t hleth_net_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); -++static netdev_tx_t hleth_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); -++ 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 (hleth_net_hard_start_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 hleth_fill_sg_desc(const struct hleth_netdev_priv *priv, -++ const struct sk_buff *skb, unsigned int pos) -++{ -++ struct sg_desc *desc_cur; -++ dma_addr_t addr; -++ int ret; -++ int i; -++ -++ desc_cur = priv->sg_desc_queue.desc + pos; -++ -++ 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) != 0)) -++ 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]; -++ unsigned int len = skb_frag_size(frag); -++ -++ addr = skb_frag_dma_map(priv->dev, frag, 0, len, DMA_TO_DEVICE); -++ ret = dma_mapping_error(priv->dev, addr); -++ if (unlikely(ret != 0)) -++ return -EINVAL; -++ -++ desc_cur->frags[i].addr = addr; -++ desc_cur->frags[i].size = len; -++ } -++ -++ return 0; -++} -++ -++static netdev_tx_t hleth_xmit_gso(struct net_device *dev, struct sk_buff *skb, -++ dma_addr_t *addr, u32 *val) -++{ -++ int ret; -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ struct hleth_queue *txq = &priv->txq; -++ -++ ret = hleth_check_hw_capability(skb); -++ if (unlikely(ret != 0)) { -++ if (ret == -ENOTSUPP) -++ return hleth_sw_gso(skb, dev); -++ return ret; -++ } -++ -++ *val = hleth_get_pkt_info(skb); -++ -++ if (!(skb_is_gso(skb) || (skb_shinfo(skb)->nr_frags != 0))) { -++ *addr = dma_map_single(priv->dev, skb->data, skb->len, DMA_TO_DEVICE); -++ if (dma_mapping_error(priv->dev, *addr)) { -++ netdev_err(priv->ndev, "DMA mapping error when sending."); -++ return -EINVAL; -++ } -++ } else { -++ ret = hleth_fill_sg_desc(priv, skb, txq->head); -++ if (unlikely(ret < 0)) { -++ return ret; -++ } -++ -++ *addr = priv->sg_desc_queue.dma_phys + txq->head * sizeof(struct sg_desc); -++ -++ /* Ensure desc info writen to memory before config hardware */ -++ wmb(); -++ } -++ -++ return 0; -++} -++ -++static netdev_tx_t hleth_net_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ struct hleth_queue *txq = &priv->txq; -++ dma_addr_t addr; -++ u32 val; -++ int ret; -++ -++ if ((hleth_hw_xmitq_ready(priv) == 0) || -++ unlikely(CIRC_SPACE(txq->head, txq->tail, (unsigned int)txq->num) == 0)) { -++ netif_stop_queue(dev); -++ hleth_irq_enable(priv, ud_bit_name(HLETH_GLB_IRQ_INT_TXQUE_RDY)); -++ return NETDEV_TX_BUSY; -++ } -++ -++ if (has_tso_cap(priv->hw_cap)) { -++ ret = hleth_xmit_gso(dev, skb, &addr, &val); -++ if (unlikely(ret < 0)) { -++ priv->stats.tx_dropped++; -++ dev_kfree_skb_any(skb); -++ return NETDEV_TX_OK; -++ } -++ } else { -++ addr = dma_map_single(priv->dev, skb->data, skb->len, DMA_TO_DEVICE); -++ if (dma_mapping_error(priv->dev, addr)) { -++ netdev_err(priv->ndev, "DMA mapping error when sending."); -++ priv->stats.tx_errors++; -++ priv->stats.tx_dropped++; -++ dev_kfree_skb_any(skb); -++ return NETDEV_TX_OK; -++ } -++ val = hleth_readl(priv->port_base, HLETH_P_GLB_EQFRM_LEN); -++ val &= ~HLETH_P_GLB_EQFRM_TXINQ_LEN_MSK; -++ val |= skb->len + ETH_FCS_LEN; -++ } -++ -++ local_lock(priv); -++ -++ /* we must use "skb->len" before sending packet to hardware, -++ * because once we send packet to hardware, -++ * "hleth_xmit_release_skb" in softirq may free this skb. -++ * This bug is reported by KASAN: use-after-free. -++ */ -++ priv->stats.tx_packets++; -++ priv->stats.tx_bytes += skb->len; -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_inc(&priv->tx_skb_occupied); -++ atomic_add(skb->truesize, &priv->tx_skb_mem_occupied); -++#endif -++ -++ txq->dma_phys[txq->head] = addr; -++ txq->skb[txq->head] = skb; -++ -++ /* for recalc CRC, 4 bytes more is needed */ -++ hleth_writel(priv->port_base, addr, HLETH_P_GLB_EQ_ADDR); -++ hleth_writel(priv->port_base, val, HLETH_P_GLB_EQFRM_LEN); -++ -++ txq->head = (txq->head + 1) % txq->num; -++ priv->tx_fifo_used_cnt++; -++ -++ netif_trans_update(dev); -++ -++ local_unlock(priv); -++ -++ return NETDEV_TX_OK; -++} -++ -++static void hleth_net_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ int ret = -1; -++ -++ ret = memcpy_s(stats, sizeof(struct rtnl_link_stats64), &priv->stats, sizeof(*stats)); -++ if (ret != EOK) { -++ pr_err("%s : %d, memcpy stats error ret=%d\n", __func__, __LINE__, ret); -++ return; -++ } -++ -++ return; -++} -++ -++static int hleth_net_set_mac_address(struct net_device *dev, void *p) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ struct sockaddr *addr = p; -++ -++ if (!is_valid_ether_addr(addr->sa_data)) -++ return -EADDRNOTAVAIL; -++ -++ eth_commit_mac_addr_change(dev, p); -++ dev->addr_assign_type &= ~NET_ADDR_RANDOM; -++ -++ hleth_hw_set_macaddress(priv, dev->dev_addr); -++ -++ return 0; -++} -++ -++static inline void hleth_enable_mac_addr_filter(const struct hleth_netdev_priv *priv, -++ unsigned int reg_n, int enable) -++{ -++ u32 val; -++ -++ if (priv == NULL) -++ return; -++ -++ val = hleth_readl(priv->glb_base, glb_mac_h16(priv->port, reg_n)); -++ if (enable) -++ val |= ud_bit_name(HLETH_GLB_MACFLT_ENA); -++ else -++ val &= ~(ud_bit_name(HLETH_GLB_MACFLT_ENA)); -++ hleth_writel(priv->glb_base, val, glb_mac_h16(priv->port, reg_n)); -++} -++ -++static void hleth_set_mac_addr(const struct hleth_netdev_priv *priv, u8 addr[6], -++ unsigned int high, unsigned int low) -++{ -++ u32 val; -++ u32 data; -++ -++ val = hleth_readl(priv->glb_base, high); -++ val |= ud_bit_name(HLETH_GLB_MACFLT_ENA); -++ hleth_writel(priv->glb_base, val, high); -++ -++ val &= ~HLETH_GLB_MACFLT_H16; -++ val |= ((addr[0] << 8) | addr[1]);/* 8:right shift val */ -++ hleth_writel(priv->glb_base, val, high); -++ /* 2,3,4,5,8,16,24:right shift val */ -++ data = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5]; -++ hleth_writel(priv->glb_base, data, low); -++ -++ val |= ud_bit_name(HLETH_GLB_MACFLT_FW2CPU); -++ hleth_writel(priv->glb_base, val, high); -++} -++ -++static inline void hleth_set_mac_addr_filter(const struct hleth_netdev_priv *priv, -++ unsigned char *addr, -++ unsigned int reg_n) -++{ -++ if (priv == NULL || addr == NULL) -++ return; -++ hleth_set_mac_addr(priv, addr, glb_mac_h16(priv->port, reg_n), -++ glb_mac_l32(priv->port, reg_n)); -++} -++ -++static void hleth_net_set_rx_mode(struct net_device *dev) -++{ -++ u32 val; -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ -++ local_lock(priv); -++ -++ val = hleth_readl(priv->glb_base, HLETH_GLB_FWCTRL); -++ if (dev->flags & IFF_PROMISC) { -++ val |= ((priv->port == HLETH_PORT_0) ? -++ HLETH_GLB_FWCTRL_FWALL2CPU_U : -++ HLETH_GLB_FWCTRL_FWALL2CPU_D); -++ hleth_writel(priv->glb_base, val, HLETH_GLB_FWCTRL); -++ } else { -++ val &= ~((priv->port == HLETH_PORT_0) ? -++ HLETH_GLB_FWCTRL_FWALL2CPU_U : -++ HLETH_GLB_FWCTRL_FWALL2CPU_D); -++ hleth_writel(priv->glb_base, val, HLETH_GLB_FWCTRL); -++ -++ val = hleth_readl(priv->glb_base, HLETH_GLB_MACTCTRL); -++ if ((netdev_mc_count(dev) > HLETH_MAX_MULTICAST_ADDRESSES) || -++ ((dev->flags & IFF_ALLMULTI) != 0)) { -++ val |= ud_bit_name(HLETH_GLB_MACTCTRL_MULTI2CPU); -++ } else { -++ int reg = HLETH_MAX_UNICAST_ADDRESSES; -++ int i = 0; -++ struct netdev_hw_addr *ha = NULL; -++ -++ for (i = reg; i < HLETH_MAX_MAC_FILTER_NUM; i++) -++ hleth_enable_mac_addr_filter(priv, i, 0); -++ -++ netdev_for_each_mc_addr(ha, dev) { -++ hleth_set_mac_addr_filter(priv, ha->addr, reg); -++ reg++; -++ } -++ -++ val &= ~(ud_bit_name(HLETH_GLB_MACTCTRL_MULTI2CPU)); -++ } -++ -++ /* Handle multiple unicast addresses (perfect filtering) */ -++ if (netdev_uc_count(dev) > HLETH_MAX_UNICAST_ADDRESSES) { -++ val |= ud_bit_name(HLETH_GLB_MACTCTRL_UNI2CPU); -++ } else { -++ int reg = 0; -++ int i; -++ struct netdev_hw_addr *ha = NULL; -++ -++ for (i = reg; i < HLETH_MAX_UNICAST_ADDRESSES; i++) -++ hleth_enable_mac_addr_filter(priv, i, 0); -++ -++ netdev_for_each_uc_addr(ha, dev) { -++ hleth_set_mac_addr_filter(priv, ha->addr, reg); -++ reg++; -++ } -++ -++ val &= ~(ud_bit_name(HLETH_GLB_MACTCTRL_UNI2CPU)); -++ } -++ hleth_writel(priv->glb_base, val, HLETH_GLB_MACTCTRL); -++ } -++ -++ local_unlock(priv); -++} -++ -++static int hleth_set_wol_on_phy(struct net_device *net_dev, -++ struct ethtool_wolinfo *wol) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(net_dev); -++ -++ int ret; -++ -++ if (net_dev->phydev == NULL) -++ return -EOPNOTSUPP; -++ -++ ret = phy_ethtool_set_wol(net_dev->phydev, wol); -++ if (ret == 0) { -++ priv->pm_state_set = true; -++ device_set_wakeup_enable(priv->dev, true); -++ pr_info("hleth: set phy wol success!\n"); -++ } else { -++ pr_err("hleth: set phy wol failed, err=%d\n", ret); -++ } -++ -++ return ret; -++} -++ -++static int hleth_set_wol_on_mac(struct net_device *net_dev, -++ struct hleth_pm_config *config) -++{ -++ int ret; -++ -++ if ((ret = hleth_pmt_config(net_dev, config)) == 0) -++ pr_info("hleth: set mac wol success!\n"); -++ else -++ pr_err("hleth: set mac wol failed, err=%d\n", ret); -++ -++ return ret; -++} -++ -++static int hleth_set_wol(struct net_device *net_dev, -++ struct hleth_pm_config *config, -++ struct ethtool_wolinfo *wol) -++{ -++ int ret; -++ -++ if (net_dev == NULL) -++ return -EINVAL; -++ -++ ret = hleth_set_wol_on_phy(net_dev, wol); -++ if (ret != 0) -++ pr_info("hleth: phy wol unsupport, try mac wol\n"); -++ -++ ret = hleth_set_wol_on_mac(net_dev, config); -++ -++ return ret; -++} -++ -++static int hleth_ioctl_set_wol(struct net_device *net_dev, -++ struct hleth_pm_config *config) -++{ -++ struct ethtool_wolinfo wol_info = {0}; -++ -++ wol_info.cmd = ETHTOOL_SWOL; -++ if (config->uc_pkts_enable) -++ wol_info.wolopts |= WAKE_UCAST; -++ if (config->magic_pkts_enable) -++ wol_info.wolopts |= WAKE_MAGIC; -++ -++ return hleth_set_wol(net_dev, config, &wol_info); -++} -++ -++static int hleth_get_wol(struct net_device *net_dev, -++ struct hleth_pm_config *config, -++ struct ethtool_wolinfo *wol) -++{ -++ if (net_dev == NULL) -++ return -EINVAL; -++ -++ if (net_dev->phydev != NULL) { -++ phy_ethtool_get_wol(net_dev->phydev, wol); -++ config->uc_pkts_enable = ((wol->wolopts & WAKE_UCAST) != 0) ? 1 : 0; -++ config->magic_pkts_enable = ((wol->wolopts & WAKE_MAGIC) != 0) ? 1 : 0; -++ } -++ -++ hleth_pmt_get_config(net_dev, config); -++ if (config->uc_pkts_enable == 1) -++ wol->wolopts |= WAKE_UCAST; -++ if (config->magic_pkts_enable == 1) -++ wol->wolopts |= WAKE_MAGIC; -++ -++ return 0; -++} -++ -++static int hleth_ioctl_get_wol(struct net_device *net_dev, -++ struct hleth_pm_config *config) -++{ -++ struct ethtool_wolinfo wol_info = {0}; -++ -++ return hleth_get_wol(net_dev, config, &wol_info); -++} -++ -++static int hleth_net_ioctl(struct net_device *net_dev, -++ struct ifreq *ifreq, int cmd) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(net_dev); -++ struct hleth_pm_config pm_config; -++ int ret; -++ -++ switch (cmd) { -++ case SIOCSETPM: -++ if (copy_from_user(&pm_config, ifreq->ifr_data, -++ sizeof(pm_config)) != 0) -++ return -EFAULT; -++ -++ return hleth_ioctl_set_wol(net_dev, &pm_config); -++ -++ case SIOCGETPM: -++ if (memset_s(&pm_config, sizeof(pm_config), 0, -++ sizeof(pm_config) != 0)) -++ return -EFAULT; -++ -++ ret = hleth_ioctl_get_wol(net_dev, &pm_config); -++ if (ret == 0) { -++ if (copy_to_user(ifreq->ifr_data, &pm_config, -++ sizeof(pm_config)) != 0) -++ return -EFAULT; -++ } -++ -++ return ret; -++ -++ default: -++ if (!netif_running(net_dev)) -++ return -EINVAL; -++ -++ if (priv->phy == NULL) -++ return -EINVAL; -++ -++ return phy_mii_ioctl(priv->phy, ifreq, cmd); -++ } -++ -++ return 0; -++} -++ -++static void hleth_ethtools_get_drvinfo(struct net_device *net_dev, -++ struct ethtool_drvinfo *info) -++{ -++ int ret; -++ -++ ret = strcpy_s(info->driver, sizeof(info->driver), "hleth driver"); -++ if (ret != EOK) { -++ pr_err("strcpy driver error ret=%d", ret); -++ return; -++ } -++ ret = strcpy_s(info->version, sizeof(info->version), "v300"); -++ if (ret != EOK) { -++ pr_err("strcpy driver error ret=%d", ret); -++ return; -++ } -++ ret = strcpy_s(info->bus_info, ETHTOOL_BUSINFO_LEN, "platform"); -++ if (ret != EOK) { -++ pr_err("strcpy driver error ret=%d", ret); -++ return; -++ } -++} -++ -++static u32 hleth_ethtools_get_link(struct net_device *net_dev) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(net_dev); -++ -++ return ((priv->phy->link != 0) ? HLETH_P_MAC_PORTSET_LINKED : 0); -++} -++ -++static void hleth_ethtool_get_wol(struct net_device *dev, -++ struct ethtool_wolinfo *wol) -++{ -++ struct hleth_pm_config mac_pm_config = {0}; -++ -++ (void)hleth_get_wol(dev, &mac_pm_config, wol); -++} -++ -++static int hleth_ethtool_set_wol(struct net_device *dev, -++ struct ethtool_wolinfo *wol) -++{ -++ struct hleth_netdev_priv *priv = netdev_priv(dev); -++ struct hleth_pm_config mac_pm_config = {0}; -++ -++ mac_pm_config.index = BIT(priv->port); -++ if (wol->wolopts & WAKE_UCAST) -++ mac_pm_config.uc_pkts_enable = 1; -++ -++ if (wol->wolopts & WAKE_MAGIC) -++ mac_pm_config.magic_pkts_enable = 1; -++ -++ return hleth_set_wol(dev, &mac_pm_config, wol); -++} -++ -++static int hleth_change_mtu(struct net_device *dev, int new_mtu) -++{ -++ dev->mtu = (unsigned int)new_mtu; -++ return 0; -++} -++ -++static struct ethtool_ops hleth_ethtools_ops = { -++ .get_drvinfo = hleth_ethtools_get_drvinfo, -++ .get_link = hleth_ethtools_get_link, -++ .get_link_ksettings = phy_ethtool_get_link_ksettings, -++ .set_link_ksettings = phy_ethtool_set_link_ksettings, -++ .get_wol = hleth_ethtool_get_wol, -++ .set_wol = hleth_ethtool_set_wol, -++ .set_pauseparam = hleth_set_pauseparam, -++ .get_pauseparam = hleth_get_pauseparam, -++}; -++ -++static const struct net_device_ops hleth_netdev_ops = { -++ .ndo_open = hleth_net_open, -++ .ndo_stop = hleth_net_close, -++ .ndo_start_xmit = hleth_net_hard_start_xmit, -++ .ndo_tx_timeout = hleth_net_timeout, -++ .ndo_do_ioctl = hleth_net_ioctl, -++ .ndo_set_mac_address = hleth_net_set_mac_address, -++ .ndo_set_rx_mode = hleth_net_set_rx_mode, -++ .ndo_change_mtu = hleth_change_mtu, -++ .ndo_get_stats64 = hleth_net_get_stats, -++}; -++ -++static void hleth_clean_rx(struct hleth_netdev_priv *priv, int *workdone, int budget) -++{ -++ int nr_recv = 0; -++ struct sk_buff *skb = NULL; -++ struct net_device *dev = NULL; -++ -++ if (priv == NULL || priv->ndev == NULL) -++ return; -++ -++ dev = priv->ndev; -++ -++ hleth_recv_budget(priv); -++ -++ while ((skb = skb_dequeue(&priv->rx_head)) != NULL) { -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_dec(&priv->rx_skb_occupied); -++ atomic_sub(skb->truesize, &priv->rx_skb_mem_occupied); -++#endif -++ -++ skb->protocol = eth_type_trans(skb, dev); -++ -++ if (hleth_invalid_rxpkg_len(skb->len)) { -++ pr_err("pkg len error"); -++ priv->stats.rx_errors++; -++ priv->stats.rx_length_errors++; -++ dev_kfree_skb_any(skb); -++ continue; -++ } -++ -++ priv->stats.rx_packets++; -++ priv->stats.rx_bytes += skb->len; -++ napi_gro_receive(&priv->napi, skb); -++ -++ nr_recv++; -++ if (nr_recv >= budget) -++ break; -++ } -++ -++ if (workdone != NULL) -++ *workdone = nr_recv; -++} -++ -++static int hleth_poll(struct napi_struct *napi, int budget) -++{ -++ struct hleth_netdev_priv *priv = NULL; -++ int work_done = 0; -++ priv = container_of(napi, struct hleth_netdev_priv, napi); -++ -++ hleth_xmit_release_skb(priv); -++ hleth_clean_rx(priv, &work_done, budget); -++ -++ if (work_done < budget) { -++ napi_complete(napi); -++ hleth_irq_enable(priv, ud_bit_name(HLETH_GLB_IRQ_INT_MULTI_RXRDY)); -++ } -++ return work_done; -++} -++ -++static int hleth_init_queue(struct device *dev, -++ struct hleth_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 hleth_init_tx_sg_desc_queue(struct hleth_netdev_priv *priv) -++{ -++ priv->sg_desc_queue.desc = (struct sg_desc *)dma_alloc_coherent(priv->dev, -++ TXQ_NUM * sizeof(struct sg_desc), &priv->sg_desc_queue.dma_phys, GFP_KERNEL); -++ if (!priv->sg_desc_queue.desc) -++ return -ENOMEM; -++ -++ return 0; -++} -++ -++static void hleth_destroy_tx_sg_desc_queue(struct hleth_netdev_priv *priv) -++{ -++ if (priv->sg_desc_queue.desc) -++ dma_free_coherent(priv->dev, TXQ_NUM * sizeof(struct sg_desc), -++ priv->sg_desc_queue.desc, priv->sg_desc_queue.dma_phys); -++ priv->sg_desc_queue.desc = NULL; -++} -++ -++static int hleth_init_tx_and_rx_queues(struct hleth_netdev_priv *priv) -++{ -++ int ret; -++ -++ ret = hleth_init_queue(priv->dev, &priv->txq, TXQ_NUM); -++ if (ret) -++ return ret; -++ -++ ret = hleth_init_queue(priv->dev, &priv->rxq, RXQ_NUM); -++ if (ret) -++ return ret; -++ -++ if (has_tso_cap(priv->hw_cap)) { -++ ret = hleth_init_tx_sg_desc_queue(priv); -++ if (ret) -++ return ret; -++ } -++ -++ priv->tx_fifo_used_cnt = 0; -++ -++ return 0; -++} -++ -++static void hleth_destroy_tx_and_rx_queues(struct hleth_netdev_priv *priv) -++{ -++ if (has_tso_cap(priv->hw_cap)) { -++ hleth_destroy_tx_sg_desc_queue(priv); -++ } -++} -++ -++static void hleth_free_skb_rings(struct hleth_netdev_priv *priv) -++{ -++ struct hleth_queue *txq = &priv->txq; -++ struct hleth_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); -++ continue; -++ } -++ -++ dma_addr = rxq->dma_phys[pos]; -++ dma_unmap_single(priv->dev, dma_addr, HLETH_MAX_FRAME_SIZE, -++ DMA_FROM_DEVICE); -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_dec(&priv->rx_skb_occupied); -++ atomic_sub(skb->truesize, &priv->rx_skb_mem_occupied); -++#endif -++ 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); -++ continue; -++ } -++ dma_addr = txq->dma_phys[pos]; -++ dma_unmap_single(priv->dev, dma_addr, skb->len, DMA_TO_DEVICE); -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_dec(&priv->tx_skb_occupied); -++ atomic_sub(skb->truesize, &priv->tx_skb_mem_occupied); -++#endif -++ 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 hleth_netdev_init(struct platform_device *pdev, struct net_device **netdev, -++ struct hleth_netdev_priv *priv, const struct hleth_netdev_priv *com_priv, int port) -++{ -++ int ret = -1; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ struct net_device *ndev; -++ -++ ndev = alloc_etherdev(sizeof(*priv)); -++ if (ndev == NULL) { -++ pr_err("alloc_etherdev fail!\n"); -++ ret = -ENOMEM; -++ return ret; -++ } -++ -++ SET_NETDEV_DEV(ndev, &pdev->dev); -++ -++ ndev->irq = com_priv->irq; -++ -++ ndev->watchdog_timeo = 3 * HZ; /* 3:hz val */ -++ ndev->netdev_ops = &hleth_netdev_ops; -++ ndev->ethtool_ops = &hleth_ethtools_ops; -++ ndev->priv_flags |= IFF_UNICAST_FLT; -++ -++ if (!IS_ERR_OR_NULL(pdata->hleth_phy_param[port].macaddr)) -++ ether_addr_copy(ndev->dev_addr, pdata->hleth_phy_param[port].macaddr); -++ else -++ eth_hw_addr_random(ndev); -++ -++ *netdev = ndev; -++ return 0; -++} -++ -++static void hleth_verify_flow_ctrl_args(struct hleth_netdev_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 int hleth_netdev_priv_init(struct platform_device *pdev, struct net_device *netdev, -++ struct hleth_netdev_priv *priv, const struct hleth_netdev_priv *com_priv, int port) -++{ -++ int ret = -1; -++ struct device *dev = &pdev->dev; -++ ret = memset_s(priv, sizeof(*priv), 0, sizeof(*priv)); -++ if (ret != EOK) { -++ pr_err("memset priv error ret=%d\n", ret); -++ return -1; -++ } -++ ret = memcpy_s(priv, sizeof(*priv), com_priv, sizeof(*priv)); -++ if (ret != EOK) { -++ pr_err("memcpy priv error ret=%d\n", ret); -++ return -1; -++ } -++ -++ local_lock_init(priv); -++ -++ priv->port = port; -++ -++ if (port == HLETH_PORT_0) -++ priv->port_base = priv->glb_base; -++ else -++ priv->port_base = priv->glb_base + 0x2000; -++ -++ priv->dev = dev; -++ priv->ndev = netdev; -++ -++ if (has_tso_cap(priv->hw_cap)) -++ netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | -++ NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6; -++ if (has_rxcsum_cap(priv->hw_cap)) -++ netdev->hw_features |= NETIF_F_RXCSUM; -++ netdev->features |= netdev->hw_features; -++ netdev->vlan_features |= netdev->features; -++ -++ timer_setup(&priv->monitor, hleth_monitor_func, 0); -++ priv->monitor.expires = jiffies + msecs_to_jiffies(HLETH_MONITOR_TIMER); -++ -++ /* wol need */ -++ device_set_wakeup_capable(priv->dev, 1); -++ device_set_wakeup_enable(priv->dev, 1); -++ -++ priv->tx_pause_en = false; -++ priv->tx_pause_active_thresh = TX_FLOW_CTRL_ACTIVE_THRESHOLD; -++ priv->tx_pause_deactive_thresh = TX_FLOW_CTRL_DEACTIVE_THRESHOLD; -++ hleth_verify_flow_ctrl_args(priv); -++ -++ priv->pm_state_set = false; -++ return 0; -++} -++ -++static int hleth_priv_rxpool_init(struct hleth_netdev_priv **priv) -++{ -++ __maybe_unused int ret = -1; -++ if ((*priv)->autoeee_enabled) -++ hleth_autoeee_init(*priv, 0); -++ -++ skb_queue_head_init(&(*priv)->rx_head); -++ -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_set(&(*priv)->tx_skb_occupied, 0); -++ atomic_set(&(*priv)->tx_skb_mem_occupied, 0); -++ atomic_set(&(*priv)->rx_skb_occupied, 0); -++ atomic_set(&(*priv)->rx_skb_mem_occupied, 0); -++#endif -++ -++#ifdef CONFIG_HLETH_MAX_RX_POOLS -++ ret = hleth_init_skb_buffers(*priv); -++ if (ret) { -++ pr_err("hleth_init_skb_buffers failed!\n"); -++ return ret; -++ } -++#endif -++ return 0; -++} -++ -++static int hleth_register_netdev(struct platform_device *pdev, struct net_device *netdev, -++ struct hleth_netdev_priv *priv) -++{ -++ int ret; -++ -++ ret = hleth_init_tx_and_rx_queues(priv); -++ if (ret) -++ return ret; -++ -++ netif_napi_add(netdev, &priv->napi, hleth_poll, HLETH_NAPI_WEIGHT); -++ -++ priv->pdev = pdev; -++ INIT_WORK(&priv->tx_timeout_task, hleth_tx_timeout_task); -++ ret = register_netdev(netdev); -++ if (ret) { -++ pr_err("register_netdev %s failed!\n", netdev->name); -++ hleth_destroy_tx_and_rx_queues(priv); -++ return ret; -++ } -++ return 0; -++} -++ -++static int hleth_platdev_probe_port(struct platform_device *pdev, -++ struct hleth_netdev_priv *com_priv, int port) -++{ -++ int ret = -1; -++ struct net_device *netdev = NULL; -++ struct hleth_netdev_priv *priv = NULL; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ if ((port != HLETH_PORT_0) && (port != HLETH_PORT_1)) { -++ ret = -ENODEV; -++ goto _error_exit; -++ } -++ -++ ret = hleth_netdev_init(pdev, &netdev, priv, com_priv, port); -++ if (ret) -++ goto _error_exit; -++ -++ /* init hleth_global somethings... */ -++ pdata->hleth_devs_save[port] = netdev; -++ -++ /* init hleth_local_driver */ -++ priv = netdev_priv(netdev); -++ if (hleth_netdev_priv_init(pdev, netdev, priv, com_priv, port)) -++ goto _error_mem; -++ -++ /* reset and init port */ -++ hleth_port_init(priv); -++ -++ priv->depth.hw_xmitq = HLETH_HWQ_XMIT_DEPTH; -++ -++ priv->phy = of_phy_connect(netdev, priv->phy_node, hleth_adjust_link, 0, priv->phy_mode); -++ if (priv->phy == NULL || IS_ERR(priv->phy)) { -++ pr_info("connect to port[%d] PHY failed!\n", port); -++ priv->phy = NULL; -++ ret = -1; -++ goto _error_phy_connect; -++ } -++ -++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, priv->phy->supported); -++ pr_info("attached port %d PHY %d to driver %s\n", port, priv->phy->mdio.addr, priv->phy->drv->name); -++ -++ if (hleth_priv_rxpool_init(&priv)) -++ goto _error_init_skb_buffers; -++ -++ if (hleth_register_netdev(pdev, netdev, priv)) -++ goto _error_register_netdev; -++ -++ phy_suspend(priv->phy); -++ -++ return ret; -++ -++_error_register_netdev: -++ priv->pdev = NULL; -++ cancel_work_sync(&priv->tx_timeout_task); -++#ifdef CONFIG_HLETH_MAX_RX_POOLS -++ hleth_destroy_skb_buffers(priv); -++ -++#endif -++_error_init_skb_buffers: -++ phy_disconnect(priv->phy); -++ priv->phy = NULL; -++ -++_error_phy_connect: -++ local_lock_exit(); -++ -++_error_mem: -++ pdata->hleth_devs_save[port] = NULL; -++ free_netdev(netdev); -++ -++_error_exit: -++ return ret; -++} -++ -++static int hleth_platdev_remove_port(struct platform_device *pdev, int port) -++{ -++ struct net_device *ndev; -++ struct hleth_netdev_priv *priv = NULL; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ ndev = pdata->hleth_devs_save[port]; -++ -++ if (ndev == NULL) -++ goto _ndev_exit; -++ -++ priv = netdev_priv(ndev); -++ cancel_work_sync(&priv->tx_timeout_task); -++ -++ unregister_netdev(ndev); -++#ifdef CONFIG_HLETH_MAX_RX_POOLS -++ hleth_destroy_skb_buffers(priv); -++#endif -++ hleth_destroy_tx_and_rx_queues(priv); -++ phy_disconnect(priv->phy); -++ priv->phy = NULL; -++ -++ iounmap((void *)priv->glb_base); -++ -++ local_lock_exit(); -++ -++ pdata->hleth_devs_save[port] = NULL; -++ free_netdev(ndev); -++ -++_ndev_exit: -++ return 0; -++} -++ -++#define DEFAULT_LD_AM 0xe -++#define DEFAULT_LDO_AM 0x3 -++#define DEFAULT_R_TUNING 0x16 -++#define BIT_OFFSET_LD_SET 6 -++#define BIT_OFFSET_LDO_SET 12 -++#define BIT_OFFSET_R_TUNING 0 -++#define LD_AM_MASK GENMASK(4, 0) -++#define LDO_AM_MASK GENMASK(2, 0) -++#define R_TUNING_MASK GENMASK(5, 0) -++static void hleth_of_get_phy_trim_params(struct hleth_platdrv_data *pdata, int port_index) -++{ -++ struct device_node *chiptrim_node = NULL; -++ u32 phy_trim_val = 0; -++ u8 ld_am, ldo_am, r_tuning; -++ int ret; -++ struct hleth_phy_param_s *phy_param = &pdata->hleth_phy_param[port_index]; -++ -++ /* currently only one internal PHY */ -++ if (port_index == HLETH_PORT_1) -++ return; -++ -++ ld_am = DEFAULT_LD_AM; -++ ldo_am = DEFAULT_LDO_AM; -++ r_tuning = DEFAULT_R_TUNING; -++ -++ chiptrim_node = of_find_node_by_path("/soc/chiptrim"); -++ if (chiptrim_node != NULL) { -++ ret = of_property_read_u32(chiptrim_node, "chiptrim_fephy", &phy_trim_val); -++ if (ret) { -++ pr_err("%s,%d: chiptrim0 property not found\n", -++ __func__, __LINE__); -++ return; -++ } -++ } -++ -++ if (phy_trim_val) { -++ ld_am = (phy_trim_val >> 24) & LD_AM_MASK; /* 24:right shift val */ -++ ldo_am = (phy_trim_val >> 16) & LDO_AM_MASK; /* 16:right shift val */ -++ r_tuning = (phy_trim_val >> 8) & R_TUNING_MASK; /* 8:right shift val */ -++ } -++ -++ if (phy_param->fephy_trim != NULL) { -++ phy_trim_val = readl(phy_param->fephy_trim); -++ ld_am = (phy_trim_val >> BIT_OFFSET_LD_SET) & LD_AM_MASK; -++ ldo_am = (phy_trim_val >> BIT_OFFSET_LDO_SET) & LDO_AM_MASK; -++ r_tuning = (phy_trim_val >> BIT_OFFSET_R_TUNING) & R_TUNING_MASK; -++ } -++ -++ phy_param->trim_params = -++ (r_tuning << 16) | (ldo_am << 8) | ld_am; /* 8,16:right shift val */ -++} -++ -++static int hleth_of_get_phy_addr(struct device_node *node, struct hleth_phy_param_s *param) -++{ -++ int data; -++ -++ if (of_property_read_u32(node, "reg", &data)) -++ return -EINVAL; -++ -++ if ((data < 0) || (data >= PHY_MAX_ADDR)) { -++ if (node->full_name != NULL) -++ pr_info("%s has invalid PHY address\n", node->full_name); -++ data = HLETH_INVALID_PHY_ADDR; -++ } -++ -++ param->phy_addr = data; -++ if (data != HLETH_INVALID_PHY_ADDR) -++ param->isvalid = true; -++ -++ return 0; -++} -++ -++#define MAX_NAME_SIZE 32 -++static int hleth_of_get_phy_resource(struct platform_device *pdev, int port) -++{ -++ struct resource *res; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ struct hleth_phy_param_s *phy_param = &pdata->hleth_phy_param[port]; -++ struct device *dev = &pdev->dev; -++ int ret; -++ char name_buf[MAX_NAME_SIZE] = {0}; -++ -++ ret = snprintf_s(name_buf, MAX_NAME_SIZE, MAX_NAME_SIZE - 1, "reset_phy%d", port); -++ if (ret < 0) -++ return ret; -++ phy_param->phy_rst = devm_reset_control_get_optional(dev, name_buf); -++ if (IS_ERR(phy_param->phy_rst)) -++ return PTR_ERR(phy_param->phy_rst); -++ -++ ret = snprintf_s(name_buf, MAX_NAME_SIZE, MAX_NAME_SIZE - 1, "phy_clk%d", port); -++ if (ret < 0) -++ return ret; -++ phy_param->phy_clk = devm_clk_get(dev, name_buf); -++ if (IS_ERR(phy_param->phy_clk)) -++ phy_param->phy_clk = NULL; -++ -++ ret = snprintf_s(name_buf, MAX_NAME_SIZE, MAX_NAME_SIZE - 1, "fephy_sysctrl%d", port); -++ if (ret < 0) -++ return ret; -++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name_buf); -++ if (res != NULL) { -++ phy_param->fephy_sysctrl = devm_ioremap_resource(dev, res); -++ if (IS_ERR(phy_param->fephy_sysctrl)) -++ phy_param->fephy_sysctrl = NULL; -++ } -++ -++ ret = snprintf_s(name_buf, MAX_NAME_SIZE, MAX_NAME_SIZE - 1, "fephy_trim%d", port); -++ if (ret < 0) -++ return ret; -++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name_buf); -++ if (res != NULL) { -++ phy_param->fephy_trim = devm_ioremap_resource(dev, res); -++ if (IS_ERR(phy_param->fephy_trim)) -++ phy_param->fephy_trim = NULL; -++ } -++ -++ return 0; -++} -++ -++static int hleth_of_get_param(struct platform_device *pdev, struct hleth_platdrv_data *pdata) -++{ -++ struct device *dev = &pdev->dev; -++ struct device_node *node = dev->of_node; -++ struct device_node *child = NULL; -++ int idx = 0; -++ int ret; -++ -++ for_each_available_child_of_node(node, child) { -++ /* get phy-addr */ -++ ret = hleth_of_get_phy_addr(child, &pdata->hleth_phy_param[idx]); -++ if (ret != 0) -++ return ret; -++ -++ pdata->hleth_phy_param[idx].fephy_phyaddr_bit = -1; -++ of_property_read_u32(child, "phyaddr-bit-offset", -++ &pdata->hleth_phy_param[idx].fephy_phyaddr_bit); -++ -++ /* get phy_mode */ -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) -++ of_get_phy_mode(child, &(pdata->hleth_phy_param[idx].phy_mode)); -++#else -++ pdata->hleth_phy_param[idx].phy_mode = of_get_phy_mode(child); -++#endif -++ -++ /* get mac */ -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) -++ of_get_mac_address(child, (u8 *)(pdata->hleth_phy_param[idx].macaddr)); -++#else -++ pdata->hleth_phy_param[idx].macaddr = of_get_mac_address(child); -++#endif -++ /* get gpio_base and bit */ -++ of_property_read_u32(child, "phy-gpio-base", -++ (u32 *)(&pdata->hleth_phy_param[idx].gpio_base)); -++ of_property_read_u32(child, "phy-gpio-bit", -++ &pdata->hleth_phy_param[idx].gpio_bit); -++ -++ /* get internal flag */ -++ pdata->hleth_phy_param[idx].isinternal = -++ of_property_read_bool(child, "internal-phy"); -++ -++ ret = hleth_of_get_phy_resource(pdev, idx); -++ if (ret != 0) -++ return ret; -++ -++ hleth_of_get_phy_trim_params(pdata, idx); -++ -++ if (++idx >= HLETH_MAX_PORT) -++ break; -++ } -++ -++ return 0; -++} -++ -++static int hleth_plat_driver_probe_res(struct platform_device *pdev, struct hleth_netdev_priv *priv, -++ struct hleth_platdrv_data *pdata) -++{ -++ struct device *dev = &pdev->dev; -++ struct device_node *node = dev->of_node; -++ struct resource *res = NULL; -++ int ret; -++ -++ if (of_device_is_compatible(node, "vendor,femac-v2")) -++ priv->hw_cap |= HW_CAP_TSO | HW_CAP_RXCSUM; -++ -++ ret = hleth_of_get_param(pdev, pdata); -++ if (ret != 0) { -++ if (ret != -EPROBE_DEFER) -++ pr_err("failed to get phy param, error: %d.\n", ret); -++ return ret; -++ } -++ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -++ priv->glb_base = devm_ioremap_resource(dev, res); -++ if (IS_ERR(priv->glb_base)) -++ return PTR_ERR(priv->glb_base); -++ -++ priv->clk = devm_clk_get(dev, "hleth_clk"); -++ if (IS_ERR(priv->clk)) { -++ pr_err("failed to get clk\n"); -++ return PTR_ERR(priv->clk); -++ } -++ -++ priv->mac_reset = devm_reset_control_get_optional(dev, "mac_reset"); -++ if (IS_ERR(priv->mac_reset)) -++ return PTR_ERR(priv->mac_reset); -++ -++ ret = platform_get_irq(pdev, 0); -++ if (ret < 0) { -++ pr_err("no IRQ defined!\n"); -++ return ret; -++ } -++ priv->irq = ret; -++ return 0; -++} -++ -++static void hleth_phy_detect(struct platform_device *pdev, struct hleth_platdrv_data *pdata) -++{ -++ int port = -1; -++ struct hleth_netdev_priv *priv = NULL; -++ struct device *dev = &pdev->dev; -++ struct device_node *node = dev->of_node; -++ struct device_node *child = NULL; -++ priv = &pdata->hleth_priv; -++ for_each_available_child_of_node(node, child) { -++ if (++port >= HLETH_MAX_PORT) -++ break; -++ -++ if (!pdata->hleth_phy_param[port].isvalid) -++ continue; -++ -++ priv->phy_node = of_parse_phandle(node, "phy-handle", port); -++ if (priv->phy_node == NULL) { -++ pr_err("not find phy-handle [%d]\n", port); -++ continue; -++ } -++ -++ priv->phy_mode = pdata->hleth_phy_param[port].phy_mode; -++ priv->autoeee_enabled = of_property_read_bool(child, "autoeee"); -++ -++ if (hleth_platdev_probe_port(pdev, priv, port) == 0) -++ pdata->hleth_real_port_cnt++; -++ } -++} -++ -++ -++static void hleth_core_reset(struct hleth_netdev_priv *priv) -++{ -++ reset_control_assert(priv->mac_reset); -++ reset_control_deassert(priv->mac_reset); -++} -++ -++static int hleth_plat_driver_probe(struct platform_device *pdev) -++{ -++ int ret; -++ struct device *dev = &pdev->dev; -++ struct hleth_netdev_priv *priv = NULL; -++ struct hleth_platdrv_data *pdata; -++ -++ pdata = devm_kzalloc(dev, sizeof(struct hleth_platdrv_data), GFP_KERNEL); -++ if (pdata == NULL) -++ return -ENOMEM; -++ -++ platform_set_drvdata(pdev, pdata); -++ priv = &pdata->hleth_priv; -++ ret = hleth_plat_driver_probe_res(pdev, priv, pdata); -++ if (ret != 0) { -++ goto exit; -++ } -++ -++ /* first disable ETH clock, then reset PHY to load PHY address */ -++ hleth_phy_reset(pdata); -++ -++ hleth_core_reset(priv); -++ ret = clk_prepare_enable(priv->clk); -++ if (ret < 0) { -++ pr_err("failed to enable clk %d\n", ret); -++ goto exit; -++ } -++ /* After MDCK clock giving, wait 5ms before MDIO access */ -++ mdelay(5); -++ -++ if (hleth_mdiobus_driver_init(pdev, priv)) { -++ pr_err("mdio bus init error!\n"); -++ ret = -ENODEV; -++ goto exit_clk_disable; -++ } -++ -++ /* phy param */ -++ hleth_phy_register_fixups(); -++ -++ hleth_phy_detect(pdev, pdata); -++ -++ if (!pdata->hleth_devs_save[HLETH_PORT_0] && !pdata->hleth_devs_save[HLETH_PORT_1]) { -++ pr_err("no dev probed!\n"); -++ ret = -ENODEV; -++ goto exit_mdiobus; -++ } -++ -++ return ret; -++ -++exit_mdiobus: -++ hleth_mdiobus_driver_exit(priv); -++ -++exit_clk_disable: -++ clk_disable_unprepare(priv->clk); -++ -++exit: -++ -++ return ret; -++} -++ -++static int hleth_plat_driver_remove(struct platform_device *pdev) -++{ -++ int i; -++ int ret; -++ struct net_device *ndev = NULL; -++ struct hleth_netdev_priv *priv = NULL; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ if (pdata->hleth_devs_save[HLETH_PORT_0]) -++ ndev = pdata->hleth_devs_save[HLETH_PORT_0]; -++ else if (pdata->hleth_devs_save[HLETH_PORT_1]) -++ ndev = pdata->hleth_devs_save[HLETH_PORT_1]; -++ -++ priv = netdev_priv(ndev); -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) -++ hleth_platdev_remove_port(pdev, i); -++ -++ hleth_mdiobus_driver_exit(priv); -++ -++ clk_disable_unprepare(priv->clk); -++ hleth_phy_clk_disable(pdata); -++ -++ ret = memset_s(pdata->hleth_devs_save, sizeof(pdata->hleth_devs_save), 0, sizeof(pdata->hleth_devs_save)); -++ if (ret != EOK) { -++ pr_err("memset hleth_devs_save error ret=%d\n", ret); -++ return ret; -++ } -++ hleth_phy_unregister_fixups(); -++ -++ return ret; -++} -++ -++#ifdef CONFIG_PM -++static int hleth_plat_driver_suspend_port(struct platform_device *pdev, -++ pm_message_t state, int port) -++{ -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ struct net_device *ndev = pdata->hleth_devs_save[port]; -++ -++ if (ndev != NULL) { -++ if (netif_running(ndev)) { -++ netif_device_detach(ndev); -++ hleth_net_close(ndev); -++ } -++ } -++ -++ return 0; -++} -++ -++static int hleth_plat_driver_suspend(struct platform_device *pdev, -++ pm_message_t state) -++{ -++ int i; -++ bool power_off = true; -++ struct hleth_netdev_priv *priv = NULL; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) -++ hleth_plat_driver_suspend_port(pdev, state, i); -++ -++ if (hleth_pmt_enter(pdev)) -++ power_off = false; -++ -++ if (power_off) { -++ for (i = 0; i < HLETH_MAX_PORT; i++) { -++ if (pdata->hleth_devs_save[i]) { -++ priv = netdev_priv(pdata->hleth_devs_save[i]); -++ genphy_suspend(priv->phy);/* power down phy */ -++ } -++ } -++ -++ /* need some time before phy suspend finished. */ -++ usleep_range(1000, 10000); /* 1000,10000:delay zone */ -++ -++ if (priv != NULL && priv->clk != NULL) -++ clk_disable_unprepare(priv->clk); -++ -++ hleth_phy_clk_disable(pdata); -++ } -++ -++ return 0; -++} -++ -++static int hleth_plat_driver_resume_port(struct platform_device *pdev, int port) -++{ -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ struct net_device *ndev = pdata->hleth_devs_save[port]; -++ struct hleth_netdev_priv *priv = netdev_priv(ndev); -++ -++ if (ndev != NULL) { -++ if (ndev->phydev != NULL) -++ phy_init_hw(ndev->phydev); -++ if (netif_running(ndev)) { -++ hleth_port_init(priv); -++ hleth_net_open(ndev); -++ netif_device_attach(ndev); -++ hleth_net_set_rx_mode(ndev); -++ } -++ } -++ -++ return 0; -++} -++ -++static bool hleth_mac_wol_enabled(struct platform_device *pdev) -++{ -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ struct hleth_netdev_priv *priv = NULL; -++ bool mac_wol_enabled = false; -++ int i; -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) { -++ if (!pdata->hleth_devs_save[i]) -++ continue; -++ -++ priv = netdev_priv(pdata->hleth_devs_save[i]); -++ if (priv->mac_wol_enabled) { -++ mac_wol_enabled = true; -++ break; -++ } -++ } -++ -++ return mac_wol_enabled; -++} -++ -++static int hleth_plat_driver_resume(struct platform_device *pdev) -++{ -++ int i; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ struct hleth_netdev_priv *priv = &pdata->hleth_priv; -++ -++ /* first disable ETH clock, then reset PHY to load PHY address */ -++ if (hleth_mac_wol_enabled(pdev)) -++ clk_disable_unprepare(priv->clk); -++ hleth_phy_reset(pdata); -++ /* enable clk */ -++ clk_prepare_enable(priv->clk); -++ /* After MDCK clock giving, wait 5ms before MDIO access */ -++ mdelay(5); -++ hleth_fix_festa_phy_trim(priv->mii_bus, pdata); -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) -++ hleth_plat_driver_resume_port(pdev, i); -++ -++ hleth_pmt_exit(pdev); -++ return 0; -++} -++#else -++static inline int hleth_plat_driver_suspend(struct platform_device *pdev, -++ pm_message_t state) -++{ -++ return 0; -++} -++static inline int hleth_plat_driver_resume(struct platform_device *pdev) -++{ -++ return 0; -++} -++#endif -++ -++static void hleth_tx_timeout_task(struct work_struct *ws) -++{ -++ struct hleth_netdev_priv *priv = NULL; -++ pm_message_t state_timeout; -++ -++ memset_s(&state_timeout, sizeof(state_timeout), 0, sizeof(state_timeout)); -++ priv = container_of(ws, struct hleth_netdev_priv, tx_timeout_task); -++#ifdef CONFIG_PM -++ state_timeout.event = PM_EVENT_INVALID; -++ hleth_plat_driver_suspend(priv->pdev, state_timeout); -++ hleth_plat_driver_resume(priv->pdev); -++#endif -++} -++ -++static const struct of_device_id hleth_of_match[] = { -++ {.compatible = "huanglong,plat_eth"}, -++ {.compatible = "huanglong,t9-eth"}, -++ {.compatible = "vendor,femac-v2"}, -++ {}, -++}; -++ -++MODULE_DEVICE_TABLE(of, hleth_of_match); -++ -++static struct platform_driver hleth_platform_driver = { -++ .probe = hleth_plat_driver_probe, -++ .remove = hleth_plat_driver_remove, -++ .suspend = hleth_plat_driver_suspend, -++ .resume = hleth_plat_driver_resume, -++ .driver = { -++ .owner = THIS_MODULE, -++ .name = HLETH_DRIVER_NAME, -++ .bus = &platform_bus_type, -++ .of_match_table = of_match_ptr(hleth_of_match), -++ }, -++}; -++ -++static int hleth_mod_init(void) -++{ -++ int ret = 0; -++ -++ if (hleth_disable) -++ return 0; -++ -++ ret = platform_driver_register(&hleth_platform_driver); -++ if (ret) -++ pr_err("register platform driver failed!\n"); -++ -++ return ret; -++} -++ -++static void hleth_mod_exit(void) -++{ -++ if (hleth_disable) -++ return; -++ -++ platform_driver_unregister(&hleth_platform_driver); -++} -++ -++module_init(hleth_mod_init); -++module_exit(hleth_mod_exit); -++ -++MODULE_DESCRIPTION("Huanglong ETH driver whith MDIO support"); -++MODULE_LICENSE("GPL"); -++ -++/* vim: set ts=8 sw=8 tw=78: */ -+diff --git a/drivers/net/ethernet/vendor/eth/hleth.h b/drivers/net/ethernet/vendor/eth/hleth.h -+new file mode 100755 -+index 000000000..dc56c72bf -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/hleth.h -+@@ -0,0 +1,507 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Header file for hleth.c -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++#ifndef __HLETH_H -++#define __HLETH_H -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define HLETH_SKB_MEMORY_STATS -++ -++#define HLETH_MIIBUS_NAME "hlmii" -++#define HLETH_DRIVER_NAME "hleth" -++ -++/* hleth max port */ -++#define HLETH_MAX_PORT 2 -++ -++/* invalid phy addr */ -++#define HLETH_INVALID_PHY_ADDR 0xff -++ -++/* hleth monitor timer, 10ms */ -++#define HLETH_MONITOR_TIMER 10 -++ -++/* hleth hardware queue send fifo depth, increase to optimize TX performance. */ -++#define HLETH_HWQ_XMIT_DEPTH 12 -++ -++/* set irq affinity to cpu1 when multi-processor */ -++#define HLETH_IRQ_AFFINITY_CPU 1 -++ -++#define HLETH_MAX_QUEUE_DEPTH 64 -++#define HLETH_MAX_RX_HEAD_LEN (10000) /* max skbs for rx */ -++#define HLETH_MAX_RCV_LEN 1535 /* max receive length */ -++#define TXQ_NUM 64 -++#define RXQ_NUM 128 -++ -++#define HLETH_NAPI_WEIGHT 32 -++/* mmu should be less than 1600 Bytes -++ */ -++ -++#define HLETH_MAX_FRAME_SIZE (1600) -++#define SKB_SIZE (HLETH_MAX_FRAME_SIZE) -++#define hleth_invalid_rxpkg_len(len) (!((len) >= 42 && \ -++ (len) <= HLETH_MAX_FRAME_SIZE)) -++ -++#define HLETH_MAX_MAC_FILTER_NUM 8 -++#define HLETH_MAX_UNICAST_ADDRESSES 2 -++#define HLETH_MAX_MULTICAST_ADDRESSES (HLETH_MAX_MAC_FILTER_NUM - \ -++ HLETH_MAX_UNICAST_ADDRESSES) -++ -++/* Register Definition -++ */ -++/*------------------------- port register -----------------------------------*/ -++/* Mac port sel */ -++#define HLETH_P_MAC_PORTSEL 0x0200 -++#define HLETH_P_MAC_PORTSEL_STAT 0 -++#define HLETH_P_MAC_PORTSEL_STAT_MDIO 0 -++#define HLETH_P_MAC_PORTSEL_STAT_CPU 1 -++#define HLETH_P_MAC_PORTSEL_MII_MODE 1 -++#define HLETH_P_MAC_PORTSEL_MII ~BIT(1) -++#define HLETH_P_MAC_PORTSEL_RMII BIT(1) -++/* Mac ro status */ -++#define HLETH_P_MAC_RO_STAT 0x0204 -++/* Mac port status set */ -++#define HLETH_P_MAC_PORTSET 0x0208 -++#define HLETH_P_MAC_PORTSET_SPD_100M BIT(2) -++#define HLETH_P_MAC_PORTSET_LINKED BIT(1) -++#define HLETH_P_MAC_PORTSET_DUP_FULL BIT(0) -++/* Mac status change */ -++#define HLETH_P_MAC_STAT_CHANGE 0x020C -++/* Mac set */ -++#define HLETH_P_MAC_SET 0x0210 -++#define BIT_PAUSE_EN BIT(18) -++#define hleth_p_mac_set_len_max(n) ((n) & 0x7FF) -++#define HLETH_P_MAC_SET_LEN_MAX_MSK GENMASK(10, 0) -++ -++#define HLETH_P_MAC_RX_IPGCTRL 0x0214 -++#define HLETH_P_MAC_TX_IPGCTRL 0x0218 -++#define HLETH_P_MAC_TX_IPGCTRL_PRE_CNT_LMT_SHIFT 23 -++#define HLETH_P_MAC_TX_IPGCTRL_PRE_CNT_LMT_MSK GENMASK(25, 23) -++/* queue length set */ -++#define HLETH_P_GLB_QLEN_SET 0x0344 -++#define HLETH_P_GLB_QLEN_SET_TXQ_DEP_MSK GENMASK(5, 0) -++#define hleth_p_glb_qlen_set_txq_dep(n) ((n) << 0) -++#define HLETH_P_GLB_QLEN_SET_RXQ_DEP_MSK GENMASK(13, 8) -++#define hleth_p_glb_qlen_set_rxq_dep(n) ((n) << 8) -++ -++#define HLETH_P_GLB_FC_LEVEL 0x0348 -++#define BITS_FC_ACTIVE_THR_OFFSET 8 -++#define HLETH_P_GLB_FC_DEACTIVE_THR_MASK GENMASK(5, 0) -++#define HLETH_P_GLB_FC_ACTIVE_THR_MASK GENMASK(13, 8) -++#define BIT_FC_EN BIT(14) -++ -++/* Rx frame start addr */ -++#define HLETH_P_GLB_RXFRM_SADDR 0x0350 -++/* Rx (read only) Queue-ID and LEN */ -++#define HLETH_P_GLB_RO_IQFRM_DES 0x0354 -++#define HLETH_P_GLB_RO_IQFRM_DES_FDIN_LEN_MSK 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 -++/* Rx ADDR */ -++#define HLETH_P_GLB_IQ_ADDR 0x0358 -++/* Tx ADDR and LEN */ -++#define HLETH_P_GLB_EQ_ADDR 0x0360 -++#define HLETH_P_GLB_EQFRM_LEN 0x0364 -++#define HLETH_P_GLB_EQFRM_TXINQ_LEN_MSK GENMASK(10, 0) -++/* Rx/Tx Queue ID */ -++#define HLETH_P_GLB_RO_QUEUE_ID 0x0368 -++/* Rx/Tx Queue staus */ -++#define HLETH_P_GLB_RO_QUEUE_STAT 0x036C -++/* check this bit to see if we can add a Tx package */ -++#define HLETH_P_GLB_RO_QUEUE_STAT_XMITQ_RDY_MSK BIT(24) -++/* check this bit to see if we can add a Rx addr */ -++#define HLETH_P_GLB_RO_QUEUE_STAT_RECVQ_RDY_MSK BIT(25) -++/* counts in queue, include currently sending */ -++#define HLETH_P_GLB_RO_QUEUE_STAT_XMITQ_CNT_INUSE_MSK GENMASK(5, 0) -++/* Rx Checksum Offload Control */ -++#define HLETH_P_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 HLETH_P_TSO_DBG_EN 0x03A4 -++#define BITS_TSO_DBG_EN BIT(31) -++#define HLETH_P_TSO_DBG_STATE 0x03A8 -++#define HLETH_P_TSO_DBG_ADDR 0x03AC -++#define HLETH_P_TSO_DBG_TX_INFO 0x03B0 -++#define HLETH_P_TSO_DBG_TX_ERR 0x03B4 -++/*------------------------- global register --------------------------------*/ -++/* host mac address */ -++#define HLETH_GLB_HOSTMAC_L32 0x1300 -++#define HLETH_GLB_HOSTMAC_H16 0x1304 -++/* soft reset */ -++#define HLETH_GLB_SOFT_RESET 0x1308 -++#define HLETH_GLB_SOFT_RESET_ALL BIT(0) -++#define HLETH_GLB_SOFT_RESET_P0 BIT(2) -++#define HLETH_GLB_SOFT_RESET_P1 BIT(3) -++/* forward contrl */ -++#define HLETH_GLB_FWCTRL 0x1310 -++#define HLETH_GLB_FWCTRL_VLAN_ENABLE BIT(0) -++#define HLETH_GLB_FWCTRL_FW2CPU_ENA_U BIT(5) -++#define HLETH_GLB_FWCTRL_FW2CPU_ENA_D BIT(9) -++#define HLETH_GLB_FWCTRL_FWALL2CPU_U BIT(7) -++#define HLETH_GLB_FWCTRL_FWALL2CPU_D BIT(11) -++#define HLETH_GLB_FWCTRL_FW2OTHPORT_ENA_U BIT(4) -++#define HLETH_GLB_FWCTRL_FW2OTHPORT_ENA_D BIT(8) -++#define HLETH_GLB_FWCTRL_FW2OTHPORT_FORCE_U BIT(6) -++#define HLETH_GLB_FWCTRL_FW2OTHPORT_FORCE_D BIT(10) -++/* Mac filter table control */ -++#define HLETH_GLB_MACTCTRL 0x1314 -++#define HLETH_GLB_MACTCTRL_MACT_ENA_U BIT(7) -++#define HLETH_GLB_MACTCTRL_MACT_ENA_D BIT(15) -++#define HLETH_GLB_MACTCTRL_BROAD2CPU_U BIT(5) -++#define HLETH_GLB_MACTCTRL_BROAD2CPU_D BIT(13) -++#define HLETH_GLB_MACTCTRL_BROAD2OTHPORT_U BIT(4) -++#define HLETH_GLB_MACTCTRL_BROAD2OTHPORT_D BIT(12) -++#define HLETH_GLB_MACTCTRL_MULTI2CPU_U BIT(3) -++#define HLETH_GLB_MACTCTRL_MULTI2CPU_D BIT(11) -++#define HLETH_GLB_MACTCTRL_MULTI2OTHPORT_U BIT(2) -++#define HLETH_GLB_MACTCTRL_MULTI2OTHPORT_D BIT(10) -++#define HLETH_GLB_MACTCTRL_UNI2CPU_U BIT(1) -++#define HLETH_GLB_MACTCTRL_UNI2CPU_D BIT(9) -++#define HLETH_GLB_MACTCTRL_UNI2OTHPORT_U BIT(0) -++#define HLETH_GLB_MACTCTRL_UNI2OTHPORT_D BIT(8) -++/* Host mac address */ -++#define HLETH_GLB_DN_HOSTMAC_L32 0x1340 -++#define HLETH_GLB_DN_HOSTMAC_H16 0x1344 -++#define HLETH_GLB_DN_HOSTMAC_ENA 0x1348 -++#define HLETH_GLB_DN_HOSTMAC_ENA_BIT BIT(0) -++/* Mac filter */ -++#define HLETH_GLB_MAC_L32_BASE 0x1400 -++#define HLETH_GLB_MAC_H16_BASE 0x1404 -++#define HLETH_GLB_MAC_L32_BASE_D (0x1400 + 16 * 0x8) -++#define HLETH_GLB_MAC_H16_BASE_D (0x1404 + 16 * 0x8) -++#define HLETH_GLB_MACFLT_H16 GENMASK(15, 0) -++#define HLETH_GLB_MACFLT_FW2CPU_U BIT(21) -++#define HLETH_GLB_MACFLT_FW2CPU_D BIT(19) -++#define HLETH_GLB_MACFLT_FW2PORT_U BIT(20) -++#define HLETH_GLB_MACFLT_FW2PORT_D BIT(18) -++#define HLETH_GLB_MACFLT_ENA_U BIT(17) -++#define HLETH_GLB_MACFLT_ENA_D BIT(16) -++/* ENDIAN */ -++#define HLETH_GLB_ENDIAN_MOD 0x1318 -++#define HLETH_GLB_ENDIAN_MOD_IN BIT(1) -++#define HLETH_GLB_ENDIAN_MOD_OUT BIT(0) -++/* IRQs */ -++#define HLETH_GLB_IRQ_STAT 0x1330 -++#define HLETH_GLB_IRQ_ENA 0x1334 -++#define HLETH_GLB_IRQ_ENA_IEN_A BIT(19) -++#define HLETH_GLB_IRQ_ENA_IEN_U BIT(18) -++#define HLETH_GLB_IRQ_ENA_IEN_D BIT(17) -++#define HLETH_GLB_IRQ_ENA_BIT_U GENMASK(7, 0) -++#define HLETH_GLB_IRQ_ENA_BIT_D GENMASK(27, 20) -++#define HLETH_GLB_IRQ_RAW 0x1338 -++#define HLETH_GLB_IRQ_INT_TX_ERR_U BIT(8) -++#define HLETH_GLB_IRQ_INT_TX_ERR_D BIT(28) -++#define HLETH_GLB_IRQ_INT_MULTI_RXRDY_U BIT(7) -++#define HLETH_GLB_IRQ_INT_MULTI_RXRDY_D BIT(27) -++#define HLETH_GLB_IRQ_INT_TXQUE_RDY_U BIT(6) -++#define HLETH_GLB_IRQ_INT_TXQUE_RDY_D BIT(26) -++#define HLETH_GLB_IRQ_INT_RX_RDY_U BIT(0) -++#define HLETH_GLB_IRQ_INT_RX_RDY_D BIT(20) -++ -++#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) -++ -++/* 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) -++/* -++ * 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 -++/* *********************************************************** -++* -++* Only for internal used! -++* -++* *********************************************************** -++*/ -++ -++/* read/write IO */ -++#define hleth_readl(base, ofs) \ -++ readl((base) + (ofs)) -++#define hleth_writel(base, v, ofs) \ -++ writel(v, ((base) + (ofs))) -++ -++/* port */ -++enum hleth_port_e { -++ HLETH_PORT_0 = 0, -++ HLETH_PORT_1, -++ HLETH_PORT_NUM, -++}; -++ -++struct hleth_queue { -++ struct sk_buff **skb; -++ dma_addr_t *dma_phys; -++ int num; -++ unsigned int head; -++ unsigned int tail; -++}; -++ -++struct frags_info { -++ /* Word(2*i+2) */ -++ u32 addr; -++ /* Word(2*i+3) */ -++ u32 size : 16; -++ u32 reserved : 16; -++}; -++ -++struct sg_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]; -++}; -++ -++struct hleth_sg_desc { -++ struct sg_desc *desc; -++ dma_addr_t dma_phys; -++}; -++ -++struct hleth_netdev_priv { -++ void __iomem *glb_base; /* virtual io global addr */ -++ void __iomem *port_base; /* virtual to port addr: -++ * port0-0; port1-0x2000 -++ */ -++ struct reset_control *mac_reset; -++ int port; /* 0 => up port, 1 => down port */ -++ int irq; -++ -++ u32 hw_cap; -++ struct device *dev; -++ struct net_device *ndev; -++ struct rtnl_link_stats64 stats; -++ struct phy_device *phy; -++ struct device_node *phy_node; -++ struct platform_device *pdev; -++ phy_interface_t phy_mode; -++ -++ struct mii_bus *mii_bus; -++ -++ struct sk_buff_head rx_head; /* received pkgs */ -++ struct hleth_queue rxq; -++ struct hleth_queue txq; -++ struct hleth_sg_desc sg_desc_queue; -++ u32 tx_fifo_used_cnt; -++ -++ struct timer_list monitor; -++ -++ struct { -++ int hw_xmitq; -++ } depth; -++ -++#ifdef CONFIG_HLETH_MAX_RX_POOLS -++ struct { -++ unsigned long rx_pool_dry_times; -++ } stat; -++ -++ struct rx_skb_pool { -++ struct sk_buff *sk_pool[CONFIG_HLETH_MAX_RX_POOLS];/* skb pool */ -++ int next_free_skb; /* next free skb */ -++ } rx_pool; -++#endif -++ -++ struct napi_struct napi; -++ -++ int link_stat; -++ int (*eee_init)(struct phy_device *phy_dev); -++ struct work_struct tx_timeout_task; -++ -++ spinlock_t lock; /* lock for reg rw */ -++ unsigned long lockflags; -++ -++ spinlock_t mdio_lock; /* lock for mdio reg */ -++ unsigned long mdio_lockflags; -++ -++ struct clk *clk; -++ bool mac_wol_enabled; -++ bool pm_state_set; -++ bool autoeee_enabled; -++ -++ /* 802.3x flow control */ -++ bool tx_pause_en; -++ u32 tx_pause_active_thresh; -++ u32 tx_pause_deactive_thresh; -++#ifdef HLETH_SKB_MEMORY_STATS -++ atomic_t tx_skb_occupied; -++ atomic_t tx_skb_mem_occupied; -++ atomic_t rx_skb_occupied; -++ atomic_t rx_skb_mem_occupied; -++#endif -++}; -++ -++/* phy parameter */ -++struct hleth_phy_param_s { -++ bool isvalid; /* valid or not */ -++ bool isinternal; /* internal phy or external phy */ -++ int phy_addr; -++ u32 trim_params; -++ phy_interface_t phy_mode; -++ const char *macaddr; -++ -++ struct clk *phy_clk; -++ struct reset_control *phy_rst; -++ /* gpio reset pin if has */ -++ void __iomem *gpio_base; -++ void __iomem *fephy_sysctrl; -++ void __iomem *fephy_trim; -++ int fephy_phyaddr_bit; -++ u32 gpio_bit; -++}; -++ -++#define MAX_MULTICAST_FILTER 8 -++#define MAX_MAC_LIMIT ETH_ALEN * MAX_MULTICAST_FILTER -++ -++struct ethstats { -++ void __iomem *base; -++ void __iomem *macbase[2]; -++ -++ char prbuf[SZ_4K]; -++ u32 sz_prbuf; -++ -++ struct dentry *dentry; -++}; -++ -++struct mcdump { -++ void __iomem *base; -++ u32 net_flags; -++ u32 mc_rcv; -++ u32 mc_drop; -++ u32 mac_nr; -++ spinlock_t lock; -++ char mac[MAX_MAC_LIMIT]; -++ char prbuf[SZ_1K]; -++ u32 sz_prbuf; -++ -++ struct dentry *dentry; -++}; -++ -++#ifdef HLETH_SKB_MEMORY_STATS -++struct eth_mem_stats { -++ char prbuf[SZ_1K]; -++ u32 sz_prbuf; -++ -++ struct dentry *dentry; -++}; -++#endif -++ -++struct hleth_platdrv_data { -++ struct hleth_phy_param_s hleth_phy_param[HLETH_MAX_PORT]; -++ struct net_device *hleth_devs_save[HLETH_MAX_PORT]; -++ struct hleth_netdev_priv hleth_priv; -++ int hleth_real_port_cnt; -++ -++ /* debugfs info */ -++ struct dentry *root; -++ struct ethstats ethstats; -++ struct mcdump mcdump; -++#ifdef HLETH_SKB_MEMORY_STATS -++ struct eth_mem_stats eth_mem_stats; -++#endif -++}; -++ -++#undef local_lock_init -++#undef local_lock -++#undef local_unlock -++ -++#define local_lock_init(priv) spin_lock_init(&(priv)->lock) -++#define local_lock_exit(priv) -++#define local_lock(priv) spin_lock_irqsave(&(priv)->lock, \ -++ (priv)->lockflags) -++#define local_unlock(priv) spin_unlock_irqrestore(&(priv)->lock, \ -++ (priv)->lockflags) -++ -++#define hleth_mdio_lock_init(priv) spin_lock_init(&(priv)->mdio_lock) -++#define hleth_mdio_lock_exit(priv) -++#define hleth_mdio_lock(priv) spin_lock_irqsave(&(priv)->mdio_lock, \ -++ (priv)->mdio_lockflags) -++#define hleth_mdio_unlock(priv) spin_unlock_irqrestore(&(priv)->mdio_lock, \ -++ (priv)->mdio_lockflags) -++ -++#define ud_bit_name(name) ((priv->port == HLETH_PORT_0) ? \ -++ name##_U : name##_D) -++ -++#define glb_mac_h16(port, reg) ((((port) == HLETH_PORT_0) ? \ -++ HLETH_GLB_MAC_H16_BASE : \ -++ HLETH_GLB_MAC_H16_BASE_D) + ((reg) * 0x8)) -++#define glb_mac_l32(port, reg) ((((port) == HLETH_PORT_0) ? \ -++ HLETH_GLB_MAC_L32_BASE : \ -++ HLETH_GLB_MAC_L32_BASE_D) + ((reg) * 0x8)) -++ -++#define SIOCGETMODE (SIOCDEVPRIVATE) /* get work mode */ -++#define SIOCSETMODE (SIOCDEVPRIVATE + 1) /* set work mode */ -++#define SIOCGETFWD (SIOCDEVPRIVATE + 2) /* get forcing forward config */ -++#define SIOCSETFWD (SIOCDEVPRIVATE + 3) /* set forcing forward config */ -++#define SIOCSETPM (SIOCDEVPRIVATE + 4) /* set pmt wake up config */ -++#define SIOCSETSUSPEND (SIOCDEVPRIVATE + 5) /* call dev->suspend */ -++#define SIOCSETRESUME (SIOCDEVPRIVATE + 6) /* call dev->resume */ -++#define SIOCGETPM (SIOCDEVPRIVATE + 7) /* call dev->resume */ -++ -++void hleth_autoeee_init(struct hleth_netdev_priv *priv, int link_stat); -++void hleth_phy_register_fixups(void); -++void hleth_phy_unregister_fixups(void); -++void hleth_phy_reset(struct hleth_platdrv_data *pdata); -++void hleth_phy_clk_disable(struct hleth_platdrv_data *pdata); -++void hleth_fix_festa_phy_trim(struct mii_bus *bus, struct hleth_platdrv_data *pdata); -++#endif -++ -++/* vim: set ts=8 sw=8 tw=78: */ -+diff --git a/drivers/net/ethernet/vendor/eth/hleth_dbg.c b/drivers/net/ethernet/vendor/eth/hleth_dbg.c -+new file mode 100755 -+index 000000000..086af4103 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/hleth_dbg.c -+@@ -0,0 +1,445 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2020-2021. All rights reserved. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#ifndef CONFIG_ARM64 -++#include -++#endif -++ -++#define MAC_FMT " MAC%d: %02x:%02x:%02x:%02x:%02x:%02x\n" -++ -++struct cmd_val_t { -++ const char *key; -++ int sz_key; -++ char *buf; -++ int sz_buf; -++}; -++ -++static int dump_eth_stats(int index, void __iomem *macbase, char *buf, int sz_buf) -++{ -++ int ix; -++ int count; -++ char *ptr = buf; -++ -++ struct regdef { -++ char *fmt; -++ u32 offset; -++ } regdef[] = { -++ {" Rx:%u Bytes\n", 0x608}, -++ {" total packets:%u ", 0x610}, -++ {"broadcast:%u ", 0x614}, -++ {"multicast:%u ", 0x618}, -++ {"unicast:%u ", 0x61C}, -++ {"to me:%u\n", 0x60C}, -++ {" error packets:%u ", 0x620}, -++ {"crc/alignment:%u ", 0x624}, -++ {"invalid size:%u ", 0x628}, -++ {"nibble error:%u\n", 0x62C}, -++ {" pause frame:%u, ", 0x630}, -++ {"overflow: %u ", 0x634}, -++ {"mac filterd: %u\n", 0x64c}, -++ {" Tx:%u Bytes\n", 0x790}, -++ {" total packets:%u ", 0x780}, -++ {"broadcast:%u ", 0x784}, -++ {"multicast:%u ", 0x788}, -++ {"unicast:%u\n", 0x78C}, -++ }; -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "eth%d:\n", index); -++ if (count < 0) { -++ pr_err("snprintf eth%d error, count=%d\n", index, count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ for (ix = 0; ix < ARRAY_SIZE(regdef); ix++) { -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, regdef[ix].fmt, readl(macbase + regdef[ix].offset)); -++ if (count < 0) { -++ pr_err("snprintf macbase error, ix=%d,count=%d\n", ix, count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ } -++ -++ return ptr - buf; -++} -++ -++#ifdef HLETH_SKB_MEMORY_STATS -++static int dump_eth_mem_stats(struct hleth_platdrv_data *pdata, char *buf, int sz_buf) -++{ -++ int ix, count; -++ char *ptr = buf; -++ struct net_device *ndev = NULL; -++ struct hleth_netdev_priv *priv = NULL; -++ -++ for (ix = 0; ix < pdata->hleth_real_port_cnt; ix++) { -++ ndev = pdata->hleth_devs_save[ix]; -++ priv = netdev_priv(ndev); -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "%s:\n", ndev->name); -++ if (count < 0) { -++ pr_err("snprintf ndev name error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "tx skb occupied: %d\n", -++ atomic_read(&priv->tx_skb_occupied)); -++ if (count < 0) { -++ pr_err("snprintf tx skb occupied error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "tx skb memory occupied: %d Bytes\n", -++ atomic_read(&priv->tx_skb_mem_occupied)); -++ if (count < 0) { -++ pr_err("snprintf tx skb memory occupied error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "rx skb occupied: %d\n", -++ atomic_read(&priv->rx_skb_occupied)); -++ if (count < 0) { -++ pr_err("snprintf rx skb occupied error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "rx skb memory occupied: %d Bytes\n", -++ atomic_read(&priv->rx_skb_mem_occupied)); -++ if (count < 0) { -++ pr_err("snprintf rx skb memory occupied error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ } -++ -++ return ptr - buf; -++} -++#endif -++ -++static ssize_t fo_dump_ethstats_read(struct file *filp, char __user *ubuf, -++ size_t sz_ubuf, loff_t *ppos) -++{ -++ struct ethstats *stats = filp->private_data; -++ -++ return simple_read_from_buffer(ubuf, sz_ubuf, ppos, stats->prbuf, -++ stats->sz_prbuf); -++} -++ -++static int fo_dump_ethstats_open(struct inode *inode, struct file *file) -++{ -++ struct ethstats *data; -++ int count = 0, sz_buf; -++ char *ptr; -++ struct hleth_platdrv_data *pdata = inode->i_private; -++ -++ data = &pdata->ethstats; -++ -++ file->private_data = (void *)data; -++ -++ ptr = data->prbuf; -++ sz_buf = sizeof(data->prbuf); -++ -++ count = dump_eth_stats(0, data->macbase[0], ptr, sz_buf); -++ -++ data->sz_prbuf = count; -++ -++ return nonseekable_open(inode, file); -++} -++ -++#ifdef HLETH_SKB_MEMORY_STATS -++static ssize_t fo_dump_eth_mem_stats_read(struct file *filp, char __user *ubuf, -++ size_t sz_ubuf, loff_t *ppos) -++{ -++ struct eth_mem_stats *mem_stats = filp->private_data; -++ -++ return simple_read_from_buffer(ubuf, sz_ubuf, ppos, mem_stats->prbuf, -++ mem_stats->sz_prbuf); -++} -++ -++static int fo_dump_eth_mem_stats_open(struct inode *inode, struct file *file) -++{ -++ struct eth_mem_stats *data; -++ int count = 0, sz_buf; -++ char *ptr; -++ struct hleth_platdrv_data *pdata = inode->i_private; -++ -++ data = &pdata->eth_mem_stats; -++ -++ file->private_data = (void *)data; -++ -++ ptr = data->prbuf; -++ sz_buf = sizeof(data->prbuf); -++ -++ count = dump_eth_mem_stats(pdata, ptr, sz_buf); -++ -++ data->sz_prbuf = count; -++ -++ return nonseekable_open(inode, file); -++} -++#endif -++ -++int multicast_dump_netdev_flags(u32 flags, struct hleth_platdrv_data *pdata) -++{ -++ u32 old = pdata->mcdump.net_flags; -++ spin_lock(&pdata->mcdump.lock); -++ pdata->mcdump.net_flags = flags; -++ spin_unlock(&pdata->mcdump.lock); -++ return old; -++} -++ -++void multicast_dump_macaddr(u32 nr, char *macaddr, struct hleth_platdrv_data *pdata) -++{ -++ char *ptr = NULL; -++ int ret; -++ if (nr > MAX_MULTICAST_FILTER) -++ return; -++ -++ ptr = pdata->mcdump.mac + nr * ETH_ALEN; -++ spin_lock(&pdata->mcdump.lock); -++ ret = memcpy_s(ptr, ETH_ALEN, macaddr, ETH_ALEN); -++ if (ret != EOK) { -++ pr_err("memcpy macaddr error, ret=%d\n", ret); -++ spin_unlock(&pdata->mcdump.lock); -++ return; -++ } -++ pdata->mcdump.mac_nr = nr + 1; -++ spin_unlock(&pdata->mcdump.lock); -++} -++static int dump_mc_format_by_net_flags(struct mcdump *dump, char *ptr, int sz_buf) -++{ -++ int count; -++ if (dump->net_flags & IFF_MULTICAST) { -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "%s", "MULTICAST "); -++ if (count < 0) { -++ pr_err("snprintf MULTICAST error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ } -++ -++ if (dump->net_flags & IFF_PROMISC) { -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "%s", "PROMISC "); -++ if (count < 0) { -++ pr_err("snprintf PROMISC error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ } -++ -++ if (dump->net_flags & IFF_ALLMULTI) { -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "%s", "ALLMULTI "); -++ if (count < 0) { -++ pr_err("snprintf ALLMULTI error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ } -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "\n mac filters:%d \n", dump->mac_nr); -++ if (count < 0) { -++ pr_err("snprintf mac filters error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ return 0; -++} -++static int dump_mc_drop(int index, struct mcdump *dump, char *buf, int sz_buf) -++{ -++ int ix, count; -++ char *ptr = buf; -++ char *pmac = NULL; -++ -++ struct regdef_s regdef[] = { -++ {" Rx packets:%u ", 0x618}, -++ {"dropped:%u\n", 0x64C}, -++ }; -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "eth%d multicast:\n", index); -++ if (count < 0) { -++ pr_err("snprintf buf error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ for (ix = 0; ix < ARRAY_SIZE(regdef); ix++) { -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, regdef[ix].fmt, readl(dump->base + regdef[ix].offset)); -++ if (count < 0) { -++ pr_err("snprintf buf error, ix=%d, count=%d\n", ix, count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ } -++ -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, "%s", " state:"); -++ if (count < 0) { -++ pr_err("snprintf state error, count=%d\n", count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ -++ count = dump_mc_format_by_net_flags(dump, ptr, sz_buf); -++ if (count) -++ return count; -++ -++ for (ix = 0; ix < dump->mac_nr; ix++) { -++ pmac = dump->mac + ix * ETH_ALEN; -++ count = snprintf_s(ptr, sz_buf, sz_buf - 1, MAC_FMT, ix, -++ pmac[0], pmac[1], pmac[2], /* 2:mac addr index */ -++ pmac[3], pmac[4], pmac[5]); /* 3,4,5:mac addr index */ -++ if (count < 0) { -++ pr_err("snprintf mac error, ix=%d, count=%d\n", ix, count); -++ return count; -++ } -++ sz_buf -= count; -++ ptr += count; -++ } -++ -++ return ptr - buf; -++} -++ -++static int fo_dump_ethmc_open(struct inode *inode, struct file *file) -++{ -++ struct mcdump *data; -++ int count = 0, sz_buf; -++ char *ptr; -++ struct hleth_platdrv_data *pdata = inode->i_private; -++ -++ data = &pdata->mcdump; -++ -++ file->private_data = (void *)data; -++ -++ ptr = data->prbuf; -++ sz_buf = sizeof(data->prbuf); -++ -++ count = dump_mc_drop(0, data, ptr, sz_buf); -++ -++ data->sz_prbuf = count; -++ -++ return nonseekable_open(inode, file); -++} -++ -++static ssize_t fo_dump_ethmc_read(struct file *filp, char __user *ubuf, -++ size_t sz_ubuf, loff_t *ppos) -++{ -++ struct mcdump *dump = (struct mcdump *)filp->private_data; -++ -++ return simple_read_from_buffer(ubuf, sz_ubuf, ppos, dump->prbuf, -++ dump->sz_prbuf); -++} -++ -++static const struct file_operations ethmc_fops = { -++ .owner = THIS_MODULE, -++ .open = fo_dump_ethmc_open, -++ .read = fo_dump_ethmc_read, -++ .llseek = no_llseek, -++}; -++ -++static const struct file_operations ethstats_fops = { -++ .owner = THIS_MODULE, -++ .open = fo_dump_ethstats_open, -++ .read = fo_dump_ethstats_read, -++ .llseek = no_llseek, -++}; -++ -++#ifdef HLETH_SKB_MEMORY_STATS -++static const struct file_operations eth_mem_stats_fops = { -++ .owner = THIS_MODULE, -++ .open = fo_dump_eth_mem_stats_open, -++ .read = fo_dump_eth_mem_stats_read, -++ .llseek = no_llseek, -++}; -++#endif -++ -++int hleth_dbg_init(void __iomem *base, struct platform_device *pdev) -++{ -++ char buf[30]; -++ int count; -++ unsigned int mode = S_IFREG | S_IRUSR | S_IWUSR; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ count = snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%s", pdev->name); -++ if (count < 0) { -++ pr_err("snprintf buf error, count=%d\n", count); -++ return -ENOENT; -++ } -++ pdata->root = debugfs_create_dir(buf, NULL); -++ if (!pdata->root) { -++ pr_err("Can't create '%s' dir.\n", buf); -++ return -ENOENT; -++ } -++ -++ pdata->mcdump.base = base; -++ pdata->mcdump.dentry = debugfs_create_file("multicast", mode, pdata->root, -++ pdata, ðmc_fops); -++ if (!pdata->mcdump.dentry) { -++ pr_err("Can't create 'read' file.\n"); -++ goto fail; -++ } -++ spin_lock_init(&pdata->mcdump.lock); -++ -++ pdata->ethstats.base = base; -++ pdata->ethstats.macbase[0] = base; -++ pdata->ethstats.macbase[1] = base + 0x2000; -++ pdata->ethstats.dentry = debugfs_create_file("stats", mode, pdata->root, -++ pdata, ðstats_fops); -++ if (!pdata->ethstats.dentry) { -++ pr_err("Can't create 'write' file.\n"); -++ goto fail; -++ } -++ -++#ifdef HLETH_SKB_MEMORY_STATS -++ pdata->eth_mem_stats.dentry = debugfs_create_file("mem_stats", mode, -++ pdata->root, pdata, -++ ð_mem_stats_fops); -++ if (!pdata->eth_mem_stats.dentry) { -++ pr_err("Can't create 'write' file.\n"); -++ goto fail; -++ } -++#endif -++ -++ return 0; -++fail: -++ debugfs_remove_recursive(pdata->root); -++ -++ return -ENOENT; -++} -++ -++int hleth_dbg_deinit(struct platform_device *pdev) -++{ -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ debugfs_remove_recursive(pdata->root); -++ return 0; -++} -+diff --git a/drivers/net/ethernet/vendor/eth/hleth_dbg.h b/drivers/net/ethernet/vendor/eth/hleth_dbg.h -+new file mode 100755 -+index 000000000..c06b7880d -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/hleth_dbg.h -+@@ -0,0 +1,18 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2020-2021. All rights reserved. -++ */ -++#ifndef HLETH_DBG_H -++#define HLETH_DBG_H -++ -++#include "hleth.h" -++ -++struct regdef_s { -++ char *fmt; -++ u32 offset; -++}; -++int hleth_dbg_init(void __iomem *base, struct platform_device *pdev); -++int hleth_dbg_deinit(struct platform_device *pdev); -++int multicast_dump_netdev_flags(u32 flags, struct hleth_platdrv_data *pdata); -++void multicast_dump_macaddr(u32 nr, char *macaddr, struct hleth_platdrv_data *pdata); -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/eth/huanglong_phy.h b/drivers/net/ethernet/vendor/eth/huanglong_phy.h -+new file mode 100755 -+index 000000000..26b2c40f2 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/huanglong_phy.h -+@@ -0,0 +1,25 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Configs for our phy -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++#ifndef _HUANGLONG_PHY_H -++#define _HUANGLONG_PHY_H -++ -++/* Mask used for ID comparisons */ -++#define HUANGLONG_PHY_ID_MASK 0xffffffff -++ -++/* Known PHY IDs */ -++#define HUANGLONG_PHY_ID_FESTAV200 0x20669813 -++#define HUANGLONG_PHY_ID_FESTAV210 0x20669823 -++#define HUANGLONG_PHY_ID_FESTAV212 0x20669833 -++#define HUANGLONG_PHY_ID_FESTAV220 0x20669823 -++#define HUANGLONG_PHY_ID_FESTAV330 0x20669853 -++#define HUANGLONG_PHY_ID_FESTAV331 0x20669863 -++#define HUANGLONG_PHY_ID_FESTAV333 0x20669902 -++#define HUANGLONG_PHY_ID_FESTA_S28V112 0x20669900 -++#define HUANGLONG_PHY_ID_FESTA_S28V200 0x20669905 -++ -++#endif /* _HUANGLONG_PHY_H */ -+diff --git a/drivers/net/ethernet/vendor/eth/mdio.c b/drivers/net/ethernet/vendor/eth/mdio.c -+new file mode 100755 -+index 000000000..f2f1ec0d4 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/mdio.c -+@@ -0,0 +1,243 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Mdio settings. -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "hleth.h" -++#include "mdio.h" -++ -++/* MDIO Bus Interface */ -++ -++static void hleth_mdio_init(struct hleth_netdev_priv *priv) -++{ -++ hleth_mdio_lock_init(priv); -++ mdio_reg_reset(priv); -++} -++ -++static void hleth_mdio_exit(struct hleth_netdev_priv *priv) -++{ -++ hleth_mdio_lock_exit(priv); -++} -++ -++static int hleth_wait_mdio_ready(const struct hleth_netdev_priv *priv) -++{ -++ int timeout_us = 1000; -++ -++ while (--timeout_us && !mdio_test_ready(priv)) -++ udelay(1); -++ -++ return timeout_us; -++} -++ -++int hleth_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) -++{ -++ int ret = 0; -++ struct hleth_netdev_priv *priv = NULL; -++ -++ if (bus == NULL) -++ return -ETIMEDOUT; -++ -++ priv = bus->priv; -++ if (priv == NULL) -++ return -ETIMEDOUT; -++ -++ hleth_mdio_lock(priv); -++ -++ if (hleth_wait_mdio_ready(priv) == 0) { -++ pr_err("%s,%d:mdio busy\n", __func__, __LINE__); -++ ret = -ETIMEDOUT; -++ goto error_exit; -++ } -++ -++ mdio_start_phyread(priv, phy_addr, regnum); -++ -++ if (hleth_wait_mdio_ready(priv)) { -++ ret = mdio_get_phyread_val(priv); -++ } else { -++ pr_err("%s,%d:mdio busy\n", __func__, __LINE__); -++ ret = -ETIMEDOUT; -++ } -++ -++error_exit: -++ -++ hleth_mdio_unlock(priv); -++ -++ pr_debug("phy_addr = %d, regnum = %d, ret = 0x%04x\n", phy_addr, -++ regnum, ret); -++ -++ return ret; -++} -++ -++int hleth_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, -++ u16 val) -++{ -++ int ret = 0; -++ struct hleth_netdev_priv *priv = NULL; -++ -++ if (bus == NULL) -++ return -ETIMEDOUT; -++ -++ priv = bus->priv; -++ if (priv == NULL) -++ return -ETIMEDOUT; -++ -++ pr_debug("phy_addr = %d, regnum = %d\n", phy_addr, regnum); -++ -++ hleth_mdio_lock(priv); -++ -++ if (hleth_wait_mdio_ready(priv) == 0) { -++ pr_err("%s,%d:mdio busy\n", __func__, __LINE__); -++ ret = -ETIMEDOUT; -++ goto error_exit; -++ } -++ -++ mdio_phywrite(priv, phy_addr, regnum, val); -++ -++ udelay(500); /* 500:delay */ -++ if (hleth_wait_mdio_ready(priv) == 0) { -++ pr_err("%s,%d:mdio busy\n", __func__, __LINE__); -++ ret = -ETIMEDOUT; -++ } -++ -++error_exit: -++ hleth_mdio_unlock(priv); -++ -++ return ret; -++} -++ -++int hleth_mdiobus_write_nodelay(struct mii_bus *bus, int phy_addr, int regnum, -++ u16 val) -++{ -++ struct hleth_netdev_priv *priv = NULL; -++ int ret = 0; -++ -++ if (bus == NULL) -++ return -ETIMEDOUT; -++ -++ priv = bus->priv; -++ if (priv == NULL) -++ return -ETIMEDOUT; -++ -++ hleth_mdio_lock(priv); -++ -++ if (hleth_wait_mdio_ready(priv) == 0) { -++ ret = -ETIMEDOUT; -++ pr_err("%s,%d:mdio busy\n", __func__, __LINE__); -++ goto error_exit; -++ } -++ -++ mdio_phywrite(priv, phy_addr, regnum, val); -++ -++ if (hleth_wait_mdio_ready(priv) == 0) { -++ ret = -ETIMEDOUT; -++ pr_err("%s,%d:mdio busy\n", __func__, __LINE__); -++ } -++ -++error_exit: -++ hleth_mdio_unlock(priv); -++ -++ return ret; -++} -++ -++static int hleth_mdiobus_reset(struct mii_bus *bus) -++{ -++ struct hleth_netdev_priv *priv = bus->priv; -++ -++ mdio_reg_reset(priv); -++ return 0; -++} -++ -++int hleth_mdiobus_driver_init(struct platform_device *pdev, -++ struct hleth_netdev_priv *priv) -++{ -++ int ret = 0; -++ struct mii_bus *bus = NULL; -++ struct device *dev = NULL; -++ struct device_node *node = NULL; -++ struct hleth_platdrv_data *pdata = NULL; -++ -++ if (pdev == NULL || priv == NULL) -++ return -ENOMEM; -++ -++ dev = &pdev->dev; -++ node = dev->of_node; -++ pdata = platform_get_drvdata(pdev); -++ hleth_mdio_init(priv); -++ -++ /* register MII bus */ -++ bus = mdiobus_alloc(); -++ if (bus == NULL) { -++ pr_err("get ioresource failed!\n"); -++ ret = -ENOMEM; -++ goto _error_exit; -++ } -++ -++ bus->name = HLETH_MIIBUS_NAME; -++ -++ ret = snprintf_s(bus->id, MII_BUS_ID_SIZE, MII_BUS_ID_SIZE - 1, "%s", pdev->name); -++ if (ret < 0) { -++ pr_err("failed to snprintf bus id, ret = %d\n", ret); -++ goto _error_free_mdiobus; -++ } -++ bus->read = hleth_mdiobus_read; -++ bus->write = hleth_mdiobus_write; -++ bus->reset = hleth_mdiobus_reset; -++ bus->priv = priv; -++ priv->mii_bus = bus; -++ bus->parent = &pdev->dev; /* for Power Management */ -++ -++ hleth_fix_festa_phy_trim(bus, pdata); -++ -++ ret = of_mdiobus_register(bus, node); -++ if (ret) { -++ pr_err("failed to register MDIO bus\n"); -++ goto _error_free_mdiobus; -++ } -++ -++ return 0; -++ -++_error_free_mdiobus: -++ mdiobus_free(bus); -++ -++_error_exit: -++ return ret; -++} -++ -++void hleth_mdiobus_driver_exit(struct hleth_netdev_priv *priv) -++{ -++ struct mii_bus *bus = priv->mii_bus; -++ -++ mdiobus_unregister(bus); -++ mdiobus_free(bus); -++ hleth_mdio_exit(priv); -++} -++ -++/* vim: set ts=8 sw=8 tw=78: */ -+diff --git a/drivers/net/ethernet/vendor/eth/mdio.h b/drivers/net/ethernet/vendor/eth/mdio.h -+new file mode 100755 -+index 000000000..6a4db0cc4 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/mdio.h -+@@ -0,0 +1,74 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Header file for mdio.c -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++#ifndef __SOCT_ETH_MDIO_H__ -++#define __SOCT_ETH_MDIO_H__ -++ -++#include "hleth.h" -++ -++#define HLETH_MDIO_FRQDIV 0 -++ -++#define HLETH_MDIO_RWCTRL 0x1100 -++#define HLETH_MDIO_RO_DATA 0x1104 -++#define HLETH_U_MDIO_PHYADDR 0x0108 -++#define HLETH_D_MDIO_PHYADDR 0x2108 -++#define HLETH_U_MDIO_RO_STAT 0x010C -++#define HLETH_D_MDIO_RO_STAT 0x210C -++#define HLETH_U_MDIO_ANEG_CTRL 0x0110 -++#define HLETH_D_MDIO_ANEG_CTRL 0x2110 -++#define HLETH_U_MDIO_IRQENA 0x0114 -++#define HLETH_D_MDIO_IRQENA 0x2114 -++ -++#define mdio_mk_rwctl(cpu_data_in, finish, rw, phy_exaddr, frq_div, phy_regnum) \ -++ (((cpu_data_in) << 16) | \ -++ (((finish) & 0x01) << 15) | \ -++ (((rw) & 0x01) << 13) | \ -++ (((phy_exaddr) & 0x1F) << 8) | \ -++ (((frq_div) & 0x7) << 5) | \ -++ ((phy_regnum) & 0x1F)) -++ -++/* hardware set bit'15 of MDIO_REG(0) if mdio ready */ -++#define mdio_test_ready(priv) (hleth_readl((priv)->glb_base, \ -++ HLETH_MDIO_RWCTRL) & (1 << 15)) -++ -++#define mdio_start_phyread(priv, phy_addr, regnum) \ -++ hleth_writel((priv)->glb_base, \ -++ mdio_mk_rwctl(0, 0, 0, phy_addr, HLETH_MDIO_FRQDIV, \ -++ regnum), \ -++ HLETH_MDIO_RWCTRL) -++ -++#define mdio_get_phyread_val(priv) (hleth_readl((priv)->glb_base, \ -++ HLETH_MDIO_RO_DATA) & 0xFFFF) -++ -++#define mdio_phywrite(priv, phy_addr, regnum, val) \ -++ hleth_writel((priv)->glb_base, \ -++ mdio_mk_rwctl(val, 0, 1, phy_addr, HLETH_MDIO_FRQDIV, \ -++ regnum), \ -++ HLETH_MDIO_RWCTRL) -++ -++/* write mdio registers reset value */ -++#define mdio_reg_reset(priv) do { \ -++ hleth_writel((priv)->glb_base, 0x00008000, HLETH_MDIO_RWCTRL); \ -++ hleth_writel((priv)->glb_base, 0x00000001, HLETH_U_MDIO_PHYADDR); \ -++ hleth_writel((priv)->glb_base, 0x00000001, HLETH_D_MDIO_PHYADDR); \ -++ hleth_writel((priv)->glb_base, 0x04631EA9, HLETH_U_MDIO_ANEG_CTRL); \ -++ hleth_writel((priv)->glb_base, 0x04631EA9, HLETH_D_MDIO_ANEG_CTRL); \ -++ hleth_writel((priv)->glb_base, 0x00000000, HLETH_U_MDIO_IRQENA); \ -++ hleth_writel((priv)->glb_base, 0x00000000, HLETH_D_MDIO_IRQENA); \ -++} while (0) -++ -++int hleth_mdiobus_driver_init(struct platform_device *pdev, -++ struct hleth_netdev_priv *priv); -++void hleth_mdiobus_driver_exit(struct hleth_netdev_priv *priv); -++ -++int hleth_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum); -++int hleth_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, -++ u16 val); -++int hleth_mdiobus_write_nodelay(struct mii_bus *bus, int phy_addr, int regnum, -++ u16 val); -++#endif -++ -++/* vim: set ts=8 sw=8 tw=78: */ -+diff --git a/drivers/net/ethernet/vendor/eth/phy.c b/drivers/net/ethernet/vendor/eth/phy.c -+new file mode 100755 -+index 000000000..69f051627 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/phy.c -+@@ -0,0 +1,368 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Phy settings. -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++#include -++#include -++#include "huanglong_phy.h" -++#include "hleth.h" -++#include "mdio.h" -++#include "phy.h" -++ -++static const u32 phy_s28v200_fix_param[] = { -++#include "festa.h" -++}; -++ -++#define CONFIG_FEPHY_TRIM -++#ifdef CONFIG_FEPHY_TRIM -++#define REG_LD_AM 0x3050 -++#define LD_AM_MASK GENMASK(4, 0) -++#define REG_LDO_AM 0x3051 -++#define LDO_AM_MASK GENMASK(2, 0) -++#define REG_R_TUNING 0x3052 -++#define R_TUNING_MASK GENMASK(5, 0) -++#define REG_WR_DONE 0x3053 -++#define REG_DEF_ATE 0x3057 -++#define DEF_LD_AM 0x0f -++#define DEF_LDO_AM 0x7 -++#define DEF_R_TUNING 0x15 -++ -++static inline int hleth_phy_expanded_read(struct mii_bus *bus, int phyaddr, -++ u32 reg_addr) -++{ -++ int ret; -++ -++ hleth_mdiobus_write(bus, phyaddr, MII_EXPMA, reg_addr); -++ ret = hleth_mdiobus_read(bus, phyaddr, MII_EXPMD); -++ -++ return ret; -++} -++ -++static inline int hleth_phy_expanded_write(struct mii_bus *bus, int phyaddr, -++ u32 reg_addr, u16 val) -++{ -++ int ret; -++ -++ hleth_mdiobus_write(bus, phyaddr, MII_EXPMA, reg_addr); -++ ret = hleth_mdiobus_write(bus, phyaddr, MII_EXPMD, val); -++ -++ return ret; -++} -++ -++static void hleth_use_default_trim(struct mii_bus *bus, int phyaddr) -++{ -++ unsigned short v; -++ int timeout = 3; -++ -++ pr_info("FEPHY: No OTP data, use default ATE parameters to auto-trim!\n"); -++ -++ do { -++ msleep(250); /* 250:delay */ -++ v = (unsigned short)hleth_phy_expanded_read(bus, phyaddr, REG_DEF_ATE); -++ v &= BIT(0); -++ } while ((v == 0) && (--timeout != 0)); -++ -++ if (timeout == 0) -++ pr_warn("FEPHY: fail to wait auto-trim finish!\n"); -++} -++ -++static void hleth_config_festa_phy_trim(struct mii_bus *bus, int phyaddr, -++ u32 trim_params) -++{ -++ unsigned short ld_amptlitude; -++ unsigned short ldo_amptlitude; -++ unsigned short r_tuning_val; -++ unsigned short v; -++ int timeout = 3000; /* 3000:timeout */ -++ -++ if (!trim_params) { -++ hleth_use_default_trim(bus, phyaddr); -++ return; -++ } -++ -++ ld_amptlitude = trim_params & LD_AM_MASK; -++ ldo_amptlitude = (trim_params >> 8) & LDO_AM_MASK; /* 8:right shift val */ -++ r_tuning_val = (trim_params >> 16) & R_TUNING_MASK; /* 16:right shift val */ -++ -++ v = hleth_phy_expanded_read(bus, phyaddr, REG_LD_AM); -++ v = (v & ~LD_AM_MASK) | (ld_amptlitude & LD_AM_MASK); -++ hleth_phy_expanded_write(bus, phyaddr, REG_LD_AM, v); -++ -++ v = hleth_phy_expanded_read(bus, phyaddr, REG_LDO_AM); -++ v = (v & ~LDO_AM_MASK) | (ldo_amptlitude & LDO_AM_MASK); -++ hleth_phy_expanded_write(bus, phyaddr, REG_LDO_AM, v); -++ -++ v = hleth_phy_expanded_read(bus, phyaddr, REG_R_TUNING); -++ v = (v & ~R_TUNING_MASK) | (r_tuning_val & R_TUNING_MASK); -++ hleth_phy_expanded_write(bus, phyaddr, REG_R_TUNING, v); -++ -++ v = hleth_phy_expanded_read(bus, phyaddr, REG_WR_DONE); -++ if (v & BIT(1)) -++ pr_warn("FEPHY: invalid trim status.\n"); -++ v = v | BIT(0); -++ hleth_phy_expanded_write(bus, phyaddr, REG_WR_DONE, v); -++ -++ do { -++ usleep_range(100, 150); /* 100,150:delay zone */ -++ v = hleth_phy_expanded_read(bus, phyaddr, REG_WR_DONE); -++ v &= BIT(1); -++ } while ((v == 0) && (--timeout != 0)); -++ if (timeout == 0) -++ pr_warn("FEPHY: faile to wait trim finish!\n"); -++ -++ pr_info("FEPHY:addr=%d, la_am=0x%x, ldo_am=0x%x, r_tuning=0x%x\n", -++ phyaddr, -++ hleth_phy_expanded_read(bus, phyaddr, REG_LD_AM), -++ hleth_phy_expanded_read(bus, phyaddr, REG_LDO_AM), -++ hleth_phy_expanded_read(bus, phyaddr, REG_R_TUNING)); -++} -++#endif -++ -++#ifdef CONFIG_FEPHY_TRIM -++void hleth_fix_festa_phy_trim(struct mii_bus *bus, struct hleth_platdrv_data *pdata) -++{ -++ struct hleth_phy_param_s *phy_param = NULL; -++ int i; -++ int phyaddr; -++ -++ if (bus == NULL || pdata == NULL) -++ return; -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) { -++ phy_param = &pdata->hleth_phy_param[i]; -++ -++ if (phy_param == NULL) -++ continue; -++ -++ if (!phy_param->isvalid || !phy_param->isinternal) -++ continue; -++ -++ phyaddr = phy_param->phy_addr; -++ hleth_config_festa_phy_trim(bus, phyaddr, -++ phy_param->trim_params); -++ mdelay(5); /* 5:delay */ -++ } -++} -++#else -++void hleth_fix_festa_phy_trim(struct mii_bus *bus, struct hleth_platdrv_data *pdata) -++{ -++ msleep(300); /* 300:delay */ -++} -++#endif -++ -++static int phy_expanded_write_bulk(struct phy_device *phy_dev, -++ const u32 reg_and_val[], -++ int count) -++{ -++ int i, v, ret = 0; -++ u32 reg_addr; -++ u16 val; -++ -++ v = phy_read(phy_dev, MII_BMCR); -++ v = (unsigned int)v | BMCR_PDOWN; -++ phy_write(phy_dev, MII_BMCR, v); -++ -++ for (i = 0; i < (2 * count); i += 2) { /* 2:operated value */ -++ if ((i % 50) == 0) /* 50:operated value */ -++ schedule(); -++ -++ reg_addr = reg_and_val[i]; -++ val = (u16)reg_and_val[i + 1]; -++ hleth_mdiobus_write_nodelay(phy_dev->mdio.bus, -++ phy_dev->mdio.addr, -++ MII_EXPMA, reg_addr); -++ ret = hleth_mdiobus_write_nodelay(phy_dev->mdio.bus, -++ phy_dev->mdio.addr, -++ MII_EXPMD, val); -++ } -++ -++ v = phy_read(phy_dev, MII_BMCR); -++ v =(unsigned int)v & (~BMCR_PDOWN); -++ phy_write(phy_dev, MII_BMCR, v); -++ -++ return ret; -++} -++ -++static int hl_fephy_s28v200_fix(struct phy_device *phy_dev) -++{ -++ int count; -++ -++ count = ARRAY_SIZE(phy_s28v200_fix_param); -++ if (count % 2) /* 2:operated value */ -++ pr_warn("internal FEPHY fix register count is not right.\n"); -++ count /= 2; /* 2:operated value */ -++ -++ phy_expanded_write_bulk(phy_dev, phy_s28v200_fix_param, count); -++ -++ return 0; -++} -++ -++static int ksz8051mnl_phy_fix(struct phy_device *phy_dev) -++{ -++ u32 v; -++ -++ v = phy_read(phy_dev, 0x1F); -++ v |= (1 << 7); /* 7:set phy RMII 50MHz clk; */ -++ phy_write(phy_dev, 0x1F, v); -++ -++ v = phy_read(phy_dev, 0x16); -++ v |= (1 << 1); /* set phy RMII override; */ -++ phy_write(phy_dev, 0x16, v); -++ -++ return 0; -++} -++ -++static int ksz8081rnb_phy_fix(struct phy_device *phy_dev) -++{ -++ u32 v; -++ -++ v = phy_read(phy_dev, 0x1F); -++ v |= (1 << 7); /* 7:set phy RMII 50MHz clk; */ -++ phy_write(phy_dev, 0x1F, v); -++ -++ return 0; -++} -++ -++void hleth_phy_register_fixups(void) -++{ -++ phy_register_fixup_for_uid(HUANGLONG_PHY_ID_FESTA_S28V200, -++ HUANGLONG_PHY_ID_MASK, -++ hl_fephy_s28v200_fix); -++ phy_register_fixup_for_uid(PHY_ID_KSZ8051MNL, -++ DEFAULT_PHY_MASK, ksz8051mnl_phy_fix); -++ phy_register_fixup_for_uid(PHY_ID_KSZ8081RNB, -++ DEFAULT_PHY_MASK, ksz8081rnb_phy_fix); -++} -++ -++void hleth_phy_unregister_fixups(void) -++{ -++ phy_unregister_fixup_for_uid(HUANGLONG_PHY_ID_FESTA_S28V200, -++ HUANGLONG_PHY_ID_MASK); -++ phy_unregister_fixup_for_uid(PHY_ID_KSZ8051MNL, DEFAULT_PHY_MASK); -++ phy_unregister_fixup_for_uid(PHY_ID_KSZ8081RNB, DEFAULT_PHY_MASK); -++} -++ -++static void hleth_internal_phy_clk_disable(struct hleth_phy_param_s *phy_param) -++{ -++ clk_disable_unprepare(phy_param->phy_clk); -++} -++ -++static void hleth_internal_phy_reset(struct hleth_phy_param_s *phy_param) -++{ -++ unsigned int val; -++ int bit_offset; -++ -++ /* FEPHY enable clock */ -++ clk_prepare_enable(phy_param->phy_clk); -++ -++ /* set FEPHY address */ -++ if (phy_param->fephy_phyaddr_bit < 0) -++ phy_param->fephy_phyaddr_bit = HLETH_PHY_ADDR_BIT; -++ bit_offset = phy_param->fephy_phyaddr_bit; -++ if (phy_param->fephy_sysctrl != NULL) { -++ val = readl(phy_param->fephy_sysctrl); -++ val &= ~((MASK_PHY_ADDR) << bit_offset); -++ val |= (((unsigned int)phy_param->phy_addr & MASK_PHY_ADDR) << bit_offset); -++ writel(val, phy_param->fephy_sysctrl); -++ } -++ -++ /* FEPHY set reset */ -++ reset_control_assert(phy_param->phy_rst); -++ usleep_range(10, 1000); /* 10,1000:delay zone */ -++ /* FEPHY cancel reset */ -++ reset_control_deassert(phy_param->phy_rst); -++ -++ msleep(20); /* 20:delay at least 15ms for MDIO operation */ -++} -++ -++static void hleth_gpio_reset(void __iomem *gpio_base, u32 gpio_bit) -++{ -++ u32 v; -++ -++#define RESET_DATA (1) -++ -++ if (gpio_base == NULL) -++ return; -++ -++ gpio_base = (void *)ioremap((uintptr_t)gpio_base, 0x1000); -++ -++ /* config gpio[x] dir to output */ -++ v = readb(gpio_base + 0x400); -++ v |= (1 << gpio_bit); -++ writeb(v, gpio_base + 0x400); -++ -++ /* output 1--0--1 */ -++ writeb(RESET_DATA << gpio_bit, gpio_base + (4 << gpio_bit)); -++ msleep(20); -++ writeb((!RESET_DATA) << gpio_bit, gpio_base + (4 << gpio_bit)); -++ msleep(20); -++ writeb(RESET_DATA << gpio_bit, gpio_base + (4 << gpio_bit)); -++ msleep(20); -++ -++ iounmap(gpio_base); -++} -++ -++static void hleth_external_phy_reset(struct hleth_phy_param_s *phy_param) -++{ -++ /************************************************/ -++ reset_control_deassert(phy_param->phy_rst); -++ -++ msleep(20); /* 20:delay */ -++ -++ reset_control_assert(phy_param->phy_rst); -++ -++ msleep(20); /* 20:delay */ -++ reset_control_deassert(phy_param->phy_rst); -++ -++ /************************************************/ -++ /* reset external phy with gpio */ -++ hleth_gpio_reset(phy_param->gpio_base, phy_param->gpio_bit); -++ -++ /************************************************/ -++ -++ /* add some delay in case mdio cann't access now! */ -++ msleep(30); /* 30:delay */ -++} -++ -++void hleth_phy_reset(struct hleth_platdrv_data *pdata) -++{ -++ int i; -++ struct hleth_phy_param_s *phy_param = NULL; -++ -++ if (pdata == NULL) -++ return; -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) { -++ phy_param = &pdata->hleth_phy_param[i]; -++ -++ if (!phy_param->isvalid) -++ continue; -++ -++ if (phy_param->isinternal) -++ hleth_internal_phy_reset(phy_param); -++ else -++ hleth_external_phy_reset(phy_param); -++ } -++} -++ -++void hleth_phy_clk_disable(struct hleth_platdrv_data *pdata) -++{ -++ struct hleth_phy_param_s *phy_param = NULL; -++ int i; -++ -++ if (pdata == NULL) -++ return; -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) { -++ phy_param = &pdata->hleth_phy_param[i]; -++ -++ if (!phy_param->isvalid) -++ continue; -++ -++ if (phy_param->isinternal) -++ hleth_internal_phy_clk_disable(phy_param); -++ } -++} -+diff --git a/drivers/net/ethernet/vendor/eth/phy.h b/drivers/net/ethernet/vendor/eth/phy.h -+new file mode 100755 -+index 000000000..03b894512 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/phy.h -+@@ -0,0 +1,24 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Header file for phy.c -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++#ifndef __HLETH_FEPHY_FIX_H -++#define __HLETH_FEPHY_FIX_H -++ -++#define HLETH_PHY_ADDR_BIT 23 -++#define MASK_PHY_ADDR 0x1F -++ -++#define MII_EXPMD 0x1D -++#define MII_EXPMA 0x1E -++ -++/* the following two copied from phy_quirk() -++ * in "./drivers/net/ethernet/hleth-sf/net.c" -++ */ -++#define PHY_ID_KSZ8051MNL 0x00221550 -++#define PHY_ID_KSZ8081RNB 0x00221560 -++#define DEFAULT_PHY_MASK 0xfffffff0 -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/eth/pm.c b/drivers/net/ethernet/vendor/eth/pm.c -+new file mode 100755 -+index 000000000..4341d182d -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/eth/pm.c -+@@ -0,0 +1,360 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2022. All rights reserved. -++ * Description: Power management settings. -++ * Author: AuthorNameMagicTag -++ * Create: 2022-4-20 -++ */ -++ -++#include -++#include -++ -++#define HLETH_PM_N (31) -++#define HLETH_PM_FILTERS (4) -++ -++struct hleth_pm_config { -++ unsigned char index; /* bit0--eth0 bit1--eth1 */ -++ unsigned char uc_pkts_enable; -++ unsigned char magic_pkts_enable; -++ unsigned char wakeup_pkts_enable; -++ struct { -++ unsigned int mask_bytes : HLETH_PM_N; -++ unsigned int reserved : 1;/* userspace ignore this bit */ -++ unsigned char offset; /* >= 12 */ -++ unsigned char value[HLETH_PM_N];/* byte string */ -++ unsigned char valid; /* valid filter */ -++ } filter[HLETH_PM_FILTERS]; -++}; -++ -++static unsigned char g_filter_value[HLETH_PM_FILTERS][HLETH_PM_N]; -++ -++#define HLETH_PMT_CTRL 0x0500 -++#define HLETH_PMT_MASK0 0x0504 -++#define HLETH_PMT_MASK1 0x0508 -++#define HLETH_PMT_MASK2 0x050c -++#define HLETH_PMT_MASK3 0x0510 -++#define HLETH_PMT_CMD 0x0514 -++#define HLETH_PMT_OFFSET 0x0518 -++#define HLETH_PMT_CRC1_0 0x051c -++#define HLETH_PMT_CRC3_2 0x0520 -++ -++static void hleth_initcrctable(void); -++static unsigned short hleth_computecrc(char* message, int nbytes); -++static unsigned short calculate_crc16(char *buf, unsigned int mask) -++{ -++ char data[HLETH_PM_N]; -++ int i, len = 0; -++ int ret; -++ -++ ret = memset_s(data, sizeof(data), 0, sizeof(data)); -++ if (ret != EOK) { -++ return (unsigned short)ret; -++ } -++ -++ for (i = 0; i < HLETH_PM_N; i++) { -++ if (mask & 0x1) -++ data[len++] = buf[i]; -++ -++ mask >>= 1; -++ } -++ -++ return hleth_computecrc(data, len); -++} -++static unsigned int config_ctrl_set(const struct hleth_pm_config *config) -++{ -++ unsigned int v = 0; -++ if (config->uc_pkts_enable) -++ v |= 1 << 9; /* 9:uc pkts wakeup */ -++ if (config->wakeup_pkts_enable) -++ v |= 1 << 2; /* 2:use filter framework */ -++ if (config->magic_pkts_enable) -++ v |= 1 << 1; /* magic pkts wakeup */ -++ -++ v |= 3 << 5; /* 3,5:clear irq status */ -++ return v; -++} -++static int hleth_pmt_config_eth(struct hleth_pm_config *config, struct hleth_netdev_priv *priv) -++{ -++ unsigned int v = 0, cmd = 0, offset = 0; -++ unsigned short crc[HLETH_PM_FILTERS] = {0}; -++ int reg_mask, i; -++ -++ if (priv == NULL || config == NULL) -++ return -EINVAL; -++ -++ local_lock(priv); -++ if (config->wakeup_pkts_enable) { -++ /* disable wakeup_pkts_enable before reconfig? */ -++ v = hleth_readl(priv->port_base, HLETH_PMT_CTRL); -++ v &= ~(1 << 2); /* 2:left shift val */ -++ hleth_writel(priv->port_base, v, HLETH_PMT_CTRL);/* any side effect? */ -++ } else { -++ goto config_ctrl; -++ } -++ -++/* -++ * filter.valid mask.valid mask_bytes effect -++ * 0 * * no use the filter -++ * 1 0 * all pkts can wake-up(non-exist) -++ * 1 1 0 all pkts can wake-up -++ * 1 1 !0 normal filter -++ */ -++ /* setup filter */ -++ for (i = 0; i < HLETH_PM_FILTERS; i++) { -++ if (config->filter[i].valid) { -++ if (config->filter[i].offset < 12) /* 12:operated value */ -++ continue; -++ /* offset and valid bit */ -++ offset |= config->filter[i].offset << (i * 8); /* 8:operated value */ -++ cmd |= 1 << (i * 8); /* 8:valid bit */ -++ /* mask */ -++ reg_mask = HLETH_PMT_MASK0 + (i * 4); /* 4:mask */ -++ -++ /* -++ * for logic, mask valid bit(bit31) must set to 0, -++ * 0 is enable -++ */ -++ v = config->filter[i].mask_bytes; -++ v &= ~(1 << 31); /* 31:left shift val */ -++ hleth_writel(priv->port_base, v, reg_mask); -++ -++ /* crc */ -++ memcpy_s(g_filter_value[i], HLETH_PM_N, config->filter[i].value, HLETH_PM_N); -++ crc[i] = calculate_crc16(config->filter[i].value, v); -++ if (i <= 1) {/* for filter0 and filter 1 */ -++ v = hleth_readl(priv->port_base, HLETH_PMT_CRC1_0); -++ v &= ~(0xFFFF << (16 * i)); /* 16:operated value */ -++ v |= crc[i] << (16 * i); /* 16:operated value */ -++ hleth_writel(priv->port_base, v, HLETH_PMT_CRC1_0); -++ } else {/* filter2 and filter3 */ -++ v = hleth_readl(priv->port_base, HLETH_PMT_CRC3_2); -++ v &= ~(0xFFFF << (16 * (i - 2))); /* 2,16:operated value */ -++ v |= crc[i] << (16 * (i - 2)); /* 2,16:operated value */ -++ hleth_writel(priv->port_base, v, HLETH_PMT_CRC3_2); -++ } -++ } -++ } -++ -++ if (cmd) { -++ hleth_writel(priv->port_base, offset, HLETH_PMT_OFFSET); -++ hleth_writel(priv->port_base, cmd, HLETH_PMT_CMD); -++ } -++ -++config_ctrl: -++ v = config_ctrl_set(config); -++ hleth_writel(priv->port_base, v, HLETH_PMT_CTRL); -++ -++ local_unlock(priv); -++ -++ return 0; -++} -++ -++/* pmt_config will overwrite pre-config */ -++int hleth_pmt_config(const struct net_device *ndev, struct hleth_pm_config *config) -++{ -++ static int init; -++ struct hleth_netdev_priv *priv = netdev_priv(ndev); -++ -++ if (init == 0) { -++ hleth_initcrctable(); -++ init = 1; -++ } -++ -++ if (hleth_pmt_config_eth(config, priv)) -++ return -1; -++ -++ priv->pm_state_set = true; -++ device_set_wakeup_enable(priv->dev, 1); -++ priv->mac_wol_enabled = true; -++ return 0; -++} -++ -++int hleth_pmt_get_config(struct net_device *ndev, struct hleth_pm_config *config) -++{ -++ unsigned int val, cmd, offset; -++ struct hleth_netdev_priv *ld = netdev_priv(ndev); -++ unsigned int i; -++ int reg_mask; -++ -++ config->index = ld->port; -++ val = hleth_readl(ld->port_base, HLETH_PMT_CTRL); -++ if (val & (1 << 9)) /* 9: bit */ -++ config->uc_pkts_enable = 1; -++ if (val & (1 << 2)) /* 2: bit */ -++ config->wakeup_pkts_enable = 1; -++ if (val & (1 << 1)) -++ config->magic_pkts_enable = 1; -++ -++ if (config->wakeup_pkts_enable) { -++ cmd = hleth_readl(ld->port_base, HLETH_PMT_CMD); -++ offset = hleth_readl(ld->port_base, HLETH_PMT_OFFSET); -++ -++ for (i = 0; i < HLETH_PM_FILTERS; i++) { -++ if ((cmd & (unsigned int)(1 << (i * 8))) == 0) /* 8: bit */ -++ continue; -++ config->filter[i].valid = 1; -++ config->filter[i].offset = offset >> (i * 8); /* 8: bit */ -++ reg_mask = HLETH_PMT_MASK0 + (i * 4); /* 4: mask */ -++ config->filter[i].mask_bytes = readl(ld->glb_base + reg_mask); -++ memcpy_s(config->filter[i].value, HLETH_PM_N, g_filter_value[i], HLETH_PM_N); -++ } -++ } -++ -++ return 0; -++} -++ -++bool hleth_pmt_enter(struct platform_device *pdev) -++{ -++ int i, pm = false; -++ unsigned int v; -++ struct hleth_netdev_priv *priv = NULL; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) { -++ if (!pdata->hleth_devs_save[i]) -++ continue; -++ -++ priv = netdev_priv(pdata->hleth_devs_save[i]); -++ -++ local_lock(priv); -++ if (priv->pm_state_set) { -++ v = hleth_readl(priv->port_base, HLETH_PMT_CTRL); -++ v |= 1 << 0; /* enter power down */ -++ v |= 1 << 3; /* 3:enable wakeup irq */ -++ v |= 3 << 5; /* 3,5:clear irq status */ -++ hleth_writel(priv->port_base, v, HLETH_PMT_CTRL); -++ -++ priv->pm_state_set = false; -++ pm = true; -++ } -++ local_unlock(priv); -++ } -++ return pm; -++} -++ -++void hleth_pmt_exit(struct platform_device *pdev) -++{ -++ int i; -++ unsigned int v; -++ struct hleth_netdev_priv *priv = NULL; -++ struct hleth_platdrv_data *pdata = platform_get_drvdata(pdev); -++ -++ for (i = 0; i < HLETH_MAX_PORT; i++) { -++ if (!pdata->hleth_devs_save[i]) -++ continue; -++ -++ priv = netdev_priv(pdata->hleth_devs_save[i]); -++ -++ /* logic auto exit power down mode */ -++ local_lock(priv); -++ -++ v = hleth_readl(priv->port_base, HLETH_PMT_CTRL); -++ v &= ~(1 << 0); /* enter power down */ -++ v &= ~(1 << 3); /* 3:enable wakeup irq */ -++ -++ v |= 3 << 5; /* 3,5:clear irq status */ -++ hleth_writel(priv->port_base, v, HLETH_PMT_CTRL); -++ -++ local_unlock(priv); -++ -++ priv->mac_wol_enabled = false; -++ } -++} -++ -++#define CRC16 /* Change it to CRC16 for CRC16 Computation */ -++ -++#define FALSE 0 -++#define TRUE !FALSE -++ -++#if defined(CRC16) -++#define CRC_NAME "CRC-16" -++#define POLYNOMIAL 0x8005 -++#define INITIAL_REMAINDER 0xFFFF -++#define FINAL_XOR_VALUE 0x0000 -++#define REVERSE_DATA TRUE -++#define REVERSE_REMAINDER FALSE -++#endif -++ -++#define WIDTH (8 * sizeof(unsigned short)) -++#define TOPBIT (1 << (WIDTH - 1)) -++ -++#if (REVERSE_DATA == TRUE) -++#undef REVERSE_DATA -++#define reverse_data(x) ((unsigned char) reverse((x), 8)) -++#else -++#undef REVERSE_DATA -++#define reverse_data(x) (x) -++#endif -++ -++#if (REVERSE_REMAINDER == TRUE) -++#undef REVERSE_REMAINDER -++#define reverse_remainder(x) ((unsigned short) reverse((x), WIDTH)) -++#else -++#undef REVERSE_REMAINDER -++#define reverse_remainder(x) (x) -++#endif -++ -++static unsigned short crctable[256]; -++ -++/* Reverse the data -++ * -++ * Input1: Data to be reversed -++ * Input2: number of bits in the data -++ * Output: The reversed data -++ */ -++static unsigned long reverse(unsigned long data, unsigned char nbits) -++{ -++ unsigned long reversed = 0x00000000; -++ unsigned char bit; -++ -++ /* Reverse the data about the center bit. */ -++ for (bit = 0; bit < nbits; ++bit) { -++ /* If the LSB bit is set, set the reflection of it. */ -++ if (data & 0x01) -++ reversed |= (1 << ((nbits - 1) - bit)); -++ -++ data = (data >> 1); -++ } -++ return reversed; -++} -++ -++/* This Initializes the partial CRC look up table */ -++static void hleth_initcrctable(void) -++{ -++ unsigned short remainder; -++ unsigned short dividend; -++ unsigned char bit; -++ -++ /* Compute the remainder of each possible dividend. */ -++ for (dividend = 0; dividend < 256; ++dividend) { /* 256:operated value */ -++ /* Start with the dividend followed by zeros. */ -++ remainder = dividend << (WIDTH - 8); /* 8:operated value */ -++ -++ /* Perform modulo-2 division, a bit at a time. */ -++ for (bit = 8; bit > 0; --bit) { /* 8:init val */ -++ /* Try to divide the current data bit. */ -++ if (remainder & TOPBIT) -++ remainder = (remainder << 1) ^ POLYNOMIAL; -++ else -++ remainder = (remainder << 1); -++ } -++ -++ /* Store the result into the table. */ -++ crctable[dividend] = remainder; -++ } -++} -++ -++static unsigned short hleth_computecrc(char *message, int nbytes) -++{ -++ unsigned short remainder = INITIAL_REMAINDER; -++ int byte; -++ unsigned char data; -++ -++ /* Divide the message by the polynomial, a byte at a time. */ -++ for (byte = 0; byte < nbytes; ++byte) { -++ data = reverse_data(message[byte]) ^ (remainder >> (WIDTH - 8)); /* 8:operated value */ -++ remainder = crctable[data] ^ (remainder << 8); /* 8:left shift val */ -++ } -++ -++ /* The final remainder is the CRC. */ -++ return (reverse_remainder(remainder) ^ FINAL_XOR_VALUE); -++} -+diff --git a/drivers/net/ethernet/vendor/femac/Makefile b/drivers/net/ethernet/vendor/femac/Makefile -+new file mode 100755 -+index 000000000..c785049fa -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/Makefile -+@@ -0,0 +1,6 @@ -++# -++# Makefile for the BSP Fast Ethernet network device drivers. -++# -++ -++obj-$(CONFIG_VENDOR_FEMAC) += bsp-femac.o -++bsp-femac-objs := bsp_femac.o phy_fix.o util.o -+diff --git a/drivers/net/ethernet/vendor/femac/bsp_femac.c b/drivers/net/ethernet/vendor/femac/bsp_femac.c -+new file mode 100755 -+index 000000000..93b2373b3 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/bsp_femac.c -+@@ -0,0 +1,1580 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * This software is licensed under the terms of the GNU General Public -++ * License version 2, as published by the Free Software Foundation, and -++ * may be copied, distributed, and modified under those terms. -++ * -++ * This program is distributed in the hope that it will be useful, -++ * but WITHOUT ANY WARRANTY; without even the implied warranty of -++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -++ * GNU General Public License for more details. -++ * -++ */ -++ -++#include "linux/err.h" -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "phy_fix.h" -++#include "bsp_femac.h" -++#include "util.h" -++ -++static void bsp_femac_irq_enable(const struct bsp_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 bsp_femac_irq_disable(const struct bsp_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 bsp_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 = (u32)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 bsp_femac_trim(const 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 = (u32)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; -++ bsp_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; -++ bsp_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; -++ bsp_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; -++ bsp_femac_trim_phy(phy_dev, val); -++ } -++} -++ -++static void bsp_femac_watchdog(struct work_struct *work) -++{ -++ struct delayed_work *dwork = to_delayed_work(work); -++ struct bsp_femac_priv *priv = container_of(dwork, struct bsp_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; -++ } -++ bsp_femac_trim(dev); -++out: -++ iounmap(sys_reg_addr); -++ schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER); -++} -++#endif -++ -++static void bsp_femac_tx_sg_dma_unmap(const struct bsp_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 bsp_femac_tx_dma_unmap(const struct bsp_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 { -++ bsp_femac_tx_sg_dma_unmap(priv, skb, pos); -++ } -++} -++ -++static void bsp_femac_xmit_reclaim(struct net_device *dev) -++{ -++ struct sk_buff *skb = NULL; -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ struct bsp_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; -++ } -++ bsp_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 bsp_femac_get_tso_err_info(const struct bsp_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 */ -++ bsp_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 bsp_femac_net_xmit(struct sk_buff *skb, -++ struct net_device *dev); -++ -++static netdev_tx_t bsp_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); -++ 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 (bsp_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 bsp_femac_fill_sg_desc(const struct bsp_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->bv_len; -++ -++ 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 bsp_femac_adjust_link(struct net_device *dev) -++{ -++ struct bsp_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; -++ bsp_femac_set_flow_ctrl(priv); -++ } -++} -++ -++static void bsp_femac_rx_refill(struct bsp_femac_priv *priv) -++{ -++ struct bsp_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 bsp_femac_recv_queue(struct net_device *dev, struct sk_buff *skb, -++ u32 rx_pkt_info) -++{ -++ struct bsp_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 bsp_femac_pre_receive(struct net_device *dev) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ struct bsp_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; -++ } -++ -++ bsp_femac_recv_queue(dev, skb, rx_pkt_info); -++next: -++ pos = (pos + 1) % rxq->num; -++ } -++ rxq->tail = pos; -++ -++ bsp_femac_rx_refill(priv); -++ spin_unlock_irqrestore(&priv->rxlock, rxflags); -++} -++ -++static u32 bsp_femac_rx(struct net_device *dev, int limit) -++{ -++ struct bsp_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); -++ dev->stats.rx_bytes += skb->len; -++ napi_gro_receive(&priv->napi, skb); -++ dev->stats.rx_packets++; -++ rx_pkts_num++; -++ -++ if (rx_pkts_num >= limit) { -++ break; -++ } -++ skb = skb_dequeue(&priv->rx_head); -++ } -++ -++ return rx_pkts_num; -++} -++#else -++static int bsp_femac_recv_queue(struct net_device *dev, struct sk_buff *skb, -++ u32 rx_pkt_info) -++{ -++ 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 bsp_femac_rx(struct net_device *dev, int limit) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ struct bsp_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 (bsp_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; -++ -++ bsp_femac_rx_refill(priv); -++ -++ return rx_pkts_num; -++} -++#endif -++ -++static int bsp_femac_poll(struct napi_struct *napi, int budget) -++{ -++ struct bsp_femac_priv *priv = container_of(napi, -++ struct bsp_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 -++ bsp_femac_pre_receive(dev); -++#endif -++ bsp_femac_xmit_reclaim(dev); -++ num = bsp_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); -++ bsp_femac_irq_enable(priv, DEF_INT_MASK & -++ (~IRQ_INT_TX_PER_PACKET)); -++ } -++ -++ return work_done; -++} -++ -++static irqreturn_t bsp_femac_interrupt(int irq, void *dev_id) -++{ -++ u32 ints; -++ struct net_device *dev = (struct net_device *)dev_id; -++ struct bsp_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 -++ bsp_femac_pre_receive(dev); -++#endif -++ writel(ints & DEF_INT_MASK, -++ priv->glb_base + GLB_IRQ_RAW); -++ bsp_femac_irq_disable(priv, DEF_INT_MASK); -++ napi_schedule(&priv->napi); -++ } -++ -++ if (has_tso_cap(priv->hw_cap) && unlikely(ints & INT_TX_ERR)) -++ bsp_femac_get_tso_err_info(priv); -++ -++ return IRQ_HANDLED; -++} -++ -++static int bsp_femac_init_tx_descriptor_ring(struct bsp_femac_priv *priv) -++{ -++ priv->tx_ring.desc = (struct tx_desc *)dma_alloc_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 bsp_femac_destroy_tx_descriptor_ring(struct bsp_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 bsp_femac_init_queue(struct device *dev, -++ struct bsp_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 bsp_femac_init_tx_and_rx_queues(struct bsp_femac_priv *priv) -++{ -++ int ret; -++ -++ ret = bsp_femac_init_queue(priv->dev, &priv->txq, TXQ_NUM); -++ if (ret) -++ return ret; -++ -++ ret = bsp_femac_init_queue(priv->dev, &priv->rxq, RXQ_NUM); -++ if (ret) -++ return ret; -++ -++ priv->tx_fifo_used_cnt = 0; -++ -++ return 0; -++} -++ -++static void bsp_femac_free_skb_rings(struct bsp_femac_priv *priv) -++{ -++ struct bsp_femac_queue *txq = &priv->txq; -++ struct bsp_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; -++ } -++ bsp_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 bsp_femac_set_hw_mac_addr(const struct bsp_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 bsp_femac_port_reset(const struct bsp_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 bsp_femac_net_open(struct net_device *dev) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ -++ bsp_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); -++ bsp_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); -++ -++ bsp_femac_irq_enable(priv, IRQ_ENA_ALL | IRQ_ENA_PORT0 | DEF_INT_MASK); -++ if (has_tso_cap(priv->hw_cap)) -++ bsp_femac_irq_enable(priv, INT_TX_ERR); -++ -++ return 0; -++} -++ -++static void bsp_femac_port_init(struct bsp_femac_priv *priv); -++ -++static int bsp_femac_net_close(struct net_device *dev) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ -++ bsp_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. -++ */ -++ bsp_femac_port_reset(priv); -++ bsp_femac_port_init(priv); -++ -++ priv->tx_pause_en = false; -++ bsp_femac_set_flow_ctrl(priv); -++ bsp_femac_free_skb_rings(priv); -++#ifdef FEMAC_RX_REFILL_IN_IRQ -++ skb_queue_purge(&priv->rx_head); -++#endif -++ -++ return 0; -++} -++ -++static bool bsp_femac_net_isready(struct net_device *dev) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ struct bsp_femac_queue *txq = &priv->txq; -++ u32 val; -++ -++ val = readl(priv->port_base + ADDRQ_STAT); -++ val &= BIT_TX_READY; -++ if (!val) { -++ bsp_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))) { -++ bsp_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 bsp_femac_net_xmit(struct sk_buff *skb, struct net_device *dev) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ struct bsp_femac_queue *txq = &priv->txq; -++ dma_addr_t addr; -++ int ret, val; -++ -++ if (!bsp_femac_net_isready(dev)) -++ return NETDEV_TX_BUSY; -++ -++ ret = bsp_femac_check_hw_capability(skb); -++ if (unlikely(ret)) { -++ if (ret == -ENOTSUPP) -++ return bsp_femac_sw_gso(skb, dev); -++ -++ dev_kfree_skb_any(skb); -++ dev->stats.tx_dropped++; -++ return NETDEV_TX_OK; -++ } -++ -++ val = bsp_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 = bsp_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(val, 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); -++ -++ val = readl(priv->port_base + ADDRQ_STAT) & BIT_TX_READY; -++ if (!val) { -++ bsp_femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET); -++ netif_stop_queue(dev); -++ } -++ -++ return NETDEV_TX_OK; -++} -++ -++static int bsp_femac_set_mac_address(struct net_device *dev, void *p) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ struct sockaddr *skaddr = p; -++ -++ if (!is_valid_ether_addr(skaddr->sa_data)) -++ return -EADDRNOTAVAIL; -++ -++ if (memcpy_s(dev->dev_addr, dev->addr_len, skaddr->sa_data, dev->addr_len) < 0) -++ printk("memcpy_s err : %s %d.\n", __func__, __LINE__); -++ dev->addr_assign_type &= ~NET_ADDR_RANDOM; -++ -++ bsp_femac_set_hw_mac_addr(priv, dev->dev_addr); -++ -++ return 0; -++} -++ -++static void bsp_femac_enable_hw_addr_filter(const struct bsp_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 bsp_femac_set_hw_addr_filter(const struct bsp_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 bsp_femac_set_promisc_mode(const struct bsp_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 bsp_femac_set_mc_addr_filter(const struct bsp_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++) -++ bsp_femac_enable_hw_addr_filter(priv, i, false); -++ -++ netdev_for_each_mc_addr(ha, dev) { -++ bsp_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 bsp_femac_set_uc_addr_filter(const struct bsp_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++) -++ bsp_femac_enable_hw_addr_filter(priv, i, false); -++ -++ netdev_for_each_uc_addr(ha, dev) { -++ bsp_femac_set_hw_addr_filter(priv, ha->addr, reg); -++ reg++; -++ } -++ val &= ~MACTCTRL_UNI2CPU; -++ } -++ writel(val, priv->glb_base + GLB_MACTCTRL); -++} -++ -++static void bsp_femac_net_set_rx_mode(struct net_device *dev) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ -++ if (dev->flags & IFF_PROMISC) { -++ bsp_femac_set_promisc_mode(priv, true); -++ } else { -++ bsp_femac_set_promisc_mode(priv, false); -++ bsp_femac_set_mc_addr_filter(priv); -++ bsp_femac_set_uc_addr_filter(priv); -++ } -++} -++ -++static int bsp_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 bsp_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 = bsp_femac_get_pauseparam, -++ // .set_pauseparam = bsp_femac_set_pauseparam, -++ .get_ts_info = ethtool_op_get_ts_info, -++}; -++ -++ -++int eth_change_mtu(struct net_device *dev, int new_mtu) -++{ -++ netdev_warn(dev, "%s is deprecated\n", __func__); -++ dev->mtu = new_mtu; -++ return 0; -++} -++ -++static const struct net_device_ops bsp_femac_netdev_ops = { -++ .ndo_open = bsp_femac_net_open, -++ .ndo_stop = bsp_femac_net_close, -++ .ndo_start_xmit = bsp_femac_net_xmit, -++ .ndo_do_ioctl = bsp_femac_net_ioctl, -++ .ndo_set_mac_address = bsp_femac_set_mac_address, -++ .ndo_set_rx_mode = bsp_femac_net_set_rx_mode, -++ .ndo_change_mtu = eth_change_mtu, -++ .ndo_set_features = bsp_femac_set_features, -++}; -++ -++static void bsp_femac_verify_flow_ctrl_args(struct bsp_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 bsp_femac_core_reset(const struct bsp_femac_priv *priv) -++{ -++ reset_control_assert(priv->mac_rst); -++ reset_control_deassert(priv->mac_rst); -++} -++ -++static void bsp_femac_phy_reset(const struct bsp_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); -++ bsp_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 -++ */ -++ bsp_femac_sleep_us(priv->phy_reset_delays[PULSE]); -++ reset_control_deassert(priv->phy_rst); -++ /* delay some time to ensure later MDIO access */ -++ bsp_femac_sleep_us(priv->phy_reset_delays[POST_DELAY]); -++} -++ -++static void bsp_femac_port_init(struct bsp_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); -++ bsp_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); -++ -++ bsp_femac_set_flow_ctrl(priv); -++} -++ -++static int bsp_femac_drv_res(struct platform_device *pdev, -++ struct bsp_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, "vendor,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 bsp_femac_drv_mac(struct platform_device *pdev, -++ struct bsp_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); -++ -++ bsp_femac_core_reset(priv); -++ -++ mac_addr = of_get_mac_address(node); -++ if (!IS_ERR_OR_NULL(mac_addr)) { -++ 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 *bsp_femac_drv_phy(struct platform_device *pdev, -++ struct bsp_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; -++ bsp_femac_phy_reset(priv); -++ } -++ -++ phy_register_fixups(); -++ -++ phy = of_phy_get_and_connect(priv->ndev, node, bsp_femac_adjust_link); -++ if (phy == NULL) { -++ phy_interface_t phy_mode; -++ /* 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. -++ */ -++ -++ *ret = of_get_phy_mode(node, &phy_mode); -++ -++ phy = of_phy_connect(priv->ndev, of_node_get(node), &bsp_femac_adjust_link, 0, phy_mode); -++ 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; -++ } -++ } -++ -++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phy->advertising); -++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phy->supported); -++ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT | ETHTOOL_LINK_MODE_1000baseT_Half_BIT, phy->advertising); -++ -++ 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 bsp_femac_drv_napi(struct platform_device *pdev, -++ struct bsp_femac_priv *priv) -++{ -++ struct net_device *ndev = priv->ndev; -++ -++ ndev->watchdog_timeo = 6 * HZ; /* 6HZ */ -++ ndev->priv_flags |= IFF_UNICAST_FLT; -++ ndev->netdev_ops = &bsp_femac_netdev_ops; -++ ndev->ethtool_ops = &bsp_femac_ethtools_ops; -++ netif_napi_add(ndev, &priv->napi, bsp_femac_poll, FEMAC_POLL_WEIGHT); -++ -++#ifdef CONFIG_FEPHY_OPT -++ INIT_DELAYED_WORK(&priv->watchdog_queue, bsp_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; -++ -++ 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; -++ -++ bsp_femac_verify_flow_ctrl_args(priv); -++ -++ bsp_femac_port_init(priv); -++ -++ if (has_rxcsum_cap(priv->hw_cap)) -++ bsp_femac_enable_rxcsum_drop(priv, true); -++} -++ -++static int bsp_femac_drv_queues(struct platform_device *pdev, -++ struct bsp_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 = bsp_femac_init_tx_and_rx_queues(priv); -++ if (ret) -++ return ret; -++ -++ if (has_tso_cap(priv->hw_cap)) { -++ ret = bsp_femac_init_tx_descriptor_ring(priv); -++ if (ret) -++ return ret; -++ } -++ return 0; -++} -++ -++static int bsp_femac_drv_register(struct platform_device *pdev, -++ struct bsp_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, bsp_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 bsp_femac_drv_probe(struct platform_device *pdev) -++{ -++ struct device *dev = &pdev->dev; -++ struct net_device *ndev = NULL; -++ struct bsp_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 = bsp_femac_drv_res(pdev, priv); -++ if (ret) -++ goto out_free_netdev; -++ -++ ret = bsp_femac_drv_mac(pdev, priv); -++ if (ret) -++ goto out_disable_clk; -++ -++ phy = bsp_femac_drv_phy(pdev, priv, &ret); -++ if (phy == NULL) -++ goto out_disable_clk; -++ -++ bsp_femac_drv_napi(pdev, priv); -++ -++ ret = bsp_femac_drv_queues(pdev, priv); -++ if (ret) -++ goto out_disconnect_phy; -++ -++ ret = bsp_femac_drv_register(pdev, priv); -++ if (ret) -++ goto out_destroy_descriptor; -++ -++ return ret; -++ -++out_destroy_descriptor: -++ if (has_tso_cap(priv->hw_cap)) -++ bsp_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 bsp_femac_drv_remove(struct platform_device *pdev) -++{ -++ struct net_device *ndev = platform_get_drvdata(pdev); -++ struct bsp_femac_priv *priv = netdev_priv(ndev); -++ -++ netif_napi_del(&priv->napi); -++ unregister_netdev(ndev); -++ if (has_tso_cap(priv->hw_cap)) -++ bsp_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 bsp_femac_drv_suspend(struct platform_device *pdev, -++ pm_message_t state) -++{ -++ struct net_device *ndev = platform_get_drvdata(pdev); -++ struct bsp_femac_priv *priv = netdev_priv(ndev); -++ -++ disable_irq(ndev->irq); -++ if (netif_running(ndev)) { -++ bsp_femac_net_close(ndev); -++ netif_device_detach(ndev); -++ } -++ -++ clk_disable_unprepare(priv->clk); -++ -++ return 0; -++} -++ -++static int bsp_femac_drv_resume(struct platform_device *pdev) -++{ -++ struct net_device *ndev = platform_get_drvdata(pdev); -++ struct bsp_femac_priv *priv = netdev_priv(ndev); -++ -++ clk_prepare_enable(priv->clk); -++ if (priv->phy_rst != NULL) -++ bsp_femac_phy_reset(priv); -++ -++ if (netif_running(ndev)) { -++ bsp_femac_port_init(priv); -++ bsp_femac_net_open(ndev); -++ netif_device_attach(ndev); -++ } -++ enable_irq(ndev->irq); -++ -++ return 0; -++} -++#endif -++ -++static const struct of_device_id bsp_femac_match[] = { -++ { -++ .compatible = "vendor,femac-v1", -++ }, -++ { -++ .compatible = "vendor,femac-v2", -++ }, -++ {}, -++}; -++ -++MODULE_DEVICE_TABLE(of, bsp_femac_match); -++ -++static struct platform_driver bsp_femac_driver = { -++ .driver = { -++ .name = "bsp-femac", -++ .of_match_table = bsp_femac_match, -++ }, -++ .probe = bsp_femac_drv_probe, -++ .remove = bsp_femac_drv_remove, -++#ifdef CONFIG_PM -++ .suspend = bsp_femac_drv_suspend, -++ .resume = bsp_femac_drv_resume, -++#endif -++}; -++ -++module_platform_driver(bsp_femac_driver); -++ -++MODULE_DESCRIPTION("Vendor Fast Ethernet MAC driver"); -++MODULE_LICENSE("GPL v2"); -++MODULE_ALIAS("platform:bsp-femac"); -+diff --git a/drivers/net/ethernet/vendor/femac/bsp_femac.h b/drivers/net/ethernet/vendor/femac/bsp_femac.h -+new file mode 100755 -+index 000000000..1f7e47bc0 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/bsp_femac.h -+@@ -0,0 +1,277 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 __ETH_BSP_FEMAC_H__ -++#define __ETH_BSP_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 "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 -++ -++#if (defined(CONFIG_ARCH_SS101V200) || defined(CONFIG_ARCH_SS101V500) || defined(CONFIG_ARCH_SS101V600)) -++#define CONFIG_FEPHY_OPT -++#endif -++ -++#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 bsp_femac_queue { -++ struct sk_buff **skb; -++ dma_addr_t *dma_phys; -++ unsigned int num; -++ unsigned int head; -++ unsigned int tail; -++}; -++ -++struct bsp_femac_tx_desc_ring { -++ struct tx_desc *desc; -++ dma_addr_t dma_phys; -++}; -++ -++// #define FEMAC_RX_REFILL_IN_IRQ -++ -++struct bsp_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 bsp_femac_queue txq; -++ struct bsp_femac_queue rxq; -++#ifdef FEMAC_RX_REFILL_IN_IRQ -++ struct sk_buff_head rx_head; -++ spinlock_t rxlock; -++#endif -++ struct bsp_femac_tx_desc_ring tx_ring; -++ u32 tx_fifo_used_cnt; -++ struct napi_struct napi; -++ -++ /* 802.3x flow control */ -++ bool tx_pause_en; -++ u32 tx_pause_active_thresh; -++ u32 tx_pause_deactive_thresh; -++}; -++ -++struct frags_info { -++ /* Word(2*i+2) */ -++ u32 addr; -++ /* Word(2*i+3) */ -++ u32 size : 16; -++ u32 reserved : 16; -++}; -++ -++struct tx_desc { -++ /* Word0 */ -++ u32 total_len : 17; -++ u32 reserv : 15; -++ /* Word1 */ -++ u32 ipv6_id; -++ /* Word2 */ -++ u32 linear_addr; -++ /* Word3 */ -++ u32 linear_len : 16; -++ u32 reserv3 : 16; -++ /* MAX_SKB_FRAGS is 30 */ -++ struct frags_info frags[30]; -++}; -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/femac/festa_s28v115_2c02.h b/drivers/net/ethernet/vendor/femac/festa_s28v115_2c02.h -+new file mode 100755 -+index 000000000..0722ecad8 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/festa_s28v115_2c02.h -+@@ -0,0 +1,199 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 __ETH_FESTA_S28V115_2C02_H__ -++#define __ETH_FESTA_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 -+\ No newline at end of file -+diff --git a/drivers/net/ethernet/vendor/femac/festa_s28v202_2e01.h b/drivers/net/ethernet/vendor/femac/festa_s28v202_2e01.h -+new file mode 100755 -+index 000000000..d4ad73f97 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/festa_s28v202_2e01.h -+@@ -0,0 +1,92 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 __ETH_FESTA_S28V202_2E01_H__ -++#define __ETH_FESTA_S28V202_2E01_H__ -++ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, -++ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, -++ 0x3402, 0x2E, 0x3403, 0x01, 0x3404, 0xFD, -++ 0x3405, 0xFF, 0x3406, 0xF2, 0x3407, 0x4F, -++ 0x3408, 0xFD, 0x3409, 0xFF, 0x340A, 0xF0, -++ 0x340B, 0xF6, 0x340C, 0x34, 0x340D, 0xD7, -++ 0x340E, 0x26, 0x340F, 0x05, 0x3410, 0xC6, -++ 0x3411, 0x01, 0x3412, 0xF7, 0x3413, 0x34, -++ 0x3414, 0xD7, 0x3415, 0xF6, 0x3416, 0x08, -++ 0x3417, 0x00, 0x3418, 0xF7, 0x3419, 0x34, -++ 0x341A, 0xD8, 0x341B, 0xC6, 0x341C, 0x01, -++ 0x341D, 0xF7, 0x341E, 0x08, 0x341F, 0x00, -++ 0x3420, 0x20, 0x3421, 0x0F, 0x3422, 0xCC, -++ 0x3423, 0x34, 0x3424, 0x3F, 0x3425, 0x1A, -++ 0x3426, 0xB3, 0x3427, 0x00, 0x3428, 0xCC, -++ 0x3429, 0x27, 0x342A, 0x03, 0x342B, 0xFD, -++ 0x342C, 0x00, 0x342D, 0xCC, 0x342E, 0x78, -++ 0x342F, 0x08, 0x3430, 0x00, 0x3431, 0xF6, -++ 0x3432, 0x08, 0x3433, 0x00, 0x3434, 0xC1, -++ 0x3435, 0x02, 0x3436, 0x26, 0x3437, 0xEA, -++ 0x3438, 0xF6, 0x3439, 0x34, 0x343A, 0xD8, -++ 0x343B, 0xF7, 0x343C, 0x08, 0x343D, 0x00, -++ 0x343E, 0x39, 0x343F, 0xBD, 0x3440, 0xF7, -++ 0x3441, 0xFA, 0x3442, 0x08, 0x3443, 0xCC, -++ 0x3444, 0x20, 0x3445, 0xA1, 0x3446, 0xED, -++ 0x3447, 0x05, 0x3448, 0xC6, 0x3449, 0xA4, -++ 0x344A, 0xED, 0x344B, 0x03, 0x344C, 0xBD, -++ 0x344D, 0x8B, 0x344E, 0x82, 0x344F, 0xE7, -++ 0x3450, 0x07, 0x3451, 0xC0, 0x3452, 0x02, -++ 0x3453, 0x27, 0x3454, 0x11, 0x3455, 0x5A, -++ 0x3456, 0x27, 0x3457, 0x0E, 0x3458, 0x5A, -++ 0x3459, 0x27, 0x345A, 0x39, 0x345B, 0x5A, -++ 0x345C, 0x27, 0x345D, 0x36, 0x345E, 0x5A, -++ 0x345F, 0x27, 0x3460, 0x51, 0x3461, 0x5A, -++ 0x3462, 0x27, 0x3463, 0x4E, 0x3464, 0x20, -++ 0x3465, 0x6D, 0x3466, 0x18, 0x3467, 0xFE, -++ 0x3468, 0x30, 0x3469, 0x1E, 0x346A, 0xF6, -++ 0x346B, 0x30, 0x346C, 0x22, 0x346D, 0x18, -++ 0x346E, 0x3A, 0x346F, 0x18, 0x3470, 0xE6, -++ 0x3471, 0x00, 0x3472, 0x58, 0x3473, 0x58, -++ 0x3474, 0xE7, 0x3475, 0x02, 0x3476, 0x1A, -++ 0x3477, 0xEE, 0x3478, 0x05, 0x3479, 0x18, -++ 0x347A, 0xE6, 0x347B, 0x00, 0x347C, 0xC4, -++ 0x347D, 0x03, 0x347E, 0xEA, 0x347F, 0x02, -++ 0x3480, 0x18, 0x3481, 0xE7, 0x3482, 0x00, -++ 0x3483, 0x1A, 0x3484, 0xEE, 0x3485, 0x03, -++ 0x3486, 0x18, 0x3487, 0xE6, 0x3488, 0x00, -++ 0x3489, 0xC4, 0x348A, 0x1F, 0x348B, 0xCA, -++ 0x348C, 0xC0, 0x348D, 0x18, 0x348E, 0xE7, -++ 0x348F, 0x00, 0x3490, 0xC6, 0x3491, 0x09, -++ 0x3492, 0x20, 0x3493, 0x3A, 0x3494, 0x1A, -++ 0x3495, 0xEE, 0x3496, 0x05, 0x3497, 0x18, -++ 0x3498, 0xE6, 0x3499, 0x00, 0x349A, 0xC4, -++ 0x349B, 0x03, 0x349C, 0xCA, 0x349D, 0x54, -++ 0x349E, 0x18, 0x349F, 0xE7, 0x34A0, 0x00, -++ 0x34A1, 0x1A, 0x34A2, 0xEE, 0x34A3, 0x03, -++ 0x34A4, 0x18, 0x34A5, 0xE6, 0x34A6, 0x00, -++ 0x34A7, 0xC4, 0x34A8, 0x1F, 0x34A9, 0xCA, -++ 0x34AA, 0x20, 0x34AB, 0x18, 0x34AC, 0xE7, -++ 0x34AD, 0x00, 0x34AE, 0xC6, 0x34AF, 0x74, -++ 0x34B0, 0x20, 0x34B1, 0x1C, 0x34B2, 0x1A, -++ 0x34B3, 0xEE, 0x34B4, 0x05, 0x34B5, 0x18, -++ 0x34B6, 0xE6, 0x34B7, 0x00, 0x34B8, 0xC4, -++ 0x34B9, 0x03, 0x34BA, 0xCA, 0x34BB, 0x48, -++ 0x34BC, 0x18, 0x34BD, 0xE7, 0x34BE, 0x00, -++ 0x34BF, 0x1A, 0x34C0, 0xEE, 0x34C1, 0x03, -++ 0x34C2, 0x18, 0x34C3, 0xE6, 0x34C4, 0x00, -++ 0x34C5, 0xC4, 0x34C6, 0x1F, 0x34C7, 0xCA, -++ 0x34C8, 0x20, 0x34C9, 0x18, 0x34CA, 0xE7, -++ 0x34CB, 0x00, 0x34CC, 0xC6, 0x34CD, 0x52, -++ 0x34CE, 0x18, 0x34CF, 0x08, 0x34D0, 0x18, -++ 0x34D1, 0xE7, 0x34D2, 0x00, 0x34D3, 0xAE, -++ 0x34D4, 0x00, 0x34D5, 0x38, 0x34D6, 0x39, -++ 0x34D7, 0x00, 0x3400, 0x01, 0x33f8, 0x01 -++#endif -+diff --git a/drivers/net/ethernet/vendor/femac/festa_v272_2723.h b/drivers/net/ethernet/vendor/femac/festa_v272_2723.h -+new file mode 100755 -+index 000000000..d94d7c4d4 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/festa_v272_2723.h -+@@ -0,0 +1,52 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 __ETH_FESTA_V272_2723_H__ -++#define __ETH_FESTA_V272_2723_H__ -++ 0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00, -++ 0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC, -++ 0x3402, 0x27, 0x3403, 0x23, 0x3404, 0xFD, -++ 0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0x20, -++ 0x3408, 0x00, 0x3409, 0x3C, 0x340A, 0x3C, -++ 0x340B, 0x30, 0x340C, 0xF6, 0x340D, 0x00, -++ 0x340E, 0x4A, 0x340F, 0xC4, 0x3410, 0x7F, -++ 0x3411, 0xE7, 0x3412, 0x01, 0x3413, 0xF6, -++ 0x3414, 0x01, 0x3415, 0xBE, 0x3416, 0xC1, -++ 0x3417, 0x02, 0x3418, 0x27, 0x3419, 0x0E, -++ 0x341A, 0xE6, 0x341B, 0x01, 0x341C, 0xC1, -++ 0x341D, 0x14, 0x341E, 0x27, 0x341F, 0x08, -++ 0x3420, 0xC1, 0x3421, 0x18, 0x3422, 0x25, -++ 0x3423, 0x09, 0x3424, 0xC1, 0x3425, 0x1B, -++ 0x3426, 0x22, 0x3427, 0x05, 0x3428, 0xC6, -++ 0x3429, 0x5C, 0x342A, 0xF7, 0x342B, 0x20, -++ 0x342C, 0xA1, 0x342D, 0xF6, 0x342E, 0x01, -++ 0x342F, 0xBF, 0x3430, 0xC1, 0x3431, 0x01, -++ 0x3432, 0x26, 0x3433, 0x29, 0x3434, 0xF6, -++ 0x3435, 0x30, 0x3436, 0x55, 0x3437, 0xC0, -++ 0x3438, 0x05, 0x3439, 0xE7, 0x343A, 0x01, -++ 0x343B, 0xC1, 0x343C, 0x13, 0x343D, 0x23, -++ 0x343E, 0x04, 0x343F, 0xC6, 0x3440, 0x13, -++ 0x3441, 0xE7, 0x3442, 0x01, 0x3443, 0x18, -++ 0x3444, 0xFE, 0x3445, 0x30, 0x3446, 0x4C, -++ 0x3447, 0x18, 0x3448, 0x3A, 0x3449, 0x18, -++ 0x344A, 0xE6, 0x344B, 0x00, 0x344C, 0x58, -++ 0x344D, 0x58, 0x344E, 0x58, 0x344F, 0x58, -++ 0x3450, 0x58, 0x3451, 0xE7, 0x3452, 0x00, -++ 0x3453, 0xF6, 0x3454, 0x20, 0x3455, 0x04, -++ 0x3456, 0xC4, 0x3457, 0x1F, 0x3458, 0xEA, -++ 0x3459, 0x00, 0x345A, 0xF7, 0x345B, 0x20, -++ 0x345C, 0x04, 0x345D, 0x38, 0x345E, 0x38, -++ 0x345F, 0x39, 0x3400, 0x01, 0x33f8, 0x01 -++#endif -+diff --git a/drivers/net/ethernet/vendor/femac/phy_fix.c b/drivers/net/ethernet/vendor/femac/phy_fix.c -+new file mode 100755 -+index 000000000..17f76e6ad -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/phy_fix.c -+@@ -0,0 +1,117 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 "phy_fix.h" -++ -++static const u32 phy_v272_fix_param[] = { -++#include "festa_v272_2723.h" -++}; -++ -++static const u32 phy_v115_fix_param[] = { -++#include "festa_s28v115_2c02.h" -++}; -++ -++static const u32 phy_v202_fix_param[] = { -++#include "festa_s28v202_2e01.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 bsp_fephy_v272_fix(struct phy_device *phy_dev) -++{ -++ int count; -++ -++ count = ARRAY_SIZE(phy_v272_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_v272_fix_param, count); -++ -++ return 0; -++} -++ -++static int bsp_fephy_v115_fix(struct phy_device *phy_dev) -++{ -++ int count; -++ -++ count = ARRAY_SIZE(phy_v115_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_v115_fix_param, count); -++ -++ return 0; -++} -++ -++static int bsp_fephy_v202_fix(struct phy_device *phy_dev) -++{ -++ int count; -++ -++ count = ARRAY_SIZE(phy_v202_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_v202_fix_param, count); -++ -++ return 0; -++} -++ -++void phy_register_fixups(void) -++{ -++ phy_register_fixup_for_uid(BSP_PHY_ID_FESTAV272, -++ BSP_PHY_MASK, -++ bsp_fephy_v272_fix); -++ -++ phy_register_fixup_for_uid(BSP_PHY_ID_FESTAV115, -++ BSP_PHY_MASK, -++ bsp_fephy_v115_fix); -++ -++ phy_register_fixup_for_uid(BSP_PHY_ID_FESTAV202, -++ BSP_PHY_MASK, -++ bsp_fephy_v202_fix); -++} -++ -++void phy_unregister_fixups(void) -++{ -++ phy_unregister_fixup_for_uid(BSP_PHY_ID_FESTAV272, -++ BSP_PHY_MASK); -++ -++ phy_unregister_fixup_for_uid(BSP_PHY_ID_FESTAV115, -++ BSP_PHY_MASK); -++ -++ phy_unregister_fixup_for_uid(BSP_PHY_ID_FESTAV202, -++ BSP_PHY_MASK); -++} -+diff --git a/drivers/net/ethernet/vendor/femac/phy_fix.h b/drivers/net/ethernet/vendor/femac/phy_fix.h -+new file mode 100755 -+index 000000000..05518c384 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/phy_fix.h -+@@ -0,0 +1,30 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 __ETH_PHY_FIX_H__ -++#define __ETH_PHY_FIX_H__ -++ -++#define BSP_PHY_ID_FESTAV272 0x20669901 -++#define BSP_PHY_ID_FESTAV115 0x20669903 -++#define BSP_PHY_ID_FESTAV202 0x20669906 -++#define BSP_PHY_MASK 0xffffffff -++ -++#define MII_EXPMD 0x1d -++#define MII_EXPMA 0x1e -++ -++void phy_register_fixups(void); -++void phy_unregister_fixups(void); -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/femac/util.c b/drivers/net/ethernet/vendor/femac/util.c -+new file mode 100755 -+index 000000000..e1cb73bea -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/util.c -+@@ -0,0 +1,321 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 "util.h" -++ -++static void bsp_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 bsp_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 bsp_femac_skb_is_ipv6(struct sk_buff *skb) -++{ -++ return (bsp_femac_get_l3_proto(skb) == htons(ETH_P_IPV6)); -++} -++ -++static int bsp_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 bsp_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 (bsp_femac_skb_is_ipv6(skb)) -++ return bsp_femac_check_hw_capability_for_ipv6(skb); -++ -++ return 0; -++} -++ -++static unsigned int bsp_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)) { -++ bsp_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 bsp_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; -++ unsigned int max_mss = ETH_DATA_LEN; -++ u32 pkt_info = 0; -++ -++ if (skb == NULL) -++ return 0; -++ -++ max_data_len = skb->len - ETH_HLEN; -++ -++ 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 |= bsp_femac_get_pkt_info_gso(skb, do_txcsum, max_mss, l4_proto); -++ -++ return pkt_info; -++} -++ -++void bsp_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 bsp_femac_set_flow_ctrl(const struct bsp_femac_priv *priv) -++{ -++ unsigned int pause_en; -++ unsigned int tx_flow_ctrl; -++ -++ if (priv == NULL) -++ return; -++ -++ 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 bsp_femac_get_pauseparam(struct net_device *dev, -++ struct ethtool_pauseparam *pause) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ -++ if (dev == NULL || dev->phydev == NULL || pause == NULL) -++ return; -++ -++ pause->autoneg = dev->phydev->autoneg; -++ pause->rx_pause = 1; -++ if (priv->tx_pause_en) -++ pause->tx_pause = 1; -++} -++ -++#ifdef __TODO__ -++int bsp_femac_set_pauseparam(struct net_device *dev, -++ struct ethtool_pauseparam *pause) -++{ -++ struct bsp_femac_priv *priv = netdev_priv(dev); -++ struct phy_device *phy = NULL; -++ int ret = 0; -++ -++ if (dev == NULL || pause == NULL || pause->rx_pause == 0) -++ return -EINVAL; -++ -++ phy = dev->phydev; -++ -++ if (pause->tx_pause != priv->tx_pause_en) { -++ priv->tx_pause_en = pause->tx_pause; -++ bsp_femac_set_flow_ctrl(priv); -++ } -++ -++ if (phy != NULL && 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; -++} -++#endif -++ -++void bsp_femac_enable_rxcsum_drop(const struct bsp_femac_priv *priv, -++ bool drop) -++{ -++ unsigned int val; -++ if (priv == NULL) -++ return; -++ -++ 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 bsp_femac_set_features(struct net_device *dev, netdev_features_t features) -++{ -++ struct bsp_femac_priv *priv = NULL; -++ netdev_features_t changed; -++ -++ if (dev == NULL) -++ return -1; -++ -++ priv = netdev_priv(dev); -++ changed = dev->features ^ features; -++ -++ if (changed & NETIF_F_RXCSUM) { -++ if (features & NETIF_F_RXCSUM) -++ bsp_femac_enable_rxcsum_drop(priv, true); -++ else -++ bsp_femac_enable_rxcsum_drop(priv, false); -++ } -++ -++ return 0; -++} -+diff --git a/drivers/net/ethernet/vendor/femac/util.h b/drivers/net/ethernet/vendor/femac/util.h -+new file mode 100755 -+index 000000000..a77edffad -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/femac/util.h -+@@ -0,0 +1,33 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 __ETH_UTIL_H__ -++#define __ETH_UTIL_H__ -++ -++#include "bsp_femac.h" -++ -++int bsp_femac_check_hw_capability(struct sk_buff *skb); -++u32 bsp_femac_get_pkt_info(struct sk_buff *skb); -++void bsp_femac_sleep_us(u32 time_us); -++void bsp_femac_set_flow_ctrl(const struct bsp_femac_priv *priv); -++void bsp_femac_get_pauseparam(struct net_device *dev, -++ struct ethtool_pauseparam *pause); -++int bsp_femac_set_pauseparam(struct net_device *dev, -++ struct ethtool_pauseparam *pause); -++void bsp_femac_enable_rxcsum_drop(const struct bsp_femac_priv *priv, -++ bool drop); -++int bsp_femac_set_features(struct net_device *dev, netdev_features_t features); -++ -++#endif -+\ No newline at end of file -+diff --git a/drivers/net/ethernet/vendor/gmac/Kconfig b/drivers/net/ethernet/vendor/gmac/Kconfig -+new file mode 100755 -+index 000000000..4e2bb132d -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/Kconfig -+@@ -0,0 +1,106 @@ -++# -++# gmac family network device configuration -++# -++ -++menuconfig ETH_GMAC -++ tristate "eth gmac family network device support" -++ select PHYLIB -++ select RESET_CONTROLLER -++ help -++ This selects the eth gmac family network device. -++ The gigabit switch fabric (GSF) receives and transmits data over Ethernet -++ ports at 10/100/1000 Mbit/s in full-duplex or half-duplex mode. -++ The Ethernet port exchanges data with the CPU port, and supports -++ the energy efficient Ethernet (EEE) and wake on LAN (WoL) functions. -++ -++if ETH_GMAC -++ -++config GMAC_DDR_64BIT -++ bool "gmac ddr width 64 bit" -++ depends on ARM64 -++ default n -++ help -++ This define the gmac supports DDR width 64 bit. -++ In the newest version, the DDR size may be 8G. -++ But in old version, the gmac only supports DDR width 32 bit. -++ The default value is false. -++ -++config GMAC_DESC_4WORD -++ bool "gmac descriptor size is 4 words" -++ default y -++ help -++ This define the size of gmac descriptor structure. -++ In the newest version, descriptor size is 4 words. -++ But in some old version, the size is 8 words. -++ The default value is true. -++ -++config GMAC_RXCSUM -++ bool "gmac Receive checksumming offload supported" -++ default y -++ help -++ This indicate MAC support Receive checksumming offload. -++ Support IPv4 and IPv6, tcp and udp. -++ The default value is enabled. -++ If old version MAC does not support, disable this option please. -++ -++config RX_FLOW_CTRL_SUPPORT -++ bool "rx flow ctrl supported" -++ default y -++ help -++ Rx flow ctrl supported, default is enabled. -++ When we received pause frame, -++ we will stop transmiting data frame for some time. -++ The stopping time is the time filled in pause frame. -++ -++config TX_FLOW_CTRL_SUPPORT -++ bool "tx flow ctrl supported" -++ default y -++ help -++ Tx flow ctrl supported, default is enabled. -++ When we has no buffer to receive packet, -++ we will send pause frame. -++ When buffer is available, we will send zero-quanta pause frame. -++ -++config TX_FLOW_CTRL_PAUSE_TIME -++ hex "tx flow ctrl pause time" -++ default "0xFFFF" -++ help -++ The pause time filled in the sending pause frame. -++ The unit is the time for transmiting 512 bit data. -++ This value is 16 bit, so its value is 0x0000~0xFFFF. -++ The default value is 0xFFFF. -++ -++config TX_FLOW_CTRL_PAUSE_INTERVAL -++ hex "tx flow ctrl pause interval" -++ default "0xFFFF" -++ help -++ The interval time for sending pause frame. -++ When the remainint amount of receive queue is below tx flow ctrl active threshold, -++ we will wait this time to transmiting pause frame. -++ The unit is the time for transmiting 512 bit data. -++ This value is 16 bit, so its value is 0x0000~0xFFFF. -++ The default value is 0xFFFF. -++ -++config TX_FLOW_CTRL_ACTIVE_THRESHOLD -++ int "tx flow ctrl active threshold" -++ default "16" -++ range 1 127 -++ help -++ 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 smaller than 64. Too bigger is not a good choice. -++ This value must be smaller than tx flow ctrl deactive threshold. -++ -++config TX_FLOW_CTRL_DEACTIVE_THRESHOLD -++ int "tx flow ctrl deactive threshold" -++ default "32" -++ range 1 127 -++ help -++ 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 smaller than 64. Too bigger is not a good choice. -++ This value must be larger than tx flow ctrl active threshold. -++ -++endif # ETH_GMAC -+diff --git a/drivers/net/ethernet/vendor/gmac/Makefile b/drivers/net/ethernet/vendor/gmac/Makefile -+new file mode 100755 -+index 000000000..90d5a73b7 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/Makefile -+@@ -0,0 +1,2 @@ -++obj-$(CONFIG_ETH_GMAC) += eth_gmac.o -++eth_gmac-objs := gmac.o gmac_ethtool_ops.o gmac_phy_fixup.o gmac_pm.o gmac_proc.o gmac_netdev_ops.o autoeee/autoeee.o autoeee/phy_id_table.o -+diff --git a/drivers/net/ethernet/vendor/gmac/autoeee/autoeee.c b/drivers/net/ethernet/vendor/gmac/autoeee/autoeee.c -+new file mode 100755 -+index 000000000..33bd74fff -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/autoeee/autoeee.c -+@@ -0,0 +1,137 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include "autoeee.h" -++#include "../gmac.h" -++#include -++#include -++ -++static u32 set_link_stat(struct gmac_netdev_local const *ld) -++{ -++ u32 link_stat = 0; -++ -++ switch (ld->phy->speed) { -++ case SPEED_10: -++ link_stat |= GMAC_SPD_10M; -++ break; -++ case SPEED_100: -++ link_stat |= GMAC_SPD_100M; -++ break; -++ case SPEED_1000: -++ link_stat |= GMAC_SPD_1000M; -++ break; -++ default: -++ break; -++ } -++ return link_stat; -++} -++ -++static void set_eee_clk(struct gmac_netdev_local const *ld, u32 phy_id) -++{ -++ u32 v; -++ -++ if ((phy_id & REALTEK_PHY_MASK) == REALTEK_PHY_ID_8211E) { -++ v = readl(ld->gmac_iobase + EEE_CLK); -++ v &= ~MASK_EEE_CLK; -++ v |= BIT_DISABLE_TX_CLK; -++ writel(v, ld->gmac_iobase + EEE_CLK); -++ } else if ((phy_id & MICREL_PHY_ID_MASK) == PHY_ID_KSZ9031) { -++ v = readl(ld->gmac_iobase + EEE_CLK); -++ v &= ~MASK_EEE_CLK; -++ v |= (BIT_DISABLE_TX_CLK | BIT_PHY_KSZ9031); -++ writel(v, ld->gmac_iobase + EEE_CLK); -++ } -++} -++ -++static void enable_eee(struct gmac_netdev_local const *ld) -++{ -++ u32 v; -++ -++ /* EEE_1us: 0x7c for 125M */ -++ writel(0x7c, ld->gmac_iobase + -++ EEE_TIME_CLK_CNT); -++ writel(0x1e0400, ld->gmac_iobase + EEE_TIMER); -++ -++ v = readl(ld->gmac_iobase + EEE_LINK_STATUS); -++ v |= 0x3 << 1; /* auto EEE and ... */ -++ v |= BIT_PHY_LINK_STATUS; /* phy linkup */ -++ writel(v, ld->gmac_iobase + EEE_LINK_STATUS); -++ -++ v = readl(ld->gmac_iobase + EEE_ENABLE); -++ v |= BIT_EEE_ENABLE; /* enable EEE */ -++ writel(v, ld->gmac_iobase + EEE_ENABLE); -++} -++ -++static void set_phy_eee_mode(struct gmac_netdev_local const *ld) -++{ -++ u32 v; -++ if (netif_msg_wol(ld)) -++ pr_info("enter phy-EEE mode\n"); -++ -++ v = readl(ld->gmac_iobase + EEE_ENABLE); -++ v &= ~BIT_EEE_ENABLE; /* disable auto-EEE */ -++ writel(v, ld->gmac_iobase + EEE_ENABLE); -++} -++ -++void init_autoeee(struct gmac_netdev_local *ld) -++{ -++ int phy_id; -++ int eee_available, lp_eee_capable; -++ u32 v, link_stat; -++ struct phy_info *phy_info = NULL; -++ if (ld == NULL || ld->eee_init == NULL || ld->phy == NULL) -++ return; -++ phy_id = ld->phy->phy_id; -++ if (ld->eee_init != NULL) -++ goto eee_init; -++ -++ phy_info = phy_search_ids(phy_id); -++ if (phy_info == NULL) -++ goto not_support; -++ -++ eee_available = phy_info->eee_available; -++ if (netif_msg_wol(ld) && phy_info->name != NULL) -++ pr_info("fit phy_id:0x%x, phy_name:%s, eee:%d\n", -++ phy_info->phy_id, phy_info->name, eee_available); -++ -++ if (!eee_available) -++ goto not_support; -++ -++ if (eee_available == PHY_EEE) { -++ set_phy_eee_mode(ld); -++ return; -++ } -++ -++ ld->eee_init = phy_info->eee_init; -++eee_init: -++ link_stat = set_link_stat(ld); -++ -++ lp_eee_capable = ld->eee_init(ld->phy); -++ if (lp_eee_capable < 0) -++ return; -++ -++ if (ld->phy->link) { -++ if (((u32)lp_eee_capable) & link_stat) { -++ set_eee_clk(ld, phy_id); -++ enable_eee(ld); -++ -++ if (netif_msg_wol(ld)) -++ pr_info("enter auto-EEE mode\n"); -++ } else { -++ if (netif_msg_wol(ld)) -++ pr_info("link partner not support EEE\n"); -++ } -++ } else { -++ v = readl(ld->gmac_iobase + EEE_LINK_STATUS); -++ v &= ~(BIT_PHY_LINK_STATUS); /* phy linkdown */ -++ writel(v, ld->gmac_iobase + EEE_LINK_STATUS); -++ } -++ -++ return; -++ -++not_support: -++ ld->eee_init = NULL; -++ if (netif_msg_wol(ld)) -++ pr_info("non-EEE mode\n"); -++} -+diff --git a/drivers/net/ethernet/vendor/gmac/autoeee/autoeee.h b/drivers/net/ethernet/vendor/gmac/autoeee/autoeee.h -+new file mode 100755 -+index 000000000..924cc604b -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/autoeee/autoeee.h -+@@ -0,0 +1,49 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _AUTO_EEE_H -++#define _AUTO_EEE_H -++ -++#include "../gmac.h" -++ -++#define NO_EEE 0 -++#define MAC_EEE 1 -++#define PHY_EEE 2 -++#define PARTNER_EEE 2 -++ -++struct phy_info { -++ char *name; -++ int phy_id; -++ char eee_available; /* eee support by this phy */ -++ int (*eee_init)(struct phy_device *phy_dev); -++}; -++ -++/* GMAC register definition */ -++#define EEE_CLK 0x800 -++#define MASK_EEE_CLK (0x3 << 20) -++#define BIT_DISABLE_TX_CLK BIT(21) -++#define BIT_PHY_KSZ9031 BIT(20) -++#define EEE_ENABLE 0x808 -++#define BIT_EEE_ENABLE BIT(0) -++#define EEE_TIMER 0x80C -++#define EEE_LINK_STATUS 0x810 -++#define BIT_PHY_LINK_STATUS BIT(0) -++#define EEE_TIME_CLK_CNT 0x814 -++ -++/* ----------------------------phy register-------------------------------*/ -++/* MMD: MDIO Manageable Device */ -++#define MACR 0x0D -++#define MAADR 0x0E -++#define EEE_DEV 0x3 -++#define EEE_CAPABILITY 0x14 -++#define EEELPAR_DEV 0x7 -++#define EEELPAR 0x3D /* EEE link partner ability register */ -++#define EEE_ADVERTISE 0x3c -++#define LP_1000BASE_EEE BIT(2) -++#define LP_100BASE_EEE BIT(1) -++ -++struct phy_info *phy_search_ids(int phy_id); -++void init_autoeee(struct gmac_netdev_local *ld); -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/gmac/autoeee/phy_id_table.c b/drivers/net/ethernet/vendor/gmac/autoeee/phy_id_table.c -+new file mode 100755 -+index 000000000..848f0112e -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/autoeee/phy_id_table.c -+@@ -0,0 +1,181 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include "../gmac.h" -++#include "autoeee.h" -++ -++struct phy_info phy_info_table[]; -++ -++struct phy_info *phy_search_ids(int phy_id) -++{ -++ int i; -++ struct phy_info *fit_info = NULL; -++ -++ for (i = 0; phy_info_table[i].name; i++) { -++ if (phy_id == phy_info_table[i].phy_id) { -++ fit_info = &phy_info_table[i]; -++ break; -++ } -++ } -++ -++ return fit_info; -++} -++ -++static inline int phy_mmd_read(struct phy_device *phy_dev, -++ u32 mmd_device, u32 regnum) -++{ -++ phy_write(phy_dev, MACR, mmd_device); /* function = 00 address */ -++ phy_write(phy_dev, MAADR, regnum); -++ phy_write(phy_dev, MACR, 0x4000 | mmd_device); /* function = 01 data */ -++ -++ return phy_read(phy_dev, MAADR); -++} -++ -++static inline int phy_mmd_write(struct phy_device *phy_dev, u32 mmd_device, -++ u32 regnum, u16 val) -++{ -++ phy_write(phy_dev, MACR, mmd_device); /* function = 00 address */ -++ phy_write(phy_dev, MAADR, regnum); -++ phy_write(phy_dev, MACR, 0x4000 | mmd_device); /* function = 01 data */ -++ -++ return phy_write(phy_dev, MAADR, val); -++} -++ -++static int smsc_lan8740_init(struct phy_device *phy_dev) -++{ -++ static int first_time = 0; -++ int v; -++ u32 eee_type = 0; -++ -++ if (!first_time) { -++ /* Realtek LAN 8740 start to enable eee */ -++ int eee_lan; -++ -++ eee_lan = phy_read(phy_dev, 0x10); -++ if (eee_lan < 0) -++ return eee_lan; -++ eee_lan = (u32)eee_lan | 0x4; -++ phy_write(phy_dev, 0x10, eee_lan); -++ eee_lan = phy_read(phy_dev, 0x10); -++ if (eee_lan < 0) -++ return eee_lan; -++ /* auto negotiate after enable eee */ -++ eee_lan = phy_read(phy_dev, 0x0); -++ if (eee_lan < 0) -++ return eee_lan; -++ eee_lan = (u32)eee_lan | 0x200; -++ phy_write(phy_dev, 0x0, eee_lan); -++ first_time = 1; -++ } -++ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); -++ if ((u32)v & LP_1000BASE_EEE) -++ eee_type |= GMAC_SPD_1000M; -++ if ((u32)v & LP_100BASE_EEE) -++ eee_type |= GMAC_SPD_100M; -++ -++ return (int)eee_type; -++} -++ -++#define RTL8211EG_MAC 0 -++#if RTL8211EG_MAC -++static int rtl8211eg_mac_init(struct phy_device *phy_dev) -++{ -++ static int first_time = 0; -++ /* Realtek 8211EG start reset to change eee to mac */ -++ int v; -++ u32 eee_type = 0; -++ -++ if (!first_time) { -++ int tmp; -++ -++ phy_write(phy_dev, 0x1f, 0x0); -++ phy_write(phy_dev, MII_BMCR, BMCR_RESET); /* reset phy */ -++ do { /* wait phy restart over */ -++ udelay(1); -++ tmp = phy_read(phy_dev, MII_BMSR); -++ /* no need to wait AN finished */ -++ tmp &= (BMSR_ANEGCOMPLETE | BMSR_ANEGCAPABLE); -++ } while (!tmp); -++ -++ phy_write(phy_dev, 0x1f, 0x7); -++ phy_write(phy_dev, 0x1e, 0x20); -++ phy_write(phy_dev, 0x1b, 0xa03a); -++ phy_write(phy_dev, 0x1f, 0x0); -++ -++ first_time = 1; -++ } -++ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); -++ if ((u32)v & LP_1000BASE_EEE) -++ eee_type |= GMAC_SPD_1000M; -++ if ((u32)v & LP_100BASE_EEE) -++ eee_type |= GMAC_SPD_100M; -++ -++ return (int)eee_type; -++} -++#else -++static int rtl8211eg_init(struct phy_device *phy_dev) -++{ -++ u32 eee_type = 0; -++ u32 v; -++ -++ v = (u32)phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); -++ if (v & LP_1000BASE_EEE) -++ eee_type |= GMAC_SPD_1000M; -++ if (v & LP_100BASE_EEE) -++ eee_type |= GMAC_SPD_100M; -++ -++ return (int)eee_type; -++} -++#endif -++ -++static int festa_v200_init(struct phy_device *phy_dev) -++{ -++ static int first_time_init = 0; -++ int v; -++ u32 eee_type = 0; -++ -++ if (!first_time_init) { -++ /* EEE_CAPABILITY register: support 100M-BaseT */ -++ v = phy_mmd_read(phy_dev, EEE_DEV, EEE_CAPABILITY); -++ phy_mmd_write(phy_dev, EEE_DEV, EEE_CAPABILITY, -++ ((u32)v) | BIT(1)); -++ -++ /* EEE_ADVERTISEMENT register: advertising 100M-BaseT */ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEE_ADVERTISE); -++ phy_mmd_write(phy_dev, EEELPAR_DEV, EEE_ADVERTISE, -++ ((u32)v) | BIT(1)); -++ -++ v = phy_read(phy_dev, MII_BMCR); -++ if (v < 0) -++ return v; -++ v = (u32)v | (BMCR_ANENABLE | BMCR_ANRESTART); -++ phy_write(phy_dev, MII_BMCR, v); /* auto-neg restart */ -++ -++ first_time_init = 1; -++ } -++ -++ v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR); -++ if ((u32)v & LP_1000BASE_EEE) -++ eee_type |= GMAC_SPD_1000M; -++ if ((u32)v & LP_100BASE_EEE) -++ eee_type |= GMAC_SPD_100M; -++ -++ return (int)eee_type; -++} -++ -++struct phy_info phy_info_table[] = { -++ /* phy_name phy_id eee_available phy_driver */ -++ {"SMSC LAN8740", 0x0007c110, MAC_EEE, &smsc_lan8740_init}, -++#if RTL8211EG_MAC -++ {"Realtek 8211EG", 0x001cc915, MAC_EEE, &rtl8211eg_mac_init}, -++#else -++ {"Realtek 8211EG", 0x001cc915, PHY_EEE, &rtl8211eg_init}, -++#endif -++ {"Festa V200", VENDOR_PHY_ID_FESTAV200, MAC_EEE, &festa_v200_init}, -++}; -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac.c b/drivers/net/ethernet/vendor/gmac/gmac.c -+new file mode 100755 -+index 000000000..b588b2e2d -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac.c -+@@ -0,0 +1,2289 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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 -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include "autoeee/autoeee.h" -++#include "gmac_ethtool_ops.h" -++#include "gmac_netdev_ops.h" -++#include "gmac_phy_fixup.h" -++#include "gmac_pm.h" -++#include "gmac_proc.h" -++#include "gmac.h" -++ -++#define has_tso_cap(hw_cap) ((((hw_cap) >> 28) & 0x3) == VER_TSO) -++#define has_rxhash_cap(hw_cap) ((hw_cap) & BIT(30)) -++#define has_rss_cap(hw_cap) ((hw_cap) & BIT(31)) -++ -++#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) -++static int debug = -1; -++module_param(debug, int, 0000); -++MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); -++ -++static void gmac_set_desc_depth(struct gmac_netdev_local const *priv, -++ u32 rx, u32 tx) -++{ -++ u32 reg, val; -++ int i; -++ -++ writel(BITS_RX_FQ_DEPTH_EN, priv->gmac_iobase + RX_FQ_REG_EN); -++ val = readl(priv->gmac_iobase + RX_FQ_DEPTH); -++ val &= ~Q_ADDR_HI8_MASK; -++ val |= rx << DESC_WORD_SHIFT; -++ writel(val, priv->gmac_iobase + RX_FQ_DEPTH); -++ writel(0, priv->gmac_iobase + RX_FQ_REG_EN); -++ -++ writel(BITS_RX_BQ_DEPTH_EN, priv->gmac_iobase + RX_BQ_REG_EN); -++ val = readl(priv->gmac_iobase + RX_BQ_DEPTH); -++ val &= ~Q_ADDR_HI8_MASK; -++ val |= rx << DESC_WORD_SHIFT; -++ writel(val, priv->gmac_iobase + RX_BQ_DEPTH); -++ for (i = 1; i < priv->num_rxqs; i++) { -++ reg = rx_bq_depth_queue(i); -++ val = readl(priv->gmac_iobase + reg); -++ val &= ~Q_ADDR_HI8_MASK; -++ val |= rx << DESC_WORD_SHIFT; -++ writel(val, priv->gmac_iobase + reg); -++ } -++ writel(0, priv->gmac_iobase + RX_BQ_REG_EN); -++ -++ writel(BITS_TX_BQ_DEPTH_EN, priv->gmac_iobase + TX_BQ_REG_EN); -++ val = readl(priv->gmac_iobase + TX_BQ_DEPTH); -++ val &= ~Q_ADDR_HI8_MASK; -++ val |= tx << DESC_WORD_SHIFT; -++ writel(val, priv->gmac_iobase + TX_BQ_DEPTH); -++ writel(0, priv->gmac_iobase + TX_BQ_REG_EN); -++ -++ writel(BITS_TX_RQ_DEPTH_EN, priv->gmac_iobase + TX_RQ_REG_EN); -++ val = readl(priv->gmac_iobase + TX_RQ_DEPTH); -++ val &= ~Q_ADDR_HI8_MASK; -++ val |= tx << DESC_WORD_SHIFT; -++ writel(val, priv->gmac_iobase + TX_RQ_DEPTH); -++ writel(0, priv->gmac_iobase + TX_RQ_REG_EN); -++} -++ -++static void gmac_set_rx_fq(struct gmac_netdev_local const *priv, -++ dma_addr_t phy_addr) -++{ -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ u32 val; -++#endif -++ writel(BITS_RX_FQ_START_ADDR_EN, priv->gmac_iobase + RX_FQ_REG_EN); -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ val = readl(priv->gmac_iobase + RX_FQ_DEPTH); -++ val &= Q_ADDR_HI8_MASK; -++ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; -++ writel(val, priv->gmac_iobase + RX_FQ_DEPTH); -++#endif -++ writel((u32)phy_addr, priv->gmac_iobase + RX_FQ_START_ADDR); -++ writel(0, priv->gmac_iobase + RX_FQ_REG_EN); -++} -++ -++static void gmac_set_rx_bq(struct gmac_netdev_local const *priv, -++ dma_addr_t phy_addr) -++{ -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ u32 val; -++#endif -++ -++ writel(BITS_RX_BQ_START_ADDR_EN, priv->gmac_iobase + RX_BQ_REG_EN); -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ val = readl(priv->gmac_iobase + RX_BQ_DEPTH); -++ val &= Q_ADDR_HI8_MASK; -++ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; -++ writel(val, priv->gmac_iobase + RX_BQ_DEPTH); -++#endif -++ writel((u32)phy_addr, priv->gmac_iobase + RX_BQ_START_ADDR); -++ writel(0, priv->gmac_iobase + RX_BQ_REG_EN); -++} -++ -++static void gmac_set_tx_bq(struct gmac_netdev_local const *priv, -++ dma_addr_t phy_addr) -++{ -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ u32 val; -++#endif -++ writel(BITS_TX_BQ_START_ADDR_EN, priv->gmac_iobase + TX_BQ_REG_EN); -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ val = readl(priv->gmac_iobase + TX_BQ_DEPTH); -++ val &= Q_ADDR_HI8_MASK; -++ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; -++ writel(val, priv->gmac_iobase + TX_BQ_DEPTH); -++#endif -++ writel((u32)phy_addr, priv->gmac_iobase + TX_BQ_START_ADDR); -++ writel(0, priv->gmac_iobase + TX_BQ_REG_EN); -++} -++ -++static void gmac_set_tx_rq(struct gmac_netdev_local const *priv, -++ dma_addr_t phy_addr) -++{ -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ u32 val; -++#endif -++ writel(BITS_TX_RQ_START_ADDR_EN, priv->gmac_iobase + TX_RQ_REG_EN); -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ val = readl(priv->gmac_iobase + TX_RQ_DEPTH); -++ val &= Q_ADDR_HI8_MASK; -++ val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET; -++ writel(val, priv->gmac_iobase + TX_RQ_DEPTH); -++#endif -++ writel((u32)phy_addr, priv->gmac_iobase + TX_RQ_START_ADDR); -++ writel(0, priv->gmac_iobase + TX_RQ_REG_EN); -++} -++ -++static void gmac_hw_set_desc_addr(struct gmac_netdev_local const *priv) -++{ -++ u32 reg; -++ int i; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ u32 val; -++#endif -++ -++ gmac_set_rx_fq(priv, priv->RX_FQ.phys_addr); -++ gmac_set_rx_bq(priv, priv->RX_BQ.phys_addr); -++ gmac_set_tx_rq(priv, priv->TX_RQ.phys_addr); -++ gmac_set_tx_bq(priv, priv->TX_BQ.phys_addr); -++ -++ for (i = 1; i < priv->num_rxqs; i++) { -++ reg = rx_bq_depth_queue(i); -++ /* -++ * Logical limitation: We must enable BITS_RX_BQ_DEPTH_EN -++ * to write rx_bq_start_addr_39to32 successfully. -++ */ -++ writel(BITS_RX_BQ_START_ADDR_EN | BITS_RX_BQ_DEPTH_EN, -++ priv->gmac_iobase + RX_BQ_REG_EN); -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ val = readl(priv->gmac_iobase + reg); -++ val &= Q_ADDR_HI8_MASK; -++ val |= ((priv->pool[BASE_QUEUE_NUMS + i].phys_addr) >> REG_BIT_WIDTH) << -++ Q_ADDR_HI8_OFFSET; -++ writel(val, priv->gmac_iobase + reg); -++#endif -++ reg = (u32)rx_bq_start_addr_queue(i); -++ /* pool 3 add i */ -++ writel((u32)(priv->pool[BASE_QUEUE_NUMS + i].phys_addr), -++ priv->gmac_iobase + reg); -++ writel(0, priv->gmac_iobase + RX_BQ_REG_EN); -++ } -++} -++ -++static void gmac_set_rss_cap(struct gmac_netdev_local const *priv) -++{ -++ u32 val = 0; -++ -++ if (priv->has_rxhash_cap) -++ val |= BIT_RXHASH_CAP; -++ if (priv->has_rss_cap) -++ val |= BIT_RSS_CAP; -++ writel(val, priv->gmac_iobase + HW_CAP_EN); -++} -++ -++static void gmac_hw_init(struct gmac_netdev_local *priv) -++{ -++ u32 val; -++ u32 reg; -++ int i; -++ -++ /* disable and clear all interrupts */ -++ writel(0, priv->gmac_iobase + ENA_PMU_INT); -++ writel(~0, priv->gmac_iobase + RAW_PMU_INT); -++ -++ for (i = 1; i < priv->num_rxqs; i++) { -++ reg = (u32)rss_ena_int_queue(i); -++ writel(0, priv->gmac_iobase + reg); -++ } -++ writel(~0, priv->gmac_iobase + RSS_RAW_PMU_INT); -++ -++ /* enable CRC erro packets filter */ -++ val = readl(priv->gmac_iobase + REC_FILT_CONTROL); -++ val |= BIT_CRC_ERR_PASS; -++ writel(val, priv->gmac_iobase + REC_FILT_CONTROL); -++ -++ /* set tx min packet length */ -++ val = readl(priv->gmac_iobase + CRF_MIN_PACKET); -++ val &= ~BIT_MASK_TX_MIN_LEN; -++ val |= ETH_HLEN << BIT_OFFSET_TX_MIN_LEN; -++ writel(val, priv->gmac_iobase + CRF_MIN_PACKET); -++ -++ /* fix bug for udp and ip error check */ -++ writel(CONTROL_WORD_CONFIG, priv->gmac_iobase + CONTROL_WORD); -++ -++ writel(0, priv->gmac_iobase + COL_SLOT_TIME); -++ -++ writel(DUPLEX_HALF, priv->gmac_iobase + MAC_DUPLEX_HALF_CTRL); -++ -++ /* interrupt when rcv packets >= RX_BQ_INT_THRESHOLD */ -++ val = RX_BQ_INT_THRESHOLD | -++ (TX_RQ_INT_THRESHOLD << BITS_OFFSET_TX_RQ_IN_TH); -++ writel(val, priv->gmac_iobase + IN_QUEUE_TH); -++ -++ /* RX_BQ/TX_RQ in timeout threshold */ -++ writel(0x10000, priv->gmac_iobase + RX_BQ_IN_TIMEOUT_TH); -++ -++ writel(0x18000, priv->gmac_iobase + TX_RQ_IN_TIMEOUT_TH); -++ -++ gmac_set_desc_depth(priv, RX_DESC_NUM, TX_DESC_NUM); -++} -++ -++/* -++ * the func stop the hw desc and relaim the software skb resource -++ * before reusing the gmac, you'd better reset the gmac -++ */ -++static void gmac_reclaim_rx_tx_resource(struct gmac_netdev_local *ld) -++{ -++ unsigned long rxflags, txflags; -++ int rd_offset, wr_offset; -++ int i; -++ -++ if (ld == NULL) -++ return; -++ -++ gmac_irq_disable_all_queue(ld); -++ gmac_hw_desc_disable(ld); -++ writel(STOP_RX_TX, ld->gmac_iobase + STOP_CMD); -++ -++ spin_lock_irqsave(&ld->rxlock, rxflags); -++ /* RX_BQ: logic write pointer */ -++ wr_offset = readl(ld->gmac_iobase + RX_BQ_WR_ADDR); -++ /* prevent to reclaim skb in rx bottom half */ -++ writel(wr_offset, ld->gmac_iobase + RX_BQ_RD_ADDR); -++ -++ for (i = 1; i < ld->num_rxqs; i++) { -++ u32 rx_bq_wr_reg, rx_bq_rd_reg; -++ -++ rx_bq_wr_reg = rx_bq_wr_addr_queue(i); -++ rx_bq_rd_reg = rx_bq_rd_addr_queue(i); -++ -++ wr_offset = readl(ld->gmac_iobase + rx_bq_wr_reg); -++ writel(wr_offset, ld->gmac_iobase + rx_bq_rd_reg); -++ } -++ -++ /* RX_FQ: logic read pointer */ -++ rd_offset = readl(ld->gmac_iobase + RX_FQ_RD_ADDR); -++ if (rd_offset == 0) -++ rd_offset = (RX_DESC_NUM - 1) << DESC_BYTE_SHIFT; -++ else -++ rd_offset -= DESC_SIZE; -++ /* stop to feed hw desc */ -++ writel(rd_offset, ld->gmac_iobase + RX_FQ_WR_ADDR); -++ -++ for (i = 0; i < ld->RX_FQ.count; i++) { -++ if (!ld->RX_FQ.skb[i]) -++ ld->RX_FQ.skb[i] = SKB_MAGIC; -++ } -++ spin_unlock_irqrestore(&ld->rxlock, rxflags); -++ -++ /* -++ * no need to wait pkts in TX_RQ finish to free all skb, -++ * because gmac_xmit_reclaim is in the tx_lock, -++ */ -++ spin_lock_irqsave(&ld->txlock, txflags); -++ /* TX_RQ: logic write */ -++ wr_offset = readl(ld->gmac_iobase + TX_RQ_WR_ADDR); -++ /* stop to reclaim tx skb */ -++ writel(wr_offset, ld->gmac_iobase + TX_RQ_RD_ADDR); -++ -++ /* TX_BQ: logic read */ -++ rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR); -++ if (rd_offset == 0) -++ rd_offset = (TX_DESC_NUM - 1) << DESC_BYTE_SHIFT; -++ else -++ rd_offset -= DESC_SIZE; -++ /* stop software tx skb */ -++ writel(rd_offset, ld->gmac_iobase + TX_BQ_WR_ADDR); -++ -++ for (i = 0; i < ld->TX_BQ.count; i++) { -++ if (!ld->TX_BQ.skb[i]) -++ ld->TX_BQ.skb[i] = SKB_MAGIC; -++ } -++ spin_unlock_irqrestore(&ld->txlock, txflags); -++} -++ -++void gmac_hw_set_mac_addr(struct net_device *dev) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(dev); -++ unsigned char *mac = dev->dev_addr; -++ u32 val; -++ -++ val = mac[1] | (mac[0] << 8); /* mac[1]->(7, 0) mac[0]->(15, 8) */ -++ writel(val, priv->gmac_iobase + STATION_ADDR_HIGH); -++ val = mac[5] | (mac[4] << 8) | /* mac[5]->(7, 0) mac[4]->(8, 15) */ -++ (mac[3] << 16) | (mac[2] << 24); /* mac[3]->(23, 16) mac[2]->(31, 24) */ -++ writel(val, priv->gmac_iobase + STATION_ADDR_LOW); -++} -++ -++static void gmac_free_rx_skb(struct gmac_netdev_local const *ld) -++{ -++ struct sk_buff *skb = NULL; -++ int i; -++ -++ for (i = 0; i < ld->RX_FQ.count; i++) { -++ skb = ld->RX_FQ.skb[i]; -++ if (skb != NULL) { -++ ld->rx_skb[i] = NULL; -++ ld->RX_FQ.skb[i] = NULL; -++ if (skb == SKB_MAGIC) -++ continue; -++ dev_kfree_skb_any(skb); -++ /* -++ * need to unmap the skb here -++ * but there is no way to get the dma_addr here, -++ * and unmap(TO_DEVICE) ops do nothing in fact, -++ * so we ignore to call -++ * dma_unmap_single(dev, dma_addr, skb->len, -++ * DMA_TO_DEVICE) -++ */ -++ } -++ } -++} -++ -++static void gmac_free_tx_skb(struct gmac_netdev_local const *ld) -++{ -++ struct sk_buff *skb = NULL; -++ int i; -++ -++ for (i = 0; i < ld->TX_BQ.count; i++) { -++ skb = ld->TX_BQ.skb[i]; -++ if (skb != NULL) { -++ ld->tx_skb[i] = NULL; -++ ld->TX_BQ.skb[i] = NULL; -++ if (skb == SKB_MAGIC) -++ continue; -++ netdev_completed_queue(ld->netdev, 1, skb->len); -++ dev_kfree_skb_any(skb); -++ } -++ } -++} -++ -++/* board related func */ -++static void gmac_mac_core_reset(struct gmac_netdev_local const *priv) -++{ -++ /* undo reset */ -++ if (priv == NULL || priv->port_rst == NULL) -++ return; -++ reset_control_deassert(priv->port_rst); -++ usleep_range(50, 60); /* wait 50~60us */ -++ -++ /* soft reset mac port */ -++ reset_control_assert(priv->port_rst); -++ usleep_range(50, 60); /* wait 50~60us */ -++ /* undo reset */ -++ reset_control_deassert(priv->port_rst); -++} -++ -++/* reset and re-config gmac */ -++static void gmac_restart(struct gmac_netdev_local *ld) -++{ -++ unsigned long rxflags, txflags; -++ -++ if (ld == NULL || ld->netdev == NULL) -++ return; -++ /* restart hw engine now */ -++ gmac_mac_core_reset(ld); -++ -++ spin_lock_irqsave(&ld->rxlock, rxflags); -++ spin_lock_irqsave(&ld->txlock, txflags); -++ -++ gmac_free_rx_skb(ld); -++ gmac_free_tx_skb(ld); -++ -++ pmt_reg_restore(ld); -++ gmac_hw_init(ld); -++ gmac_hw_set_mac_addr(ld->netdev); -++ gmac_hw_set_desc_addr(ld); -++ -++ /* we don't set macif here, it will be set in adjust_link */ -++ if (netif_running(ld->netdev)) { -++ /* -++ * when resume, only do the following operations -++ * when dev is up before suspend. -++ */ -++ gmac_rx_refill(ld); -++ gmac_set_multicast_list(ld->netdev); -++ -++ gmac_hw_desc_enable(ld); -++ gmac_port_enable(ld); -++ gmac_irq_enable_all_queue(ld); -++ } -++ spin_unlock_irqrestore(&ld->txlock, txflags); -++ spin_unlock_irqrestore(&ld->rxlock, rxflags); -++} -++ -++#define GMAC_LINK_CHANGE_PROTECT -++#define GMAC_MAC_TX_RESET_IN_LINKUP -++ -++#ifdef GMAC_LINK_CHANGE_PROTECT -++#define GMAC_MS_TO_NS (1000000ULL) -++#define GMAC_FLUSH_WAIT_TIME (100*GMAC_MS_TO_NS) -++/* protect code */ -++static void gmac_linkup_flush(struct gmac_netdev_local const *ld) -++{ -++ int tx_bq_wr_offset, tx_bq_rd_offset; -++ unsigned long long time_limit, time_now; -++ -++ time_now = sched_clock(); -++ time_limit = time_now + GMAC_FLUSH_WAIT_TIME; -++ -++ do { -++ tx_bq_wr_offset = readl(ld->gmac_iobase + TX_BQ_WR_ADDR); -++ tx_bq_rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR); -++ -++ time_now = sched_clock(); -++ if (unlikely(((long long)time_now - (long long)time_limit) >= 0)) -++ break; -++ } while (tx_bq_rd_offset != tx_bq_wr_offset); -++ -++ mdelay(1); -++} -++#endif -++ -++#ifdef GMAC_MAC_TX_RESET_IN_LINKUP -++static void gmac_mac_tx_state_engine_reset(struct gmac_netdev_local const *priv) -++{ -++ u32 val; -++ val = readl(priv->gmac_iobase + MAC_CLEAR); -++ val |= BIT_TX_SOFT_RESET; -++ writel(val, priv->gmac_iobase + MAC_CLEAR); -++ -++ mdelay(5); /* wait 5ms */ -++ -++ val = readl(priv->gmac_iobase + MAC_CLEAR); -++ val &= ~BIT_TX_SOFT_RESET; -++ writel(val, priv->gmac_iobase + MAC_CLEAR); -++} -++#endif -++ -++static void gmac_config_port(struct net_device const *dev, u32 speed, u32 duplex) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(dev); -++ u32 val; -++ -++ switch (priv->phy_mode) { -++ case PHY_INTERFACE_MODE_RGMII: -++ case PHY_INTERFACE_MODE_RGMII_ID: -++ case PHY_INTERFACE_MODE_RGMII_RXID: -++ case PHY_INTERFACE_MODE_RGMII_TXID: -++ if (speed == SPEED_1000) -++ val = RGMII_SPEED_1000; -++ else if (speed == SPEED_100) -++ val = RGMII_SPEED_100; -++ else -++ val = RGMII_SPEED_10; -++ break; -++ case PHY_INTERFACE_MODE_MII: -++ if (speed == SPEED_100) -++ val = MII_SPEED_100; -++ else -++ val = MII_SPEED_10; -++ break; -++ case PHY_INTERFACE_MODE_RMII: -++ if (speed == SPEED_100) -++ val = RMII_SPEED_100; -++ else -++ val = RMII_SPEED_10; -++ break; -++ default: -++ netdev_warn(dev, "not supported mode\n"); -++ val = MII_SPEED_10; -++ break; -++ } -++ -++ if (duplex) -++ val |= GMAC_FULL_DUPLEX; -++ -++ reset_control_assert(priv->macif_rst); -++ writel_relaxed(val, priv->macif_base); -++ reset_control_deassert(priv->macif_rst); -++ -++ writel_relaxed(BIT_MODE_CHANGE_EN, priv->gmac_iobase + MODE_CHANGE_EN); -++ if (speed == SPEED_1000) -++ val = GMAC_SPEED_1000; -++ else if (speed == SPEED_100) -++ val = GMAC_SPEED_100; -++ else -++ val = GMAC_SPEED_10; -++ writel_relaxed(val, priv->gmac_iobase + PORT_MODE); -++ writel_relaxed(0, priv->gmac_iobase + MODE_CHANGE_EN); -++ writel_relaxed(duplex, priv->gmac_iobase + MAC_DUPLEX_HALF_CTRL); -++} -++ -++static unsigned int flow_ctrl_en = FLOW_OFF; -++static int tx_flow_ctrl_pause_time = CONFIG_TX_FLOW_CTRL_PAUSE_TIME; -++static int tx_flow_ctrl_pause_interval = CONFIG_TX_FLOW_CTRL_PAUSE_INTERVAL; -++static int tx_flow_ctrl_active_threshold = CONFIG_TX_FLOW_CTRL_ACTIVE_THRESHOLD; -++static int tx_flow_ctrl_deactive_threshold = -++ CONFIG_TX_FLOW_CTRL_DEACTIVE_THRESHOLD; -++ -++static void gmac_set_flow_ctrl_args(struct gmac_netdev_local *ld) -++{ -++ if (ld == NULL) -++ return; -++ ld->flow_ctrl = flow_ctrl_en; -++ ld->pause = tx_flow_ctrl_pause_time; -++ ld->pause_interval = tx_flow_ctrl_pause_interval; -++ ld->flow_ctrl_active_threshold = tx_flow_ctrl_active_threshold; -++ ld->flow_ctrl_deactive_threshold = tx_flow_ctrl_deactive_threshold; -++} -++ -++static void gmac_set_flow_ctrl_params(struct gmac_netdev_local const *ld) -++{ -++ unsigned int rx_fq_empty_th; -++ unsigned int rx_fq_full_th; -++ unsigned int rx_bq_empty_th; -++ unsigned int rx_bq_full_th; -++ unsigned int rec_filter; -++ if (ld == NULL) -++ return; -++ writel(ld->pause, ld->gmac_iobase + FC_TX_TIMER); -++ writel(ld->pause_interval, ld->gmac_iobase + PAUSE_THR); -++ -++ rx_fq_empty_th = readl(ld->gmac_iobase + RX_FQ_ALEMPTY_TH); -++ rx_fq_empty_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); -++ rx_fq_empty_th |= (ld->flow_ctrl_active_threshold << -++ BITS_Q_PAUSE_TH_OFFSET); -++ writel(rx_fq_empty_th, ld->gmac_iobase + RX_FQ_ALEMPTY_TH); -++ -++ rx_fq_full_th = readl(ld->gmac_iobase + RX_FQ_ALFULL_TH); -++ rx_fq_full_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); -++ rx_fq_full_th |= (ld->flow_ctrl_deactive_threshold << -++ BITS_Q_PAUSE_TH_OFFSET); -++ writel(rx_fq_full_th, ld->gmac_iobase + RX_FQ_ALFULL_TH); -++ -++ rx_bq_empty_th = readl(ld->gmac_iobase + RX_BQ_ALEMPTY_TH); -++ rx_bq_empty_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); -++ rx_bq_empty_th |= (ld->flow_ctrl_active_threshold << -++ BITS_Q_PAUSE_TH_OFFSET); -++ writel(rx_bq_empty_th, ld->gmac_iobase + RX_BQ_ALEMPTY_TH); -++ -++ rx_bq_full_th = readl(ld->gmac_iobase + RX_BQ_ALFULL_TH); -++ rx_bq_full_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET); -++ rx_bq_full_th |= (ld->flow_ctrl_deactive_threshold << -++ BITS_Q_PAUSE_TH_OFFSET); -++ writel(rx_bq_full_th, ld->gmac_iobase + RX_BQ_ALFULL_TH); -++ -++ writel(0, ld->gmac_iobase + CRF_TX_PAUSE); -++ -++ rec_filter = readl(ld->gmac_iobase + REC_FILT_CONTROL); -++ rec_filter |= BIT_PAUSE_FRM_PASS; -++ writel(rec_filter, ld->gmac_iobase + REC_FILT_CONTROL); -++} -++ -++void gmac_set_flow_ctrl_state(struct gmac_netdev_local const *ld, int pause) -++{ -++ unsigned int flow_rx_q_en; -++ unsigned int flow; -++ if (ld == NULL) -++ return; -++ flow_rx_q_en = readl(ld->gmac_iobase + RX_PAUSE_EN); -++ flow_rx_q_en &= ~(BIT_RX_FQ_PAUSE_EN | BIT_RX_BQ_PAUSE_EN); -++ if (pause && (ld->flow_ctrl & FLOW_TX)) -++ flow_rx_q_en |= (BIT_RX_FQ_PAUSE_EN | BIT_RX_BQ_PAUSE_EN); -++ writel(flow_rx_q_en, ld->gmac_iobase + RX_PAUSE_EN); -++ -++ flow = readl(ld->gmac_iobase + PAUSE_EN); -++ flow &= ~(BIT_RX_FDFC | BIT_TX_FDFC); -++ if (pause) { -++ if (ld->flow_ctrl & FLOW_RX) -++ flow |= BIT_RX_FDFC; -++ if (ld->flow_ctrl & FLOW_TX) -++ flow |= BIT_TX_FDFC; -++ } -++ writel(flow, ld->gmac_iobase + PAUSE_EN); -++} -++ -++static void gmac_adjust_link(struct net_device *dev) -++{ -++ struct gmac_netdev_local *priv = NULL; -++ struct phy_device *phy = NULL; -++ bool link_status_changed = false; -++ if (dev == NULL) -++ return; -++ priv = netdev_priv(dev); -++ if (priv == NULL || priv->phy == NULL) -++ return; -++ phy = priv->phy; -++ if (phy->link) { -++ if ((priv->old_speed != phy->speed) || -++ (priv->old_duplex != phy->duplex)) { -++#ifdef GMAC_LINK_CHANGE_PROTECT -++ unsigned long txflags; -++ -++ spin_lock_irqsave(&priv->txlock, txflags); -++ -++ gmac_linkup_flush(priv); -++#endif -++ gmac_config_port(dev, phy->speed, phy->duplex); -++#ifdef GMAC_MAC_TX_RESET_IN_LINKUP -++ gmac_mac_tx_state_engine_reset(priv); -++#endif -++#ifdef GMAC_LINK_CHANGE_PROTECT -++ spin_unlock_irqrestore(&priv->txlock, txflags); -++#endif -++ gmac_set_flow_ctrl_state(priv, phy->pause); -++ -++ if (priv->autoeee) -++ init_autoeee(priv); -++ -++ link_status_changed = true; -++ priv->old_link = 1; -++ priv->old_speed = phy->speed; -++ priv->old_duplex = phy->duplex; -++ } -++ } else if (priv->old_link) { -++ link_status_changed = true; -++ priv->old_link = 0; -++ netif_carrier_off(dev); -++ priv->old_speed = SPEED_UNKNOWN; -++ priv->old_duplex = DUPLEX_UNKNOWN; -++ } -++ -++ if (link_status_changed && netif_msg_link(priv)) -++ phy_print_status(phy); -++} -++ -++static int gmac_init_sg_desc_queue(struct gmac_netdev_local *ld) -++{ -++ ld->sg_count = ld->TX_BQ.count + GMAC_SG_DESC_ADD; -++ ld->dma_sg_desc = (struct sg_desc *)dma_alloc_coherent(ld->dev, -++ ld->sg_count * sizeof(struct sg_desc), -++ &ld->dma_sg_phy, GFP_KERNEL); -++ -++ if (ld->dma_sg_desc == NULL) { -++ pr_err("alloc sg desc dma error!\n"); -++ return -ENOMEM; -++ } -++ -++ ld->sg_head = 0; -++ ld->sg_tail = 0; -++ -++ return 0; -++} -++ -++static void gmac_destroy_sg_desc_queue(struct gmac_netdev_local *ld) -++{ -++ if (ld->dma_sg_desc) { -++ dma_free_coherent(ld->dev, -++ ld->sg_count * sizeof(struct sg_desc), -++ ld->dma_sg_desc, ld->dma_sg_phy); -++ ld->dma_sg_desc = NULL; -++ } -++} -++ -++static bool gmac_rx_fq_empty(struct gmac_netdev_local const *priv) -++{ -++ u32 start, end; -++ -++ start = readl(priv->gmac_iobase + RX_FQ_WR_ADDR); -++ end = readl(priv->gmac_iobase + RX_FQ_RD_ADDR); -++ if (start == end) -++ return true; -++ else -++ return false; -++} -++ -++static bool gmac_rxq_has_packets(struct gmac_netdev_local const *priv, int rxq_id) -++{ -++ u32 rx_bq_rd_reg, rx_bq_wr_reg; -++ u32 start, end; -++ -++ rx_bq_rd_reg = rx_bq_rd_addr_queue(rxq_id); -++ rx_bq_wr_reg = rx_bq_wr_addr_queue(rxq_id); -++ -++ start = readl(priv->gmac_iobase + rx_bq_rd_reg); -++ end = readl(priv->gmac_iobase + rx_bq_wr_reg); -++ if (start == end) -++ return false; -++ else -++ return true; -++} -++ -++static void gmac_trace(int level, const char *fmt, ...) -++{ -++ if (level >= GMAC_TRACE_LEVEL) { -++ va_list args; -++ va_start(args, fmt); -++ printk("gmac_trace:"); -++ printk(fmt, args); -++ printk("\n"); -++ va_end(args); -++ } -++} -++ -++static void gmac_monitor_func(struct timer_list *t) -++{ -++ struct gmac_netdev_local *ld = from_timer(ld, t, monitor); -++ struct net_device *dev = NULL; -++ u32 refill_cnt; -++ -++ if (ld == NULL) { -++ gmac_trace(GMAC_NORMAL_LEVEL, "ld is null"); -++ return; -++ } -++ -++ if (ld->netdev == NULL) { -++ gmac_trace(GMAC_NORMAL_LEVEL, "ld->netdev is null"); -++ return; -++ } -++ dev_hold(ld->netdev); -++ dev = ld->netdev; -++ if (!netif_running(dev)) { -++ dev_put(dev); -++ gmac_trace(GMAC_NORMAL_LEVEL, "network driver is stopped"); -++ return; -++ } -++ dev_put(dev); -++ -++ spin_lock(&ld->rxlock); -++ refill_cnt = gmac_rx_refill(ld); -++ if (!refill_cnt && gmac_rx_fq_empty(ld)) { -++ int rxq_id; -++ -++ for (rxq_id = 0; rxq_id < ld->num_rxqs; rxq_id++) { -++ if (gmac_rxq_has_packets(ld, rxq_id)) -++ napi_schedule(&ld->q_napi[rxq_id].napi); -++ } -++ } -++ spin_unlock(&ld->rxlock); -++ -++ ld->monitor.expires = jiffies + GMAC_MONITOR_TIMER; -++ mod_timer(&ld->monitor, ld->monitor.expires); -++} -++ -++u32 gmac_rx_refill(struct gmac_netdev_local *priv) -++{ -++ struct gmac_desc *desc = NULL; -++ struct sk_buff *skb = NULL; -++ struct cyclic_queue_info dma_info; -++ u32 len = ETH_MAX_FRAME_SIZE; -++ dma_addr_t addr; -++ u32 refill_cnt = 0; -++ u32 i; -++ /* software write pointer */ -++ dma_info.start = dma_cnt(readl(priv->gmac_iobase + RX_FQ_WR_ADDR)); -++ /* logic read pointer */ -++ dma_info.end = dma_cnt(readl(priv->gmac_iobase + RX_FQ_RD_ADDR)); -++ dma_info.num = CIRC_SPACE(dma_info.start, dma_info.end, RX_DESC_NUM); -++ -++ for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) { -++ if (priv->RX_FQ.skb[dma_info.pos] || priv->rx_skb[dma_info.pos]) -++ break; -++ -++ skb = netdev_alloc_skb_ip_align(priv->netdev, len); -++ if (unlikely(skb == NULL)) -++ break; -++ -++ 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; -++ } -++ -++ desc = priv->RX_FQ.desc + dma_info.pos; -++ desc->data_buff_addr = (u32)addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ desc->reserve31 = addr >> REG_BIT_WIDTH; -++#endif -++ priv->RX_FQ.skb[dma_info.pos] = skb; -++ priv->rx_skb[dma_info.pos] = skb; -++ -++ desc->buffer_len = len - 1; -++ desc->data_len = 0; -++ desc->fl = 0; -++ desc->descvid = DESC_VLD_FREE; -++ desc->skb_id = dma_info.pos; -++ -++ refill_cnt++; -++ dma_info.pos = dma_ring_incr(dma_info.pos, RX_DESC_NUM); -++ } -++ -++ /* -++ * This barrier is important here. It is required to ensure -++ * the ARM CPU flushes it's DMA write buffers before proceeding -++ * to the next instruction, to ensure that GMAC will see -++ * our descriptor changes in memory -++ */ -++ gmac_sync_barrier(); -++ -++ if (dma_info.pos != dma_info.start) -++ writel(dma_byte(dma_info.pos), priv->gmac_iobase + RX_FQ_WR_ADDR); -++ -++ return refill_cnt; -++} -++ -++static int gmac_rx_checksum(struct net_device *dev, struct sk_buff *skb, -++ struct gmac_desc const *desc) -++{ -++ int hdr_csum_done, payload_csum_done; -++ int hdr_csum_err, payload_csum_err; -++ if (skb == NULL || desc == NULL || dev == NULL) -++ return -EINVAL; -++ if (dev->features & NETIF_F_RXCSUM) { -++ hdr_csum_done = desc->header_csum_done; -++ payload_csum_done = desc->payload_csum_done; -++ hdr_csum_err = desc->header_csum_err; -++ payload_csum_err = desc->payload_csum_err; -++ -++ if (hdr_csum_done && payload_csum_done) { -++ if (unlikely(hdr_csum_err || payload_csum_err)) { -++ dev->stats.rx_errors++; -++ dev->stats.rx_crc_errors++; -++ dev_kfree_skb_any(skb); -++ return -1; -++ } else { -++ skb->ip_summed = CHECKSUM_UNNECESSARY; -++ } -++ } -++ } -++ return 0; -++} -++ -++static void gmac_rx_skbput(struct net_device *dev, struct sk_buff *skb, -++ struct gmac_desc const *desc, int rxq_id) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ dma_addr_t addr; -++ u32 len; -++ int ret; -++ -++ len = desc->data_len; -++ -++ addr = desc->data_buff_addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ addr |= (dma_addr_t)(desc->reserve31) << REG_BIT_WIDTH; -++#endif -++ dma_unmap_single(ld->dev, addr, ETH_MAX_FRAME_SIZE, DMA_FROM_DEVICE); -++ -++ if ((addr & NET_IP_ALIGN) == 0) -++ skb_reserve(skb, 2); /* 2:NET_IP_ALIGN */ -++ -++ skb_put(skb, len); -++ if (skb->len > ETH_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); -++ return; -++ } -++ -++ skb->protocol = eth_type_trans(skb, dev); -++ skb->ip_summed = CHECKSUM_NONE; -++ -++#if defined(CONFIG_GMAC_RXCSUM) -++ ret = gmac_rx_checksum(dev, skb, desc); -++ if (unlikely(ret)) -++ return; -++#endif -++ if ((dev->features & NETIF_F_RXHASH) && desc->has_hash) -++ skb_set_hash(skb, desc->rxhash, desc->l3_hash ? -++ PKT_HASH_TYPE_L3 : PKT_HASH_TYPE_L4); -++ -++ skb_record_rx_queue(skb, rxq_id); -++ -++ napi_gro_receive(&ld->q_napi[rxq_id].napi, skb); -++ dev->stats.rx_packets++; -++ dev->stats.rx_bytes += len; -++} -++ -++static int gmac_rx_skb(struct net_device *dev, struct gmac_desc *desc, -++ u16 skb_id, int rxq_id) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ struct sk_buff *skb = NULL; -++ -++ spin_lock(&ld->rxlock); -++ skb = ld->rx_skb[skb_id]; -++ if (unlikely(skb == NULL)) { -++ spin_unlock(&ld->rxlock); -++ netdev_err(dev, "inconsistent rx_skb\n"); -++ return -1; -++ } -++ -++ /* data consistent check */ -++ if (unlikely(skb != ld->RX_FQ.skb[skb_id])) { -++ netdev_err(dev, "desc->skb(0x%p),RX_FQ.skb[%d](0x%p)\n", -++ skb, skb_id, ld->RX_FQ.skb[skb_id]); -++ if (ld->RX_FQ.skb[skb_id] == SKB_MAGIC) { -++ spin_unlock(&ld->rxlock); -++ return 0; -++ } -++ WARN_ON(1); -++ } else { -++ ld->RX_FQ.skb[skb_id] = NULL; -++ } -++ spin_unlock(&ld->rxlock); -++ -++ gmac_rx_skbput(dev, skb, desc, rxq_id); -++ return 0; -++} -++ -++static int gmac_rx(struct net_device *dev, int limit, int rxq_id) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ struct gmac_desc *desc = NULL; -++ struct cyclic_queue_info dma_info; -++ u32 rx_bq_rd_reg, rx_bq_wr_reg; -++ u16 skb_id; -++ u32 i; -++ -++ rx_bq_rd_reg = rx_bq_rd_addr_queue(rxq_id); -++ rx_bq_wr_reg = rx_bq_wr_addr_queue(rxq_id); -++ -++ /* software read pointer */ -++ dma_info.start = dma_cnt(readl(ld->gmac_iobase + rx_bq_rd_reg)); -++ /* logic write pointer */ -++ dma_info.end = dma_cnt(readl(ld->gmac_iobase + rx_bq_wr_reg)); -++ dma_info.num = CIRC_CNT(dma_info.end, dma_info.start, RX_DESC_NUM); -++ if (dma_info.num > limit) -++ dma_info.num = limit; -++ -++ /* ensure get updated desc */ -++ rmb(); -++ for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) { -++ if (rxq_id) -++ desc = ld->pool[BASE_QUEUE_NUMS + rxq_id].desc + dma_info.pos; -++ else -++ desc = ld->RX_BQ.desc + dma_info.pos; -++ skb_id = desc->skb_id; -++ -++ if (unlikely(gmac_rx_skb(dev, desc, skb_id, rxq_id))) -++ break; -++ -++ spin_lock(&ld->rxlock); -++ ld->rx_skb[skb_id] = NULL; -++ spin_unlock(&ld->rxlock); -++ dma_info.pos = dma_ring_incr(dma_info.pos, RX_DESC_NUM); -++ } -++ -++ if (dma_info.pos != dma_info.start) -++ writel(dma_byte(dma_info.pos), ld->gmac_iobase + rx_bq_rd_reg); -++ -++ spin_lock(&ld->rxlock); -++ gmac_rx_refill(ld); -++ spin_unlock(&ld->rxlock); -++ -++ return dma_info.num; -++} -++ -++static int gmac_check_tx_err(struct gmac_netdev_local const *ld, -++ struct gmac_tso_desc const *tx_bq_desc, unsigned int desc_pos) -++{ -++ unsigned int tx_err = tx_bq_desc->tx_err; -++ -++ if (unlikely(tx_err & ERR_ALL)) { -++ struct sg_desc *desc_cur = NULL; -++ int *sg_word = NULL; -++ int i; -++ -++ WARN((tx_err & ERR_ALL), -++ "TX ERR: desc1=0x%x, desc2=0x%x, desc5=0x%x\n", -++ tx_bq_desc->data_buff_addr, -++ tx_bq_desc->desc1.val, tx_bq_desc->tx_err); -++ -++ desc_cur = ld->dma_sg_desc + ld->TX_BQ.sg_desc_offset[desc_pos]; -++ sg_word = (int *)desc_cur; -++ for (i = 0; i < sizeof(struct sg_desc) / sizeof(int); i++) -++ pr_err("%s,%d: sg_desc word[%d]=0x%x\n", -++ __func__, __LINE__, i, sg_word[i]); -++ -++ return -1; -++ } -++ -++ return 0; -++} -++ -++static void gmac_xmit_release_gso_sg(struct gmac_netdev_local *ld, -++ struct gmac_tso_desc const *tx_rq_desc, unsigned int desc_pos) -++{ -++ struct sg_desc *desc_cur = NULL; -++ int nfrags = tx_rq_desc->desc1.tx.nfrags_num; -++ unsigned int desc_offset; -++ dma_addr_t addr; -++ size_t len; -++ int i; -++ -++ desc_offset = ld->TX_BQ.sg_desc_offset[desc_pos]; -++ WARN_ON(desc_offset != ld->sg_tail); -++ desc_cur = ld->dma_sg_desc + desc_offset; -++ -++ addr = desc_cur->linear_addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ addr |= (dma_addr_t)(desc_cur->reserv3 >> SG_DESC_HI8_OFFSET) << REG_BIT_WIDTH; -++#endif -++ len = desc_cur->linear_len; -++ dma_unmap_single(ld->dev, addr, len, DMA_TO_DEVICE); -++ for (i = 0; i < nfrags; i++) { -++ addr = desc_cur->frags[i].addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ addr |= (dma_addr_t) (desc_cur->frags[i].reserved >> SG_DESC_HI8_OFFSET) << REG_BIT_WIDTH; -++#endif -++ len = desc_cur->frags[i].size; -++ dma_unmap_page(ld->dev, addr, len, DMA_TO_DEVICE); -++ } -++} -++ -++static int gmac_xmit_release_gso(struct gmac_netdev_local *ld, -++ struct gmac_tso_desc *tx_rq_desc, unsigned int desc_pos) -++{ -++ int pkt_type; -++ unsigned int nfrags = tx_rq_desc->desc1.tx.nfrags_num; -++ dma_addr_t addr; -++ size_t len; -++ -++ if (unlikely(gmac_check_tx_err(ld, tx_rq_desc, desc_pos) < 0)) { -++ /* dev_close */ -++ gmac_irq_disable_all_queue(ld); -++ gmac_hw_desc_disable(ld); -++ -++ netif_carrier_off(ld->netdev); -++ netif_stop_queue(ld->netdev); -++ -++ phy_stop(ld->phy); -++ del_timer_sync(&ld->monitor); -++ return -1; -++ } -++ -++ if (tx_rq_desc->desc1.tx.tso_flag || (nfrags != 0)) -++ pkt_type = PKT_SG; -++ else -++ pkt_type = PKT_NORMAL; -++ -++ if (pkt_type == PKT_NORMAL) { -++ addr = tx_rq_desc->data_buff_addr; -++#if defined(CONFIG_GMAC_DDR_64BIT) -++ addr |= (dma_addr_t)(tx_rq_desc->reserve_desc2 & TX_DESC_HI8_MASK) << REG_BIT_WIDTH; -++#endif -++ len = tx_rq_desc->desc1.tx.data_len; -++ dma_unmap_single(ld->dev, addr, len, DMA_TO_DEVICE); -++ } else { -++ gmac_xmit_release_gso_sg(ld, tx_rq_desc, desc_pos); -++ -++ ld->sg_tail = (ld->sg_tail + 1) % ld->sg_count; -++ } -++ -++ return 0; -++} -++ -++static int gmac_xmit_reclaim_release(struct net_device const *dev, -++ struct sk_buff *skb, struct gmac_desc *desc, u32 pos) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(dev); -++ struct gmac_tso_desc *tso_desc = NULL; -++ dma_addr_t addr; -++ -++ if (priv->tso_supported) { -++ tso_desc = (struct gmac_tso_desc *)desc; -++ return gmac_xmit_release_gso(priv, tso_desc, pos); -++ } else { -++ addr = desc->data_buff_addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ addr |= (dma_addr_t)(desc->rxhash & TX_DESC_HI8_MASK) << REG_BIT_WIDTH; -++#endif -++ dma_unmap_single(priv->dev, addr, skb->len, DMA_TO_DEVICE); -++ } -++ return 0; -++} -++ -++static void gmac_xmit_reclaim(struct net_device *dev) -++{ -++ struct sk_buff *skb = NULL; -++ struct gmac_desc *desc = NULL; -++ struct gmac_netdev_local *priv = netdev_priv(dev); -++ unsigned int bytes_compl = 0; -++ unsigned int pkts_compl = 0; -++ struct cyclic_queue_info dma_info; -++ u32 i; -++ -++ spin_lock(&priv->txlock); -++ -++ /* software read */ -++ dma_info.start = dma_cnt(readl(priv->gmac_iobase + TX_RQ_RD_ADDR)); -++ /* logic write */ -++ dma_info.end = dma_cnt(readl(priv->gmac_iobase + TX_RQ_WR_ADDR)); -++ dma_info.num = CIRC_CNT(dma_info.end, dma_info.start, TX_DESC_NUM); -++ -++ for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) { -++ skb = priv->tx_skb[dma_info.pos]; -++ if (unlikely(skb == NULL)) { -++ netdev_err(dev, "inconsistent tx_skb\n"); -++ break; -++ } -++ -++ if (skb != priv->TX_BQ.skb[dma_info.pos]) { -++ netdev_err(dev, "wired, tx skb[%d](%p) != skb(%p)\n", -++ dma_info.pos, priv->TX_BQ.skb[dma_info.pos], skb); -++ if (priv->TX_BQ.skb[dma_info.pos] == SKB_MAGIC) -++ goto next; -++ } -++ -++ pkts_compl++; -++ bytes_compl += skb->len; -++ desc = priv->TX_RQ.desc + dma_info.pos; -++ if (gmac_xmit_reclaim_release(dev, skb, desc, dma_info.pos) < 0) -++ break; -++ -++ priv->TX_BQ.skb[dma_info.pos] = NULL; -++next: -++ priv->tx_skb[dma_info.pos] = NULL; -++ dev_consume_skb_any(skb); -++ dma_info.pos = dma_ring_incr(dma_info.pos, TX_DESC_NUM); -++ } -++ -++ if (dma_info.pos != dma_info.start) -++ writel(dma_byte(dma_info.pos), priv->gmac_iobase + TX_RQ_RD_ADDR); -++ -++ if ((pkts_compl != 0) || (bytes_compl != 0)) -++ netdev_completed_queue(dev, pkts_compl, bytes_compl); -++ -++ if (unlikely(netif_queue_stopped(priv->netdev)) && (pkts_compl != 0)) -++ netif_wake_queue(priv->netdev); -++ -++ spin_unlock(&priv->txlock); -++} -++ -++static int gmac_poll(struct napi_struct *napi, int budget) -++{ -++ struct gmac_napi *q_napi = container_of(napi, -++ struct gmac_napi, napi); -++ struct gmac_netdev_local *priv = q_napi->ndev_priv; -++ struct net_device *dev = priv->netdev; -++ int work_done = 0; -++ int task = budget; -++ u32 ints, num; -++ u32 raw_int_reg, raw_int_mask; -++ -++ dev_hold(dev); -++ if (q_napi->rxq_id) { -++ raw_int_reg = RSS_RAW_PMU_INT; -++ raw_int_mask = def_int_mask_queue((u32)q_napi->rxq_id); -++ } else { -++ raw_int_reg = RAW_PMU_INT; -++ raw_int_mask = DEF_INT_MASK; -++ } -++ -++ do { -++ if (!q_napi->rxq_id) -++ gmac_xmit_reclaim(dev); -++ num = gmac_rx(dev, task, q_napi->rxq_id); -++ work_done += num; -++ task -= num; -++ if (work_done >= budget) -++ break; -++ -++ ints = readl(priv->gmac_iobase + raw_int_reg); -++ ints &= raw_int_mask; -++ writel(ints, priv->gmac_iobase + raw_int_reg); -++ } while (ints || gmac_rxq_has_packets(priv, q_napi->rxq_id)); -++ -++ if (work_done < budget) { -++ napi_complete(napi); -++ gmac_irq_enable_queue(priv, q_napi->rxq_id); -++ } -++ -++ dev_put(dev); -++ return work_done; -++} -++ -++static irqreturn_t gmac_interrupt(int irq, void *dev_id) -++{ -++ struct gmac_napi *q_napi = (struct gmac_napi *)dev_id; -++ struct gmac_netdev_local *ld = q_napi->ndev_priv; -++ u32 ints; -++ u32 raw_int_reg, raw_int_mask; -++ -++ if (gmac_queue_irq_disabled(ld, q_napi->rxq_id)) -++ return IRQ_NONE; -++ -++ if (q_napi->rxq_id) { -++ raw_int_reg = RSS_RAW_PMU_INT; -++ raw_int_mask = def_int_mask_queue((u32)q_napi->rxq_id); -++ } else { -++ raw_int_reg = RAW_PMU_INT; -++ raw_int_mask = DEF_INT_MASK; -++ } -++ -++ ints = readl(ld->gmac_iobase + raw_int_reg); -++ ints &= raw_int_mask; -++ writel(ints, ld->gmac_iobase + raw_int_reg); -++ -++ if (likely(ints || gmac_rxq_has_packets(ld, q_napi->rxq_id))) { -++ gmac_irq_disable_queue(ld, q_napi->rxq_id); -++ napi_schedule(&q_napi->napi); -++ } -++ -++ return IRQ_HANDLED; -++} -++ -++void gmac_enable_napi(struct gmac_netdev_local *priv) -++{ -++ struct gmac_napi *q_napi = NULL; -++ int i; -++ -++ if (priv == NULL) -++ return; -++ -++ for (i = 0; i < priv->num_rxqs; i++) { -++ q_napi = &priv->q_napi[i]; -++ napi_enable(&q_napi->napi); -++ } -++} -++ -++void gmac_disable_napi(struct gmac_netdev_local *priv) -++{ -++ struct gmac_napi *q_napi = NULL; -++ int i; -++ -++ if (priv == NULL) -++ return; -++ -++ for (i = 0; i < priv->num_rxqs; i++) { -++ q_napi = &priv->q_napi[i]; -++ napi_disable(&q_napi->napi); -++ } -++} -++ -++void gmac_enable_rxcsum_drop(struct gmac_netdev_local const *ld, bool drop) -++{ -++ unsigned int v; -++ -++ v = readl(ld->gmac_iobase + TSO_COE_CTRL); -++ if (drop) -++ v |= COE_ERR_DROP; -++ else -++ v &= ~COE_ERR_DROP; -++ writel(v, ld->gmac_iobase + TSO_COE_CTRL); -++} -++ -++static const struct ethtool_ops eth_ethtools_ops = { -++ .get_drvinfo = gmac_get_drvinfo, -++ .get_link = gmac_get_link, -++ .get_pauseparam = gmac_get_pauseparam, -++ .set_pauseparam = gmac_set_pauseparam, -++ .get_msglevel = gmac_ethtool_getmsglevel, -++ .set_msglevel = gmac_ethtool_setmsglevel, -++ .get_rxfh_key_size = gmac_get_rxfh_key_size, -++ .get_rxfh_indir_size = gmac_get_rxfh_indir_size, -++ .get_rxfh = gmac_get_rxfh, -++ .set_rxfh = gmac_set_rxfh, -++ .get_rxnfc = gmac_get_rxnfc, -++ .set_rxnfc = gmac_set_rxnfc, -++ .get_link_ksettings = phy_ethtool_get_link_ksettings, -++ .set_link_ksettings = phy_ethtool_set_link_ksettings, -++}; -++ -++static const struct net_device_ops eth_netdev_ops = { -++ .ndo_open = gmac_net_open, -++ .ndo_stop = gmac_net_close, -++ .ndo_start_xmit = gmac_net_xmit, -++ .ndo_set_rx_mode = gmac_set_multicast_list, -++ .ndo_set_features = gmac_set_features, -++ .ndo_do_ioctl = gmac_ioctl, -++ .ndo_set_mac_address = gmac_net_set_mac_address, -++ .ndo_change_mtu = eth_change_mtu, -++ .ndo_get_stats = gmac_net_get_stats, -++}; -++ -++static int gmac_of_get_param(struct gmac_netdev_local *ld, -++ struct device_node const *node) -++{ -++ /* get auto eee */ -++ ld->autoeee = of_property_read_bool(node, "autoeee"); -++ /* get internal flag */ -++ ld->internal_phy = -++ of_property_read_bool(node, "internal-phy"); -++ -++ return 0; -++} -++ -++static void gmac_destroy_hw_desc_queue(struct gmac_netdev_local *priv) -++{ -++ int i; -++ -++ for (i = 0; i < QUEUE_NUMS + RSS_NUM_RXQS - 1; i++) { -++ if (priv->pool[i].desc) { -++ dma_free_coherent(priv->dev, priv->pool[i].size, -++ priv->pool[i].desc, -++ priv->pool[i].phys_addr); -++ priv->pool[i].desc = NULL; -++ } -++ } -++ -++ kfree(priv->RX_FQ.skb); -++ kfree(priv->TX_BQ.skb); -++ priv->RX_FQ.skb = NULL; -++ priv->TX_BQ.skb = NULL; -++ -++ if (priv->tso_supported) { -++ kfree(priv->TX_BQ.sg_desc_offset); -++ priv->TX_BQ.sg_desc_offset = NULL; -++ } -++ -++ kfree(priv->tx_skb); -++ priv->tx_skb = NULL; -++ -++ kfree(priv->rx_skb); -++ priv->rx_skb = NULL; -++} -++ -++static int gmac_init_desc_queue_mem(struct gmac_netdev_local *priv) -++{ -++ priv->RX_FQ.skb = kzalloc(priv->RX_FQ.count -++ * sizeof(struct sk_buff *), GFP_KERNEL); -++ if (!priv->RX_FQ.skb) -++ return -ENOMEM; -++ -++ priv->rx_skb = kzalloc(priv->RX_FQ.count -++ * sizeof(struct sk_buff *), GFP_KERNEL); -++ if (priv->rx_skb == NULL) -++ return -ENOMEM; -++ -++ priv->TX_BQ.skb = kzalloc(priv->TX_BQ.count -++ * sizeof(struct sk_buff *), GFP_KERNEL); -++ if (!priv->TX_BQ.skb) -++ return -ENOMEM; -++ -++ priv->tx_skb = kzalloc(priv->TX_BQ.count -++ * sizeof(struct sk_buff *), GFP_KERNEL); -++ if (priv->tx_skb == NULL) -++ return -ENOMEM; -++ -++ if (priv->tso_supported) { -++ priv->TX_BQ.sg_desc_offset = kzalloc(priv->TX_BQ.count -++ * sizeof(int), GFP_KERNEL); -++ if (!priv->TX_BQ.sg_desc_offset) -++ return -ENOMEM; -++ } -++ -++ return 0; -++} -++ -++static int gmac_init_hw_desc_queue(struct gmac_netdev_local *priv) -++{ -++ struct device *dev = NULL; -++ struct gmac_desc *virt_addr = NULL; -++ dma_addr_t phys_addr = 0; -++ int size, i; -++ if (priv == NULL || priv->dev == NULL) -++ return -EINVAL; -++ dev = priv->dev; -++ if (dev == NULL) -++ return -EINVAL; -++ priv->RX_FQ.count = RX_DESC_NUM; -++ priv->RX_BQ.count = RX_DESC_NUM; -++ priv->TX_BQ.count = TX_DESC_NUM; -++ priv->TX_RQ.count = TX_DESC_NUM; -++ -++ for (i = 1; i < RSS_NUM_RXQS; i++) -++ priv->pool[BASE_QUEUE_NUMS + i].count = RX_DESC_NUM; -++ -++ for (i = 0; i < (QUEUE_NUMS + RSS_NUM_RXQS - 1); i++) { -++ size = priv->pool[i].count * sizeof(struct gmac_desc); -++ virt_addr = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL); -++ if (virt_addr == NULL) -++ goto error_free_pool; -++ -++ if (memset_s(virt_addr, size, 0, size) != EOK) { -++ pr_info("gmac init hw desc queue: memset_s failed\n"); -++ goto error_free_pool; -++ } -++ priv->pool[i].size = (unsigned int)size; -++ priv->pool[i].desc = virt_addr; -++ priv->pool[i].phys_addr = phys_addr; -++ } -++ -++ if (gmac_init_desc_queue_mem(priv) == -ENOMEM) -++ goto error_free_pool; -++ -++ gmac_hw_set_desc_addr(priv); -++ -++ return 0; -++ -++error_free_pool: -++ gmac_destroy_hw_desc_queue(priv); -++ -++ return -ENOMEM; -++} -++ -++static void gmac_init_napi(struct gmac_netdev_local *priv) -++{ -++ struct gmac_napi *q_napi = NULL; -++ int i; -++ -++ if (priv == NULL || priv->netdev == NULL) -++ return; -++ -++ for (i = 0; i < priv->num_rxqs; i++) { -++ q_napi = &priv->q_napi[i]; -++ q_napi->rxq_id = (unsigned int)i; -++ q_napi->ndev_priv = priv; -++ netif_napi_add(priv->netdev, &q_napi->napi, gmac_poll, -++ NAPI_POLL_WEIGHT); -++ } -++} -++ -++static void gmac_destroy_napi(struct gmac_netdev_local *priv) -++{ -++ struct gmac_napi *q_napi = NULL; -++ int i; -++ -++ if (priv == NULL) -++ return; -++ -++ for (i = 0; i < priv->num_rxqs; i++) { -++ q_napi = &priv->q_napi[i]; -++ netif_napi_del(&q_napi->napi); -++ } -++} -++ -++static int gmac_request_irqs(struct platform_device *pdev, -++ struct gmac_netdev_local *priv) -++{ -++ struct device *dev = NULL; -++ int ret; -++ int i; -++ -++ if (priv == NULL || pdev == NULL || pdev->name == NULL) -++ return -1; -++ -++ dev = priv->dev; -++ if (dev == NULL) -++ return -1; -++ -++ for (i = 0; i < priv->num_rxqs; i++) { -++ ret = platform_get_irq(pdev, i); -++ if (ret < 0) { -++ dev_err(dev, "No irq[%d] resource, ret=%d\n", i, ret); -++ return ret; -++ } -++ priv->irq[i] = (unsigned int)ret; -++ -++ ret = devm_request_irq(dev, priv->irq[i], gmac_interrupt, -++ IRQF_SHARED, pdev->name, &priv->q_napi[i]); -++ if (ret) { -++ dev_err(dev, "devm_request_irq failed, ret=%d\n", ret); -++ return ret; -++ } -++ } -++ -++ return 0; -++} -++ -++static int gmac_dev_probe_res(struct platform_device *pdev, -++ struct gmac_netdev_local *priv) -++{ -++ struct device *dev = &pdev->dev; -++ struct net_device *ndev = priv->netdev; -++ struct resource *res = NULL; -++ int ret; -++ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_GMAC_IOBASE); -++ priv->gmac_iobase = devm_ioremap_resource(dev, res); -++ if (IS_ERR(priv->gmac_iobase)) { -++ ret = PTR_ERR(priv->gmac_iobase); -++ return ret; -++ } -++ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_MACIF_IOBASE); -++ priv->macif_base = devm_ioremap_resource(dev, res); -++ if (IS_ERR(priv->macif_base)) { -++ ret = PTR_ERR(priv->macif_base); -++ return ret; -++ } -++ -++ /* only for some chip to fix AXI bus burst and outstanding config */ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_AXI_BUS_CFG_IOBASE); -++ priv->axi_bus_cfg_base = devm_ioremap_resource(dev, res); -++ if (IS_ERR(priv->axi_bus_cfg_base)) -++ priv->axi_bus_cfg_base = NULL; -++ -++ priv->port_rst = devm_reset_control_get(dev, GMAC_PORT_RST_NAME); -++ if (IS_ERR(priv->port_rst)) { -++ ret = PTR_ERR(priv->port_rst); -++ return ret; -++ } -++ -++ priv->macif_rst = devm_reset_control_get(dev, GMAC_MACIF_RST_NAME); -++ if (IS_ERR(priv->macif_rst)) { -++ ret = PTR_ERR(priv->macif_rst); -++ return ret; -++ } -++ -++ priv->phy_rst = devm_reset_control_get(dev, GMAC_PHY_RST_NAME); -++ if (IS_ERR(priv->phy_rst)) -++ priv->phy_rst = NULL; -++ -++ priv->clk = devm_clk_get(&pdev->dev, GMAC_MAC_CLK_NAME); -++ if (IS_ERR(priv->clk)) { -++ netdev_err(ndev, "failed to get clk\n"); -++ ret = -ENODEV; -++ return ret; -++ } -++ -++ ret = clk_prepare_enable(priv->clk); -++ if (ret < 0) { -++ netdev_err(ndev, "failed to enable clk %d\n", ret); -++ return ret; -++ } -++ return 0; -++} -++ -++static int gmac_dev_macif_clk(struct platform_device *pdev, -++ struct gmac_netdev_local *priv, struct net_device *ndev) -++{ -++ int ret; -++ -++ priv->macif_clk = devm_clk_get(&pdev->dev, GMAC_MACIF_CLK_NAME); -++ if (IS_ERR(priv->macif_clk)) -++ priv->macif_clk = NULL; -++ -++ if (priv->macif_clk != NULL) { -++ ret = clk_prepare_enable(priv->macif_clk); -++ if (ret < 0) { -++ netdev_err(ndev, "failed enable macif_clk %d\n", ret); -++ return ret; -++ } -++ } -++ return 0; -++} -++ -++static int gmac_dev_probe_init(struct platform_device *pdev, -++ struct gmac_netdev_local *priv, struct net_device *ndev) -++{ -++ int ret; -++#if defined(CONFIG_GMAC_DDR_64BIT) -++ struct device *dev = &pdev->dev; -++#endif -++ -++ gmac_init_napi(priv); -++ spin_lock_init(&priv->rxlock); -++ spin_lock_init(&priv->txlock); -++ spin_lock_init(&priv->pmtlock); -++ -++ /* init netdevice */ -++ ndev->irq = priv->irq[0]; -++ ndev->watchdog_timeo = 3 * HZ; /* 3HZ */ -++ ndev->netdev_ops = ð_netdev_ops; -++ ndev->ethtool_ops = ð_ethtools_ops; -++ -++ if (priv->has_rxhash_cap) -++ ndev->hw_features |= NETIF_F_RXHASH; -++ if (priv->has_rss_cap) -++ ndev->hw_features |= NETIF_F_NTUPLE; -++ if (priv->tso_supported) -++ ndev->hw_features |= NETIF_F_SG | -++ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -++ NETIF_F_TSO | NETIF_F_TSO6; -++ -++#if defined(CONFIG_GMAC_RXCSUM) -++ ndev->hw_features |= NETIF_F_RXCSUM; -++ gmac_enable_rxcsum_drop(priv, true); -++#endif -++ -++ ndev->features |= ndev->hw_features; -++ ndev->features |= NETIF_F_HIGHDMA | NETIF_F_GSO; -++ ndev->vlan_features |= ndev->features; -++ -++ timer_setup(&priv->monitor, gmac_monitor_func, 0); -++ -++ device_set_wakeup_capable(priv->dev, 1); -++ /* -++ * when we can let phy powerdown? -++ * In some mode, we don't want phy powerdown, -++ * so I set wakeup enable all the time -++ */ -++ device_set_wakeup_enable(priv->dev, 1); -++ -++ priv->wol_enable = false; -++ -++ priv->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); -++ -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); /* 64bit */ -++ if (ret) { -++ pr_err("dma set mask 64 failed! ret=%d", ret); -++ return ret; -++ } -++#endif -++ -++ /* init hw desc queue */ -++ ret = gmac_init_hw_desc_queue(priv); -++ if (ret) -++ return ret; -++ -++ return 0; -++} -++ -++static int gmac_dev_probe_phy(struct platform_device *pdev, -++ struct gmac_netdev_local *priv, struct net_device *ndev, -++ bool fixed_link) -++{ -++ int ret; -++ -++ /* phy fix here?? other way ??? */ -++ gmac_phy_register_fixups(); -++ /* Unable to handle kernel paging request at virtual address 08ffffff80052fc0 */ -++ priv->phy = of_phy_connect(ndev, priv->phy_node, -++ &gmac_adjust_link, 0, priv->phy_mode); -++ if (priv->phy == NULL || priv->phy->drv == NULL) { -++ ret = -ENODEV; -++ return ret; -++ } -++ -++ /* If the phy_id is all zero and not fixed link, there is no device there */ -++ if ((priv->phy->phy_id == 0) && !fixed_link) { -++ pr_info("phy %d not found\n", priv->phy->mdio.addr); -++ ret = -ENODEV; -++ return ret; -++ } -++ -++ pr_info("attached PHY %d to driver %s, PHY_ID=0x%x\n", -++ priv->phy->mdio.addr, priv->phy->drv->name, priv->phy->phy_id); -++ -++ /* Stop Advertising 1000BASE Capability if interface is not RGMII */ -++ if ((priv->phy_mode == PHY_INTERFACE_MODE_MII) || -++ (priv->phy_mode == PHY_INTERFACE_MODE_RMII)) { -++ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT | ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -++ priv->phy->advertising); -++ /* -++ * Internal FE phy's reg BMSR bit8 is wrong, make the kernel -++ * believe it has the 1000base Capability, so fix it here -++ */ -++ if (priv->phy->phy_id == VENDOR_PHY_ID_FESTAV200) -++ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT | ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -++ priv->phy->supported); -++ } -++ -++ gmac_set_flow_ctrl_args(priv); -++ gmac_set_flow_ctrl_params(priv); -++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, priv->phy->supported); -++ if (priv->flow_ctrl) -++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, priv->phy->advertising); -++ if (priv->autoeee) -++ init_autoeee(priv); -++ -++ ret = gmac_request_irqs(pdev, priv); -++ if (ret) -++ return ret; -++ -++ return 0; -++} -++ -++static void gmac_set_hw_cap(struct platform_device *pdev, -++ struct gmac_netdev_local *priv) -++{ -++ unsigned int hw_cap; -++ -++ hw_cap = readl(priv->gmac_iobase + CRF_MIN_PACKET); -++ priv->tso_supported = has_tso_cap(hw_cap); -++ priv->has_rxhash_cap = has_rxhash_cap(hw_cap); -++ priv->has_rss_cap = has_rss_cap(hw_cap); -++ -++ gmac_set_rss_cap(priv); -++ gmac_get_rss_key(priv); -++ if (priv->has_rss_cap) { -++ priv->rss_info.ind_tbl_size = RSS_INDIRECTION_TABLE_SIZE; -++ gmac_get_rss(priv); -++ } -++ -++ if (priv->has_rxhash_cap) { -++ priv->rss_info.hash_cfg = DEF_HASH_CFG; -++ gmac_config_hash_policy(priv); -++ } -++} -++ -++static void gmac_set_mac_addr(struct net_device *ndev, -++ struct device_node *node) -++{ -++ const char *mac_addr = NULL; -++ -++ mac_addr = of_get_mac_address(node); -++ if (!IS_ERR_OR_NULL(mac_addr)) -++ ether_addr_copy(ndev->dev_addr, mac_addr); -++ else -++ eth_hw_addr_random(ndev); -++ -++ gmac_hw_set_mac_addr(ndev); -++} -++ -++/* board independent func */ -++static void gmac_hw_internal_phy_reset(struct gmac_netdev_local const *priv) -++{ -++} -++ -++/* board independent func */ -++static void gmac_hw_external_phy_reset(struct gmac_netdev_local const *priv) -++{ -++ if (priv == NULL) -++ return; -++ if (priv->phy_rst != NULL) { -++ /* write 0 to cancel reset */ -++ reset_control_deassert(priv->phy_rst); -++ msleep(50); /* wait 50ms */ -++ -++ /* XX use CRG register to reset phy */ -++ /* RST_BIT, write 0 to reset phy, write 1 to cancel reset */ -++ reset_control_assert(priv->phy_rst); -++ -++ /* -++ * delay some time to ensure reset ok, -++ * this depends on PHY hardware feature -++ */ -++ msleep(50); /* wait 50ms */ -++ -++ /* write 0 to cancel reset */ -++ reset_control_deassert(priv->phy_rst); -++ /* delay some time to ensure later MDIO access */ -++ msleep(50); /* wait 50ms */ -++ } -++} -++ -++/* board independent func */ -++static void gmac_hw_phy_reset(struct gmac_netdev_local *priv) -++{ -++ if (priv == NULL) -++ return; -++ if (priv->internal_phy) -++ gmac_hw_internal_phy_reset(priv); -++ else -++ gmac_hw_external_phy_reset(priv); -++} -++ -++static int gmac_phy_init(struct device *dev, struct net_device *ndev, -++ struct gmac_netdev_local *priv, struct device_node *node, bool *fixed_link) -++{ -++ int ret; -++ -++ /* -++ * phy reset, should be early than "of_mdiobus_register". -++ * becausue "of_mdiobus_register" will read PHY register by MDIO. -++ */ -++ gmac_hw_phy_reset(priv); -++ -++ gmac_of_get_param(priv, node); -++ -++ ret = of_get_phy_mode(node, &priv->phy_mode); -++ if (ret < 0) { -++ netdev_err(ndev, "not find phy-mode\n"); -++ return ret; -++ } -++ -++ priv->phy_node = of_parse_phandle(node, "phy-handle", 0); -++ if (priv->phy_node == 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 register fixed PHY %d\n", ret); -++ return ret; -++ } -++ -++ /* -++ * In the case of a fixed PHY, the DT node associated -++ * to the PHY is the Ethernet MAC DT node. -++ */ -++ priv->phy_node = of_node_get(node); -++ *fixed_link = true; -++ } else { -++ netdev_err(ndev, "not find phy-handle\n"); -++ ret = -EINVAL; -++ return ret; -++ } -++ } -++ return 0; -++} -++ -++static void gmac_verify_flow_ctrl_args(void) -++{ -++#if defined(CONFIG_TX_FLOW_CTRL_SUPPORT) -++ flow_ctrl_en |= FLOW_TX; -++#endif -++#if defined(CONFIG_RX_FLOW_CTRL_SUPPORT) -++ flow_ctrl_en |= FLOW_RX; -++#endif -++ if (tx_flow_ctrl_active_threshold < FC_ACTIVE_MIN || -++ tx_flow_ctrl_active_threshold > FC_ACTIVE_MAX) -++ tx_flow_ctrl_active_threshold = FC_ACTIVE_DEFAULT; -++ -++ if (tx_flow_ctrl_deactive_threshold < FC_DEACTIVE_MIN || -++ tx_flow_ctrl_deactive_threshold > FC_DEACTIVE_MAX) -++ tx_flow_ctrl_deactive_threshold = FC_DEACTIVE_DEFAULT; -++ -++ if (tx_flow_ctrl_active_threshold >= tx_flow_ctrl_deactive_threshold) { -++ tx_flow_ctrl_active_threshold = FC_ACTIVE_DEFAULT; -++ tx_flow_ctrl_deactive_threshold = FC_DEACTIVE_DEFAULT; -++ } -++ -++ if (tx_flow_ctrl_pause_time < 0 || -++ tx_flow_ctrl_pause_time > FC_PAUSE_TIME_MAX) -++ tx_flow_ctrl_pause_time = FC_PAUSE_TIME_DEFAULT; -++ -++ if (tx_flow_ctrl_pause_interval < 0 || -++ tx_flow_ctrl_pause_interval > FC_PAUSE_TIME_MAX) -++ tx_flow_ctrl_pause_interval = FC_PAUSE_INTERVAL_DEFAULT; -++ -++ /* -++ * pause interval should not bigger than pause time, -++ * but should not too smaller to avoid sending too many pause frame. -++ */ -++ if ((tx_flow_ctrl_pause_interval > tx_flow_ctrl_pause_time) || -++ (tx_flow_ctrl_pause_interval < ((unsigned int)tx_flow_ctrl_pause_time >> 1))) -++ tx_flow_ctrl_pause_interval = tx_flow_ctrl_pause_time; -++} -++ -++static int gmac_dev_probe_device(struct platform_device *pdev, -++ struct net_device **p_ndev, struct gmac_netdev_local **p_priv) -++{ -++ struct device *dev = &pdev->dev; -++ struct device_node *node = dev->of_node; -++ struct net_device *ndev = NULL; -++ struct gmac_netdev_local *priv = NULL; -++ int num_rxqs; -++ -++ gmac_verify_flow_ctrl_args(); -++ -++ if (of_device_is_compatible(node, "vendor,gmac-v5")) -++ num_rxqs = RSS_NUM_RXQS; -++ else -++ num_rxqs = 1; -++ -++ ndev = alloc_etherdev_mqs(sizeof(struct gmac_netdev_local), 1, -++ num_rxqs); -++ if (ndev == NULL) -++ return -ENOMEM; -++ -++ platform_set_drvdata(pdev, ndev); -++ SET_NETDEV_DEV(ndev, dev); -++ -++ priv = netdev_priv(ndev); -++ priv->dev = dev; -++ priv->netdev = ndev; -++ priv->num_rxqs = num_rxqs; -++ -++ *p_ndev = ndev; -++ *p_priv = priv; -++ return 0; -++} -++ -++static int gmac_dev_probe_queue(struct platform_device *pdev, -++ struct gmac_netdev_local *priv, struct net_device *ndev, bool fixed_link) -++{ -++ int ret; -++ -++ ret = gmac_dev_probe_init(pdev, priv, ndev); -++ if (ret) -++ goto _error_hw_desc_queue; -++ -++ if (priv->tso_supported) { -++ ret = gmac_init_sg_desc_queue(priv); -++ if (ret) -++ goto _error_sg_desc_queue; -++ } -++ -++ /* register netdevice */ -++ ret = register_netdev(priv->netdev); -++ if (ret) { -++ pr_err("register_ndev failed!"); -++ goto _error_sg_desc_queue; -++ } -++ -++ /* -++ * reset queue here to make BQL only reset once. -++ * if we put netdev_reset_queue() in gmac_net_open(), -++ * the BQL will be reset when ifconfig eth0 down and up, -++ * but the tx ring is not cleared before. -++ * As a result, the NAPI poll will call netdev_completed_queue() -++ * and BQL throw a bug. -++ */ -++ netdev_reset_queue(ndev); -++ -++ /* config PHY power down to save power */ -++ phy_suspend(priv->phy); -++ -++ clk_disable_unprepare(priv->clk); -++ if (priv->macif_clk != NULL) -++ clk_disable_unprepare(priv->macif_clk); -++ -++ pr_info("ETH: %s, phy_addr=%d\n", -++ phy_modes(priv->phy_mode), priv->phy->mdio.addr); -++ -++ return ret; -++ -++_error_sg_desc_queue: -++ if (priv->tso_supported) -++ gmac_destroy_sg_desc_queue(priv); -++_error_hw_desc_queue: -++ gmac_destroy_hw_desc_queue(priv); -++ gmac_destroy_napi(priv); -++ -++ return ret; -++} -++ -++static int gmac_dev_probe(struct platform_device *pdev) -++{ -++ struct device *dev = &pdev->dev; -++ struct device_node *node = dev->of_node; -++ struct net_device *ndev = NULL; -++ struct gmac_netdev_local *priv = NULL; -++ int ret; -++ bool fixed_link = false; -++ -++ ret = gmac_dev_probe_device(pdev, &ndev, &priv); -++ if (ret) -++ return ret; -++ -++ ret = gmac_dev_probe_res(pdev, priv); -++ if (ret) -++ goto out_free_netdev; -++ -++ ret = gmac_dev_macif_clk(pdev, priv, ndev); -++ if (ret) -++ goto out_clk_disable; -++ -++ gmac_mac_core_reset(priv); -++ -++ ret = gmac_phy_init(dev, ndev, priv, node, &fixed_link); -++ if (ret) -++ goto out_macif_clk_disable; -++ -++ gmac_set_mac_addr(ndev, node); -++ gmac_set_hw_cap(pdev, priv); -++ -++ /* init hw controller */ -++ gmac_hw_init(priv); -++ -++ ret = gmac_dev_probe_phy(pdev, priv, ndev, fixed_link); -++ if (ret) { -++ if (priv->phy == NULL) -++ goto out_phy_node; -++ else -++ goto out_phy_disconnect; -++ } -++ -++ ret = gmac_dev_probe_queue(pdev, priv, ndev, fixed_link); -++ if (ret) -++ goto out_phy_disconnect; -++ -++ return ret; -++ -++out_phy_disconnect: -++ phy_disconnect(priv->phy); -++out_phy_node: -++ of_node_put(priv->phy_node); -++out_macif_clk_disable: -++ if (priv->macif_clk != NULL) -++ clk_disable_unprepare(priv->macif_clk); -++out_clk_disable: -++ clk_disable_unprepare(priv->clk); -++out_free_netdev: -++ free_netdev(ndev); -++ -++ return ret; -++} -++ -++static int gmac_dev_remove(struct platform_device *pdev) -++{ -++ struct net_device *ndev = platform_get_drvdata(pdev); -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ -++ /* stop the gmac and free all resource */ -++ del_timer_sync(&priv->monitor); -++ gmac_destroy_napi(priv); -++ -++ unregister_netdev(ndev); -++ -++ gmac_reclaim_rx_tx_resource(priv); -++ gmac_free_rx_skb(priv); -++ gmac_free_tx_skb(priv); -++ -++ if (priv->tso_supported) -++ gmac_destroy_sg_desc_queue(priv); -++ gmac_destroy_hw_desc_queue(priv); -++ -++ phy_disconnect(priv->phy); -++ of_node_put(priv->phy_node); -++ -++ free_netdev(ndev); -++ -++ gmac_phy_unregister_fixups(); -++ -++ return 0; -++} -++ -++#ifdef CONFIG_PM -++static void gmac_disable_irq(struct gmac_netdev_local *priv) -++{ -++ int i; -++ -++ for (i = 0; i < priv->num_rxqs; i++) -++ disable_irq(priv->irq[i]); -++} -++ -++static void gmac_enable_irq(struct gmac_netdev_local *priv) -++{ -++ int i; -++ -++ for (i = 0; i < priv->num_rxqs; i++) -++ enable_irq(priv->irq[i]); -++} -++ -++/* board related func */ -++static void gmac_internal_phy_clk_disable(struct gmac_netdev_local const *priv) -++{ -++} -++ -++/* board related func */ -++static void gmac_hw_all_clk_disable(struct gmac_netdev_local *priv) -++{ -++ /* -++ * If macif clock is enabled when suspend, we should -++ * disable it here. -++ * Because when resume, PHY will link up again and -++ * macif clock will be enabled too. If we don't disable -++ * macif clock in suspend, macif clock will be enabled twice. -++ */ -++ if (priv == NULL || priv->clk == NULL || priv->netdev == NULL || priv->macif_clk == NULL) -++ return; -++ -++ if (priv->netdev->flags & IFF_UP) -++ clk_disable_unprepare(priv->macif_clk); -++ -++ /* -++ * This is called in suspend, when net device is down, -++ * MAC clk is disabled. -++ * So we need to judge whether MAC clk is enabled, -++ * otherwise kernel will WARNING if clk disable twice. -++ */ -++ if (priv->netdev->flags & IFF_UP) -++ clk_disable_unprepare(priv->clk); -++ -++ if (priv->internal_phy) -++ gmac_internal_phy_clk_disable(priv); -++} -++ -++int gmac_dev_suspend(struct platform_device *pdev, pm_message_t state) -++{ -++ struct net_device *ndev = platform_get_drvdata(pdev); -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ -++ gmac_disable_irq(priv); -++ /* -++ * If support Wake on LAN, we should not disconnect phy -++ * because it will call phy_suspend to power down phy. -++ */ -++ if (!priv->wol_enable) -++ phy_disconnect(priv->phy); -++ del_timer_sync(&priv->monitor); -++ /* -++ * If suspend when netif is not up, the napi_disable will run into -++ * dead loop and dpm_drv_timeout will give warning. -++ */ -++ if (netif_running(ndev)) -++ gmac_disable_napi(priv); -++ netif_device_detach(ndev); -++ -++ netif_carrier_off(ndev); -++ -++ /* -++ * If netdev is down, MAC clock is disabled. -++ * So if we want to reclaim MAC rx and tx resource, -++ * we must first enable MAC clock and then disable it. -++ */ -++ if (!(ndev->flags & IFF_UP)) -++ clk_prepare_enable(priv->clk); -++ -++ gmac_reclaim_rx_tx_resource(priv); -++ -++ if (!(ndev->flags & IFF_UP)) -++ clk_disable_unprepare(priv->clk); -++ -++ pmt_enter(priv); -++ -++ if (!priv->wol_enable) { -++ /* -++ * if no WOL, then poweroff -++ * no need to call genphy_resume() in resume, -++ * because we reset everything -++ */ -++ genphy_suspend(priv->phy); /* power down phy */ -++ msleep(20); /* wait 20ms */ -++ gmac_hw_all_clk_disable(priv); -++ } -++ -++ return 0; -++} -++EXPORT_SYMBOL(gmac_dev_suspend); -++ -++/* board related func */ -++static void gmac_internal_phy_clk_enable(struct gmac_netdev_local const *priv) -++{ -++} -++ -++/* board related func */ -++static void gmac_hw_all_clk_enable(struct gmac_netdev_local *priv) -++{ -++ if (priv == NULL || priv->netdev == NULL || priv->clk == NULL) -++ return; -++ -++ if (priv->internal_phy) -++ gmac_internal_phy_clk_enable(priv); -++ -++ if (priv->netdev->flags & IFF_UP) -++ clk_prepare_enable(priv->macif_clk); -++ -++ /* If net device is down when suspend, we should not enable MAC clk. */ -++ if (priv->netdev->flags & IFF_UP) -++ clk_prepare_enable(priv->clk); -++} -++ -++int gmac_dev_resume(struct platform_device *pdev) -++{ -++ struct net_device *ndev = platform_get_drvdata(pdev); -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ int ret; -++ -++ /* -++ * If we support Wake on LAN, we doesn't call clk_disable. -++ * But when we resume, the uboot may off mac clock and reset phy -++ * by re-write the mac CRG register. -++ * So we first call clk_disable, and then clk_enable. -++ */ -++ if (priv->wol_enable) -++ gmac_hw_all_clk_disable(priv); -++ -++ gmac_hw_all_clk_enable(priv); -++ /* internal FE_PHY: enable clk and reset */ -++ gmac_hw_phy_reset(priv); -++ -++ /* -++ * If netdev is down, MAC clock is disabled. -++ * So if we want to restart MAC and re-initialize it, -++ * we must first enable MAC clock and then disable it. -++ */ -++ if (!(ndev->flags & IFF_UP)) -++ clk_prepare_enable(priv->clk); -++ -++ /* power on gmac */ -++ gmac_restart(priv); -++ -++ /* -++ * If support WoL, we didn't disconnect phy. -++ * But when we resume, we reset PHY, so we want to -++ * call phy_connect to make phy_fixup excuted. -++ * This is important for internal PHY fix. -++ */ -++ if (priv->wol_enable) -++ phy_disconnect(priv->phy); -++ -++ ret = phy_connect_direct(ndev, priv->phy, gmac_adjust_link, -++ priv->phy_mode); -++ if (ret) -++ return ret; -++ -++ /* -++ * If we suspend and resume when net device is down, -++ * some operations are unnecessary. -++ */ -++ if (ndev->flags & IFF_UP) { -++ priv->monitor.expires = jiffies + GMAC_MONITOR_TIMER; -++ mod_timer(&priv->monitor, priv->monitor.expires); -++ priv->old_link = 0; -++ priv->old_speed = SPEED_UNKNOWN; -++ priv->old_duplex = DUPLEX_UNKNOWN; -++ } -++ if (netif_running(ndev)) -++ gmac_enable_napi(priv); -++ netif_device_attach(ndev); -++ if (ndev->flags & IFF_UP) -++ phy_start(priv->phy); -++ gmac_enable_irq(priv); -++ -++ pmt_exit(priv); -++ -++ if (!(ndev->flags & IFF_UP)) -++ clk_disable_unprepare(priv->clk); -++ -++ return 0; -++} -++EXPORT_SYMBOL(gmac_dev_resume); -++#endif -++ -++static const struct of_device_id gmac_of_match[] = { -++ { .compatible = "vendor,gmac", }, -++ { .compatible = "vendor,gmac-v1", }, -++ { .compatible = "vendor,gmac-v2", }, -++ { .compatible = "vendor,gmac-v3", }, -++ { .compatible = "vendor,gmac-v4", }, -++ { .compatible = "vendor,gmac-v5", }, -++ { }, -++}; -++ -++MODULE_DEVICE_TABLE(of, gmac_of_match); -++ -++static struct platform_driver gmac_dev_driver = { -++ .probe = gmac_dev_probe, -++ .remove = gmac_dev_remove, -++#ifdef CONFIG_PM -++ .suspend = gmac_dev_suspend, -++ .resume = gmac_dev_resume, -++#endif -++ .driver = { -++ .owner = THIS_MODULE, -++ .name = GMAC_DRIVER_NAME, -++ .of_match_table = gmac_of_match, -++ }, -++}; -++ -++static int __init gmac_init(void) -++{ -++ int ret; -++ -++ ret = platform_driver_register(&gmac_dev_driver); -++ if (ret) -++ return ret; -++ -++ gmac_proc_create(); -++ -++ return 0; -++} -++ -++static void __exit gmac_exit(void) -++{ -++ platform_driver_unregister(&gmac_dev_driver); -++ -++ gmac_proc_destroy(); -++} -++ -++module_init(gmac_init); -++module_exit(gmac_exit); -++ -++MODULE_AUTHOR("Vendor"); -++MODULE_DESCRIPTION("Vendor double GMAC driver, base on driver gmacv200"); -++MODULE_LICENSE("GPL v2"); -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac.h b/drivers/net/ethernet/vendor/gmac/gmac.h -+new file mode 100755 -+index 000000000..450d7dc4c -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac.h -+@@ -0,0 +1,778 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef GMAC_GMAC_H -++#define GMAC_GMAC_H -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define STATION_ADDR_LOW 0x0000 -++#define STATION_ADDR_HIGH 0x0004 -++#define MAC_DUPLEX_HALF_CTRL 0x0008 -++ -++#define PORT_MODE 0x0040 -++ -++#define PORT_EN 0x0044 -++#define BITS_TX_EN BIT(2) -++#define BITS_RX_EN BIT(1) -++ -++#define FC_TX_TIMER 0x001C -++ -++#define PAUSE_THR 0x0038 -++ -++#define PAUSE_EN 0x0048 -++#define BIT_RX_FDFC BIT(0) -++#define BIT_TX_FDFC BIT(1) -++ -++#define RX_PAUSE_EN 0x02A4 -++#define BIT_RX_FQ_PAUSE_EN BIT(0) -++#define BIT_RX_BQ_PAUSE_EN BIT(1) -++ -++#define CRF_TX_PAUSE 0x0340 -++ -++#define BITS_Q_PAUSE_TH_OFFSET 16 -++#define BITS_Q_PAUSE_TH_MASK 0xFFFF -++ -++#define REC_FILT_CONTROL 0x0064 -++#define BIT_CRC_ERR_PASS BIT(5) -++#define BIT_PAUSE_FRM_PASS BIT(4) -++#define BIT_VLAN_DROP_EN BIT(3) -++#define BIT_BC_DROP_EN BIT(2) -++#define BIT_MC_MATCH_EN BIT(1) -++#define BIT_UC_MATCH_EN BIT(0) -++ -++#define PORT_MC_ADDR_LOW 0x0068 -++#define PORT_MC_ADDR_HIGH 0x006C -++#define MAC_CLEAR 0x0070 -++#define BIT_TX_SOFT_RESET BIT(0) -++ -++#define MODE_CHANGE_EN 0x01b4 -++#define BIT_MODE_CHANGE_EN BIT(0) -++ -++#define COL_SLOT_TIME 0x01c0 -++ -++#define CRF_MIN_PACKET 0x0210 -++#define BIT_OFFSET_TX_MIN_LEN 8 -++#define BIT_MASK_TX_MIN_LEN GENMASK(13, 8) -++ -++#define CONTROL_WORD 0x0214 -++#define CONTROL_WORD_CONFIG 0x640 -++ -++#define TSO_COE_CTRL 0x02e8 -++#define BIT_COE_IPHDR_DROP BIT(4) -++#define BIT_COE_PAYLOAD_DROP BIT(5) -++#define BIT_COE_IPV6_UDP_ZERO_DROP BIT(6) -++#define COE_ERR_DROP (BIT_COE_IPHDR_DROP | \ -++ BIT_COE_PAYLOAD_DROP | \ -++ BIT_COE_IPV6_UDP_ZERO_DROP) -++ -++#define RX_FQ_START_ADDR 0x0500 -++#define RX_FQ_DEPTH 0x0504 -++#define REG_BIT_WIDTH 32 -++#define Q_ADDR_HI8_OFFSET 24 -++#define Q_ADDR_HI8_MASK (BIT(Q_ADDR_HI8_OFFSET) - 1) -++#define TX_DESC_HI8_MASK 0xff -++#define SG_DESC_HI8_OFFSET 8 -++#define RX_FQ_WR_ADDR 0x0508 -++#define BITS_RX_FQ_WR_ADDR mk_bits(0, 21) -++#define RX_FQ_RD_ADDR 0x050c -++#define BITS_RX_FQ_RD_ADDR mk_bits(0, 21) -++#define RX_FQ_VLDDESC_CNT 0x0510 -++#define BITS_RX_FQ_VLDDESC_CNT mk_bits(0, 16) -++#define RX_FQ_ALEMPTY_TH 0x0514 -++#define BITS_RX_FQ_ALEMPTY_TH mk_bits(0, 16) -++#define RX_FQ_REG_EN 0x0518 -++#define BITS_RX_FQ_START_ADDR_EN BIT(2) -++#define BITS_RX_FQ_DEPTH_EN BIT(1) -++#define BITS_RX_FQ_RD_ADDR_EN mk_bits(0, 1) -++#define RX_FQ_ALFULL_TH 0x051c -++#define BITS_RX_FQ_ALFULL_TH mk_bits(0, 16) -++ -++#define RX_BQ_START_ADDR 0x0520 -++#define RX_BQ_DEPTH 0x0524 -++#define RX_BQ_WR_ADDR 0x0528 -++#define RX_BQ_RD_ADDR 0x052c -++#define RX_BQ_FREE_DESC_CNT 0x0530 -++#define BITS_RX_BQ_FREE_DESC_CNT mk_bits(0, 16) -++#define RX_BQ_ALEMPTY_TH 0x0534 -++#define BITS_RX_BQ_ALEMPTY_TH mk_bits(0, 16) -++#define RX_BQ_REG_EN 0x0538 -++#define BITS_RX_BQ_START_ADDR_EN BIT(2) -++#define BITS_RX_BQ_DEPTH_EN BIT(1) -++#define BITS_RX_BQ_WR_ADDR_EN mk_bits(0, 1) -++#define RX_BQ_ALFULL_TH 0x053c -++#define BITS_RX_BQ_ALFULL_TH mk_bits(0, 16) -++ -++#define TX_BQ_START_ADDR 0x0580 -++#define TX_BQ_DEPTH 0x0584 -++#define TX_BQ_WR_ADDR 0x0588 -++#define BITS_TX_BQ_WR_ADDR mk_bits(0, 21) -++#define TX_BQ_RD_ADDR 0x058c -++#define BITS_TX_BQ_RD_ADDR mk_bits(0, 21) -++#define TX_BQ_VLDDESC_CNT 0x0590 -++#define BITS_TX_BQ_VLDDESC_CNT mk_bits(0, 16) -++#define TX_BQ_ALEMPTY_TH 0x0594 -++#define BITS_TX_BQ_ALEMPTY_TH mk_bits(0, 16) -++#define TX_BQ_REG_EN 0x0598 -++#define BITS_TX_BQ_START_ADDR_EN BIT(2) -++#define BITS_TX_BQ_DEPTH_EN BIT(1) -++#define BITS_TX_BQ_RD_ADDR_EN mk_bits(0, 1) -++#define TX_BQ_ALFULL_TH 0x059c -++#define BITS_TX_BQ_ALFULL_TH mk_bits(0, 16) -++ -++#define TX_RQ_START_ADDR 0x05a0 -++#define TX_RQ_DEPTH 0x05a4 -++#define TX_RQ_WR_ADDR 0x05a8 -++#define BITS_TX_RQ_WR_ADDR mk_bits(0, 21) -++#define TX_RQ_RD_ADDR 0x05ac -++#define BITS_TX_RQ_RD_ADDR mk_bits(0, 21) -++#define TX_RQ_FREE_DESC_CNT 0x05b0 -++#define BITS_TX_RQ_FREE_DESC_CNT mk_bits(0, 16) -++#define TX_RQ_ALEMPTY_TH 0x05b4 -++#define BITS_TX_RQ_ALEMPTY_TH mk_bits(0, 16) -++#define TX_RQ_REG_EN 0x05b8 -++#define BITS_TX_RQ_START_ADDR_EN BIT(2) -++#define BITS_TX_RQ_DEPTH_EN BIT(1) -++#define BITS_TX_RQ_WR_ADDR_EN mk_bits(0, 1) -++#define TX_RQ_ALFULL_TH 0x05bc -++#define BITS_TX_RQ_ALFULL_TH mk_bits(0, 16) -++ -++#define RAW_PMU_INT 0x05c0 -++#define ENA_PMU_INT 0x05c4 -++ -++#define DESC_WR_RD_ENA 0x05CC -++ -++#define IN_QUEUE_TH 0x05d8 -++#define BITS_OFFSET_TX_RQ_IN_TH 16 -++ -++#define RX_BQ_IN_TIMEOUT_TH 0x05E0 -++ -++#define TX_RQ_IN_TIMEOUT_TH 0x05e4 -++ -++#define STOP_CMD 0x05e8 -++#define BITS_TX_STOP_EN BIT(1) -++#define BITS_RX_STOP_EN BIT(0) -++#define STOP_RX_TX (BITS_TX_STOP_EN | BITS_RX_STOP_EN) -++ -++#define RSS_IND_TBL 0x0c0c -++#define BIT_IND_TBL_READY BIT(13) -++#define BIT_IND_TLB_WR BIT(12) -++#define RSS_RAW_PMU_INT 0x0c10 -++#define RSS_QUEUE1_START_ADDR 0x0c20 -++#define rx_bq_start_addr_queue(i) (RSS_QUEUE1_START_ADDR + \ -++ ((i) - 1) * 0x10) -++#define RSS_QUEUE1_DEPTH 0x0c24 -++#define RX_BQ_WR_ADDR_QUEUE1 0x0c28 -++#define RX_BQ_RD_ADDR_QUEUE1 0x0c2c -++#define RSS_QUEUE1_ENA_INT 0x0c90 -++#define rss_ena_int_queue(i) (RSS_QUEUE1_ENA_INT + ((i) - 1) * 0x4) -++#define rx_bq_depth_queue(i) (RSS_QUEUE1_DEPTH + ((i) - 1) * 0x10) -++#define rx_bq_wr_addr_queue(i) ((i) ? (RX_BQ_WR_ADDR_QUEUE1 + \ -++ ((i) - 1) * 0x10) : RX_BQ_WR_ADDR) -++#define rx_bq_rd_addr_queue(i) ((i) ? (RX_BQ_RD_ADDR_QUEUE1 + \ -++ ((i) - 1) * 0x10) : RX_BQ_RD_ADDR) -++ -++#define def_int_mask_queue(i) (0x3 << (2 * ((i) - 1))) -++ -++/* AXI burst and outstanding config */ -++#define BURST_OUTSTANDING_REG 0x3014 -++#define BURST4_OUTSTANDING1 0x81ff -++#define BURST_OUTSTANDING_OFFSET 16 -++ -++#define GMAC_SPEED_1000 0x05 -++#define GMAC_SPEED_100 0x01 -++#define GMAC_SPEED_10 0x00 -++ -++#define IPV4_HEAD_LENGTH 0x5 -++ -++enum gmac_tx_err { -++ ERR_NONE = 0, -++ ERR_DESC_CFG = (1 << 0), -++ ERR_DATA_LEN = (1 << 1), -++ ERR_DESC_NFRAG_NUM = (1 << 2), /* bit2 */ -++ ERR_DESC_IP_HDR_LEN = (1 << 3), /* bit3 */ -++ ERR_DESC_PROT_HDR_LEN = (1 << 4), /* bit4 */ -++ ERR_DESC_MTU = (1 << 5), /* bit5 */ -++ ERR_LINK_SGPKT_LEN = (1 << 8), /* bit8 */ -++ ERR_LINK_TSOPKT_LINEAR = (1 << 9), /* bit9 */ -++ ERR_LINK_NFRAG_LEN = (1 << 10), /* bit10 */ -++ ERR_LINK_TOTAL_LEN = (1 << 11), /* bit11 */ -++ ERR_HDR_TCP_BCMC = (1 << 12), /* bit12 */ -++ ERR_HDR_UDP_BC = (1 << 13), /* bit13 */ -++ ERR_HDR_VLAN_IP_TYPE = (1 << 14), /* bit14 */ -++ ERR_HDR_IP_TYPE = (1 << 15), /* bit15 */ -++ ERR_HDR_IP_VERSION = (1 << 16), /* bit16 */ -++ ERR_HDR_IP_HDR_LEN = (1 << 17), /* bit17 */ -++ ERR_HDR_IP_TOTAL_LEN = (1 << 18), /* bit18 */ -++ ERR_HDR_IPV6_TTL_PROT = (1 << 19), /* bit19 */ -++ ERR_HDR_IPV4_OFFSET = (1 << 20), /* bit20 */ -++ ERR_HDR_IPV4_TTL_PROT = (1 << 21), /* bit21 */ -++ ERR_HDR_UDP_LEN = (1 << 22), /* bit22 */ -++ ERR_HDR_TCP_LEN = (1 << 23), /* bit23 */ -++ ERR_DESC = (ERR_DESC_CFG | ERR_DATA_LEN | -++ ERR_DESC_NFRAG_NUM | ERR_DESC_IP_HDR_LEN | -++ ERR_DESC_PROT_HDR_LEN | ERR_DESC_MTU), -++ ERR_LINK = (ERR_LINK_SGPKT_LEN | ERR_LINK_TSOPKT_LINEAR | -++ ERR_LINK_NFRAG_LEN | ERR_LINK_TOTAL_LEN), -++ ERR_HDR = (ERR_HDR_TCP_BCMC | ERR_HDR_UDP_BC | -++ ERR_HDR_VLAN_IP_TYPE | ERR_HDR_IP_TYPE | -++ ERR_HDR_IP_VERSION | ERR_HDR_IP_HDR_LEN | -++ ERR_HDR_IP_TOTAL_LEN | ERR_HDR_IPV6_TTL_PROT | -++ ERR_HDR_IPV4_OFFSET | ERR_HDR_IPV4_TTL_PROT | -++ ERR_HDR_UDP_LEN | ERR_HDR_TCP_LEN), -++ ERR_ALL = (ERR_DESC | ERR_LINK | ERR_HDR), -++}; -++ -++#define GMAC_DRIVER_NAME "gmac_v200" -++ -++#define GMAC_MAC_CLK_NAME "gmac_clk" -++#define GMAC_MACIF_CLK_NAME "macif_clk" -++ -++#define GMAC_PORT_RST_NAME "port_reset" -++#define GMAC_MACIF_RST_NAME "macif_reset" -++#define GMAC_PHY_RST_NAME "phy_reset" -++ -++#define GMAC_IOSIZE 0x1000 -++#define GMAC_OFFSET (GMAC_IOSIZE) -++ -++#define RX_BQ_IN_INT BIT(17) -++#define TX_RQ_IN_INT BIT(19) -++#define RX_BQ_IN_TIMEOUT_INT BIT(28) -++#define TX_RQ_IN_TIMEOUT_INT BIT(29) -++ -++#define DEF_INT_MASK (RX_BQ_IN_INT | RX_BQ_IN_TIMEOUT_INT | \ -++ TX_RQ_IN_INT | TX_RQ_IN_TIMEOUT_INT) -++ -++/* write or read descriptor need memory barrier */ -++#define gmac_sync_barrier() do { isb(); smp_mb(); } while (0) -++ -++#define VENDOR_PHY_ID_FESTAV200 0x20669823 -++#define PHY_ID_KSZ8051MNL 0x00221550 -++#define PHY_ID_KSZ8081RNB 0x00221560 -++#define PHY_ID_UNKNOWN 0x00221513 -++#define DEFAULT_PHY_MASK 0xfffffff0 -++#define REALTEK_PHY_ID_8211E 0x001cc915 -++#define REALTEK_PHY_MASK 0x001fffff -++ -++enum { -++ GMAC_PORT0, -++ GMAC_PORT1, -++ GMAC_MAX_PORT, -++}; -++ -++enum { -++ MEM_GMAC_IOBASE, -++ MEM_MACIF_IOBASE, -++ MEM_AXI_BUS_CFG_IOBASE, -++ MEM_FWD_IOBASE, -++ MEM_CTRL_IOBASE, -++}; -++ -++#define GMAC_LINKED BIT(0) -++#define GMAC_DUP_FULL BIT(1) -++#define GMAC_SPD_10M BIT(2) -++#define GMAC_SPD_100M BIT(3) -++#define GMAC_SPD_1000M BIT(4) -++/* Flow Control defines */ -++#define FLOW_OFF 0 -++#define FLOW_RX 1 -++#define FLOW_TX 2 -++#define FLOW_AUTO (FLOW_TX | FLOW_RX) -++ -++#define RX_BQ_INT_THRESHOLD 0x40 -++#define TX_RQ_INT_THRESHOLD 0x20 -++ -++#define GMAC_MONITOR_TIMER (msecs_to_jiffies(200)) -++ -++#define ETH_MAX_FRAME_SIZE (1600 + 128) -++#define SKB_SIZE (ETH_MAX_FRAME_SIZE) -++ -++#define DESC_VLD_FREE 0 -++#define DESC_VLD_BUSY 1 -++ -++#define DESC_FL_FIRST 2 -++#define DESC_FL_MID 0 -++#define DESC_FL_LAST 1 -++#define DESC_FL_FULL 3 -++ -++#if defined(CONFIG_GMAC_DESC_4WORD) -++#define DESC_WORD_SHIFT 2 -++#else -++#define DESC_WORD_SHIFT 3 -++#endif -++#define DESC_BYTE_SHIFT (DESC_WORD_SHIFT + 2) -++#define DESC_WORD_CNT (1 << DESC_WORD_SHIFT) -++#define DESC_SIZE (1 << DESC_BYTE_SHIFT) -++ -++#define RX_DESC_NUM 1024 -++#define TX_DESC_NUM 1024 -++ -++/* DMA descriptor ring helpers */ -++#define dma_ring_incr(n, s) (((n) + 1) & ((s) - 1)) -++#define dma_cnt(n) ((n) >> DESC_BYTE_SHIFT) -++#define dma_byte(n) ((n) << DESC_BYTE_SHIFT) -++ -++#define RSS_HASH_KEY_SIZE 4 -++#define RSS_INDIRECTION_TABLE_SIZE 128 -++#define RSS_NUM_RXQS 4 -++ -++#define HW_CAP_TSO BIT(0) -++#define HW_CAP_RXCSUM BIT(1) -++#define HW_CAP_CCI BIT(2) -++#define has_cap_tso(hw_cap) ((hw_cap) & HW_CAP_TSO) -++#define has_cap_rxcsum(hw_cap) ((hw_cap) & HW_CAP_RXCSUM) -++ -++#define GMAC_TRACE_LEVEL 10 -++#define GMAC_NORMAL_LEVEL 7 -++ -++#define mk_bits(shift, nbits) ((((shift) & 0x1F) << 16) | ((nbits) & 0x3F)) -++ -++#define FC_ACTIVE_MIN 1 -++#define FC_ACTIVE_DEFAULT 16 -++#define FC_ACTIVE_MAX 127 -++#define FC_DEACTIVE_MIN 1 -++#define FC_DEACTIVE_DEFAULT 32 -++#define FC_DEACTIVE_MAX 127 -++ -++#define FC_PAUSE_TIME_DEFAULT 0xFFFF -++#define FC_PAUSE_INTERVAL_DEFAULT 0xFFFF -++#define FC_PAUSE_TIME_MAX 0xFFFF -++ -++#define HW_CAP_EN 0x0c00 -++#define BIT_RSS_CAP BIT(0) -++#define BIT_RXHASH_CAP BIT(1) -++#define RSS_HASH_KEY 0x0c04 -++#define RSS_HASH_CONFIG 0x0c08 -++#define TCPV4_L3_HASH_EN BIT(0) -++#define TCPV4_L4_HASH_EN BIT(1) -++#define TCPV4_VLAN_HASH_EN BIT(2) -++#define UDPV4_L3_HASH_EN BIT(4) -++#define UDPV4_L4_HASH_EN BIT(5) -++#define UDPV4_VLAN_HASH_EN BIT(6) -++#define IPV4_L3_HASH_EN BIT(8) -++#define IPV4_VLAN_HASH_EN BIT(9) -++#define TCPV6_L3_HASH_EN BIT(12) -++#define TCPV6_L4_HASH_EN BIT(13) -++#define TCPV6_VLAN_HASH_EN BIT(14) -++#define UDPV6_L3_HASH_EN BIT(16) -++#define UDPV6_L4_HASH_EN BIT(17) -++#define UDPV6_VLAN_HASH_EN BIT(18) -++#define IPV6_L3_HASH_EN BIT(20) -++#define IPV6_VLAN_HASH_EN BIT(21) -++#define DEF_HASH_CFG 0x377377 -++ -++#define RGMII_SPEED_1000 0x2c -++#define RGMII_SPEED_100 0x2f -++#define RGMII_SPEED_10 0x2d -++#define MII_SPEED_100 0x0f -++#define MII_SPEED_10 0x0d -++#define RMII_SPEED_100 0x8f -++#define RMII_SPEED_10 0x8d -++#define GMAC_FULL_DUPLEX BIT(4) -++ -++/* tso stuff */ -++#define SG_FLAG BIT(30) -++#define COE_FLAG BIT(29) -++#define TSO_FLAG BIT(28) -++#define VLAN_FLAG BIT(10) -++#define IPV6_FLAG BIT(9) -++#define UDP_FLAG BIT(8) -++ -++#define PKT_IPV6_HDR_LEN 10 -++#define PKT_UDP_HDR_LEN 2 -++#define WORD_TO_BYTE 4 -++enum { -++ PKT_NORMAL, -++ PKT_SG -++}; -++ -++enum { -++ PKT_IPV4, -++ PKT_IPV6 -++}; -++ -++enum { -++ PKT_TCP, -++ PKT_UDP -++}; -++ -++struct frags_info { -++ /* Word(2*i+2) */ -++ u32 addr; -++ /* Word(2*i+3) */ -++ u32 size : 16; -++ u32 reserved : 16; -++}; -++ -++struct sg_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 18 */ -++ struct frags_info frags[18]; -++}; -++/* tso stuff end */ -++ -++#if defined(CONFIG_GMAC_DESC_4WORD) -++struct gmac_desc { -++ unsigned int data_buff_addr; -++ -++ unsigned int buffer_len : 11; -++#if defined(CONFIG_GMAC_RXCSUM) -++ unsigned int reserve2 : 1; -++ unsigned int payload_csum_err : 1; -++ unsigned int header_csum_err : 1; -++ unsigned int payload_csum_done : 1; -++ unsigned int header_csum_done : 1; -++#else -++ unsigned int reserve2 : 5; -++#endif -++ unsigned int data_len : 11; -++ unsigned int reserve1 : 2; -++ unsigned int fl : 2; -++ unsigned int descvid : 1; -++ -++ unsigned int rxhash; -++ unsigned int reserve3 : 8; -++ unsigned int l3_hash : 1; -++ unsigned int has_hash : 1; -++ unsigned int skb_id : 14; -++ unsigned int reserve31 : 8; -++}; -++ -++struct gmac_tso_desc { -++ unsigned int data_buff_addr; -++ union { -++ struct { -++ unsigned int prot_hdr_len : 4; -++ unsigned int ip_hdr_len : 4; -++ unsigned int prot_type : 1; -++ unsigned int ip_ver : 1; -++ unsigned int vlan_flag : 1; -++ unsigned int nfrags_num : 5; -++ unsigned int data_len : 11; -++ unsigned int reservel : 1; -++ unsigned int tso_flag : 1; -++ unsigned int coe_flag : 1; -++ unsigned int sg_flag : 1; -++ unsigned int hw_own : 1; -++ } tx; -++ unsigned int val; -++ } desc1; -++ unsigned int reserve_desc2; -++ unsigned int tx_err; -++}; -++#else -++struct gmac_desc { -++ unsigned int data_buff_addr; -++ -++ unsigned int buffer_len : 11; -++#if defined(CONFIG_GMAC_RXCSUM) -++ unsigned int reserve2 : 1; -++ unsigned int payload_csum_err : 1; -++ unsigned int header_csum_err : 1; -++ unsigned int payload_csum_done : 1; -++#else -++ unsigned int reserve2 : 5; -++#endif -++ unsigned int data_len : 11; -++ unsigned int reserve1 : 2; -++ unsigned int fl : 2; -++ unsigned int descvid : 1; -++ -++ unsigned int rxhash; -++ unsigned int reserve3 : 8; -++ unsigned int l3_hash : 1; -++ unsigned int has_hash : 1; -++ unsigned int skb_id : 14; -++ unsigned int reserve31 : 8; -++ -++ unsigned int reserve4; -++ unsigned int reserve5; -++ unsigned int reserve6; -++ unsigned int reserve7; -++}; -++ -++struct gmac_tso_desc { -++ unsigned int data_buff_addr; -++ union { -++ struct { -++ unsigned int prot_hdr_len : 4; -++ unsigned int ip_hdr_len : 4; -++ unsigned int prot_type : 1; -++ unsigned int ip_ver : 1; -++ unsigned int vlan_flag : 1; -++ unsigned int nfrags_num : 5; -++ unsigned int data_len : 11; -++ unsigned int reservel : 1; -++ unsigned int tso_flag : 1; -++ unsigned int coe_flag : 1; -++ unsigned int sg_flag : 1; -++ unsigned int hw_own : 1; -++ } tx; -++ unsigned int val; -++ } desc1; -++ unsigned int reserve_desc2; -++ unsigned int reserve3; -++ -++ unsigned int tx_err; -++ unsigned int reserve5; -++ unsigned int reserve6; -++ unsigned int reserve7; -++}; -++#endif -++ -++#define SKB_MAGIC ((struct sk_buff *)0x5a) -++ -++struct gmac_napi { -++ struct napi_struct napi; -++ struct gmac_netdev_local *ndev_priv; -++ int rxq_id; -++}; -++ -++struct gmac_rss_info { -++ u32 hash_cfg; -++ u32 ind_tbl_size; -++ u8 ind_tbl[RSS_INDIRECTION_TABLE_SIZE]; -++ u8 key[RSS_HASH_KEY_SIZE]; -++}; -++ -++#define QUEUE_NUMS 4 -++#define BASE_QUEUE_NUMS 3 -++ -++struct gmac_netdev_local { -++#define GMAC_SG_DESC_ADD 64U -++ struct sg_desc *dma_sg_desc ____cacheline_aligned; -++ dma_addr_t dma_sg_phy; -++ unsigned int sg_head; -++ unsigned int sg_tail; -++ unsigned int sg_count; -++ -++ void __iomem *gmac_iobase; -++ void __iomem *macif_base; -++ void __iomem *axi_bus_cfg_base; -++ int index; /* 0 -- mac0, 1 -- mac1 */ -++ -++ u32 hw_cap; -++ bool tso_supported; -++ bool has_rxhash_cap; -++ bool has_rss_cap; -++ int num_rxqs; -++ struct gmac_napi q_napi[RSS_NUM_RXQS]; -++ int irq[RSS_NUM_RXQS]; -++ struct gmac_rss_info rss_info; -++ -++ struct reset_control *port_rst; -++ struct reset_control *macif_rst; -++ struct reset_control *phy_rst; -++ -++ struct { -++ struct gmac_desc *desc; -++ dma_addr_t phys_addr; -++ int *sg_desc_offset; -++ /* how many desc in the desc pool */ -++ unsigned int count; -++ struct sk_buff **skb; -++ unsigned int size; -++ } pool[QUEUE_NUMS + RSS_NUM_RXQS - 1]; -++#define RX_FQ pool[0] -++#define RX_BQ pool[1] -++#define TX_BQ pool[2] -++#define TX_RQ pool[3] -++ -++ struct sk_buff **tx_skb; -++ struct sk_buff **rx_skb; -++ -++ struct device *dev; -++ struct net_device *netdev; -++ struct clk *clk; -++ struct clk *macif_clk; -++ -++ struct gmac_adapter *adapter; -++ -++ struct timer_list monitor; -++ -++ char phy_name[MII_BUS_ID_SIZE]; -++ struct phy_device *phy; -++ struct device_node *phy_node; -++ phy_interface_t phy_mode; -++ bool autoeee; -++ bool internal_phy; -++ int (*eee_init)(struct phy_device *phy_dev); -++ -++ unsigned int flow_ctrl; -++ unsigned int pause; -++ unsigned int pause_interval; -++ unsigned int flow_ctrl_active_threshold; -++ unsigned int flow_ctrl_deactive_threshold; -++ -++ int old_link; -++ int old_speed; -++ int old_duplex; -++ -++ /* receive packet lock */ -++ spinlock_t rxlock; -++ /* transmit packet lock */ -++ spinlock_t txlock; -++ /* power management lock */ -++ spinlock_t pmtlock; -++ -++ int dev_state; /* INIT/OPEN/CLOSE */ -++ char pm_state; -++ bool wol_enable; -++ u32 msg_enable; -++#define INIT 0 /* init gmac */ -++#define OPEN 1 /* power on gmac */ -++#define CLOSE 2 /* power off gmac */ -++}; -++ -++enum tso_version { -++ VER_NO_TSO = 0x0, -++ VER_BYTE_SPLICE = 0x1, -++ VER_SG_COE = 0x2, -++ VER_TSO = 0x3, -++}; -++ -++struct cyclic_queue_info { -++ u32 start; -++ u32 end; -++ u32 num; -++ u32 pos; -++}; -++ -++/* ethtool ops related func */ -++void gmac_set_flow_ctrl_state(struct gmac_netdev_local const *ld, int pause); -++ -++/* netdev ops related func */ -++void gmac_hw_set_mac_addr(struct net_device *dev); -++void gmac_enable_napi(struct gmac_netdev_local *priv); -++void gmac_disable_napi(struct gmac_netdev_local *priv); -++u32 gmac_rx_refill(struct gmac_netdev_local *priv); -++void gmac_enable_rxcsum_drop(struct gmac_netdev_local const *ld, bool drop); -++ -++static inline void gmac_irq_enable(struct gmac_netdev_local const *ld) -++{ -++ if (ld == NULL) -++ return; -++ -++ writel(RX_BQ_IN_INT | RX_BQ_IN_TIMEOUT_INT -++ | TX_RQ_IN_INT | TX_RQ_IN_TIMEOUT_INT, -++ ld->gmac_iobase + ENA_PMU_INT); -++} -++ -++static inline void gmac_irq_enable_queue(struct gmac_netdev_local *ld, unsigned int rxq_id) -++{ -++ if (ld == NULL) -++ return; -++ -++ if (rxq_id) { -++ const u32 reg = rss_ena_int_queue(rxq_id); -++ writel(~0, ld->gmac_iobase + reg); -++ } else { -++ gmac_irq_enable(ld); -++ } -++} -++ -++static inline void gmac_irq_enable_all_queue(struct gmac_netdev_local *ld) -++{ -++ unsigned int i; -++ -++ if (ld == NULL) -++ return; -++ -++ for (i = 0; i < (unsigned int)ld->num_rxqs; i++) -++ gmac_irq_enable_queue(ld, i); -++} -++ -++static inline void gmac_irq_disable(struct gmac_netdev_local const *ld) -++{ -++ if (ld == NULL) -++ return; -++ -++ writel(0, ld->gmac_iobase + ENA_PMU_INT); -++} -++ -++static inline void gmac_irq_disable_queue(struct gmac_netdev_local const *ld, -++ int rxq_id) -++{ -++ if (ld == NULL) -++ return; -++ -++ if (rxq_id) { -++ u32 reg = (u32)rss_ena_int_queue(rxq_id); -++ writel(0, ld->gmac_iobase + reg); -++ } else { -++ gmac_irq_disable(ld); -++ } -++} -++ -++static inline void gmac_irq_disable_all_queue(struct gmac_netdev_local const *ld) -++{ -++ int i; -++ -++ if (ld == NULL) -++ return; -++ -++ for (i = 0; i < ld->num_rxqs; i++) -++ gmac_irq_disable_queue(ld, i); -++} -++ -++static inline bool gmac_queue_irq_disabled(struct gmac_netdev_local *ld, -++ int rxq_id) -++{ -++ u32 reg, val; -++ -++ if (ld == NULL) -++ return false; -++ -++ if (rxq_id) -++ reg = (u32)rss_ena_int_queue(rxq_id); -++ else -++ reg = ENA_PMU_INT; -++ val = readl(ld->gmac_iobase + reg); -++ -++ return !val; -++} -++ -++static inline void gmac_hw_desc_enable(struct gmac_netdev_local const *ld) -++{ -++ if (ld == NULL) -++ return; -++ writel(0xF, ld->gmac_iobase + DESC_WR_RD_ENA); -++} -++ -++static inline void gmac_hw_desc_disable(struct gmac_netdev_local const *ld) -++{ -++ if (ld == NULL) -++ return; -++ writel(0, ld->gmac_iobase + DESC_WR_RD_ENA); -++} -++ -++static inline void gmac_port_enable(struct gmac_netdev_local const *ld) -++{ -++ if (ld == NULL) -++ return; -++ writel(BITS_TX_EN | BITS_RX_EN, ld->gmac_iobase + PORT_EN); -++} -++ -++static inline void gmac_port_disable(struct gmac_netdev_local const *ld) -++{ -++ if (ld != NULL) -++ writel(0, ld->gmac_iobase + PORT_EN); -++} -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.c b/drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.c -+new file mode 100755 -+index 000000000..646a93d56 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.c -+@@ -0,0 +1,401 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++ -++#include "gmac.h" -++#include "gmac_ethtool_ops.h" -++ -++void gmac_get_drvinfo(struct net_device *net_dev, -++ struct ethtool_drvinfo *info) -++{ -++ if (info == NULL) -++ return; -++ if (strncpy_s(info->driver, sizeof(info->driver), "gmac driver", sizeof(info->driver))) -++ printk("strncpy_s err : %s %d.\n", __func__, __LINE__); -++ if (strncpy_s(info->version, sizeof(info->version), "gmac v200", sizeof(info->version))) -++ printk("strncpy_s err : %s %d.\n", __func__, __LINE__); -++ if (strncpy_s(info->bus_info, sizeof(info->bus_info), "platform", sizeof(info->bus_info))) -++ printk("strncpy_s err : %s %d.\n", __func__, __LINE__); -++} -++ -++unsigned int gmac_get_link(struct net_device *net_dev) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(net_dev); -++ -++ return ld->phy->link ? GMAC_LINKED : 0; -++} -++ -++void gmac_get_pauseparam(struct net_device *net_dev, -++ struct ethtool_pauseparam *pause) -++{ -++ struct gmac_netdev_local *ld = NULL; -++ if (net_dev == NULL || pause == NULL) -++ return; -++ ld = netdev_priv(net_dev); -++ -++ pause->rx_pause = 0; -++ pause->tx_pause = 0; -++ pause->autoneg = ld->phy->autoneg; -++ -++ if (ld->phy->pause && (ld->flow_ctrl & FLOW_RX)) -++ pause->rx_pause = 1; -++ if (ld->phy->pause && (ld->flow_ctrl & FLOW_TX)) -++ pause->tx_pause = 1; -++} -++ -++int gmac_set_pauseparam(struct net_device *net_dev, -++ struct ethtool_pauseparam *pause) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(net_dev); -++ struct phy_device *phy = ld->phy; -++ unsigned int new_pause = FLOW_OFF; -++ -++ if (pause == NULL) -++ return -ENOMEM; -++ -++ if (pause->rx_pause) -++ new_pause |= FLOW_RX; -++ if (pause->tx_pause) -++ new_pause |= FLOW_TX; -++ -++ if (new_pause != ld->flow_ctrl) -++ ld->flow_ctrl = new_pause; -++ -++ gmac_set_flow_ctrl_state(ld, phy->pause); -++ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phy->advertising); -++ if (ld->flow_ctrl) -++ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phy->advertising); -++ -++ if (phy->autoneg) { -++ if (netif_running(net_dev)) -++ return phy_start_aneg(phy); -++ } -++ -++ return 0; -++} -++ -++u32 gmac_ethtool_getmsglevel(struct net_device *ndev) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ -++ return priv->msg_enable; -++} -++ -++void gmac_ethtool_setmsglevel(struct net_device *ndev, u32 level) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ -++ priv->msg_enable = level; -++} -++ -++u32 gmac_get_rxfh_key_size(struct net_device *ndev) -++{ -++ return RSS_HASH_KEY_SIZE; -++} -++ -++u32 gmac_get_rxfh_indir_size(struct net_device *ndev) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ -++ return priv->rss_info.ind_tbl_size; -++} -++ -++int gmac_get_rxfh(struct net_device *ndev, u32 *indir, u8 *hkey, -++ u8 *hfunc) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ struct gmac_rss_info *rss = &priv->rss_info; -++ -++ if (hfunc != NULL) -++ *hfunc = ETH_RSS_HASH_TOP; -++ -++ if (hkey != NULL) -++ if (memcpy_s(hkey, RSS_HASH_KEY_SIZE, rss->key, RSS_HASH_KEY_SIZE) < 0) -++ printk("memcpy_s err : %s %d.\n", __func__, __LINE__); -++ -++ if (indir != NULL) { -++ int i; -++ -++ for (i = 0; i < rss->ind_tbl_size; i++) -++ indir[i] = rss->ind_tbl[i]; -++ } -++ -++ return 0; -++} -++ -++void gmac_get_rss_key(struct gmac_netdev_local *priv) -++{ -++ struct gmac_rss_info *rss = NULL; -++ u32 hkey; -++ if (priv == NULL) -++ return; -++ rss = &priv->rss_info; -++ hkey = readl(priv->gmac_iobase + RSS_HASH_KEY); -++ *((u32 *)rss->key) = hkey; -++} -++ -++static void gmac_set_rss_key(struct gmac_netdev_local *priv) -++{ -++ struct gmac_rss_info *rss = &priv->rss_info; -++ -++ writel(*((u32 *)rss->key), priv->gmac_iobase + RSS_HASH_KEY); -++} -++ -++static int gmac_wait_rss_ready(struct gmac_netdev_local const *priv) -++{ -++ void __iomem *base = priv->gmac_iobase; -++ int i; -++ const int timeout = 10000; -++ -++ for (i = 0; !(readl(base + RSS_IND_TBL) & BIT_IND_TBL_READY); i++) { -++ if (i == timeout) { -++ netdev_err(priv->netdev, "wait rss ready timeout!\n"); -++ return -ETIMEDOUT; -++ } -++ usleep_range(10, 20); /* wait 10~20us */ -++ } -++ -++ return 0; -++} -++ -++ -++static void gmac_config_rss(struct gmac_netdev_local *priv) -++{ -++ struct gmac_rss_info *rss = NULL; -++ u32 rss_val; -++ unsigned int i; -++ if (priv == NULL) -++ return; -++ rss = &priv->rss_info; -++ for (i = 0; i < rss->ind_tbl_size; i++) { -++ if (gmac_wait_rss_ready(priv) != 0) -++ break; -++ rss_val = BIT_IND_TLB_WR | (rss->ind_tbl[i] << 8) | i; /* shift 8 */ -++ writel(rss_val, priv->gmac_iobase + RSS_IND_TBL); -++ } -++} -++ -++void gmac_get_rss(struct gmac_netdev_local *priv) -++{ -++ struct gmac_rss_info *rss = NULL; -++ u32 rss_val; -++ int i; -++ if (priv == NULL) -++ return; -++ rss = &priv->rss_info; -++ for (i = 0; i < rss->ind_tbl_size; i++) { -++ if (gmac_wait_rss_ready(priv) != 0) -++ break; -++ writel(i, priv->gmac_iobase + RSS_IND_TBL); -++ if (gmac_wait_rss_ready(priv) != 0) -++ break; -++ rss_val = readl(priv->gmac_iobase + RSS_IND_TBL); -++ rss->ind_tbl[i] = (rss_val >> 10) & 0x3; /* right shift 10 */ -++ } -++} -++ -++int gmac_set_rxfh(struct net_device *ndev, const u32 *indir, -++ const u8 *hkey, const u8 hfunc) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ struct gmac_rss_info *rss = &priv->rss_info; -++ -++ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) -++ return -EOPNOTSUPP; -++ -++ if (indir != NULL) { -++ int i; -++ -++ for (i = 0; i < rss->ind_tbl_size; i++) -++ rss->ind_tbl[i] = indir[i]; -++ } -++ -++ if (hkey != NULL) { -++ if (memcpy_s(rss->key, RSS_HASH_KEY_SIZE, hkey, RSS_HASH_KEY_SIZE) < 0) -++ printk("memcpy_s err : %s %d.\n", __func__, __LINE__); -++ gmac_set_rss_key(priv); -++ } -++ -++ gmac_config_rss(priv); -++ -++ return 0; -++} -++ -++static void gmac_get_rss_hash(struct ethtool_rxnfc *info, u32 hash_cfg, -++ u32 l3_hash_en, u32 l4_hash_en, u32 vlan_hash_en) -++{ -++ if (hash_cfg & l3_hash_en) -++ info->data |= RXH_IP_SRC | RXH_IP_DST; -++ if (hash_cfg & l4_hash_en) -++ info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; -++ if (hash_cfg & vlan_hash_en) -++ info->data |= RXH_VLAN; -++} -++ -++static int gmac_get_rss_hash_opts(struct gmac_netdev_local const *priv, -++ struct ethtool_rxnfc *info) -++{ -++ u32 hash_cfg = priv->rss_info.hash_cfg; -++ -++ info->data = 0; -++ -++ switch (info->flow_type) { -++ case TCP_V4_FLOW: -++ gmac_get_rss_hash(info, hash_cfg, TCPV4_L3_HASH_EN, TCPV4_L4_HASH_EN, -++ TCPV4_VLAN_HASH_EN); -++ break; -++ case TCP_V6_FLOW: -++ gmac_get_rss_hash(info, hash_cfg, TCPV6_L3_HASH_EN, TCPV6_L4_HASH_EN, -++ TCPV6_VLAN_HASH_EN); -++ break; -++ case UDP_V4_FLOW: -++ gmac_get_rss_hash(info, hash_cfg, UDPV4_L3_HASH_EN, UDPV4_L4_HASH_EN, -++ UDPV4_VLAN_HASH_EN); -++ break; -++ case UDP_V6_FLOW: -++ gmac_get_rss_hash(info, hash_cfg, UDPV6_L3_HASH_EN, UDPV6_L4_HASH_EN, -++ UDPV6_VLAN_HASH_EN); -++ break; -++ case IPV4_FLOW: -++ gmac_get_rss_hash(info, hash_cfg, IPV4_L3_HASH_EN, 0, -++ IPV4_VLAN_HASH_EN); -++ break; -++ case IPV6_FLOW: -++ gmac_get_rss_hash(info, hash_cfg, IPV6_L3_HASH_EN, 0, -++ IPV6_VLAN_HASH_EN); -++ break; -++ default: -++ return -EINVAL; -++ } -++ -++ return 0; -++} -++ -++int gmac_get_rxnfc(struct net_device *ndev, -++ struct ethtool_rxnfc *info, u32 *rules) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ int ret = -EOPNOTSUPP; -++ if (info == NULL) -++ return -EINVAL; -++ switch (info->cmd) { -++ case ETHTOOL_GRXRINGS: -++ info->data = priv->num_rxqs; -++ ret = 0; -++ break; -++ case ETHTOOL_GRXFH: -++ return gmac_get_rss_hash_opts(priv, info); -++ default: -++ break; -++ } -++ return ret; -++} -++ -++void gmac_config_hash_policy(struct gmac_netdev_local const *priv) -++{ -++ if (priv == NULL) -++ return; -++ writel(priv->rss_info.hash_cfg, priv->gmac_iobase + RSS_HASH_CONFIG); -++} -++ -++static int gmac_set_tcp_udp_hash_cfg(struct ethtool_rxnfc const *info, -++ u32 *hash_cfg, u32 l4_mask, u32 vlan_mask) -++{ -++ switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { -++ case 0: // all bits is 0 -++ *hash_cfg &= ~l4_mask; -++ break; -++ case (RXH_L4_B_0_1 | RXH_L4_B_2_3): -++ *hash_cfg |= l4_mask; -++ break; -++ default: -++ return -EINVAL; -++ } -++ if (info->data & RXH_VLAN) -++ *hash_cfg |= vlan_mask; -++ else -++ *hash_cfg &= ~vlan_mask; -++ return 0; -++} -++ -++static int gmac_ip_hash_cfg(struct ethtool_rxnfc const *info, -++ u32 *hash_cfg, u32 vlan_mask) -++{ -++ if (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) -++ return -EINVAL; -++ if (info->data & RXH_VLAN) -++ *hash_cfg |= vlan_mask; -++ else -++ *hash_cfg &= ~vlan_mask; -++ return 0; -++} -++ -++static int gmac_set_rss_hash_opts(struct gmac_netdev_local *priv, -++ struct ethtool_rxnfc const *info) -++{ -++ u32 hash_cfg; -++ if (priv == NULL || priv->netdev == NULL) -++ return -EINVAL; -++ hash_cfg = priv->rss_info.hash_cfg; -++ netdev_info(priv->netdev, "Set RSS flow type = %d, data = %lld\n", -++ info->flow_type, info->data); -++ -++ if (!(info->data & RXH_IP_SRC) || !(info->data & RXH_IP_DST)) -++ return -EINVAL; -++ -++ switch (info->flow_type) { -++ case TCP_V4_FLOW: -++ if (gmac_set_tcp_udp_hash_cfg(info, &hash_cfg, -++ TCPV4_L4_HASH_EN, TCPV4_VLAN_HASH_EN) == -EINVAL) -++ return -EINVAL; -++ break; -++ case TCP_V6_FLOW: -++ if (gmac_set_tcp_udp_hash_cfg(info, &hash_cfg, -++ TCPV6_L4_HASH_EN, TCPV6_VLAN_HASH_EN) == -EINVAL) -++ return -EINVAL; -++ break; -++ case UDP_V4_FLOW: -++ if (gmac_set_tcp_udp_hash_cfg(info, &hash_cfg, -++ UDPV4_L4_HASH_EN, UDPV4_L4_HASH_EN) == -EINVAL) -++ return -EINVAL; -++ break; -++ case UDP_V6_FLOW: -++ if (gmac_set_tcp_udp_hash_cfg(info, &hash_cfg, -++ UDPV6_L4_HASH_EN, UDPV6_L4_HASH_EN) == -EINVAL) -++ return -EINVAL; -++ break; -++ case IPV4_FLOW: -++ if (gmac_ip_hash_cfg(info, &hash_cfg, -++ IPV4_VLAN_HASH_EN) == -EINVAL) -++ return -EINVAL; -++ break; -++ case IPV6_FLOW: -++ if (gmac_ip_hash_cfg(info, &hash_cfg, -++ IPV6_VLAN_HASH_EN) == -EINVAL) -++ return -EINVAL; -++ break; -++ default: -++ return -EINVAL; -++ } -++ -++ priv->rss_info.hash_cfg = hash_cfg; -++ gmac_config_hash_policy(priv); -++ -++ return 0; -++} -++ -++int gmac_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *info) -++{ -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ if (info == NULL) -++ return -EINVAL; -++ switch (info->cmd) { -++ case ETHTOOL_SRXFH: -++ return gmac_set_rss_hash_opts(priv, info); -++ default: -++ break; -++ } -++ return -EOPNOTSUPP; -++} -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.h b/drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.h -+new file mode 100755 -+index 000000000..f77681838 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_ethtool_ops.h -+@@ -0,0 +1,35 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef GMAC_ETHTOOL_OPS_H -++#define GMAC_ETHTOOL_OPS_H -++ -++#include "gmac.h" -++ -++void gmac_get_drvinfo(struct net_device *net_dev, -++ struct ethtool_drvinfo *info); -++unsigned int gmac_get_link(struct net_device *net_dev); -++int gmac_get_settings(struct net_device *net_dev, struct ethtool_cmd *cmd); -++int gmac_set_settings(struct net_device *net_dev, struct ethtool_cmd *cmd); -++void gmac_get_pauseparam(struct net_device *net_dev, -++ struct ethtool_pauseparam *pause); -++int gmac_set_pauseparam(struct net_device *net_dev, -++ struct ethtool_pauseparam *pause); -++u32 gmac_ethtool_getmsglevel(struct net_device *ndev); -++void gmac_ethtool_setmsglevel(struct net_device *ndev, u32 level); -++u32 gmac_get_rxfh_key_size(struct net_device *ndev); -++u32 gmac_get_rxfh_indir_size(struct net_device *ndev); -++int gmac_get_rxfh(struct net_device *ndev, u32 *indir, u8 *hkey, u8 *hfunc); -++int gmac_set_rxfh(struct net_device *ndev, const u32 *indir, -++ const u8 *hkey, const u8 hfunc); -++int gmac_get_rxnfc(struct net_device *ndev, -++ struct ethtool_rxnfc *info, u32 *rules); -++int gmac_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *info); -++ -++/* gmac.c related func */ -++void gmac_get_rss_key(struct gmac_netdev_local *priv); -++void gmac_get_rss(struct gmac_netdev_local *priv); -++void gmac_config_hash_policy(struct gmac_netdev_local const *priv); -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.c b/drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.c -+new file mode 100755 -+index 000000000..027b16c0b -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.c -+@@ -0,0 +1,730 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++ -++#include "gmac_pm.h" -++#include "gmac_proc.h" -++#include "gmac_netdev_ops.h" -++ -++int gmac_net_open(struct net_device *dev) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ unsigned long flags; -++ -++ clk_prepare_enable(ld->macif_clk); -++ clk_prepare_enable(ld->clk); -++ -++ /* -++ * If we configure mac address by -++ * "ifconfig ethX hw ether XX:XX:XX:XX:XX:XX", -++ * the ethX must be down state and mac core clock is disabled -++ * which results the mac address has not been configured -++ * in mac core register. -++ * So we must set mac address again here, -++ * because mac core clock is enabled at this time -++ * and we can configure mac address to mac core register. -++ */ -++ gmac_hw_set_mac_addr(dev); -++ -++ /* -++ * We should use netif_carrier_off() here, -++ * because the default state should be off. -++ * And this call should before phy_start(). -++ */ -++ netif_carrier_off(dev); -++ gmac_enable_napi(ld); -++ phy_start(ld->phy); -++ -++ gmac_hw_desc_enable(ld); -++ gmac_port_enable(ld); -++ gmac_irq_enable_all_queue(ld); -++ -++ spin_lock_irqsave(&ld->rxlock, flags); -++ gmac_rx_refill(ld); -++ spin_unlock_irqrestore(&ld->rxlock, flags); -++ -++ ld->monitor.expires = jiffies + GMAC_MONITOR_TIMER; -++ mod_timer(&ld->monitor, ld->monitor.expires); -++ -++ netif_start_queue(dev); -++ -++ return 0; -++} -++ -++int gmac_net_close(struct net_device *dev) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ -++ gmac_irq_disable_all_queue(ld); -++ gmac_hw_desc_disable(ld); -++ -++ gmac_disable_napi(ld); -++ -++ netif_carrier_off(dev); -++ netif_stop_queue(dev); -++ -++ phy_stop(ld->phy); -++ del_timer_sync(&ld->monitor); -++ -++ clk_disable_unprepare(ld->clk); -++ clk_disable_unprepare(ld->macif_clk); -++ -++ return 0; -++} -++ -++static int gmac_check_skb_len(struct sk_buff *skb, struct net_device *dev) -++{ -++ if (skb->len < ETH_HLEN) { -++ dev_kfree_skb_any(skb); -++ dev->stats.tx_errors++; -++ dev->stats.tx_dropped++; -++ return -1; -++ } -++ return 0; -++} -++ -++static int gmac_net_xmit_normal(struct sk_buff *skb, struct net_device *dev, -++ struct gmac_desc *desc, u32 pos) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ dma_addr_t addr; -++ -++ addr = dma_map_single(ld->dev, skb->data, skb->len, DMA_TO_DEVICE); -++ if (unlikely(dma_mapping_error(ld->dev, addr))) { -++ dev_kfree_skb_any(skb); -++ dev->stats.tx_dropped++; -++ ld->tx_skb[pos] = NULL; -++ ld->TX_BQ.skb[pos] = NULL; -++ return -1; -++ } -++ desc->data_buff_addr = (u32)addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ desc->rxhash = (addr >> REG_BIT_WIDTH) & TX_DESC_HI8_MASK; -++#endif -++ desc->buffer_len = ETH_MAX_FRAME_SIZE - 1; -++ desc->data_len = skb->len; -++ desc->fl = DESC_FL_FULL; -++ desc->descvid = DESC_VLD_BUSY; -++ -++ return 0; -++} -++ -++static int gmac_tx_avail(struct gmac_netdev_local const *ld) -++{ -++ unsigned int tx_bq_wr_offset, tx_bq_rd_offset; -++ -++ if (ld == NULL) -++ return -1; -++ -++ tx_bq_wr_offset = readl(ld->gmac_iobase + TX_BQ_WR_ADDR); -++ tx_bq_rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR); -++ -++ return (int)((tx_bq_rd_offset >> DESC_BYTE_SHIFT) + TX_DESC_NUM -++ - (tx_bq_wr_offset >> DESC_BYTE_SHIFT) - 1); -++} -++ -++static netdev_tx_t gmac_sw_gso(struct gmac_netdev_local *ld, -++ struct sk_buff *skb) -++{ -++ struct sk_buff *segs = NULL; -++ struct sk_buff *curr_skb = NULL; -++ int ret; -++ int gso_segs = skb_shinfo(skb)->gso_segs; -++ if (gso_segs == 0 && skb_shinfo(skb)->gso_size != 0) -++ gso_segs = DIV_ROUND_UP(skb->len, skb_shinfo(skb)->gso_size); -++ -++ /* Estimate the number of fragments in the worst case */ -++ if (unlikely(gmac_tx_avail(ld) < gso_segs)) { -++ netif_stop_queue(ld->netdev); -++ if (gmac_tx_avail(ld) < gso_segs) { -++ ld->netdev->stats.tx_dropped++; -++ ld->netdev->stats.tx_fifo_errors++; -++ return NETDEV_TX_BUSY; -++ } -++ netif_wake_queue(ld->netdev); -++ } -++ -++ segs = skb_gso_segment(skb, ld->netdev->features & ~(NETIF_F_CSUM_MASK | -++ NETIF_F_SG | NETIF_F_GSO_SOFTWARE)); -++ if (IS_ERR_OR_NULL(segs)) -++ goto drop; -++ -++ do { -++ curr_skb = segs; -++ segs = segs->next; -++ curr_skb->next = NULL; -++ ret = gmac_net_xmit(curr_skb, ld->netdev); -++ if (unlikely(ret != NETDEV_TX_OK)) -++ pr_err_once("gmac_net_xmit error ret=%d\n", ret); -++ } while (segs != NULL); -++ -++ dev_kfree_skb_any(skb); -++ return NETDEV_TX_OK; -++ -++drop: -++ dev_kfree_skb_any(skb); -++ ld->netdev->stats.tx_dropped++; -++ return NETDEV_TX_OK; -++} -++ -++static int gmac_xmit_gso_sg_frag(struct gmac_netdev_local *ld, -++ struct sk_buff *skb, struct sg_desc *desc_cur, -++ struct gmac_tso_desc *tx_bq_desc, unsigned int desc_pos) -++{ -++ int nfrags = skb_shinfo(skb)->nr_frags; -++ dma_addr_t addr; -++ dma_addr_t dma_addr; -++ int i, ret, len; -++ -++ for (i = 0; i < nfrags; i++) { -++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -++ len = frag->bv_len; -++ -++ dma_addr = skb_frag_dma_map(ld->dev, frag, 0, len, DMA_TO_DEVICE); -++ ret = dma_mapping_error(ld->dev, dma_addr); -++ if (unlikely(ret)) { -++ pr_err("skb frag DMA Mapping fail"); -++ return -EFAULT; -++ } -++ desc_cur->frags[i].addr = (u32)dma_addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ desc_cur->frags[i].reserved = (dma_addr >> REG_BIT_WIDTH) << SG_DESC_HI8_OFFSET; -++#endif -++ desc_cur->frags[i].size = len; -++ } -++ -++ addr = ld->dma_sg_phy + ld->sg_head * sizeof(struct sg_desc); -++ tx_bq_desc->data_buff_addr = (u32)addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) & -++ TX_DESC_HI8_MASK; -++#endif -++ ld->TX_BQ.sg_desc_offset[desc_pos] = ld->sg_head; -++ -++ ld->sg_head = (ld->sg_head + 1) % ld->sg_count; -++ -++ return 0; -++} -++ -++static int gmac_xmit_gso_sg(struct gmac_netdev_local *ld, -++ struct sk_buff *skb, -++ struct gmac_tso_desc *tx_bq_desc, unsigned int desc_pos) -++{ -++ struct sg_desc *desc_cur = NULL; -++ dma_addr_t dma_addr; -++ int ret; -++ -++ if (unlikely(((ld->sg_head + 1) % ld->sg_count) == ld->sg_tail)) { -++ /* SG pkt, but sg desc all used */ -++ pr_err("WARNING: sg desc all used.\n"); -++ return -EBUSY; -++ } -++ -++ desc_cur = ld->dma_sg_desc + ld->sg_head; -++ -++ desc_cur->total_len = skb->len; -++ desc_cur->linear_len = skb_headlen(skb); -++ dma_addr = dma_map_single(ld->dev, skb->data, desc_cur->linear_len, DMA_TO_DEVICE); -++ ret = dma_mapping_error(ld->dev, dma_addr); -++ if (unlikely(ret)) { -++ pr_err("DMA Mapping fail"); -++ return -EFAULT; -++ } -++ desc_cur->linear_addr = (u32)dma_addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ desc_cur->reserv3 = (dma_addr >> REG_BIT_WIDTH) << SG_DESC_HI8_OFFSET; -++#endif -++ ret = gmac_xmit_gso_sg_frag(ld, skb, desc_cur, tx_bq_desc, desc_pos); -++ if (unlikely(ret)) -++ return ret; -++ -++ return 0; -++} -++ -++static int gmac_get_pkt_info(struct gmac_netdev_local *ld, -++ struct sk_buff *skb, struct gmac_tso_desc *tx_bq_desc); -++ -++static int gmac_check_hw_capability(struct sk_buff *skb); -++ -++static int gmac_xmit_gso(struct gmac_netdev_local *ld, struct sk_buff *skb, -++ struct gmac_tso_desc *tx_bq_desc, unsigned int desc_pos) -++{ -++ int pkt_type = PKT_NORMAL; -++ int nfrags = skb_shinfo(skb)->nr_frags; -++ dma_addr_t addr; -++ int ret; -++ -++ if (skb_is_gso(skb) || nfrags) -++ pkt_type = PKT_SG; /* TSO pkt or SG pkt */ -++ -++ ret = gmac_check_hw_capability(skb); -++ if (unlikely(ret)) -++ return ret; -++ -++ ret = gmac_get_pkt_info(ld, skb, tx_bq_desc); -++ if (unlikely(ret)) -++ return ret; -++ -++ if (pkt_type == PKT_NORMAL) { -++ addr = dma_map_single(ld->dev, skb->data, skb->len, DMA_TO_DEVICE); -++ ret = dma_mapping_error(ld->dev, addr); -++ if (unlikely(ret)) { -++ pr_err("Normal Packet DMA Mapping fail.\n"); -++ return -EFAULT; -++ } -++ tx_bq_desc->data_buff_addr = (u32)addr; -++#if defined(CONFIG_GMAC_DDR_64BIT ) -++ tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) & TX_DESC_HI8_MASK; -++#endif -++ } else { -++ ret = gmac_xmit_gso_sg(ld, skb, tx_bq_desc, desc_pos); -++ if (unlikely(ret)) -++ return ret; -++ } -++ -++ return 0; -++} -++ -++netdev_tx_t gmac_net_xmit(struct sk_buff *skb, struct net_device *dev) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ struct gmac_desc *desc = NULL; -++ unsigned long txflags; -++ int ret; -++ u32 pos; -++ -++ if (unlikely(gmac_check_skb_len(skb, dev) < 0)) -++ return NETDEV_TX_OK; -++ -++ /* -++ * if adding gmac_xmit_reclaim here, iperf tcp client -++ * performance will be affected, from 550M(avg) to 513M~300M -++ */ -++ -++ /* software write pointer */ -++ pos = dma_cnt(readl(ld->gmac_iobase + TX_BQ_WR_ADDR)); -++ -++ spin_lock_irqsave(&ld->txlock, txflags); -++ -++ if (unlikely(ld->tx_skb[pos] || ld->TX_BQ.skb[pos])) { -++ dev->stats.tx_dropped++; -++ dev->stats.tx_fifo_errors++; -++ netif_stop_queue(dev); -++ spin_unlock_irqrestore(&ld->txlock, txflags); -++ -++ return NETDEV_TX_BUSY; -++ } -++ -++ ld->TX_BQ.skb[pos] = skb; -++ ld->tx_skb[pos] = skb; -++ -++ desc = ld->TX_BQ.desc + pos; -++ -++ if (ld->tso_supported) { -++ ret = gmac_xmit_gso(ld, skb, (struct gmac_tso_desc *)desc, pos); -++ if (unlikely(ret < 0)) { -++ ld->tx_skb[pos] = NULL; -++ ld->TX_BQ.skb[pos] = NULL; -++ spin_unlock_irqrestore(&ld->txlock, txflags); -++ -++ if (ret == -ENOTSUPP) -++ return gmac_sw_gso(ld, skb); -++ -++ dev_kfree_skb_any(skb); -++ dev->stats.tx_dropped++; -++ return NETDEV_TX_OK; -++ } -++ } else { -++ ret = gmac_net_xmit_normal(skb, dev, desc, pos); -++ if (unlikely(ret < 0)) { -++ spin_unlock_irqrestore(&ld->txlock, txflags); -++ return NETDEV_TX_OK; -++ } -++ } -++ -++ /* -++ * This barrier is important here. It is required to ensure -++ * the ARM CPU flushes it's DMA write buffers before proceeding -++ * to the next instruction, to ensure that GMAC will see -++ * our descriptor changes in memory -++ */ -++ gmac_sync_barrier(); -++ pos = dma_ring_incr(pos, TX_DESC_NUM); -++ writel(dma_byte(pos), ld->gmac_iobase + TX_BQ_WR_ADDR); -++ -++ netif_trans_update(dev); -++ dev->stats.tx_packets++; -++ dev->stats.tx_bytes += skb->len; -++ netdev_sent_queue(dev, skb->len); -++ -++ spin_unlock_irqrestore(&ld->txlock, txflags); -++ -++ return NETDEV_TX_OK; -++} -++ -++/* set gmac's multicast list, here we setup gmac's mc filter */ -++static void gmac_gmac_multicast_list(struct net_device const *dev) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ struct netdev_hw_addr *ha = NULL; -++ unsigned int d; -++ unsigned int rec_filter; -++ -++ rec_filter = readl(ld->gmac_iobase + REC_FILT_CONTROL); -++ /* -++ * when set gmac in promisc mode -++ * a. dev in IFF_PROMISC mode -++ */ -++ if ((dev->flags & IFF_PROMISC)) { -++ /* promisc mode.received all pkgs. */ -++ rec_filter &= ~(BIT_BC_DROP_EN | BIT_MC_MATCH_EN | -++ BIT_UC_MATCH_EN); -++ } else { -++ /* drop uc pkgs with field 'DA' not match our's */ -++ rec_filter |= BIT_UC_MATCH_EN; -++ -++ if (dev->flags & IFF_BROADCAST) /* no broadcast */ -++ rec_filter &= ~BIT_BC_DROP_EN; -++ else -++ rec_filter |= BIT_BC_DROP_EN; -++ -++ if (netdev_mc_empty(dev) || !(dev->flags & IFF_MULTICAST)) { -++ /* haven't join any mc group */ -++ writel(0, ld->gmac_iobase + PORT_MC_ADDR_LOW); -++ writel(0, ld->gmac_iobase + PORT_MC_ADDR_HIGH); -++ rec_filter |= BIT_MC_MATCH_EN; -++ } else if ((netdev_mc_count(dev) == 1) && -++ (dev->flags & IFF_MULTICAST)) { -++ netdev_for_each_mc_addr(ha, dev) { -++ d = (ha->addr[0] << 8) | (ha->addr[1]); /* mac[0]->(15, 8) mac[1]->(7, 0) */ -++ writel(d, ld->gmac_iobase + PORT_MC_ADDR_HIGH); -++ -++ d = (ha->addr[2] << 24) | (ha->addr[3] << 16) | /* mac[2]->(31, 24) mac[3]->(23, 16) */ -++ (ha->addr[4] << 8) | (ha->addr[5]); /* mac[4]->(15, 8) mac[5]->(7, 0) */ -++ writel(d, ld->gmac_iobase + PORT_MC_ADDR_LOW); -++ } -++ rec_filter |= BIT_MC_MATCH_EN; -++ } else { -++ rec_filter &= ~BIT_MC_MATCH_EN; -++ } -++ } -++ writel(rec_filter, ld->gmac_iobase + REC_FILT_CONTROL); -++} -++ -++void gmac_set_multicast_list(struct net_device *dev) -++{ -++ gmac_gmac_multicast_list(dev); -++} -++ -++int gmac_set_features(struct net_device *dev, netdev_features_t features) -++{ -++ struct gmac_netdev_local *ld = netdev_priv(dev); -++ netdev_features_t changed = dev->features ^ features; -++ -++ if (changed & NETIF_F_RXCSUM) { -++ if (features & NETIF_F_RXCSUM) -++ gmac_enable_rxcsum_drop(ld, true); -++ else -++ gmac_enable_rxcsum_drop(ld, false); -++ } -++ -++ return 0; -++} -++ -++int gmac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) -++{ -++ struct gmac_netdev_local *priv = NULL; -++ struct pm_config config; -++ int val = 0; -++ if (ndev == NULL || rq == NULL) -++ return -EINVAL; -++ priv = netdev_priv(ndev); -++ switch (cmd) { -++ case SIOCSETPM: -++ if (rq->ifr_data == NULL || -++ copy_from_user(&config, rq->ifr_data, sizeof(config))) -++ return -EFAULT; -++ return pmt_config(ndev, &config); -++ -++ case SIOCSETSUSPEND: -++ if (rq->ifr_data == NULL || copy_from_user(&val, rq->ifr_data, sizeof(val))) -++ return -EFAULT; -++ return set_suspend(val); -++ -++ case SIOCSETRESUME: -++ if (rq->ifr_data == NULL || copy_from_user(&val, rq->ifr_data, sizeof(val))) -++ return -EFAULT; -++ return set_resume(val); -++ -++ default: -++ if (!netif_running(ndev)) -++ return -EINVAL; -++ -++ if (priv->phy == NULL) -++ return -EINVAL; -++ -++ return phy_mii_ioctl(priv->phy, rq, cmd); -++ } -++ return 0; -++} -++ -++int gmac_net_set_mac_address(struct net_device *dev, void *p) -++{ -++ int ret; -++ -++ ret = eth_mac_addr(dev, p); -++ if (!ret) -++ gmac_hw_set_mac_addr(dev); -++ -++ return ret; -++} -++ -++int eth_change_mtu(struct net_device *dev, int new_mtu) -++{ -++ netdev_warn(dev, "%s is deprecated\n", __func__); -++ dev->mtu = new_mtu; -++ return 0; -++} -++ -++struct net_device_stats *gmac_net_get_stats(struct net_device *dev) -++{ -++ return &dev->stats; -++} -++ -++static void gmac_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 int gmac_get_pkt_info_l3l4(struct gmac_tso_desc *tx_bq_desc, -++ struct sk_buff *skb, unsigned int *l4_proto, unsigned int *max_mss, -++ unsigned char *coe_enable) -++{ -++ __be16 l3_proto; /* level 3 protocol */ -++ int max_data_len = skb->len - ETH_HLEN; -++ -++ l3_proto = skb->protocol; -++ if (skb->protocol == htons(ETH_P_8021Q)) { -++ l3_proto = vlan_get_protocol(skb); -++ tx_bq_desc->desc1.tx.vlan_flag = 1; -++ max_data_len -= VLAN_HLEN; -++ } -++ -++ if (l3_proto == htons(ETH_P_IP)) { -++ struct iphdr *iph; -++ -++ iph = ip_hdr(skb); -++ tx_bq_desc->desc1.tx.ip_ver = PKT_IPV4; -++ tx_bq_desc->desc1.tx.ip_hdr_len = iph->ihl; -++ -++ if ((max_data_len >= GSO_MAX_SIZE) && -++ (ntohs(iph->tot_len) <= (iph->ihl << 2))) /* shift left 2 */ -++ iph->tot_len = htons(GSO_MAX_SIZE - 1); -++ -++ *max_mss -= iph->ihl * WORD_TO_BYTE; -++ *l4_proto = iph->protocol; -++ } else if (l3_proto == htons(ETH_P_IPV6)) { -++ tx_bq_desc->desc1.tx.ip_ver = PKT_IPV6; -++ tx_bq_desc->desc1.tx.ip_hdr_len = PKT_IPV6_HDR_LEN; -++ *max_mss -= PKT_IPV6_HDR_LEN * WORD_TO_BYTE; -++ *l4_proto = ipv6_hdr(skb)->nexthdr; -++ } else { -++ *coe_enable = 0; -++ } -++ -++ if (*l4_proto == IPPROTO_TCP) { -++ tx_bq_desc->desc1.tx.prot_type = PKT_TCP; -++ if (tcp_hdr(skb)->doff < sizeof(struct tcphdr) / WORD_TO_BYTE) -++ return -EFAULT; -++ tx_bq_desc->desc1.tx.prot_hdr_len = tcp_hdr(skb)->doff; -++ *max_mss -= tcp_hdr(skb)->doff * WORD_TO_BYTE; -++ } else if (*l4_proto == IPPROTO_UDP) { -++ tx_bq_desc->desc1.tx.prot_type = PKT_UDP; -++ tx_bq_desc->desc1.tx.prot_hdr_len = PKT_UDP_HDR_LEN; -++ if (l3_proto == htons(ETH_P_IPV6)) -++ *max_mss -= sizeof(struct frag_hdr); -++ } else { -++ *coe_enable = 0; -++ } -++ -++ return 0; -++} -++ -++static int gmac_get_pkt_info(struct gmac_netdev_local *ld, -++ struct sk_buff *skb, struct gmac_tso_desc *tx_bq_desc) -++{ -++ int nfrags; -++ unsigned int l4_proto = IPPROTO_MAX; -++ unsigned int max_mss = ETH_DATA_LEN; -++ unsigned char coe_enable = 0; -++ int ret; -++ if (skb == NULL || tx_bq_desc == NULL) -++ return -EINVAL; -++ -++ nfrags = skb_shinfo(skb)->nr_frags; -++ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) -++ coe_enable = 1; -++ -++ tx_bq_desc->desc1.val = 0; -++ -++ if (skb_is_gso(skb)) { -++ tx_bq_desc->desc1.tx.tso_flag = 1; -++ tx_bq_desc->desc1.tx.sg_flag = 1; -++ } else if (nfrags) { -++ tx_bq_desc->desc1.tx.sg_flag = 1; -++ } -++ -++ ret = gmac_get_pkt_info_l3l4(tx_bq_desc, skb, &l4_proto, &max_mss, -++ &coe_enable); -++ if (ret < 0) -++ return ret; -++ -++ if (skb_is_gso(skb)) -++ tx_bq_desc->desc1.tx.data_len = -++ (skb_shinfo(skb)->gso_size > max_mss) ? max_mss : -++ skb_shinfo(skb)->gso_size; -++ else -++ tx_bq_desc->desc1.tx.data_len = skb->len; -++ -++ if (coe_enable && skb_is_gso(skb) && (l4_proto == IPPROTO_UDP)) -++ gmac_do_udp_checksum(skb); -++ -++ if (coe_enable) -++ tx_bq_desc->desc1.tx.coe_flag = 1; -++ -++ tx_bq_desc->desc1.tx.nfrags_num = nfrags; -++ -++ tx_bq_desc->desc1.tx.hw_own = DESC_VLD_BUSY; -++ return 0; -++} -++ -++static int gmac_check_hw_capability_for_udp(struct sk_buff const *skb) -++{ -++ struct ethhdr *eth; -++ -++ /* hardware can't dea with UFO broadcast packet */ -++ eth = (struct ethhdr *)(skb->data); -++ if (skb_is_gso(skb) && is_broadcast_ether_addr(eth->h_dest)) -++ return -ENOTSUPP; -++ -++ return 0; -++} -++ -++static int gmac_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 -EFAULT; -++ } -++ -++ return 0; -++} -++ -++static __be16 gmac_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 unsigned int gmac_get_l4_proto(struct sk_buff *skb) -++{ -++ __be16 l3_proto; -++ unsigned int l4_proto = IPPROTO_MAX; -++ -++ l3_proto = gmac_get_l3_proto(skb); -++ if (l3_proto == htons(ETH_P_IP)) -++ l4_proto = ip_hdr(skb)->protocol; -++ else if (l3_proto == htons(ETH_P_IPV6)) -++ l4_proto = ipv6_hdr(skb)->nexthdr; -++ -++ return l4_proto; -++} -++ -++static inline bool gmac_skb_is_ipv6(struct sk_buff *skb) -++{ -++ return (gmac_get_l3_proto(skb) == htons(ETH_P_IPV6)); -++} -++ -++static inline bool gmac_skb_is_udp(struct sk_buff *skb) -++{ -++ return (gmac_get_l4_proto(skb) == IPPROTO_UDP); -++} -++ -++static inline bool gmac_skb_is_ipv4_with_options(struct sk_buff *skb) -++{ -++ return ((gmac_get_l3_proto(skb) == htons(ETH_P_IP)) && -++ (ip_hdr(skb)->ihl > IPV4_HEAD_LENGTH)); -++} -++ -++static int gmac_check_hw_capability(struct sk_buff *skb) -++{ -++ int ret; -++ -++ /* -++ * 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 == NULL) -++ return -EINVAL; -++ if (skb_is_gso(skb) && (skb_headlen(skb) > 2048)) /* 2048(2k) */ -++ return -ENOTSUPP; -++ -++ if (gmac_skb_is_ipv6(skb)) { -++ ret = gmac_check_hw_capability_for_ipv6(skb); -++ if (ret) -++ return ret; -++ } -++ -++ if (gmac_skb_is_udp(skb)) { -++ ret = gmac_check_hw_capability_for_udp(skb); -++ if (ret) -++ return ret; -++ } -++ -++ if (((skb->ip_summed == CHECKSUM_PARTIAL) || skb_is_gso(skb)) && -++ gmac_skb_is_ipv4_with_options(skb)) -++ return -ENOTSUPP; -++ -++ return 0; -++} -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.h b/drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.h -+new file mode 100755 -+index 000000000..6d4f088ae -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_netdev_ops.h -+@@ -0,0 +1,22 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef GMAC_NETDEV_OPS_H -++#define GMAC_NETDEV_OPS_H -++ -++#include -++ -++#include "gmac.h" -++ -++int gmac_net_open(struct net_device *dev); -++int gmac_net_close(struct net_device *dev); -++netdev_tx_t gmac_net_xmit(struct sk_buff *skb, struct net_device *dev); -++void gmac_set_multicast_list(struct net_device *dev); -++int gmac_set_features(struct net_device *dev, netdev_features_t features); -++int gmac_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd); -++int gmac_net_set_mac_address(struct net_device *dev, void *p); -++int eth_change_mtu(struct net_device *dev, int new_mtu); -++struct net_device_stats *gmac_net_get_stats(struct net_device *dev); -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.c b/drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.c -+new file mode 100755 -+index 000000000..5267bbb52 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.c -+@@ -0,0 +1,110 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include "gmac_phy_fixup.h" -++ -++static int ksz8051mnl_phy_fix(struct phy_device *phy_dev) -++{ -++ u32 v; -++ int ret; -++ -++ if (phy_dev->interface != PHY_INTERFACE_MODE_RMII) -++ return 0; -++ -++ ret = phy_read(phy_dev, 0x1F); -++ if (ret < 0) -++ return ret; -++ v = ret; -++ v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */ -++ phy_write(phy_dev, 0x1F, v); -++ -++ ret = phy_read(phy_dev, 0x16); -++ if (ret < 0) -++ return ret; -++ v = ret; -++ v |= (1 << 1); /* set phy RMII override; */ -++ phy_write(phy_dev, 0x16, v); -++ -++ return 0; -++} -++ -++static int ksz8081rnb_phy_fix(struct phy_device *phy_dev) -++{ -++ u32 v; -++ int ret; -++ -++ if (phy_dev->interface != PHY_INTERFACE_MODE_RMII) -++ return 0; -++ -++ ret = phy_read(phy_dev, 0x1F); -++ if (ret < 0) -++ return ret; -++ v = ret; -++ v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */ -++ phy_write(phy_dev, 0x1F, v); -++ -++ return 0; -++} -++ -++static int unknown_phy_fix(struct phy_device *phy_dev) -++{ -++ u32 v; -++ int ret; -++ -++ if (phy_dev->interface != PHY_INTERFACE_MODE_RMII) -++ return 0; -++ -++ ret = phy_read(phy_dev, 0x1F); -++ if (ret < 0) -++ return ret; -++ v = ret; -++ v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */ -++ phy_write(phy_dev, 0x1F, v); -++ -++ return 0; -++} -++ -++static int rtl8211e_phy_fix(struct phy_device *phy_dev) -++{ -++ u32 v; -++ int ret; -++ -++ /* select Extension page */ -++ phy_write(phy_dev, 0x1f, 0x7); -++ /* switch ExtPage 164 */ -++ phy_write(phy_dev, 0x1e, 0xa4); -++ -++ /* config RGMII rx pin io driver max */ -++ ret = phy_read(phy_dev, 0x1c); -++ if (ret < 0) -++ return ret; -++ v = ret; -++ v = (v & 0xff03) | 0xfc; -++ phy_write(phy_dev, 0x1c, v); -++ -++ /* select to page 0 */ -++ phy_write(phy_dev, 0x1f, 0); -++ -++ return 0; -++} -++ -++void gmac_phy_register_fixups(void) -++{ -++ phy_register_fixup_for_uid(PHY_ID_UNKNOWN, DEFAULT_PHY_MASK, -++ unknown_phy_fix); -++ phy_register_fixup_for_uid(PHY_ID_KSZ8051MNL, DEFAULT_PHY_MASK, -++ ksz8051mnl_phy_fix); -++ phy_register_fixup_for_uid(PHY_ID_KSZ8081RNB, DEFAULT_PHY_MASK, -++ ksz8081rnb_phy_fix); -++ phy_register_fixup_for_uid(REALTEK_PHY_ID_8211E, REALTEK_PHY_MASK, -++ rtl8211e_phy_fix); -++} -++ -++void gmac_phy_unregister_fixups(void) -++{ -++ phy_unregister_fixup_for_uid(PHY_ID_UNKNOWN, DEFAULT_PHY_MASK); -++ phy_unregister_fixup_for_uid(PHY_ID_KSZ8051MNL, DEFAULT_PHY_MASK); -++ phy_unregister_fixup_for_uid(PHY_ID_KSZ8081RNB, DEFAULT_PHY_MASK); -++ phy_unregister_fixup_for_uid(REALTEK_PHY_ID_8211E, REALTEK_PHY_MASK); -++} -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.h b/drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.h -+new file mode 100755 -+index 000000000..e8fe68f72 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_phy_fixup.h -+@@ -0,0 +1,13 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef GMAC_PHY_FIXUP_H -++#define GMAC_PHY_FIXUP_H -++ -++#include "gmac.h" -++ -++void gmac_phy_register_fixups(void); -++void gmac_phy_unregister_fixups(void); -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_pm.c b/drivers/net/ethernet/vendor/gmac/gmac_pm.c -+new file mode 100755 -+index 000000000..cee4f62d6 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_pm.c -+@@ -0,0 +1,340 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include "gmac_pm.h" -++ -++struct pm_reg_config pm_reg_config_backup; -++ -++static void init_crc_table(void); -++static unsigned short compute_crc(const char *message, int nbytes); -++static unsigned short calculate_crc16(const char *buf, unsigned int mask) -++{ -++ char data[N]; -++ int i; -++ int len = 0; -++ -++ if (memset_s(data, sizeof(data), 0, sizeof(data)) != EOK) -++ printk("memset_s err : %s %d.\n", __func__, __LINE__); -++ -++ for (i = 0; i < N; i++) { -++ if (mask & 0x1) -++ data[len++] = buf[i]; -++ -++ mask >>= 1; -++ } -++ -++ return compute_crc(data, len); -++} -++ -++/* use this func in config pm func */ -++static void _pmt_reg_backup(struct gmac_netdev_local const *ld) -++{ -++ if (ld == NULL) -++ return; -++ pm_reg_config_backup.pmt_ctrl = readl(ld->gmac_iobase + PMT_CTRL); -++ pm_reg_config_backup.pmt_mask0 = readl(ld->gmac_iobase + PMT_MASK0); -++ pm_reg_config_backup.pmt_mask1 = readl(ld->gmac_iobase + PMT_MASK1); -++ pm_reg_config_backup.pmt_mask2 = readl(ld->gmac_iobase + PMT_MASK2); -++ pm_reg_config_backup.pmt_mask3 = readl(ld->gmac_iobase + PMT_MASK3); -++ pm_reg_config_backup.pmt_cmd = readl(ld->gmac_iobase + PMT_CMD); -++ pm_reg_config_backup.pmt_offset = readl(ld->gmac_iobase + PMT_OFFSET); -++ pm_reg_config_backup.pmt_crc1_0 = readl(ld->gmac_iobase + PMT_CRC1_0); -++ pm_reg_config_backup.pmt_crc3_2 = readl(ld->gmac_iobase + PMT_CRC3_2); -++} -++ -++#define PM_SET 1 -++#define PM_CLEAR 0 -++ -++static void pmt_config_filter(struct pm_config const *config, -++ struct gmac_netdev_local const *ld) -++{ -++ unsigned int v; -++ unsigned int cmd = 0; -++ unsigned int offset = 0; -++ unsigned short crc[FILTERS] = { 0 }; -++ int reg_mask; -++ unsigned int i; -++ -++ /* -++ * filter.valid mask.valid mask_bytes effect -++ * 0 * * no use the filter -++ * 1 0 * all pkts can wake-up(non-exist) -++ * 1 1 0 all pkts can wake-up -++ * 1 1 !0 normal filter -++ */ -++ /* setup filter */ -++ for (i = 0; i < FILTERS; i++) { -++ if (config->filter[i].valid) { -++ if (config->filter[i].offset < PM_FILTER_OFFSET_MIN) -++ continue; -++ /* high 8 bits offset and low 8 bits valid bit */ -++ offset |= config->filter[i].offset << (i * 8); -++ cmd |= BIT(i * 8); /* valid bit8 */ -++ /* mask offset 4i */ -++ reg_mask = PMT_MASK0 + (i * 4); -++ -++ /* -++ * for logic, mask valid bit(bit31) must set to 0, -++ * 0 is enable -++ */ -++ v = config->filter[i].mask_bytes; -++ v &= ~BIT(31); /* bit31 */ -++ writel(v, ld->gmac_iobase + reg_mask); -++ -++ /* crc */ -++ crc[i] = calculate_crc16(config->filter[i].value, v); -++ if (i <= 1) { /* for filter0 and filter 1 */ -++ v = readl(ld->gmac_iobase + PMT_CRC1_0); -++ v &= ~(0xFFFF << (16 * i)); /* 16 bits mask */ -++ v |= crc[i] << (16 * i); /* 16 bits mask */ -++ writel(v, ld->gmac_iobase + PMT_CRC1_0); -++ } else { /* filter2 and filter3 */ -++ v = readl(ld->gmac_iobase + PMT_CRC3_2); -++ v &= ~(0xFFFF << (16 * (i - 2))); /* filer 2 3, 16 bits mask */ -++ v |= crc[i] << (16 * (i - 2)); /* filer 2 3, 16 bits mask */ -++ writel(v, ld->gmac_iobase + PMT_CRC3_2); -++ } -++ } -++ } -++ -++ if (cmd) { -++ writel(offset, ld->gmac_iobase + PMT_OFFSET); -++ writel(cmd, ld->gmac_iobase + PMT_CMD); -++ } -++} -++ -++static int pmt_config_gmac(struct pm_config const *config, struct gmac_netdev_local *ld) -++{ -++ unsigned int v; -++ unsigned long flags; -++ -++ if (ld == NULL || config == NULL) -++ return -EINVAL; -++ -++ spin_lock_irqsave(&ld->pmtlock, flags); -++ if (config->wakeup_pkts_enable) { -++ /* disable wakeup_pkts_enable before reconfig? */ -++ v = readl(ld->gmac_iobase + PMT_CTRL); -++ v &= ~BIT(2); /* bit2 */ -++ writel(v, ld->gmac_iobase + PMT_CTRL); /* any side effect? */ -++ } else { -++ goto config_ctrl; -++ } -++ -++ pmt_config_filter(config, ld); -++ -++config_ctrl: -++ v = 0; -++ if (config->uc_pkts_enable) -++ v |= BIT(9); /* bit9 uc pkts wakeup */ -++ if (config->wakeup_pkts_enable) -++ v |= BIT(2); /* bit2 use filter framework */ -++ if (config->magic_pkts_enable) -++ v |= BIT(1); /* magic pkts wakeup */ -++ -++ v |= 0x3 << 5; /* set bit5 bit6, clear irq status */ -++ writel(v, ld->gmac_iobase + PMT_CTRL); -++ -++ _pmt_reg_backup(ld); -++ -++ spin_unlock_irqrestore(&ld->pmtlock, flags); -++ -++ return 0; -++} -++ -++/* pmt_config will overwrite pre-config */ -++int pmt_config(struct net_device const *ndev, struct pm_config const *config) -++{ -++ static int init; -++ int ret; -++ struct gmac_netdev_local *priv = netdev_priv(ndev); -++ -++ if (!init) -++ init_crc_table(); -++ -++ ret = pmt_config_gmac(config, priv); -++ if (ret) -++ return ret; -++ -++ priv->pm_state = PM_SET; -++ priv->wol_enable = true; -++ device_set_wakeup_enable(priv->dev, 1); -++ -++ return 0; -++} -++ -++bool pmt_enter(struct gmac_netdev_local *ld) -++{ -++ int pm = false; -++ unsigned long flags; -++ if (ld == NULL) -++ return -EINVAL; -++ spin_lock_irqsave(&ld->pmtlock, flags); -++ if (ld->pm_state == PM_SET) { -++ unsigned int v; -++ -++ v = readl(ld->gmac_iobase + PMT_CTRL); -++ v |= BIT(0); /* enter power down */ -++ v |= BIT(3); /* bit3, enable wakeup irq */ -++ v |= 0x3 << 5; /* set bit5 bit6, clear irq status */ -++ writel(v, ld->gmac_iobase + PMT_CTRL); -++ -++ ld->pm_state = PM_CLEAR; -++ pm = true; -++ } -++ spin_unlock_irqrestore(&ld->pmtlock, flags); -++ return pm; -++} -++ -++void pmt_exit(struct gmac_netdev_local *ld) -++{ -++ unsigned int v; -++ unsigned long flags; -++ if (ld == NULL) -++ return; -++ /* logic auto exit power down mode */ -++ spin_lock_irqsave(&ld->pmtlock, flags); -++ -++ v = readl(ld->gmac_iobase + PMT_CTRL); -++ v &= ~BIT(0); /* enter power down */ -++ v &= ~BIT(3); /* bit3, enable wakeup irq */ -++ -++ v |= 0x3 << 5; /* set bit5 bit6, clear irq status */ -++ writel(v, ld->gmac_iobase + PMT_CTRL); -++ -++ spin_unlock_irqrestore(&ld->pmtlock, flags); -++ -++ ld->wol_enable = false; -++} -++ -++void pmt_reg_restore(struct gmac_netdev_local *ld) -++{ -++ unsigned int v; -++ unsigned long flags; -++ if (ld == NULL) -++ return; -++ spin_lock_irqsave(&ld->pmtlock, flags); -++ v = pm_reg_config_backup.pmt_mask0; -++ writel(v, ld->gmac_iobase + PMT_MASK0); -++ -++ v = pm_reg_config_backup.pmt_mask1; -++ writel(v, ld->gmac_iobase + PMT_MASK1); -++ -++ v = pm_reg_config_backup.pmt_mask2; -++ writel(v, ld->gmac_iobase + PMT_MASK2); -++ -++ v = pm_reg_config_backup.pmt_mask3; -++ writel(v, ld->gmac_iobase + PMT_MASK3); -++ -++ v = pm_reg_config_backup.pmt_cmd; -++ writel(v, ld->gmac_iobase + PMT_CMD); -++ -++ v = pm_reg_config_backup.pmt_offset; -++ writel(v, ld->gmac_iobase + PMT_OFFSET); -++ -++ v = pm_reg_config_backup.pmt_crc1_0; -++ writel(v, ld->gmac_iobase + PMT_CRC1_0); -++ -++ v = pm_reg_config_backup.pmt_crc3_2; -++ writel(v, ld->gmac_iobase + PMT_CRC3_2); -++ -++ v = pm_reg_config_backup.pmt_ctrl; -++ writel(v, ld->gmac_iobase + PMT_CTRL); -++ spin_unlock_irqrestore(&ld->pmtlock, flags); -++} -++ -++/* ========the following code copy from Synopsys DWC_gmac_crc_example.c====== */ -++#define CRC16 /* Change it to CRC16 for CRC16 Computation */ -++ -++#if defined(CRC16) -++#define CRC_NAME "CRC-16" -++#define POLYNOMIAL 0x8005 -++#define INITIAL_REMAINDER 0xFFFF -++#define FINAL_XOR_VALUE 0x0000 -++#define REVERSE_DATA -++#undef REVERSE_REMAINDER -++#endif -++ -++#define WIDTH (8 * sizeof(unsigned short)) -++#define TOPBIT BIT(WIDTH - 1) -++ -++#ifdef REVERSE_DATA -++#undef REVERSE_DATA -++#define reverse_data(X) ((unsigned char)reverse((X), 8)) -++#else -++#undef REVERSE_DATA -++#define reverse_data(X) (X) -++#endif -++ -++#ifdef REVERSE_REMAINDER -++#undef REVERSE_REMAINDER -++#define reverse_remainder(X) ((unsigned short)reverse((X), WIDTH)) -++#else -++#undef REVERSE_REMAINDER -++#define reverse_remainder(X) (X) -++#endif -++ -++#define CRC_TABLE_LEN 256 -++static unsigned short crc_table[CRC_TABLE_LEN]; -++ -++static unsigned int reverse(unsigned int data, unsigned char nbits) -++{ -++ unsigned int reversed = 0x00000000; -++ unsigned char bit; -++ -++ /* Reverse the data about the center bit. */ -++ for (bit = 0; bit < nbits; ++bit) { -++ /* If the LSB bit is set, set the reflection of it. */ -++ if (data & 0x01) -++ reversed |= BIT((nbits - 1) - bit); -++ -++ data = (data >> 1); -++ } -++ return reversed; -++} -++ -++/* This Initializes the partial CRC look up table */ -++static void init_crc_table(void) -++{ -++ unsigned short remainder; -++ unsigned int dividend; -++ unsigned char bit; -++ -++ /* Compute the remainder of each possible dividend. */ -++ for (dividend = 0; dividend < CRC_TABLE_LEN; ++dividend) { -++ /* Start with the dividend followed by zeros, WIDTH - 8. */ -++ remainder = (unsigned short)(dividend << (WIDTH - 8)); -++ -++ /* Perform modulo-2 division, a bit at a time for 8 times. */ -++ for (bit = 8; bit > 0; --bit) { -++ /* Try to divide the current data bit. */ -++ if (remainder & TOPBIT) -++ remainder = (remainder << 1) ^ POLYNOMIAL; -++ else -++ remainder = (remainder << 1); -++ } -++ -++ /* Store the result into the table. */ -++ crc_table[dividend] = remainder; -++ } -++} -++ -++static unsigned short compute_crc(const char *message, int nbytes) -++{ -++ unsigned short remainder = INITIAL_REMAINDER; -++ int byte; -++ unsigned char data; -++ -++ /* Divide the message by the polynomial, a byte at a time. */ -++ for (byte = 0; byte < nbytes; ++byte) { -++ /* high 8 bits */ -++ data = reverse_data(message[byte]) ^ (remainder >> (WIDTH - 8)); -++ remainder = crc_table[data] ^ (remainder << 8); /* shift left 8 bits */ -++ } -++ -++ /* The final remainder is the CRC. */ -++ return (reverse_remainder(remainder) ^ FINAL_XOR_VALUE); -++} -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_pm.h b/drivers/net/ethernet/vendor/gmac/gmac_pm.h -+new file mode 100755 -+index 000000000..92d06ad8d -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_pm.h -+@@ -0,0 +1,56 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __GMAC_PM_H__ -++#define __GMAC_PM_H__ -++ -++#include "gmac.h" -++ -++#define N 31 -++#define FILTERS 4 -++#define PM_FILTER_OFFSET_MIN 12 -++struct pm_config { -++ unsigned char index; /* bit0--eth0 bit1--eth1 */ -++ unsigned char uc_pkts_enable; -++ unsigned char magic_pkts_enable; -++ unsigned char wakeup_pkts_enable; -++ struct { -++ unsigned int mask_bytes : N; -++ unsigned int reserved : 1; /* userspace ignore this bit */ -++ unsigned char offset; /* >= 12 */ -++ unsigned char value[N]; /* byte string */ -++ unsigned char valid; /* valid filter */ -++ } filter[FILTERS]; -++}; -++ -++struct pm_reg_config { -++ unsigned int pmt_ctrl; -++ unsigned int pmt_mask0; -++ unsigned int pmt_mask1; -++ unsigned int pmt_mask2; -++ unsigned int pmt_mask3; -++ unsigned int pmt_cmd; -++ unsigned int pmt_offset; -++ unsigned int pmt_crc1_0; -++ unsigned int pmt_crc3_2; -++}; -++ -++#define PMT_CTRL 0xa00 -++#define PMT_MASK0 0xa04 -++#define PMT_MASK1 0xa08 -++#define PMT_MASK2 0xa0c -++#define PMT_MASK3 0xa10 -++#define PMT_CMD 0xa14 -++#define PMT_OFFSET 0xa18 -++#define PMT_CRC1_0 0xa1c -++#define PMT_CRC3_2 0xa20 -++#define MASK_INVALID_BIT BIT(31) -++ -++ -++int pmt_config(struct net_device const *ndev, struct pm_config const *config); -++bool pmt_enter(struct gmac_netdev_local *ld); -++void pmt_exit(struct gmac_netdev_local *ld); -++void pmt_reg_restore(struct gmac_netdev_local *ld); -++ -++#endif -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_proc.c b/drivers/net/ethernet/vendor/gmac/gmac_proc.c -+new file mode 100755 -+index 000000000..0fa531a11 -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_proc.c -+@@ -0,0 +1,80 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++ -++#include "gmac_pm.h" -++#include "gmac_proc.h" -++ -++/* debug code */ -++int set_suspend(int eth_n) -++{ -++ return 0; -++} -++ -++/* debug code */ -++int set_resume(int eth_n) -++{ -++ return 0; -++} -++ -++static int hw_states_read(struct seq_file *m, void *v) -++{ -++ return 0; -++} -++ -++static struct proc_dir_entry *gmac_proc_root; -++ -++static int proc_open_hw_states_read(struct inode *inode, struct file *file) -++{ -++ return single_open(file, hw_states_read, PDE_DATA(inode)); -++} -++ -++static struct proc_file { -++ char *name; -++ const struct proc_ops ops; -++ -++} proc_file[] = { -++ { -++ .name = "hw_stats", -++ .ops = { -++ .proc_open = proc_open_hw_states_read, -++ .proc_read = seq_read, -++ .proc_lseek = seq_lseek, -++ .proc_release = single_release, -++ }, -++ } -++}; -++ -++/* -++ * /proc/gmac/ -++ * |---hw_stats -++ * |---skb_pools -++ */ -++void gmac_proc_create(void) -++{ -++ struct proc_dir_entry *entry = NULL; -++ int i; -++ -++ gmac_proc_root = proc_mkdir("gmac", NULL); -++ if (gmac_proc_root == NULL) -++ return; -++ -++ for (i = 0; i < ARRAY_SIZE(proc_file); i++) { -++ entry = proc_create(proc_file[i].name, 0, gmac_proc_root, -++ &proc_file[i].ops); -++ if (entry == NULL) -++ pr_err("failed to create %s\n", proc_file[i].name); -++ } -++} -++ -++void gmac_proc_destroy(void) -++{ -++ int i; -++ -++ for (i = 0; i < ARRAY_SIZE(proc_file); i++) -++ remove_proc_entry(proc_file[i].name, gmac_proc_root); -++ -++ remove_proc_entry("gmac", NULL); -++} -+diff --git a/drivers/net/ethernet/vendor/gmac/gmac_proc.h b/drivers/net/ethernet/vendor/gmac/gmac_proc.h -+new file mode 100755 -+index 000000000..4db48281d -+--- /dev/null -++++ b/drivers/net/ethernet/vendor/gmac/gmac_proc.h -+@@ -0,0 +1,21 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef GMAC_PROC_H -++#define GMAC_PROC_H -++ -++#include -++ -++#define SIOCSETPM (SIOCDEVPRIVATE + 4) /* set pmt wake up config */ -++#define SIOCSETSUSPEND (SIOCDEVPRIVATE + 5) /* call dev->suspend, debug */ -++#define SIOCSETRESUME (SIOCDEVPRIVATE + 6) /* call dev->resume, debug */ -++ -++void gmac_proc_create(void); -++void gmac_proc_destroy(void); -++ -++/* netdev ops related func */ -++int set_suspend(int eth_n); -++int set_resume(int eth_n); -++ -++#endif -+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig -+index 698bea312..5fd924813 100644 -+--- a/drivers/net/phy/Kconfig -++++ b/drivers/net/phy/Kconfig -+@@ -302,6 +302,21 @@ config DP83869_PHY -+ Currently supports the DP83869 PHY. This PHY supports copper and -+ fiber connections. -+ -++if ARCH_BSP -++config MDIO_VENDOR_FEMAC -++ tristate "Vendor FEMAC MDIO bus controller" -++ depends on HAS_IOMEM && OF_MDIO -++ help -++ This module provides a driver for the MDIO busses found in the -++ Vendor SoC that have an Fast Ethernet MAC. -++config MDIO_VENDOR_GEMAC -++ tristate "Vendor GEMAC MDIO bus controller" -++ depends on HAS_IOMEM && OF_MDIO -++ help -++ This module provides a driver for the MDIO busses found in the -++ Vendor SoC that have an Gigabit Ethernet MAC. -++endif # ARCH_BSP -++ -+ config VITESSE_PHY -+ tristate "Vitesse PHYs" -+ help -+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile -+index a13e40207..ba715052d 100644 -+--- a/drivers/net/phy/Makefile -++++ b/drivers/net/phy/Makefile -+@@ -25,6 +25,10 @@ obj-$(CONFIG_PHYLINK) += phylink.o -+ obj-$(CONFIG_PHYLIB) += libphy.o -+ -+ obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o -++ifneq ($(CONFIG_ARCH_BSP), ) -++obj-$(CONFIG_MDIO_VENDOR_GEMAC) += mdio_gemac.o -++obj-$(CONFIG_MDIO_VENDOR_FEMAC) += mdio_bsp_femac.o -++endif -+ -+ obj-$(CONFIG_SFP) += sfp.o -+ sfp-obj-$(CONFIG_SFP) += sfp-bus.o -+diff --git a/drivers/net/phy/mdio_bsp_femac.c b/drivers/net/phy/mdio_bsp_femac.c -+new file mode 100755 -+index 000000000..93bfc9c53 -+--- /dev/null -++++ b/drivers/net/phy/mdio_bsp_femac.c -+@@ -0,0 +1,494 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Shenshu Technologies Co., Ltd. -++ * -++ * 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 -++#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_HI3516CV610_FAMILY) -++#define BIT_OFFSET_LD_SET 6 -++#define BIT_OFFSET_LDO_SET 12 -++#define BIT_OFFSET_R_TUNING 0 -++#define DEF_LD_AM 0x9 -++#define DEF_LDO_AM 0x3 -++#define DEF_R_TUNING 0x16 -++#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 "phy-reset-delays-us" -++ -++enum phy_reset_delays { -++ PRE_DELAY, -++ PULSE, -++ POST_DELAY, -++ DELAYS_NUM, -++}; -++ -++struct bsp_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 bsp_femac_mdio_wait_ready(struct bsp_femac_mdio_data *data) -++{ -++ u32 val; -++#define DELAY_US 20 -++#define TIMEOUT_US 10000 -++ return readl_poll_timeout_atomic(data->membase + MDIO_RWCTRL, -++ val, val & MDIO_RW_FINISH, DELAY_US, TIMEOUT_US); -++} -++ -++static int bsp_femac_mdio_read(struct mii_bus *bus, int mii_id, int regnum) -++{ -++ struct bsp_femac_mdio_data *data = bus->priv; -++ int ret; -++ -++ ret = bsp_femac_mdio_wait_ready(data); -++ if (ret) -++ return ret; -++ -++ writel(((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum), -++ data->membase + MDIO_RWCTRL); -++ -++ ret = bsp_femac_mdio_wait_ready(data); -++ if (ret) -++ return ret; -++ -++ return readl(data->membase + MDIO_RO_DATA) & 0xFFFF; -++} -++ -++static int bsp_femac_mdio_write(struct mii_bus *bus, int mii_id, int regnum, -++ u16 value) -++{ -++ struct bsp_femac_mdio_data *data = bus->priv; -++ int ret; -++ -++ ret = bsp_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 bsp_femac_mdio_wait_ready(data); -++} -++ -++static void bsp_femac_sleep_us(u32 time_us) -++{ -++ u32 time_ms; -++ -++ if (!time_us) -++ return; -++ -++ time_ms = DIV_ROUND_UP(time_us, 1000); /* 1000:time_us */ -++ if (time_ms < 20) /* 20:time cmp */ -++ usleep_range(time_us, time_us + 500); /* 500:time add */ -++ else -++ msleep(time_ms); -++} -++ -++static void bsp_femac_phy_reset(const struct bsp_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); -++ bsp_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 -++ */ -++ bsp_femac_sleep_us(data->phy_reset_delays[PULSE]); -++ reset_control_deassert(data->phy_rst); -++ /* delay some time to ensure later MDIO access */ -++ bsp_femac_sleep_us(data->phy_reset_delays[POST_DELAY]); -++} -++ -++static void bsp_femac_get_phy_addr(struct bsp_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 bsp_femac_use_fephy(struct bsp_femac_mdio_data *data) -++{ -++ return true; -++} -++ -++static void bsp_femac_fephy_reset(struct bsp_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); /* 10:delay */ -++ -++ reset_control_assert(data->fephy_rst); -++ udelay(10); /* 10:delay */ -++ reset_control_deassert(data->fephy_rst); -++ /* delay at least 15ms for MDIO operation */ -++ msleep(20); /* 20:delay */ -++ -++ clk_prepare_enable(data->clk); -++ /* delay 5ms after enable MDCK to make sure FEPHY trim safe */ -++ mdelay(5); /* 5:delay */ -++} -++ -++static int fephy_expanded_read(struct mii_bus *bus, int phy_addr, -++ u32 reg_addr) -++{ -++ int ret; -++ -++ bsp_femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); -++ ret = bsp_femac_mdio_read(bus, phy_addr, MII_EXPMD); -++ -++ return ret; -++} -++ -++static int fephy_expanded_write(struct mii_bus *bus, int phy_addr, -++ u32 reg_addr, u16 val) -++{ -++ int ret; -++ -++ bsp_femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr); -++ ret = bsp_femac_mdio_write(bus, phy_addr, MII_EXPMD, val); -++ -++ return ret; -++} -++ -++void bsp_femac_fephy_use_default_trim(struct bsp_femac_mdio_data *data) -++{ -++ unsigned short val; -++ int timeout = 3; -++ -++ pr_info("No OTP data, festa PHY use default ATE parameters!\n"); -++ -++ do { -++ msleep(250); /* 250:delay */ -++ val = fephy_expanded_read(data->bus, data->phy_addr, -++ REG_DEF_ATE); -++ val &= BIT_AUTOTRIM_DONE; -++ } while (!val && --timeout); -++ -++ if (!timeout) -++ pr_err("festa PHY wait autotrim done timeout!\n"); -++ -++ mdelay(5); /* 5:delay */ -++} -++ -++static void bsp_femac_fephy_trim(struct bsp_femac_mdio_data *data) -++{ -++ struct mii_bus *bus = data->bus; -++ u32 phy_addr = data->phy_addr; -++ int timeout = 3000; -++ u32 val, ld_set, ldo_set, r_tuning; -++ -++ /* FEPHY get OTP trim data from special reg not fephy control reg1 */ -++#if defined(CONFIG_ARCH_HI3516CV610_FAMILY) -++ val = readl(data->fephy_trim_iobase); -++#else -++ val = readl(data->fephy_iobase); -++#endif -++ 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 defined(CONFIG_ARCH_HI3516CV610_FAMILY) -++ if (!ld_set && !ldo_set && !r_tuning) { -++ ld_set = DEF_LD_AM; -++ ldo_set = DEF_LDO_AM; -++ r_tuning = DEF_R_TUNING; -++ } -++#endif -++ -++ if (!ld_set && !ldo_set && !r_tuning) { -++ bsp_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("festa 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); /* 100,150:delay */ -++ val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE); -++ val &= BIT_CFG_ACK; -++ } while (!val && --timeout); -++ if (!timeout) -++ pr_err("festa PHY 0x3053 wait bit CFG_ACK timeout!\n"); -++ -++ mdelay(5); /* 5:delay */ -++ -++ 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 bsp_femac_fephy_reset_and_trim(struct bsp_femac_mdio_data *data) -++{ -++ bsp_femac_fephy_reset(data); -++ bsp_femac_fephy_trim(data); -++} -++ -++static void bsp_femac_fephy_set_phy_addr(struct bsp_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 bsp_femac_ioresource_remap(struct bsp_femac_mdio_data *data, struct platform_device *pdev) -++{ -++ int ret; -++ struct resource *res = NULL; -++ 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); -++ return ret;; -++ } -++ -++ 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); -++ return ret;; -++ } -++ } else { -++ data->fephy_iobase = NULL; -++ } -++ -++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); /* 2:index */ -++ 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); -++ return ret; -++ } -++ } else { -++ data->fephy_trim_iobase = NULL; -++ } -++ -++ data->clk = devm_clk_get(&pdev->dev, "mdio"); -++ if (IS_ERR(data->clk)) { -++ ret = PTR_ERR(data->clk); -++ return ret;; -++ } -++ -++ 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) -++ return ret; -++ return 0; -++} -++ -++#define REG_CRG_BASE 0x11010000UL -++#define OFST_CRG_FEPHY 0x37CC -++#define SIZE_16KB 0x40000UL -++ -++static void bsp_femac_mdio_preinit(void) -++{ -++ void *reg_base = ioremap(REG_CRG_BASE, SIZE_16KB); -++ if (reg_base == NULL) -++ return; -++ writel(0x6, reg_base + OFST_CRG_FEPHY); -++ iounmap(reg_base); -++} -++ -++static int bsp_femac_mdio_probe(struct platform_device *pdev) -++{ -++ struct device_node *np = pdev->dev.of_node; -++ struct mii_bus *bus = NULL; -++ struct bsp_femac_mdio_data *data = NULL; -++ -++ int ret, str_len; -++ -++ bsp_femac_mdio_preinit(); -++ -++ bus = mdiobus_alloc_size(sizeof(*data)); -++ if (!bus) -++ return -ENOMEM; -++ str_len = strlen(pdev->name); -++ bus->name = "bsp_femac_mii_bus"; -++ bus->read = &bsp_femac_mdio_read; -++ bus->write = &bsp_femac_mdio_write; -++ if (snprintf_s(bus->id, MII_BUS_ID_SIZE, str_len, "%s", pdev->name) < 0) -++ printk("snprintf_s failed! func:%s, line: %d\n", __func__, __LINE__); -++ bus->parent = &pdev->dev; -++ -++ data = bus->priv; -++ data->bus = bus; -++ ret = bsp_femac_ioresource_remap(data, pdev); -++ if (ret != 0) -++ 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; -++ bsp_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; -++ -++ bsp_femac_get_phy_addr(data, np); -++ if (bsp_femac_use_fephy(data)) -++ bsp_femac_fephy_reset_and_trim(data); -++ else -++ bsp_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 bsp_femac_mdio_remove(struct platform_device *pdev) -++{ -++ struct mii_bus *bus = platform_get_drvdata(pdev); -++ struct bsp_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 bsp_femac_mdio_dt_ids[] = { -++ { .compatible = "vendor,femac-mdio" }, -++ { } -++}; -++MODULE_DEVICE_TABLE(of, bsp_femac_mdio_dt_ids); -++ -++static struct platform_driver bsp_femac_mdio_driver = { -++ .probe = bsp_femac_mdio_probe, -++ .remove = bsp_femac_mdio_remove, -++ .driver = { -++ .name = "bsp-femac-mdio", -++ .of_match_table = bsp_femac_mdio_dt_ids, -++ }, -++}; -++ -++module_platform_driver(bsp_femac_mdio_driver); -++ -++MODULE_DESCRIPTION("Fast Ethernet MAC MDIO interface driver"); -++MODULE_LICENSE("GPL v2"); -+diff --git a/drivers/net/phy/mdio_gemac.c b/drivers/net/phy/mdio_gemac.c -+new file mode 100755 -+index 000000000..43437913d -+--- /dev/null -++++ b/drivers/net/phy/mdio_gemac.c -+@@ -0,0 +1,221 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Hisilicon Technologies Co., Ltd. -++ * -++ * 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 "mdio_gemac.h" -++ -++#define MDIO_SINGLE_CMD 0x00 -++#define MDIO_SINGLE_DATA 0x04 -++#define MDIO_RDATA_STATUS 0x10 -++#define BIT_PHY_ADDR_OFFSET 8 -++#define MDIO_WRITE BIT(16) -++#define MDIO_READ BIT(17) -++#define MDIO_START BIT(20) -++#define MDIO_START_READ (MDIO_START | MDIO_READ) -++#define MDIO_START_WRITE (MDIO_START | MDIO_WRITE) -++ -++struct gemac_mdio_data { -++ struct clk *clk; -++ struct reset_control *phy_rst; -++ void __iomem *membase; -++}; -++ -++static int gemac_mdio_wait_ready(struct gemac_mdio_data *data) -++{ -++ u32 val; -++#define DELAY_US 20 -++#define TIMEOUT_US 10000 -++ return readl_poll_timeout(data->membase + MDIO_SINGLE_CMD, -++ val, !(val & MDIO_START), DELAY_US, TIMEOUT_US); -++} -++ -++static int gemac_mdio_read(struct mii_bus *bus, int mii_id, int regnum) -++{ -++ struct gemac_mdio_data *data = bus->priv; -++ int ret; -++ -++ ret = gemac_mdio_wait_ready(data); -++ if (ret) -++ return ret; -++ -++ writel(MDIO_START_READ | ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | -++ ((u32)regnum), -++ data->membase + MDIO_SINGLE_CMD); -++ -++ ret = gemac_mdio_wait_ready(data); -++ if (ret) -++ return ret; -++ -++ /* if read data is invalid, we just return 0 instead of -EAGAIN. -++ * This can make MDIO more robust when reading PHY status. -++ */ -++ if (readl(data->membase + MDIO_RDATA_STATUS)) -++ return 0; -++ -++ return readl(data->membase + MDIO_SINGLE_DATA) >> 16; /* 16:right shift */ -++} -++ -++static int gemac_mdio_write(struct mii_bus *bus, int mii_id, int regnum, -++ u16 value) -++{ -++ struct gemac_mdio_data *data = bus->priv; -++ int ret; -++ -++ ret = gemac_mdio_wait_ready(data); -++ if (ret) -++ return ret; -++ -++ writel(value, data->membase + MDIO_SINGLE_DATA); -++ writel(MDIO_START_WRITE | ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | -++ ((u32)regnum), -++ data->membase + MDIO_SINGLE_CMD); -++ -++ return gemac_mdio_wait_ready(data); -++} -++ -++static void gemac_external_phy_reset(struct gemac_mdio_data const *data) -++{ -++ if (data->phy_rst) { -++ /* write 0 to cancel reset */ -++ reset_control_deassert(data->phy_rst); -++ msleep(50); /* 50:delay */ -++ -++ /* XX use CRG register to reset phy */ -++ /* RST_BIT, write 0 to reset phy, write 1 to cancel reset */ -++ reset_control_assert(data->phy_rst); -++ -++ /* delay some time to ensure reset ok, -++ * this depends on PHY hardware feature -++ */ -++ msleep(20); /* 20:delay */ -++ -++ /* write 0 to cancel reset */ -++ reset_control_deassert(data->phy_rst); -++ /* delay some time to ensure later MDIO access */ -++ msleep(80); /* 80:delay */ -++ } -++} -++static void gmac_mdiobus_init(struct mii_bus *bus, struct platform_device *const pdev) -++{ -++ bus->name = "gemac_mii_bus"; -++ bus->read = &gemac_mdio_read; -++ bus->write = &gemac_mdio_write; -++ if (snprintf_s(bus->id, MII_BUS_ID_SIZE, MII_BUS_ID_SIZE, "%s", pdev->name) < 0) -++ printk("snprintf_s failed!func:%s, line: %d\n", __func__, __LINE__); -++ bus->parent = &pdev->dev; -++ return; -++} -++ -++static int gmac_mdio_probe(struct platform_device *pdev) -++{ -++ struct device_node *np = pdev->dev.of_node; -++ struct mii_bus *bus = NULL; -++ struct gemac_mdio_data *data = NULL; -++ struct resource *res = NULL; -++ -++ int ret = gemac_pinctrl_config(pdev); -++ if (ret) { -++ pr_err("gmac pinctrl config error=%d.\n", ret); -++ return ret; -++ } -++ -++ bus = mdiobus_alloc_size(sizeof(*data)); -++ if (bus == NULL) -++ return -ENOMEM; -++ -++ gmac_mdiobus_init(bus, pdev); -++ -++ data = bus->priv; -++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -++ if (res == NULL || data == NULL) { -++ ret = -ENXIO; -++ goto err_out_free_mdiobus; -++ } -++ data->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); -++ if (!data->membase) { -++ ret = -ENOMEM; -++ goto err_out_free_mdiobus; -++ } -++ -++ data->clk = devm_clk_get(&pdev->dev, NULL); -++ if (IS_ERR(data->clk)) { -++ ret = PTR_ERR(data->clk); -++ goto err_out_free_mdiobus; -++ } -++ -++ ret = clk_prepare_enable(data->clk); -++ if (ret) -++ goto err_out_free_mdiobus; -++ -++ data->phy_rst = devm_reset_control_get(&pdev->dev, "phy_reset"); -++ if (IS_ERR(data->phy_rst)) -++ data->phy_rst = NULL; -++ gemac_external_phy_reset(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->clk); -++err_out_free_mdiobus: -++ mdiobus_free(bus); -++ return ret; -++} -++ -++static int gemac_mdio_remove(struct platform_device *pdev) -++{ -++ struct mii_bus *bus = platform_get_drvdata(pdev); -++ struct gemac_mdio_data *data = bus->priv; -++ -++ mdiobus_unregister(bus); -++ clk_disable_unprepare(data->clk); -++ mdiobus_free(bus); -++ -++ return 0; -++} -++ -++static const struct of_device_id gemac_mdio_dt_ids[] = { -++ { .compatible = "vendor,gemac-mdio" }, -++ { } -++}; -++MODULE_DEVICE_TABLE(of, gemac_mdio_dt_ids); -++ -++static struct platform_driver gemac_mdio_driver = { -++ .probe = gmac_mdio_probe, -++ .remove = gemac_mdio_remove, -++ .driver = { -++ .name = "vendor-gemac-mdio", -++ .of_match_table = gemac_mdio_dt_ids, -++ }, -++}; -++ -++module_platform_driver(gemac_mdio_driver); -++ -++MODULE_DESCRIPTION("Vendor Gigabit Ethernet MAC MDIO interface driver"); -++MODULE_AUTHOR("Vendor>"); -++MODULE_LICENSE("GPL v2"); -+diff --git a/drivers/net/phy/mdio_gemac.h b/drivers/net/phy/mdio_gemac.h -+new file mode 100755 -+index 000000000..84baf9505 -+--- /dev/null -++++ b/drivers/net/phy/mdio_gemac.h -+@@ -0,0 +1,24 @@ -++/* -++ * -++ * Copyright (c) 2012-2021 Hisilicon Technologies Co., Ltd. -++ * -++ * 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 __MDIO_VENDOR_GEMAC_H__ -++#define __MDIO_VENDOR_GEMAC_H__ -++ -++static inline int gemac_pinctrl_config(struct platform_device const *pdev) -++{ -++ return 0; -++} -++ -++#endif /* __MDIO_VENDOR_GEMAC_H__ */ -+diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -+index d231c35aa..bed574f4b 100644 -+--- a/drivers/net/phy/realtek.c -++++ b/drivers/net/phy/realtek.c -+@@ -139,6 +139,20 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev) -+ return (err < 0) ? err : 0; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static int rtl8201_config_intr(struct phy_device *phydev) -++{ -++ u16 val; -++ -++ val = phy_read_paged(phydev, 0x7, RTL8201F_IER); -++ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) -++ val |= (BIT(13) | BIT(12) | BIT(11)); -++ else -++ val &= ~(BIT(13) | BIT(12) | BIT(11)); /* bit11/12/13:all interrupt mask */ -++ -++ return phy_write_paged(phydev, 0x7, RTL8201F_IER, val); -++} -++#else -+ static int rtl8201_config_intr(struct phy_device *phydev) -+ { -+ u16 val; -+@@ -150,6 +164,7 @@ static int rtl8201_config_intr(struct phy_device *phydev) -+ -+ return phy_write_paged(phydev, 0x7, RTL8201F_IER, val); -+ } -++#endif -+ -+ static int rtl8211b_config_intr(struct phy_device *phydev) -+ { -+@@ -689,6 +704,9 @@ static struct phy_driver realtek_drvs[] = { -+ .name = "RTL8211F Gigabit Ethernet", -+ .probe = rtl821x_probe, -+ .config_init = &rtl8211f_config_init, -++#ifdef CONFIG_ARCH_BSP -++ .read_status = rtlgen_read_status, -++#endif -+ .ack_interrupt = &rtl8211f_ack_interrupt, -+ .config_intr = &rtl8211f_config_intr, -+ .suspend = genphy_suspend, -+diff --git a/drivers/of/base.c b/drivers/of/base.c -+index eb02974f3..98037e3ec 100644 -+--- a/drivers/of/base.c -++++ b/drivers/of/base.c -+@@ -163,6 +163,7 @@ void __of_phandle_cache_inv_entry(phandle handle) -+ phandle_cache[handle_hash] = NULL; -+ } -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ void __init of_core_init(void) -+ { -+ struct device_node *np; -+@@ -187,6 +188,7 @@ void __init of_core_init(void) -+ if (of_root) -+ proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); -+ } -++#endif -+ -+ static struct property *__of_find_property(const struct device_node *np, -+ const char *name, int *lenp) -+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -+index e5230ba30..b41192da9 100644 -+--- a/drivers/of/fdt.c -++++ b/drivers/of/fdt.c -+@@ -1271,6 +1271,7 @@ void __init unflatten_and_copy_device_tree(void) -+ } -+ -+ #ifdef CONFIG_SYSFS -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ static ssize_t of_fdt_raw_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *bin_attr, -+ char *buf, loff_t off, size_t count) -+@@ -1295,6 +1296,9 @@ static int __init of_fdt_raw_init(void) -+ of_fdt_raw_attr.size = fdt_totalsize(initial_boot_params); -+ return sysfs_create_bin_file(firmware_kobj, &of_fdt_raw_attr); -+ } -++#else -++static int __init of_fdt_raw_init(void) { return 0; } -++#endif -+ late_initcall(of_fdt_raw_init); -+ #endif -+ -+diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig -+index 9ed5f167a..c34ab6ed7 100644 -+--- a/drivers/phy/Kconfig -++++ b/drivers/phy/Kconfig -+@@ -84,4 +84,10 @@ source "drivers/phy/ti/Kconfig" -+ source "drivers/phy/intel/Kconfig" -+ source "drivers/phy/xilinx/Kconfig" -+ -++if ARCH_BSP -++ -++source "drivers/phy/vendor/Kconfig" -++ -++endif # ARCH_BSP -++ -+ endmenu -+diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile -+index 6eb291677..2b79711c8 100644 -+--- a/drivers/phy/Makefile -++++ b/drivers/phy/Makefile -+@@ -9,6 +9,7 @@ obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o -+ obj-$(CONFIG_PHY_XGENE) += phy-xgene.o -+ obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o -+ obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o -++obj-$(CONFIG_ARCH_BSP) += vendor/ -+ obj-y += allwinner/ \ -+ amlogic/ \ -+ broadcom/ \ -+diff --git a/drivers/phy/vendor/Kconfig b/drivers/phy/vendor/Kconfig -+new file mode 100755 -+index 000000000..e69de29bb -+diff --git a/drivers/phy/vendor/Makefile b/drivers/phy/vendor/Makefile -+new file mode 100755 -+index 000000000..ae99d84c9 -+--- /dev/null -++++ b/drivers/phy/vendor/Makefile -+@@ -0,0 +1,3 @@ -++# -++# Makefile for the phy drivers. -++# -+diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig -+index d55b3727e..d4608d601 100644 -+--- a/drivers/power/reset/Kconfig -++++ b/drivers/power/reset/Kconfig -+@@ -99,6 +99,13 @@ config POWER_RESET_HISI -+ help -+ Reboot support for Hisilicon boards. -+ -++if ARCH_BSP -++config POWER_RESET_BSP -++ bool "Vendor power-off driver" -++ help -++ Reboot support for Vendor boards. -++endif -++ -+ config POWER_RESET_LINKSTATION -+ tristate "Buffalo LinkStation power-off driver" -+ depends on ARCH_MVEBU || COMPILE_TEST -+diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile -+index c51eceba9..3f7b2f227 100644 -+--- a/drivers/power/reset/Makefile -++++ b/drivers/power/reset/Makefile -+@@ -33,3 +33,10 @@ obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o -+ obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o -+ obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o -+ obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o -++ifdef CONFIG_ARCH_BSP -++ifdef CONFIG_ARCH_HI3516CV610_FAMILY -++obj-$(CONFIG_POWER_RESET_BSP) += bsp-reboot-hi3516cv610.o -++else -++obj-$(CONFIG_POWER_RESET_BSP) += bsp-reboot.o -++endif -++endif -+diff --git a/drivers/power/reset/bsp-reboot-hi3516cv610.c b/drivers/power/reset/bsp-reboot-hi3516cv610.c -+new file mode 100755 -+index 000000000..8a0c5c0d2 -+--- /dev/null -++++ b/drivers/power/reset/bsp-reboot-hi3516cv610.c -+@@ -0,0 +1,114 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++ -++static void __iomem *base; -++static void __iomem *wdg_base; -++static void __iomem *gic_base; -++static u32 reboot_offset; -++ -++#define REG_BASE_WATCH_DOG 0x11030000 -++#define WATCH_DOG_LOAD_VAL 0x30 -++#define WATCH_DOG_CONTROL_OFFSET 0x8 -++#define WATCH_DOG_ENABLE 0x3 -++#define WATCH_DOG_UNLOCK_VAL 0x1ACCE551 -++#define WATCH_DOG_LOCK 0xC00 -++ -++#define GICD_DISABLE 0x0 -++#define GIC_DIST_CTRL 0x000 -++#define GICD_BASE 0x12401000 -++ -++static int bsp_restart_handler(struct notifier_block *this, unsigned long mode, -++ void *cmd) -++{ -++ // ignore wdg irq -++ writel_relaxed(GICD_DISABLE, gic_base + GIC_DIST_CTRL); -++ -++ writel_relaxed(WATCH_DOG_UNLOCK_VAL, wdg_base + WATCH_DOG_LOCK); -++ -++ writel_relaxed(WATCH_DOG_LOAD_VAL, wdg_base); -++ writel_relaxed(WATCH_DOG_ENABLE, wdg_base + WATCH_DOG_CONTROL_OFFSET); -++ -++ while (1) -++ cpu_do_idle(); -++ -++ return NOTIFY_DONE; -++} -++ -++static struct notifier_block bsp_restart_nb = { -++ .notifier_call = bsp_restart_handler, -++ .priority = 128, -++}; -++ -++#define HI3516CV610_CRG_BASE 0x11010000 -++#define SIZE_4K 0x4000 -++ -++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; -++ } -++ -++ wdg_base = ioremap(REG_BASE_WATCH_DOG, SIZE_4K); -++ if (!wdg_base) { -++ iounmap(base); -++ WARN(1, "failed to map crg base address"); -++ return -ENODEV; -++ } -++ -++ gic_base = ioremap(GICD_BASE, SIZE_4K); -++ if (!gic_base) { -++ iounmap(base); -++ iounmap(wdg_base); -++ WARN(1, "failed to map crg 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); -++ iounmap(wdg_base); -++ iounmap(gic_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); -++ iounmap(wdg_base); -++ iounmap(gic_base); -++ } -++ -++ return err; -++} -++ -++static const struct of_device_id bsp_reboot_of_match[] = { -++ { .compatible = "vendor,sysctrl" }, -++ {} -++}; -++ -++static struct platform_driver bsp_reboot_driver = { -++ .probe = bsp_reboot_probe, -++ .driver = { -++ .name = "bsp-reboot", -++ .of_match_table = bsp_reboot_of_match, -++ }, -++}; -++module_platform_driver(bsp_reboot_driver); -+diff --git a/drivers/power/reset/bsp-reboot.c b/drivers/power/reset/bsp-reboot.c -+new file mode 100755 -+index 000000000..2b81994fc -+--- /dev/null -++++ b/drivers/power/reset/bsp-reboot.c -+@@ -0,0 +1,73 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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 = "vendor,sysctrl" }, -++ {} -++}; -++ -++static struct platform_driver bsp_reboot_driver = { -++ .probe = bsp_reboot_probe, -++ .driver = { -++ .name = "bsp-reboot", -++ .of_match_table = bsp_reboot_of_match, -++ }, -++}; -++module_platform_driver(bsp_reboot_driver); -+diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig -+index 63be5362f..c9c469ea4 100644 -+--- a/drivers/pwm/Kconfig -++++ b/drivers/pwm/Kconfig -+@@ -570,4 +570,15 @@ config PWM_ZX -+ To compile this driver as a module, choose M here: the module -+ will be called pwm-zx. -+ -++if ARCH_BSP -++config PWM_BSP -++ tristate "Vendor PWM support" -++ help -++ Generic PWM framework driver for Vendor SoCs. -++ -++ To compile this driver as a module, choose M here: the module -++ will be called pwm-bsp. -++ -++endif # ARCH_BSP -++ -+ endif -+diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile -+index cbdcd55d6..b85c4238c 100644 -+--- a/drivers/pwm/Makefile -++++ b/drivers/pwm/Makefile -+@@ -1,6 +1,9 @@ -+ # SPDX-License-Identifier: GPL-2.0 -+ obj-$(CONFIG_PWM) += core.o -+ obj-$(CONFIG_PWM_SYSFS) += sysfs.o -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_PWM_SYSFS) += sysfs_bsp.o -++endif -+ obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o -+ obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o -+ obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o -+@@ -16,6 +19,9 @@ 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_HIBVT) += pwm-hibvt.o -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_PWM_BSP) += pwm-bsp.o -++endif -+ obj-$(CONFIG_PWM_IMG) += pwm-img.o -+ obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o -+ obj-$(CONFIG_PWM_IMX27) += pwm-imx27.o -+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c -+index 1f16f5365..0b5d43487 100644 -+--- a/drivers/pwm/core.c -++++ b/drivers/pwm/core.c -+@@ -581,11 +581,16 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) -+ -+ chip = pwm->chip; -+ -++#ifdef CONFIG_ARCH_BSP -++ if (!memcmp(state, &pwm->state, sizeof(struct pwm_state))) -++ return 0; -++#else -+ if (state->period == pwm->state.period && -+ state->duty_cycle == pwm->state.duty_cycle && -+ state->polarity == pwm->state.polarity && -+ state->enabled == pwm->state.enabled) -+ return 0; -++#endif /* CONFIG_ARCH_BSP */ -+ -+ if (chip->ops->apply) { -+ err = chip->ops->apply(chip, pwm, state); -+diff --git a/drivers/pwm/pwm-bsp.c b/drivers/pwm/pwm-bsp.c -+new file mode 100755 -+index 000000000..0a7b8a8e5 -+--- /dev/null -++++ b/drivers/pwm/pwm-bsp.c -+@@ -0,0 +1,486 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++/* reg addr of the xth chn. */ -++#define pwm_period_cfg_addr(x) (0x0000 + (0x100 * (x))) -++#define pwm_duty0_cfg_addr(x) (0x0004 + (0x100 * (x))) -++#define pwm_duty1_cfg_addr(x) (0x0008 + (0x100 * (x))) -++#define pwm_duty2_cfg_addr(x) (0x000C + (0x100 * (x))) -++#define pwm_num_cfg_addr(x) (0x0010 + (0x100 * (x))) -++#define pwm_ctrl_addr(x) (0x0014 + (0x100 * (x))) -++#define pwm_dt_value_cfg_addr(x) (0x0020 + (0x100 * (x))) -++#define pwm_dt_ctrl_cfg_addr(x) (0x0024 + (0x100 * (x))) -++#define pwm_sync_cfg_addr(x) (0x0030 + (0x100 * (x))) -++#define pwm_sync_delay_cfg_addr(x) (0x0034 + (0x100 * (x))) -++#define pwm_period_addr(x) (0x0040 + (0x100 * (x))) -++#define pwm_duty0_addr(x) (0x0044 + (0x100 * (x))) -++#define pwm_duty1_addr(x) (0x0048 + (0x100 * (x))) -++#define pwm_duty2_addr(x) (0x004C + (0x100 * (x))) -++#define pwm_num_addr(x) (0x0050 + (0x100 * (x))) -++#define pwm_ctrl_st_addr(x) (0x0054 + (0x100 * (x))) -++#define pwm_dt_value_addr(x) (0x0060 + (0x100 * (x))) -++#define pwm_dt_ctrl_addr(x) (0x0064 + (0x100 * (x))) -++#define pwm_sync_delay_addr(x) (0x0074 + (0x100 * (x))) -++ -++#define PWM_SYNC_START_ADDR 0x0ff0 -++ -++#define PWM_ALIGN_MODE_SHIFT 4 -++#define PWM_ALIGN_MODE_MASK GENMASK(5, 4) -++ -++#define PWM_PRE_DIV_SEL_SHIFT 8 -++#define PWM_PRE_DIV_SEL_MASK GENMASK(11, 8) -++ -++/* pwm dt value */ -++#define PWM_DT_A_SHIFT 0 -++#define PWM_DT_A_MASK GENMASK(31, 16) -++ -++#define PWM_DT_B_SHIFT 16 -++#define PWM_DT_B_MASK GENMASK(15, 0) -++ -++/* pwm dt ctrl */ -++#define PWM_DTS_OUT_0P_SHIFT 0 -++#define PWM_DTS_OUT_0P_MASK BIT(0) -++ -++#define PWM_DTS_OUT_0N_SHIFT 1 -++#define PWM_DTS_OUT_0N_MASK BIT(1) -++ -++#define PWM_DTS_OUT_1P_SHIFT 2 -++#define PWM_DTS_OUT_1P_MASK BIT(2) -++ -++#define PWM_DTS_OUT_1N_SHIFT 3 -++#define PWM_DTS_OUT_1N_MASK BIT(3) -++ -++#define PWM_DTS_OUT_2P_SHIFT 4 -++#define PWM_DTS_OUT_2P_MASK BIT(4) -++ -++#define PWM_DTS_OUT_2N_SHIFT 5 -++#define PWM_DTS_OUT_2N_MASK BIT(5) -++ -++#elif defined(CONFIG_ARCH_HI3516CV610_FAMILY) -++#define pwm_period_cfg_addr(x) (0x0000 + (0x100 * (x))) -++#define pwm_duty0_cfg_addr(x) (0x0004 + (0x100 * (x))) -++ -++#define pwm_num_cfg_addr(x) (0x0010 + (0x100 * (x))) -++#define pwm_ctrl_addr(x) (0x0014 + (0x100 * (x))) -++ -++#define pwm_sync_cfg_addr(x) (0x0030 + (0x100 * (x))) -++#define pwm_sync_delay_cfg_addr(x) (0x0034 + (0x100 * (x))) -++#define pwm_period_addr(x) (0x0040 + (0x100 * (x))) -++#define pwm_duty0_addr(x) (0x0044 + (0x100 * (x))) -++#define pwm_num_addr(x) (0x0050 + (0x100 * (x))) -++#define pwm_ctrl_st_addr(x) (0x0054 + (0x100 * (x))) -++#define pwm_sync_delay_addr(x) (0x0074 + (0x100 * (x))) -++ -++#define PWM_SYNC_START_ADDR 0x0ff0 -++ -++#define PWM_ALIGN_MODE_SHIFT 4 -++#define PWM_ALIGN_MODE_MASK GENMASK(5, 4) -++ -++#define PWM_PRE_DIV_SEL_SHIFT 8 -++#define PWM_PRE_DIV_SEL_MASK GENMASK(11, 8) -++ -++#else -++ -++#define pwm_period_cfg_addr(x) (((x) * 0x20) + 0x0) -++#define pwm_duty0_cfg_addr(x) (((x) * 0x20) + 0x4) -++#define pwm_cfg2_addr(x) (((x) * 0x20) + 0x8) -++#define pwm_ctrl_addr(x) (((x) * 0x20) + 0xC) -++ -++#endif -++ -++/* pwm ctrl */ -++#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) -++ -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++/* pwm period */ -++#define PWM_PERIOD_MASK GENMASK(31, 0) -++ -++/* pwm duty */ -++#define PWM_DUTY_MASK GENMASK(31, 0) -++#endif -++ -++#ifdef CONFIG_ARCH_HI3516CV610_FAMILY -++/* pwm period */ -++#define PWM_PERIOD_MASK GENMASK(19, 0) -++ -++/* pwm duty */ -++#define PWM_DUTY_MASK GENMASK(19, 0) -++#endif -++ -++#define PWM_PERIOD_HZ 1000 -++ -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++#define MAX_COUNT_VALUE 0xffffffff -++#endif -++ -++#ifdef CONFIG_ARCH_HI3516CV610_FAMILY -++#define MAX_COUNT_VALUE 0xfffff -++#endif -++ -++enum pwm_pre_div { -++ PWM_PRE_DIV_1 = 0, -++ PWM_PRE_DIV_2, -++ PWM_PRE_DIV_4, -++ PWM_PRE_DIV_8, -++ PWM_PRE_DIV_16, -++ PWM_PRE_DIV_32, -++ PWM_PRE_DIV_64, -++ PWM_PRE_DIV_128, -++ PWM_PRE_DIV_256, -++}; -++ -++enum pwm_align { -++ PWM_ALIGN_RIGHT = 0, -++ PWM_ALIGN_LEFT, -++ PWM_ALIGN_MIDDLE, -++}; -++ -++typedef enum { -++ PWM_CONTROLLER_0 = 0, -++ PWM_CONTROLLER_1, -++ PWM_CONTROLLER_2, -++} pwm_controller_index; -++ -++typedef enum { -++ PWM_CHN_0 = 0, -++ PWM_CHN_1, -++ PWM_CHN_2, -++ PWM_CHN_3, -++ PWM_CHN_4, -++ PWM_CHN_5, -++} pwm_chn_index; -++ -++struct bsp_pwm_chip { -++ pwm_controller_index controller_index; -++ struct pwm_chip chip; -++ struct clk *clk; -++ void __iomem *base; -++ struct reset_control *rstc; -++}; -++ -++struct bsp_pwm_soc { -++ u32 num_pwms; -++ const char *pwm_name; -++}; -++ -++#ifdef CONFIG_ARCH_HI3516CV610_FAMILY -++#define CHIP_PWM_NUM 1 -++#define CHIP_PWM_CONTROLLER_1_NAME "pwm1" -++ -++static const struct bsp_pwm_soc pwm_soc[CHIP_PWM_NUM] = { -++ { .num_pwms = 8, .pwm_name = CHIP_PWM_CONTROLLER_1_NAME }, -++}; -++#endif -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++#define CHIP_PWM_NUM 3 -++#define CHIP_PWM_CONTROLLER_0_NAME "pwm0" -++#define CHIP_PWM_CONTROLLER_1_NAME "pwm1" -++#define CHIP_PWM_CONTROLLER_2_NAME "pwm2" -++ -++static const struct bsp_pwm_soc pwm_soc[CHIP_PWM_NUM] = { -++ { .num_pwms = 6, .pwm_name = CHIP_PWM_CONTROLLER_0_NAME }, -++ { .num_pwms = 6, .pwm_name = CHIP_PWM_CONTROLLER_1_NAME }, -++ { .num_pwms = 5, .pwm_name = CHIP_PWM_CONTROLLER_2_NAME }, -++}; -++#endif -++ -++static inline struct bsp_pwm_chip *to_bsp_pwm_chip(struct pwm_chip *chip) -++{ -++ return container_of(chip, struct bsp_pwm_chip, chip); -++} -++ -++static void bsp_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 bsp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -++{ -++ struct bsp_pwm_chip *bsp_pwm_chip = to_bsp_pwm_chip(chip); -++ -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_ctrl_addr(pwm->hwpwm), -++ PWM_ENABLE_MASK, 0x1); -++} -++ -++static void bsp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -++{ -++ struct bsp_pwm_chip *bsp_pwm_chip = to_bsp_pwm_chip(chip); -++ -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_ctrl_addr(pwm->hwpwm), -++ PWM_ENABLE_MASK, 0x0); -++} -++ -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++static bool bsp_pwm_is_complementary_chn(pwm_controller_index controller_index, pwm_chn_index chn_index) -++{ -++ if (controller_index == PWM_CONTROLLER_0 && chn_index == PWM_CHN_3) -++ return 1; -++ return 0; -++} -++#endif -++ -++static void bsp_pwm_config(struct pwm_chip *chip, -++ struct pwm_device *pwm, -++ struct pwm_state *state) -++{ -++ struct bsp_pwm_chip *bsp_pwm_chip = to_bsp_pwm_chip(chip); -++ u64 freq, period, duty; -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++ u64 duty1, duty2; -++#endif -++ freq = div_u64(clk_get_rate(bsp_pwm_chip->clk), 1000000); -++ -++ period = div_u64(freq * state->period, PWM_PERIOD_HZ); -++ if (period > MAX_COUNT_VALUE) { -++ period = MAX_COUNT_VALUE; -++ state->period = div_u64((u64)MAX_COUNT_VALUE * PWM_PERIOD_HZ, freq); -++ printk("Period register value should not more than max config value:0x%08x, \ -++ so period duration value is modified to %llu ns.\n", MAX_COUNT_VALUE, state->period); -++ } else if (period == 0) { -++ printk("Period duration value is less than min config value:%llu ns, \ -++ please enter a larger period duration value.\n", div_u64(PWM_PERIOD_HZ, freq)); -++ } -++ -++ duty = div_u64(period * state->duty_cycle, state->period); -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++ duty1 = div_u64(period * state->duty_cycle1, state->period); -++ if (duty1 > MAX_COUNT_VALUE) { -++ duty1 = MAX_COUNT_VALUE; -++ state->duty_cycle1 = div_u64((u64)MAX_COUNT_VALUE * state->period, period); -++ printk("Duty1 register value should not more than max config value:0x%08x, \ -++ so duty1 duration value is modified to %llu ns.\n", MAX_COUNT_VALUE, state->duty_cycle1); -++ } -++ duty2 = div_u64(period * state->duty_cycle2, state->period); -++ if (duty2 > MAX_COUNT_VALUE) { -++ duty2 = MAX_COUNT_VALUE; -++ state->duty_cycle2 = div_u64((u64)MAX_COUNT_VALUE * state->period, period); -++ printk("Duty2 register value should not more than max config value:0x%08x, \ -++ so duty2 duration value is modified to %llu ns.\n", MAX_COUNT_VALUE, state->duty_cycle2); -++ } -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_ctrl_addr(pwm->hwpwm), -++ PWM_PRE_DIV_SEL_MASK, (PWM_PRE_DIV_1 << PWM_PRE_DIV_SEL_SHIFT)); -++#endif -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_period_cfg_addr(pwm->hwpwm), -++ PWM_PERIOD_MASK, period); -++ -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_duty0_cfg_addr(pwm->hwpwm), -++ PWM_DUTY_MASK, duty); -++ -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++ if (bsp_pwm_is_complementary_chn(bsp_pwm_chip->controller_index, pwm->hwpwm) == 1) { -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_duty1_cfg_addr(pwm->hwpwm), -++ PWM_DUTY_MASK, duty1); -++ -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_duty2_cfg_addr(pwm->hwpwm), -++ PWM_DUTY_MASK, duty2); -++ } -++#endif -++} -++ -++static void bsp_pwm_set_polarity(struct pwm_chip *chip, -++ struct pwm_device *pwm, -++ enum pwm_polarity polarity) -++{ -++ struct bsp_pwm_chip *bsp_pwm_chip = to_bsp_pwm_chip(chip); -++ -++ if (polarity == PWM_POLARITY_INVERSED) -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_ctrl_addr(pwm->hwpwm), -++ PWM_POLARITY_MASK, (0x1 << PWM_POLARITY_SHIFT)); -++ else -++ bsp_pwm_set_bits(bsp_pwm_chip->base, pwm_ctrl_addr(pwm->hwpwm), -++ PWM_POLARITY_MASK, (0x0 << PWM_POLARITY_SHIFT)); -++} -++ -++static void bsp_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, -++ struct pwm_state *state) -++{ -++ struct bsp_pwm_chip *bsp_pwm_chip = to_bsp_pwm_chip(chip); -++ void __iomem *base; -++ u32 freq, value; -++ -++ freq = div_u64(clk_get_rate(bsp_pwm_chip->clk), 1000000); -++ base = bsp_pwm_chip->base; -++ -++ value = readl(base + pwm_period_cfg_addr(pwm->hwpwm)); -++ state->period = div_u64(value * PWM_PERIOD_HZ, freq); -++ -++ value = readl(base + pwm_duty0_cfg_addr(pwm->hwpwm)); -++ state->duty_cycle = div_u64(value * PWM_PERIOD_HZ, freq); -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++ if (bsp_pwm_is_complementary_chn(bsp_pwm_chip->controller_index, pwm->hwpwm) == 1) { -++ value = readl(base + pwm_duty1_cfg_addr(pwm->hwpwm)); -++ state->duty_cycle1 = div_u64(value * PWM_PERIOD_HZ, freq); -++ value = readl(base + pwm_duty2_cfg_addr(pwm->hwpwm)); -++ state->duty_cycle2 = div_u64(value * PWM_PERIOD_HZ, freq); -++ } -++#endif -++ value = readl(base + pwm_ctrl_addr(pwm->hwpwm)); -++ state->enabled = (PWM_ENABLE_MASK & value); -++} -++ -++static int bsp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, -++ struct pwm_state *state) -++{ -++ if (state->polarity != pwm->state.polarity) -++ bsp_pwm_set_polarity(chip, pwm, state->polarity); -++ -++ if (state->period != pwm->state.period || -++ state->duty_cycle != pwm->state.duty_cycle || -++ state->duty_cycle1 != pwm->state.duty_cycle1 || -++ state->duty_cycle2 != pwm->state.duty_cycle2) -++ bsp_pwm_config(chip, pwm, state); -++ -++ if (state->enabled != pwm->state.enabled) { -++ if (state->enabled) -++ bsp_pwm_enable(chip, pwm); -++ else -++ bsp_pwm_disable(chip, pwm); -++ } -++ -++ return 0; -++} -++ -++static const struct pwm_ops bsp_pwm_ops = { -++ .get_state = bsp_pwm_get_state, -++ .apply = bsp_pwm_apply, -++ -++ .owner = THIS_MODULE, -++}; -++ -++static void bsp_pwm_probe_set_chip_ops(struct platform_device *pdev, struct bsp_pwm_chip *pwm_chip, int chip_loop) -++{ -++ pwm_chip->chip.ops = &bsp_pwm_ops; -++ pwm_chip->chip.dev = &pdev->dev; -++ pwm_chip->chip.base = -1; -++ pwm_chip->chip.npwm = pwm_soc[chip_loop].num_pwms; -++ pwm_chip->chip.of_xlate = of_pwm_xlate_with_flags; -++ pwm_chip->chip.of_pwm_n_cells = 3; -++} -++ -++static int bsp_pwm_probe(struct platform_device *pdev) -++{ -++ struct bsp_pwm_chip *pwm_chip, *pwm_chip_tmp; -++ struct resource *res; -++ int ret; -++ int i; -++ int chip_loop; -++ const char *pwm_name = NULL; -++ -++ pwm_chip_tmp = devm_kzalloc(&pdev->dev, sizeof(*pwm_chip_tmp) * CHIP_PWM_NUM, GFP_KERNEL); -++ if (pwm_chip_tmp == NULL) -++ return -ENOMEM; -++ -++ for (chip_loop = 0; chip_loop < CHIP_PWM_NUM; chip_loop++) { -++ pwm_chip = pwm_chip_tmp + chip_loop; -++ pwm_name = pwm_soc[chip_loop].pwm_name; -++ pwm_chip->controller_index = chip_loop; -++ pwm_chip->clk = devm_clk_get(&pdev->dev, pwm_name); -++ 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); -++ } -++ -++ bsp_pwm_probe_set_chip_ops(pdev, pwm_chip, chip_loop); -++ -++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pwm_name); -++ 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_exclusive(&pdev->dev, pwm_name); -++ 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++) { -++ bsp_pwm_set_bits(pwm_chip->base, pwm_ctrl_addr(i), PWM_KEEP_MASK, (0x1 << PWM_KEEP_SHIFT)); -++ } -++ } -++ -++ platform_set_drvdata(pdev, pwm_chip_tmp); -++ -++ return 0; -++} -++ -++static int bsp_pwm_remove(struct platform_device *pdev) -++{ -++ int ret = 0; -++ int chip_loop; -++ struct bsp_pwm_chip *pwm_chip; -++ struct bsp_pwm_chip *pwm_chip_tmp; -++ -++ pwm_chip_tmp = platform_get_drvdata(pdev); -++ -++ for (chip_loop = 0; chip_loop < CHIP_PWM_NUM; chip_loop++) { -++ pwm_chip = pwm_chip_tmp + chip_loop; -++ reset_control_assert(pwm_chip->rstc); -++ msleep(30); -++ reset_control_deassert(pwm_chip->rstc); -++ -++ clk_disable_unprepare(pwm_chip->clk); -++ -++ ret |= pwmchip_remove(&pwm_chip->chip); -++ } -++ -++ return ret; -++} -++ -++static const struct of_device_id bsp_pwm_of_match[] = { -++ { .compatible = "vendor,pwm", .data = &pwm_soc[0] }, -++ { } -++}; -++MODULE_DEVICE_TABLE(of, bsp_pwm_of_match); -++ -++static struct platform_driver bsp_pwm_driver = { -++ .driver = { -++ .name = "bsp-pwm", -++ .of_match_table = bsp_pwm_of_match, -++ }, -++ .probe = bsp_pwm_probe, -++ .remove = bsp_pwm_remove, -++}; -++module_platform_driver(bsp_pwm_driver); -++ -++MODULE_LICENSE("GPL"); -+diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c -+index b8417a8d2..7d731ebba 100644 -+--- a/drivers/pwm/sysfs.c -++++ b/drivers/pwm/sysfs.c -+@@ -14,6 +14,12 @@ -+ #include -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++void pwm_pn_export_child(struct device *parent, struct pwm_device *pwm, struct device child); -++#endif /* CONFIG_ARCH_HI3519DV500_FAMILY */ -++#endif /* CONFIG_ARCH_BSP */ -++ -+ struct pwm_export { -+ struct device child; -+ struct pwm_device *pwm; -+@@ -260,6 +266,13 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm) -+ export->child.parent = parent; -+ export->child.devt = MKDEV(0, 0); -+ export->child.groups = pwm_groups; -++ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_ARCH_HI3519DV500_FAMILY -++ pwm_pn_export_child(parent, pwm, export->child); -++#endif /* CONFIG_ARCH_HI3519DV500_FAMILY */ -++#endif /* CONFIG_ARCH_BSP */ -++ -+ dev_set_name(&export->child, "pwm%u", pwm->hwpwm); -+ -+ ret = device_register(&export->child); -+diff --git a/drivers/pwm/sysfs_bsp.c b/drivers/pwm/sysfs_bsp.c -+new file mode 100755 -+index 000000000..65c972ec3 -+--- /dev/null -++++ b/drivers/pwm/sysfs_bsp.c -+@@ -0,0 +1,320 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++struct pwm_export { -++ struct device child; -++ struct pwm_device *pwm; -++ struct mutex lock; -++ struct pwm_state suspend; -++}; -++ -++static struct pwm_export *child_to_pwm_export(struct device *child) -++{ -++ return container_of(child, struct pwm_export, child); -++} -++ -++static struct pwm_device *child_to_pwm_device(struct device *child) -++{ -++ struct pwm_export *export = child_to_pwm_export(child); -++ -++ return export->pwm; -++} -++ -++static ssize_t period_show(struct device *child, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ const struct pwm_device *pwm = child_to_pwm_device(child); -++ struct pwm_state state; -++ -++ pwm_get_state(pwm, &state); -++ -++ return sprintf_s(buf, sizeof(buf), "%llu\n", state.period); -++} -++ -++static ssize_t period_store(struct device *child, -++ struct device_attribute *attr, -++ const char *buf, size_t size) -++{ -++ struct pwm_export *export = child_to_pwm_export(child); -++ struct pwm_device *pwm = export->pwm; -++ struct pwm_state state; -++ u64 val; -++ int ret; -++ -++ ret = kstrtou64(buf, 0, &val); -++ if (ret) -++ return ret; -++ -++ mutex_lock(&export->lock); -++ pwm_get_state(pwm, &state); -++ state.period = val; -++ ret = pwm_apply_state(pwm, &state); -++ mutex_unlock(&export->lock); -++ -++ return ret ? : size; -++} -++ -++static ssize_t duty_cycle_show(struct device *child, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ const struct pwm_device *pwm = child_to_pwm_device(child); -++ struct pwm_state state; -++ -++ pwm_get_state(pwm, &state); -++ -++ return sprintf_s(buf, sizeof(buf), "%llu\n", state.duty_cycle); -++} -++ -++static ssize_t duty_cycle_store(struct device *child, -++ struct device_attribute *attr, -++ const char *buf, size_t size) -++{ -++ struct pwm_export *export = child_to_pwm_export(child); -++ struct pwm_device *pwm = export->pwm; -++ struct pwm_state state; -++ u64 val; -++ int ret; -++ -++ ret = kstrtou64(buf, 0, &val); -++ if (ret) -++ return ret; -++ -++ mutex_lock(&export->lock); -++ pwm_get_state(pwm, &state); -++ state.duty_cycle = val; -++ ret = pwm_apply_state(pwm, &state); -++ mutex_unlock(&export->lock); -++ -++ return ret ? : size; -++} -++ -++static ssize_t enable_show(struct device *child, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ const struct pwm_device *pwm = child_to_pwm_device(child); -++ struct pwm_state state; -++ -++ pwm_get_state(pwm, &state); -++ -++ return sprintf_s(buf, sizeof(buf), "%d\n", state.enabled); -++} -++ -++static ssize_t enable_store(struct device *child, -++ struct device_attribute *attr, -++ const char *buf, size_t size) -++{ -++ struct pwm_export *export = child_to_pwm_export(child); -++ struct pwm_device *pwm = export->pwm; -++ struct pwm_state state; -++ int val, ret; -++ -++ ret = kstrtoint(buf, 0, &val); -++ if (ret) -++ return ret; -++ -++ mutex_lock(&export->lock); -++ -++ pwm_get_state(pwm, &state); -++ -++ switch (val) { -++ case 0: -++ state.enabled = false; -++ break; -++ case 1: -++ state.enabled = true; -++ break; -++ default: -++ ret = -EINVAL; -++ goto unlock; -++ } -++ -++ ret = pwm_apply_state(pwm, &state); -++ -++unlock: -++ mutex_unlock(&export->lock); -++ return ret ? : size; -++} -++ -++static ssize_t polarity_show(struct device *child, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ const struct pwm_device *pwm = child_to_pwm_device(child); -++ const char *polarity = "unknown"; -++ struct pwm_state state; -++ -++ pwm_get_state(pwm, &state); -++ -++ switch (state.polarity) { -++ case PWM_POLARITY_NORMAL: -++ polarity = "normal"; -++ break; -++ -++ case PWM_POLARITY_INVERSED: -++ polarity = "inversed"; -++ break; -++ } -++ -++ return sprintf_s(buf, sizeof(buf), "%s\n", polarity); -++} -++ -++static ssize_t polarity_store(struct device *child, -++ struct device_attribute *attr, -++ const char *buf, size_t size) -++{ -++ struct pwm_export *export = child_to_pwm_export(child); -++ struct pwm_device *pwm = export->pwm; -++ enum pwm_polarity polarity; -++ struct pwm_state state; -++ int ret; -++ -++ if (sysfs_streq(buf, "normal")) -++ polarity = PWM_POLARITY_NORMAL; -++ else if (sysfs_streq(buf, "inversed")) -++ polarity = PWM_POLARITY_INVERSED; -++ else -++ return -EINVAL; -++ -++ mutex_lock(&export->lock); -++ pwm_get_state(pwm, &state); -++ state.polarity = polarity; -++ ret = pwm_apply_state(pwm, &state); -++ mutex_unlock(&export->lock); -++ -++ return ret ? : size; -++} -++ -++static ssize_t capture_show(struct device *child, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ struct pwm_device *pwm = child_to_pwm_device(child); -++ struct pwm_capture result; -++ int ret; -++ -++ ret = pwm_capture(pwm, &result, jiffies_to_msecs(HZ)); -++ if (ret) -++ return ret; -++ -++ return sprintf_s(buf, sizeof(buf), "%u %u\n", result.period, result.duty_cycle); -++} -++ -++ssize_t duty_cycle1_show(struct device *child, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ const struct pwm_device *pwm = child_to_pwm_device(child); -++ struct pwm_state state; -++ -++ pwm_get_state(pwm, &state); -++ -++ return sprintf_s(buf, sizeof(buf), "%llu\n", state.duty_cycle1); -++} -++ -++ssize_t duty_cycle1_store(struct device *child, -++ struct device_attribute *attr, -++ const char *buf, size_t size) -++{ -++ struct pwm_export *export = child_to_pwm_export(child); -++ struct pwm_device *pwm = export->pwm; -++ struct pwm_state state; -++ u64 val; -++ int ret; -++ -++ ret = kstrtou64(buf, 0, &val); -++ if (ret) -++ return ret; -++ -++ mutex_lock(&export->lock); -++ pwm_get_state(pwm, &state); -++ state.duty_cycle1 = val; -++ ret = pwm_apply_state(pwm, &state); -++ mutex_unlock(&export->lock); -++ -++ return ret ? : size; -++} -++ -++ssize_t duty_cycle2_show(struct device *child, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ const struct pwm_device *pwm = child_to_pwm_device(child); -++ struct pwm_state state; -++ -++ pwm_get_state(pwm, &state); -++ -++ return sprintf_s(buf, sizeof(buf), "%llu\n", state.duty_cycle2); -++} -++ -++ssize_t duty_cycle2_store(struct device *child, -++ struct device_attribute *attr, -++ const char *buf, size_t size) -++{ -++ struct pwm_export *export = child_to_pwm_export(child); -++ struct pwm_device *pwm = export->pwm; -++ struct pwm_state state; -++ u64 val; -++ int ret; -++ -++ ret = kstrtou64(buf, 0, &val); -++ if (ret) -++ return ret; -++ -++ mutex_lock(&export->lock); -++ pwm_get_state(pwm, &state); -++ state.duty_cycle2 = val; -++ ret = pwm_apply_state(pwm, &state); -++ mutex_unlock(&export->lock); -++ -++ return ret ? : size; -++} -++ -++#define PWM_BASE_0 0 -++#define PWM_BASE_6 6 -++ -++#define PWM_COMPLEMENTARY_CHN_0 0 -++#define PWM_COMPLEMENTARY_CHN_3 3 -++#define PWM_COMPLEMENTARY_CHN_4 4 -++#define PWM_COMPLEMENTARY_CHN_5 5 -++ -++static DEVICE_ATTR_RW(period); -++static DEVICE_ATTR_RW(duty_cycle); -++static DEVICE_ATTR_RW(enable); -++static DEVICE_ATTR_RW(polarity); -++static DEVICE_ATTR_RO(capture); -++static DEVICE_ATTR_RW(duty_cycle1); -++static DEVICE_ATTR_RW(duty_cycle2); -++static struct attribute *pwm_pn_attrs[] = { -++ &dev_attr_period.attr, -++ &dev_attr_duty_cycle.attr, -++ &dev_attr_duty_cycle1.attr, -++ &dev_attr_duty_cycle2.attr, -++ &dev_attr_enable.attr, -++ &dev_attr_polarity.attr, -++ &dev_attr_capture.attr, -++ NULL -++}; -++ATTRIBUTE_GROUPS(pwm_pn); -++ -++void pwm_pn_export_child(struct device *parent, struct pwm_device *pwm, struct device child) -++{ -++ struct pwm_chip *chip = dev_get_drvdata(parent); -++ -++ if (chip->base == PWM_BASE_0 && pwm->hwpwm == PWM_COMPLEMENTARY_CHN_3) { -++ child.groups = pwm_pn_groups; -++ } -++ -++ return; -++} -+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig -+index 1d005a001..d9083af71 100644 -+--- a/drivers/rtc/Kconfig -++++ b/drivers/rtc/Kconfig -+@@ -944,6 +944,17 @@ comment "Platform RTC drivers" -+ # defining CMOS_READ/CMOS_WRITE, and a -+ # global rtc_lock ... it's not yet just another platform_device. -+ -++if ARCH_BSP -++config RTC_DRV_BSP -++ tristate "Vendor RTC support" -++ depends on ARCH_BSP -++ help -++ Generic RTC framework driver for Vendor SoCs. -++ -++ To compile this driver as a module, choose M here: the module -++ will be called rtc-bsp. -++endif -++ -+ config RTC_DRV_CMOS -+ tristate "PC-style 'CMOS'" -+ depends on X86 || ARM || PPC || MIPS || SPARC64 -+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile -+index ec0bed7fd..18b23d3e9 100644 -+--- a/drivers/rtc/Makefile -++++ b/drivers/rtc/Makefile -+@@ -22,6 +22,9 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o -+ -+ # Keep the list ordered. -+ -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_RTC_DRV_BSP) += rtc-bsp.o -++endif -+ obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o -+ obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o -+ obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o -+diff --git a/drivers/rtc/rtc-bsp.c b/drivers/rtc/rtc-bsp.c -+new file mode 100755 -+index 000000000..34fd30bbe -+--- /dev/null -++++ b/drivers/rtc/rtc-bsp.c -+@@ -0,0 +1,628 @@ -++/* -++ * Copyright (C) 2016 HiSilicon (Shanghai) Technologies Co., Ltd. -++ * -++ * rtc-bsp.c -++ * -++ * RTC driver for Vendor -++ * -++ * 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. -++ */ -++ -++#include -++#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; -++}; -++ -++struct bsp_time_str { -++ unsigned char dayl; -++ unsigned char dayh; -++ unsigned char second; -++ unsigned char minute; -++ unsigned char hour; -++}; -++ -++#define SPI_CLK_DIV 0x000 -++#define SPI_RW 0x004 -++ -++#define SPI_WRITE 0 -++#define SPI_READ 1 -++ -++#if defined(CONFIG_ARCH_HI3519DV500_FAMILY) -++#define RTC_DEFAULT_DRIVER_CAPABILITY 0x2 -++#endif -++ -++#if defined(CONFIG_ARCH_HI3516CV610_FAMILY) -++#define RTC_DEFAULT_DRIVER_CAPABILITY 0x1 -++#endif -++ -++#if defined(CONFIG_ARCH_HI3519DV500_FAMILY) || defined(CONFIG_ARCH_HI3516CV610_FAMILY) -++/* RTC REG */ -++#define RTC_10MS_COUN 0x00 -++#define RTC_S_COUNT 0x04 -++#define RTC_M_COUNT 0x08 -++#define RTC_H_COUNT 0x0C -++#define RTC_D_COUNT_L 0x10 -++#define RTC_D_COUNT_H 0x14 -++ -++#define RTC_MR_10MS 0x18 -++#define RTC_MR_S 0x1C -++#define RTC_MR_M 0x20 -++#define RTC_MR_H 0x24 -++#define RTC_MR_D_L 0x28 -++#define RTC_MR_D_H 0x2C -++ -++#define RTC_LR_10MS 0x30 -++#define RTC_LR_S 0x34 -++#define RTC_LR_M 0x38 -++#define RTC_LR_H 0x3C -++#define RTC_LR_D_L 0x40 -++#define RTC_LR_D_H 0x44 -++ -++#define RTC_LORD 0x48 -++ -++#define RTC_IMSC 0x4C -++#define RTC_INT_CLR 0x50 -++#define RTC_INT 0x54 -++#define RTC_INT_RAW 0x58 -++ -++#define RTC_CLK 0x5C -++#define RTC_POR_N 0x60 -++#define RTC_SAR_CTRL 0x68 -++#define RTC_CLK_CFG 0x6C -++ -++#define RTC_FREQ_H 0x144 -++#define RTC_FREQ_L 0x148 -++ -++#define RTC_REG_LOCK1 0x190 -++#define RTC_REG_LOCK2 0x194 -++#define RTC_REG_LOCK3 0x198 -++#define RTC_REG_LOCK4 0x19C -++ -++#else -++ -++#define SPI_RTC_TYPE -++ -++/* 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 -++ -++#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 bsp_rtc { -++ struct rtc_device *rtc_dev; -++ void __iomem *regs; -++ int rtc_irq; -++}; -++#define bsp_rtc_readl(x) (*((volatile unsigned char *)(x))) -++#define bsp_rtc_writel(v, x) (*((volatile unsigned char *)(x)) = (v)) -++ -++#if defined(SPI_RTC_TYPE) -++static int bsp_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 bsp_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; -++} -++#else -++static unsigned int bsp_write_reg(void *spi_reg, unsigned long offset, -++ unsigned char val) -++{ -++ bsp_rtc_writel(val, (spi_reg + offset)); -++ return 0; -++} -++ -++static unsigned int bsp_read_reg(void *spi_reg, unsigned long offset, -++ unsigned char *val) -++{ -++ *val = bsp_rtc_readl(spi_reg + offset); -++ return 0; -++} -++#endif -++ -++ -++static unsigned int bsp_rtc_write(void *spi_reg, unsigned long offset, -++ unsigned char val) -++{ -++#if defined(SPI_RTC_TYPE) -++ return bsp_spi_write(spi_reg, offset, val); -++#else -++ return bsp_write_reg(spi_reg, offset, val); -++#endif -++} -++ -++static unsigned int bsp_rtc_read(void *spi_reg, unsigned long offset, -++ unsigned char *val) -++{ -++#if defined(SPI_RTC_TYPE) -++ return bsp_spi_read(spi_reg, offset, val); -++#else -++ return bsp_read_reg(spi_reg, offset, val); -++#endif -++} -++ -++static int bsp_rtc_read_time(struct device *dev, struct rtc_time *time) -++{ -++ struct bsp_rtc *rtc = dev_get_drvdata(dev); -++ struct bsp_time_str time_str = {0}; -++ unsigned long seconds = 0; -++ unsigned int day; -++ unsigned char raw_value = 0; -++ int cnt = RTC_RW_RETRY_CNT; -++ -++ bsp_rtc_read(rtc->regs, RTC_INT_RAW, &raw_value); -++ -++ if (raw_value & LV_INT_MASK) -++ /* low voltage detected, date/time is not reliable. */ -++ bsp_rtc_write(rtc->regs, RTC_INT_CLR, 1); -++ -++ bsp_rtc_read(rtc->regs, RTC_LORD, &raw_value); -++ if (raw_value & REG_LOCK_BYPASS) -++ bsp_rtc_write(rtc->regs, RTC_LORD, -++ (~(REG_LOCK_BYPASS)) & raw_value); -++ -++ bsp_rtc_read(rtc->regs, RTC_LORD, &raw_value); -++ /* lock the time */ -++ bsp_rtc_write(rtc->regs, RTC_LORD, (REG_LOCK_STAT) | raw_value); -++ /* wait rtc load flag */ -++ do { -++ bsp_rtc_read(rtc->regs, RTC_LORD, &raw_value); -++ msleep(RTC_SLEEP_TIME_MS); -++ } while ((raw_value & REG_LOCK_STAT) && (--cnt)); -++ -++ if (raw_value & REG_LOCK_STAT) -++ return -EBUSY; -++ -++ bsp_rtc_read(rtc->regs, RTC_S_COUNT, &time_str.second); -++ bsp_rtc_read(rtc->regs, RTC_M_COUNT, &time_str.minute); -++ bsp_rtc_read(rtc->regs, RTC_H_COUNT, &time_str.hour); -++ bsp_rtc_read(rtc->regs, RTC_D_COUNT_L, &time_str.dayl); -++ bsp_rtc_read(rtc->regs, RTC_D_COUNT_H, &time_str.dayh); -++ -++ day = (time_str.dayl | (time_str.dayh << 8)); /* Move to a high 8 bit. */ -++ seconds = date_to_sec(day, time_str.hour, time_str.minute, time_str.second); -++ -++ rtc_time64_to_tm(seconds, time); -++ -++ return rtc_valid_tm(time); -++} -++ -++static int bsp_rtc_set_time(struct device *dev, struct rtc_time *time) -++{ -++ struct bsp_rtc *rtc = dev_get_drvdata(dev); -++ unsigned int days; -++ unsigned long seconds = 0; -++ unsigned int cnt = RTC_RW_RETRY_CNT; -++ unsigned char raw_value = 0; -++ -++ seconds = rtc_tm_to_time64(time); -++ -++ days = sec_to_day(seconds); -++ -++ bsp_rtc_write(rtc->regs, RTC_LR_10MS, 0); -++ bsp_rtc_write(rtc->regs, RTC_LR_S, time->tm_sec); -++ bsp_rtc_write(rtc->regs, RTC_LR_M, time->tm_min); -++ bsp_rtc_write(rtc->regs, RTC_LR_H, time->tm_hour); -++ bsp_rtc_write(rtc->regs, RTC_LR_D_L, (days & 0xFF)); -++ bsp_rtc_write(rtc->regs, RTC_LR_D_H, (days >> 8)); /* Move to a Low 8 bit. */ -++ -++ bsp_rtc_write(rtc->regs, RTC_LORD, -++ (raw_value | REG_LOAD_STAT)); -++ /* wait rtc load flag */ -++ do { -++ bsp_rtc_read(rtc->regs, RTC_LORD, &raw_value); -++ msleep(RTC_SLEEP_TIME_MS); -++ } while ((raw_value & REG_LOAD_STAT) && (--cnt)); -++ -++ if (raw_value & REG_LOAD_STAT) -++ return -EBUSY; -++ -++ return 0; -++} -++ -++static int bsp_rtc_read_alarm(struct device *dev, -++ struct rtc_wkalrm *alrm) -++{ -++ struct bsp_rtc *rtc = dev_get_drvdata(dev); -++ struct bsp_time_str time_str = {0}; -++ unsigned long seconds = 0; -++ unsigned int day; -++ unsigned char int_state = 0; -++ -++ (void)memset_s(alrm, sizeof(struct rtc_wkalrm), 0, -++ sizeof(struct rtc_wkalrm)); -++ -++ bsp_rtc_read(rtc->regs, RTC_MR_S, &time_str.second); -++ bsp_rtc_read(rtc->regs, RTC_MR_M, &time_str.minute); -++ bsp_rtc_read(rtc->regs, RTC_MR_H, &time_str.hour); -++ bsp_rtc_read(rtc->regs, RTC_MR_D_L, &time_str.dayl); -++ bsp_rtc_read(rtc->regs, RTC_MR_D_H, &time_str.dayh); -++ -++ day = (unsigned int)(time_str.dayl | (time_str.dayh << 8)); /* Move to a high 8 bit. */ -++ seconds = date_to_sec(day, time_str.hour, time_str.minute, time_str.second); -++ -++ rtc_time64_to_tm(seconds, &alrm->time); -++ -++ bsp_rtc_read(rtc->regs, RTC_IMSC, &int_state); -++ -++ alrm->enabled = !!(int_state & AIE_INT_MASK); -++ alrm->pending = alrm->enabled; -++ -++ return 0; -++} -++ -++static int bsp_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -++{ -++ struct bsp_rtc *rtc = dev_get_drvdata(dev); -++ unsigned int days; -++ unsigned long seconds = 0; -++ unsigned char val = 0; -++ -++ seconds = rtc_tm_to_time64(&alrm->time); -++ -++ days = sec_to_day(seconds); -++ -++ bsp_rtc_write(rtc->regs, RTC_MR_10MS, 0); -++ bsp_rtc_write(rtc->regs, RTC_MR_S, alrm->time.tm_sec); -++ bsp_rtc_write(rtc->regs, RTC_MR_M, alrm->time.tm_min); -++ bsp_rtc_write(rtc->regs, RTC_MR_H, alrm->time.tm_hour); -++ bsp_rtc_write(rtc->regs, RTC_MR_D_L, (days & 0xFF)); -++ bsp_rtc_write(rtc->regs, RTC_MR_D_H, (days >> 8)); /* Move to a Low 8 bit. */ -++ -++ bsp_rtc_read(rtc->regs, RTC_IMSC, &val); -++ if (alrm->enabled) -++ bsp_rtc_write(rtc->regs, RTC_IMSC, val | AIE_INT_MASK); -++ else -++ bsp_rtc_write(rtc->regs, RTC_IMSC, val & ~AIE_INT_MASK); -++ -++ return 0; -++} -++ -++static int bsp_rtc_alarm_irq_enable(struct device *dev, -++ unsigned int enabled) -++{ -++ struct bsp_rtc *rtc = dev_get_drvdata(dev); -++ unsigned char val = 0; -++ -++ bsp_rtc_read(rtc->regs, RTC_IMSC, &val); -++ if (enabled) -++ bsp_rtc_write(rtc->regs, RTC_IMSC, val | AIE_INT_MASK); -++ else -++ bsp_rtc_write(rtc->regs, RTC_IMSC, val & ~AIE_INT_MASK); -++ -++ return 0; -++} -++ -++/* -++ * interrupt function -++ * do nothing. left for future -++ */ -++static irqreturn_t bsp_rtc_alm_interrupt(int irq, void *data) -++{ -++ struct bsp_rtc *rtc = (struct bsp_rtc *)data; -++ unsigned char val = 0; -++ -++ bsp_rtc_read(rtc->regs, RTC_INT, &val); -++ bsp_rtc_write(rtc->regs, RTC_INT_CLR, AIE_INT_MASK); -++ -++ 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 bsp_rtc_ioctl(struct device *dev, -++ unsigned int cmd, unsigned long arg) -++{ -++ struct bsp_rtc *rtc = dev_get_drvdata(dev); -++ -++ switch (cmd) { -++ case RTC_PLL_SET: { -++ char freq_l, freq_h; -++ struct rtc_pll_info pll_info = {0}; -++ -++ 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; -++ -++ /* freq convert: (freq-3270000) * 3052 / 10000 */ -++ pll_info.pll_value = (pll_info.pll_value - 3270000) * -++ 3052 / 10000; -++ -++ /* & 0xff Obtains the lower eight bits of data. */ -++ freq_l = (char)(pll_info.pll_value & 0xff); -++ /* pll_info.pll_value >> 8 & 0xf Obtains the last four bits of the higher eight bits. */ -++ freq_h = (char)((pll_info.pll_value >> 8) & 0xf); -++ -++ bsp_rtc_write(rtc->regs, RTC_FREQ_H, freq_h); -++ bsp_rtc_write(rtc->regs, RTC_FREQ_L, freq_l); -++ -++ return 0; -++ } -++ case RTC_PLL_GET: { -++ char freq_l = 0; -++ char freq_h = 0; -++ struct rtc_pll_info pll_info = {0}; -++ -++ bsp_rtc_read(rtc->regs, RTC_FREQ_H, &freq_h); -++ bsp_rtc_read(rtc->regs, RTC_FREQ_L, &freq_l); -++ -++ if ((void __user *)(uintptr_t)arg == NULL) { -++ dev_err(dev, "IO err or user buf is NULL..\n"); -++ return -1; -++ } -++ -++ /* freq_h & 0xf << 8 :Shifts leftwards by 8 bits and obtains the lower 4 bits. */ -++ pll_info.pll_value = (((unsigned)freq_h & 0xf) << 8) + freq_l; -++ -++ /* freq convert: 3270000 + (freq * 10000) / 3052 */ -++ pll_info.pll_value = 3270000 + ((unsigned int)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 bsp_rtc_ops = { -++ .read_time = bsp_rtc_read_time, -++ .set_time = bsp_rtc_set_time, -++ .read_alarm = bsp_rtc_read_alarm, -++ .set_alarm = bsp_rtc_set_alarm, -++ .alarm_irq_enable = bsp_rtc_alarm_irq_enable, -++ .ioctl = bsp_rtc_ioctl, -++}; -++ -++static int bsp_rtc_init(struct bsp_rtc *rtc) -++{ -++ void *spi_reg = rtc->regs; -++ 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)); -++ -++ bsp_rtc_write(spi_reg, RTC_IMSC, INT_MSK_DEFAULT); -++ bsp_rtc_write(spi_reg, RTC_SAR_CTRL, LV_CTL_DEFAULT); -++ -++ /* default driver capability */ -++ bsp_rtc_write(spi_reg, RTC_REG_LOCK4, 0x5A); /* 0x5A:ctl order */ -++ bsp_rtc_write(spi_reg, RTC_REG_LOCK3, 0x5A); /* 0x5A:ctl order */ -++ bsp_rtc_write(spi_reg, RTC_REG_LOCK2, 0xAB); /* 0xAB:ctl order */ -++ bsp_rtc_write(spi_reg, RTC_REG_LOCK1, 0xCD); /* 0xCD:ctl order */ -++ -++ bsp_rtc_write(spi_reg, RTC_CLK_CFG, RTC_DEFAULT_DRIVER_CAPABILITY); -++ -++ /* default FREQ COEF */ -++ bsp_rtc_write(spi_reg, RTC_FREQ_H, FREQ_H_DEFAULT); -++ bsp_rtc_write(spi_reg, RTC_FREQ_L, FREQ_L_DEFAULT); -++ -++ bsp_rtc_read(spi_reg, RTC_INT_RAW, &val); -++ -++ if (val & LV_INT_MASK) -++ /* low voltage detected, date/time is not reliable. */ -++ bsp_rtc_write(rtc->regs, RTC_INT_CLR, 1); -++ -++ return 0; -++} -++ -++static int bsp_rtc_probe(struct platform_device *pdev) -++{ -++ struct resource *mem = NULL; -++ struct bsp_rtc *rtc = NULL; -++ 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, -++ bsp_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, -++ &bsp_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 (bsp_rtc_init(rtc)) { -++ dev_err(&pdev->dev, "bsp_rtc_init failed.\n"); -++ return -EIO; -++ } -++ -++ dev_info(&pdev->dev, "RTC driver for bsp enabled\n"); -++ -++ return 0; -++} -++ -++static int bsp_rtc_remove(struct platform_device *pdev) -++{ -++ return 0; -++} -++ -++static const struct of_device_id bsp_rtc_match[] = { -++ { .compatible = "vendor,rtc" }, -++ {}, -++}; -++ -++static struct platform_driver bsp_rtc_driver = { -++ .probe = bsp_rtc_probe, -++ .remove = bsp_rtc_remove, -++ .driver = { -++ .name = "bsp_rtc", -++ .of_match_table = bsp_rtc_match, -++ }, -++}; -++ -++module_platform_driver(bsp_rtc_driver); -++ -++#define OSDRV_MODULE_VERSION_STRING "RTC_V1.0" -++ -++MODULE_DESCRIPTION("RTC driver"); -++MODULE_LICENSE("GPL v2"); -++MODULE_VERSION("VERSION=" OSDRV_MODULE_VERSION_STRING); -+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile -+index f21f7fd36..e20d791de 100644 -+--- a/drivers/spi/Makefile -++++ b/drivers/spi/Makefile -+@@ -86,6 +86,7 @@ obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o -+ obj-$(CONFIG_SPI_ORION) += spi-orion.o -+ obj-$(CONFIG_SPI_PIC32) += spi-pic32.o -+ obj-$(CONFIG_SPI_PIC32_SQI) += spi-pic32-sqi.o -++obj-$(CONFIG_ARCH_BSP) += vendor/ -+ obj-$(CONFIG_SPI_PL022) += spi-pl022.o -+ obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o -+ spi-pxa2xx-platform-objs := spi-pxa2xx.o spi-pxa2xx-dma.o -+diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c -+index f7603c209..cb966d541 100644 -+--- a/drivers/spi/spi-pl022.c -++++ b/drivers/spi/spi-pl022.c -+@@ -34,6 +34,7 @@ -+ #include -+ #include -+ #include -++#include "vendor/vendor_spi.h" -+ -+ /* -+ * This macro is used to define some register default values. -+@@ -399,6 +400,9 @@ struct pl022 { -+ #endif -+ int cur_cs; -+ int *chipselects; -++#ifdef CONFIG_ARCH_BSP -++ struct ssp_vendor_data vendor_data; -++#endif -+ }; -+ -+ /** -+@@ -455,7 +459,10 @@ static void null_cs_control(u32 command) -+ static void internal_cs_control(struct pl022 *pl022, u32 command) -+ { -+ u32 tmp; -+- -++#ifdef CONFIG_ARCH_BSP -++ vendor_internal_cs_control(&pl022->vendor_data, pl022->cur_cs, command); -++ return; -++#endif -+ tmp = readw(SSP_CSR(pl022->virtbase)); -+ if (command == SSP_CHIP_SELECT) -+ tmp &= ~BIT(pl022->cur_cs); -+@@ -2038,7 +2045,9 @@ static int pl022_setup(struct spi_device *spi) -+ SSP_WRITE_BITS(chip->cr0, chip_info->iface, -+ SSP_CR0_MASK_FRF, 4); -+ } -+- -++#ifdef CONFIG_ARCH_BSP -++ vendor_ssp_setup(&pl022->vendor_data, &chip_info_dt, spi, &chip->cr1); -++#endif -+ /* Stuff that is common for all versions */ -+ if (spi->mode & SPI_CPOL) -+ tmp = SSP_CLK_POL_IDLE_HIGH; -+@@ -2228,7 +2237,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) -+ status = -ENOMEM; -+ goto err_no_ioremap; -+ } -+- dev_info(&adev->dev, "mapped registers from %pa to %p\n", -++ dev_dbg(&adev->dev, "mapped registers from %pa to %p\n", -+ &adev->res.start, pl022->virtbase); -+ -+ pl022->clk = devm_clk_get(&adev->dev, NULL); -+@@ -2247,7 +2256,11 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) -+ /* Initialize transfer pump */ -+ tasklet_init(&pl022->pump_transfers, pump_transfers, -+ (unsigned long)pl022); -+- -++#ifdef CONFIG_ARCH_BSP -++ status = vendor_ssp_init(&pl022->vendor_data, pl022->virtbase, master, adev); -++ if (status) -++ goto err_no_irq; -++#endif -+ /* Disable SSP */ -+ writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), -+ SSP_CR1(pl022->virtbase)); -+@@ -2445,6 +2458,17 @@ static struct vendor_data vendor_lsi = { -+ .internal_cs_ctrl = true, -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++static struct vendor_data vendor_bsp = { -++ .fifodepth = 256, -++ .max_bpw = 16, -++ .unidir = false, -++ .extended_cr = false, -++ .pl023 = false, -++ .loopback = true, -++ .internal_cs_ctrl = true, -++}; -++#endif -+ static const struct amba_id pl022_ids[] = { -+ { -+ /* -+@@ -2485,6 +2509,17 @@ static const struct amba_id pl022_ids[] = { -+ .mask = 0x000fffff, -+ .data = &vendor_lsi, -+ }, -++#ifdef CONFIG_ARCH_BSP -++ { -++ /* -++ * Vendor derivative, this has a 16bit wide -++ * and 256 locations deep TX/RX FIFO -++ */ -++ .id = 0x00800022, -++ .mask = 0xffffffff, -++ .data = &vendor_bsp, -++ }, -++#endif -+ { 0, 0 }, -+ }; -+ -+diff --git a/drivers/spi/vendor/Makefile b/drivers/spi/vendor/Makefile -+new file mode 100755 -+index 000000000..cce6cd60b -+--- /dev/null -++++ b/drivers/spi/vendor/Makefile -+@@ -0,0 +1 @@ -++obj-$(CONFIG_ARCH_BSP) += vendor_spi.o -+diff --git a/drivers/spi/vendor/vendor_spi.c b/drivers/spi/vendor/vendor_spi.c -+new file mode 100755 -+index 000000000..b09823a8a -+--- /dev/null -++++ b/drivers/spi/vendor/vendor_spi.c -+@@ -0,0 +1,211 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include "vendor_spi.h" -++ -++void vendor_internal_cs_control(struct ssp_vendor_data *vendor_data, -++ int cur_cs, u32 command) -++{ -++ u32 tmp; -++ -++ if (vendor_data->num_cs > 1) { -++ tmp = readl(vendor_data->cs_data.virt_addr); -++ tmp &= ~(vendor_data->cs_data.cs_mask_bit); -++ tmp |= ((u32)cur_cs) << vendor_data->cs_data.cs_sb; -++ writel(tmp, vendor_data->cs_data.virt_addr); -++ } -++ if (command == SSP_CHIP_SELECT) -++ /* Enable SSP */ -++ writew((readw(VENDOR_SSP_CR1(vendor_data->virtbase)) | -++ VENDOR_SSP_CR1_MASK_SSE), -++ VENDOR_SSP_CR1(vendor_data->virtbase)); -++ else -++ /* disable SSP */ -++ writew((readw(VENDOR_SSP_CR1(vendor_data->virtbase)) & -++ (~VENDOR_SSP_CR1_MASK_SSE)), -++ VENDOR_SSP_CR1(vendor_data->virtbase)); -++} -++ -++void vendor_ssp_setup(struct ssp_vendor_data *vendor_data, -++ struct pl022_config_chip *chip_info, struct spi_device *spi, u16 *cr1) -++{ -++ u32 tmp; -++ -++ if (spi->master->slave) -++ chip_info->hierarchy = SSP_SLAVE; -++ else -++ chip_info->hierarchy = SSP_MASTER; -++ -++ if (vendor_data->slave_tx_disable) -++ chip_info->slave_tx_disable = VENDOR_SSP_DO_NOT_DRIVE_TX; -++ else -++ chip_info->slave_tx_disable = VENDOR_SSP_DRIVE_TX; -++ -++ if (spi->mode & SPI_LSB_FIRST) -++ tmp = !!SPI_LSB_FIRST; -++ else -++ tmp = !SPI_LSB_FIRST; -++ VENDOR_SSP_WRITE_BITS(*cr1, tmp, VENDOR_SSP_CR1_MASK_BITEND, -++ VENDOR_SSP_BITEND_SHIFT_BIT); -++ -++ if (spi->mode & SPI_CPHA) -++ VENDOR_SSP_WRITE_BITS(*cr1, 0x1, VENDOR_SSP_CR1_MASK_ALTASENS, -++ VENDOR_SSP_ALTASENS_SHIFT_BIT); -++ else -++ VENDOR_SSP_WRITE_BITS(*cr1, 0x0, VENDOR_SSP_CR1_MASK_ALTASENS, -++ VENDOR_SSP_ALTASENS_SHIFT_BIT); -++} -++ -++static void try_deassert_spi_reset(struct amba_device *adev) -++{ -++ struct reset_control *spi_rst = NULL; -++ spi_rst = devm_reset_control_get(&adev->dev, "bsp_spi_rst"); -++ if (IS_ERR_OR_NULL(spi_rst)) -++ return; -++ /* deassert reset if "resets" property is set */ -++ dev_info(&adev->dev, "deassert reset\n"); -++ reset_control_deassert(spi_rst); -++} -++ -++/* Before using the SPI, you need to read and write a piece -++ of data to clear the abnormal status of the RAT memory */ -++#ifdef CONFIG_ARCH_HI3516CV610_FAMILY -++static void vendor_ssp_clr_ratmem_abnormal(struct ssp_vendor_data *vendor_data) -++{ -++ int polling_count = 0; -++ -++ /* Disable SSP */ -++ writew((readw(VENDOR_SSP_CR1(vendor_data->virtbase)) & (~VENDOR_SSP_CR1_MASK_SSE)), -++ VENDOR_SSP_CR1(vendor_data->virtbase)); -++ -++ writew(VENDOR_SSP_DISABLE_IRQ, VENDOR_SSP_IMSC(vendor_data->virtbase)); -++ -++ writew(VENDOR_SSP_TRAINING_DATA, VENDOR_SSP_DR(vendor_data->virtbase)); -++ -++ writew(VENDOR_SSP_TRAINING_START, VENDOR_SSP_ITCR(vendor_data->virtbase)); -++ -++ while (VENDOR_SSP_POLLING_TIMEOUT > polling_count) { -++ if (readw(VENDOR_SSP_SR(vendor_data->virtbase)) == VENDOR_SSP_TX_STATUS) -++ break; -++ udelay(VENDOR_SSP_WAIT_TIME); -++ polling_count++; -++ } -++ -++ readw(VENDOR_SSP_TDR(vendor_data->virtbase)); -++ -++ polling_count = 0; -++ while (VENDOR_SSP_POLLING_TIMEOUT > polling_count) { -++ if (readw(VENDOR_SSP_SR(vendor_data->virtbase)) == VENDOR_SSP_DEFAULT_STATUS) -++ break; -++ udelay(VENDOR_SSP_WAIT_TIME); -++ polling_count++; -++ } -++ -++ writew(VENDOR_SSP_TRAINING_DATA, VENDOR_SSP_TDR(vendor_data->virtbase)); -++ -++ polling_count = 0; -++ while (VENDOR_SSP_POLLING_TIMEOUT > polling_count) { -++ if (readw(VENDOR_SSP_SR(vendor_data->virtbase)) == VENDOR_SSP_RX_STATUS) -++ break; -++ udelay(VENDOR_SSP_WAIT_TIME); -++ polling_count++; -++ } -++ -++ readw(VENDOR_SSP_DR(vendor_data->virtbase)); -++ -++ polling_count = 0; -++ while (VENDOR_SSP_POLLING_TIMEOUT > polling_count) { -++ if (readw(VENDOR_SSP_SR(vendor_data->virtbase)) == VENDOR_SSP_DEFAULT_STATUS) -++ break; -++ udelay(VENDOR_SSP_WAIT_TIME); -++ polling_count++; -++ } -++ -++ writew(VENDOR_SSP_TRAINING_END, VENDOR_SSP_ITCR(vendor_data->virtbase)); -++} -++#endif -++ -++static int vendor_ssp_get_slave_mode_data(struct ssp_vendor_data *vendor_data, -++ struct spi_master *master, struct amba_device *adev) -++{ -++ unsigned int slave_mode; -++ struct device_node *np = adev->dev.of_node; -++ -++ if (of_property_read_u32(np, "vendor,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, "cannot get slave mode!!!\n"); -++ return -EINVAL; -++ } -++ } -++ -++ if (of_property_read_u32(np, "vendor,slave_tx_disable", -++ &vendor_data->slave_tx_disable)) { -++ dev_err(&adev->dev, "cannot get slave_tx_disable!!!\n"); -++ return -EPROBE_DEFER; -++ } -++ -++ return 0; -++} -++ -++static int vendor_ssp_get_cs_data(struct ssp_vendor_data *vendor_data, -++ struct amba_device *adev) -++{ -++ struct device_node *np = adev->dev.of_node; -++ -++ if (vendor_data->num_cs > 1) { -++ if (of_address_to_resource(np, 1, -++ &vendor_data->cs_data.res)) { -++ return -EPROBE_DEFER; -++ } -++ if (of_property_read_u32(np, "spi_cs_sb", -++ &vendor_data->cs_data.cs_sb)) { -++ return -EPROBE_DEFER; -++ } -++ if (of_property_read_u32(np, "spi_cs_mask_bit", -++ &vendor_data->cs_data.cs_mask_bit)) { -++ return -EPROBE_DEFER; -++ } -++ vendor_data->cs_data.virt_addr = devm_ioremap(&adev->dev, -++ vendor_data->cs_data.res.start, -++ resource_size(&vendor_data->cs_data.res)); -++ if (vendor_data->cs_data.virt_addr == NULL) { -++ dev_err(&adev->dev, "cs_data.virt_addr nomem!!!\n"); -++ return -ENOMEM; -++ } -++ } -++ -++ return 0; -++} -++ -++int vendor_ssp_init(struct ssp_vendor_data *vendor_data, void __iomem *virtbase, -++ struct spi_master *master, struct amba_device *adev) -++{ -++ int ret; -++ -++ master->mode_bits |= SPI_LSB_FIRST; -++ vendor_data->virtbase = virtbase; -++ vendor_data->num_cs = master->num_chipselect; -++ -++ ret = vendor_ssp_get_slave_mode_data(vendor_data, master, adev); -++ if (ret != 0) -++ return ret; -++ -++ ret = vendor_ssp_get_cs_data(vendor_data, adev); -++ if (ret != 0) -++ return ret; -++ -++ -++ try_deassert_spi_reset(adev); -++#ifdef CONFIG_ARCH_HI3516CV610_FAMILY -++ vendor_ssp_clr_ratmem_abnormal(vendor_data); -++#endif -++ writew(0x0, VENDOR_SSP_TX_FIFO_CR(vendor_data->virtbase)); -++ writew(0x0, VENDOR_SSP_RX_FIFO_CR(vendor_data->virtbase)); -++ -++ return 0; -++} -+diff --git a/drivers/spi/vendor/vendor_spi.h b/drivers/spi/vendor/vendor_spi.h -+new file mode 100755 -+index 000000000..02a982965 -+--- /dev/null -++++ b/drivers/spi/vendor/vendor_spi.h -+@@ -0,0 +1,85 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#ifndef __VENDOR_LINUX_SPI_H -++#define __VENDOR_LINUX_SPI_H -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define VENDOR_SSP_WRITE_BITS(reg, val, mask, sb) \ -++ ((reg) = (((reg) & ~(mask)) | (((val)<<(sb)) & (mask)))) -++/* -++ * The Vendor version of this block adds some bits -++ * in SSP_CR1 -++ */ -++#define VENDOR_SSP_CR1_MASK_SSE (0x1UL << 1) -++#define VENDOR_SSP_CR1_MASK_BITEND (0x1UL << 4) -++#define VENDOR_SSP_CR1_MASK_ALTASENS (0x1UL << 6) -++ -++#define VENDOR_SSP_CR0(r) (r + 0x000) -++#define VENDOR_SSP_CR1(r) (r + 0x004) -++#define VENDOR_SSP_DR(r) (r + 0x008) -++#define VENDOR_SSP_SR(r) (r + 0x00C) -++#define VENDOR_SSP_CPSR(r) (r + 0x010) -++#define VENDOR_SSP_IMSC(r) (r + 0x014) -++#define VENDOR_SSP_RIS(r) (r + 0x018) -++#define VENDOR_SSP_MIS(r) (r + 0x01C) -++#define VENDOR_SSP_ICR(r) (r + 0x020) -++#define VENDOR_SSP_DMACR(r) (r + 0x024) -++#define VENDOR_SSP_CSR(r) (r + 0x030) -++#define VENDOR_SSP_ITCR(r) (r + 0x080) -++#define VENDOR_SSP_ITIP(r) (r + 0x084) -++#define VENDOR_SSP_ITOP(r) (r + 0x088) -++#define VENDOR_SSP_TDR(r) (r + 0x08C) -++#define VENDOR_SSP_TX_FIFO_CR(r) (r + 0x028) -++#define VENDOR_SSP_RX_FIFO_CR(r) (r + 0x02C) -++ -++#define VENDOR_SSP_POLLING_TIMEOUT 1000 -++#define VENDOR_SSP_DRIVE_TX 0 -++#define VENDOR_SSP_DO_NOT_DRIVE_TX 1 -++ -++#define VENDOR_SSP_DISABLE_IRQ 0x0 -++#define VENDOR_SSP_TRAINING_DATA 0x5aa5 -++#define VENDOR_SSP_TRAINING_START 0x2 -++#define VENDOR_SSP_TRAINING_END 0x0 -++#define VENDOR_SSP_WAIT_TIME 100 -++#define VENDOR_SSP_DEFAULT_STATUS 0x3 -++#define VENDOR_SSP_RX_STATUS 0x7 -++#define VENDOR_SSP_TX_STATUS 0x2 -++ -++#define VENDOR_SSP_BITEND_SHIFT_BIT 4 -++#define VENDOR_SSP_ALTASENS_SHIFT_BIT 6 -++ -++struct cs_data { -++ struct resource res; -++ void __iomem *virt_addr; -++ unsigned int cs_sb; -++ unsigned int cs_mask_bit; -++}; -++ -++struct ssp_vendor_data { -++ unsigned int slave_tx_disable; -++ unsigned int num_cs; -++ struct cs_data cs_data; -++ void __iomem *virtbase; -++}; -++ -++int vendor_ssp_init(struct ssp_vendor_data *vendor_data, void __iomem *virtbase, -++ struct spi_master *master, struct amba_device *adev); -++ -++void vendor_ssp_setup(struct ssp_vendor_data *vendor_data, -++ struct pl022_config_chip *chip_info, struct spi_device *spi, u16 *cr1); -++ -++void vendor_internal_cs_control(struct ssp_vendor_data *vendor_data, -++ int cur_cs, u32 command); -++ -++#endif /* __VENDOR_LINUX_SPI_H */ -+diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig -+index 3ca71e381..0ffc061d3 100644 -+--- a/drivers/tee/optee/Kconfig -++++ b/drivers/tee/optee/Kconfig -+@@ -15,3 +15,16 @@ config OPTEE_SHM_NUM_PRIV_PAGES -+ help -+ This sets the number of private shared memory pages to be -+ used by OP-TEE TEE driver. -++ -++if ARCH_BSP -++config SYNC_OPTEE_MEMORY_LAYOUT -++ bool "Synchronizing OP-TEE memory layout" -++ depends on OPTEE -++ help -++ This synchronize OP-TEE memory layout at compile time. -++ -++config OPTEE_DIR -++ string "OP-TEE directory" -++ default "" -++ depends on SYNC_OPTEE_MEMORY_LAYOUT -++endif -+diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h -+index c7ac7d02d..146ae916a 100644 -+--- a/drivers/tee/optee/optee_msg.h -++++ b/drivers/tee/optee/optee_msg.h -+@@ -34,6 +34,12 @@ -+ #define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT 0xa -+ #define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT 0xb -+ -++#ifdef CONFIG_ARCH_BSP -++#define OPTEE_MSG_ATTR_TYPE_RMEM_MMZ_MASK (1 << 4) -++#define OPTEE_MSG_ATTR_TYPE_RMEM_MMZ_INPUT (OPTEE_MSG_ATTR_TYPE_RMEM_MMZ_MASK | OPTEE_MSG_ATTR_TYPE_RMEM_INPUT) -++#define OPTEE_MSG_ATTR_TYPE_RMEM_MMZ_OUTPUT (OPTEE_MSG_ATTR_TYPE_RMEM_MMZ_MASK | OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT) -++#define OPTEE_MSG_ATTR_TYPE_RMEM_MMZ_INOUT (OPTEE_MSG_ATTR_TYPE_RMEM_MMZ_MASK | OPTEE_MSG_ATTR_TYPE_RMEM_INOUT) -++#endif -+ #define OPTEE_MSG_ATTR_TYPE_MASK GENMASK(7, 0) -+ -+ /* -+@@ -373,6 +379,16 @@ struct optee_msg_arg { -+ #define OPTEE_MSG_RPC_CMD_WAIT_QUEUE 4 -+ #define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP 0 -+ #define OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP 1 -++#ifdef CONFIG_ARCH_BSP -++/* -++ * Waiting on a key -++ * [in] value[0].a OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP_TIMEOUT -++ * [in] value[0].b wait key -++ * [in] value[0].c timeout time in ms -++ * [out] value[1].a time left before timeout -++ */ -++#define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP_TIMEOUT 2 -++#endif -+ -+ /* -+ * Suspend execution -+diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c -+index f1e0332b0..1489fc527 100644 -+--- a/drivers/tee/optee/rpc.c -++++ b/drivers/tee/optee/rpc.c -+@@ -184,11 +184,32 @@ static void wq_wakeup(struct optee_wait_queue *wq, u32 key) -+ complete(&w->c); -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static u32 wq_sleep_timeout(struct optee_wait_queue *wq, u32 key, u32 timeout_ms) -++{ -++ struct wq_entry *w = wq_entry_get(wq, key); -++ unsigned long timeout = msecs_to_jiffies(timeout_ms); -++ u32 time_left = 0; -++ -++ if (w) { -++ time_left = wait_for_completion_timeout(&w->c, timeout); -++ mutex_lock(&wq->mu); -++ list_del(&w->link); -++ mutex_unlock(&wq->mu); -++ kfree(w); -++ } -++ -++ return jiffies_to_msecs(time_left); -++} -++#endif -++ -+ static void handle_rpc_func_cmd_wq(struct optee *optee, -+ struct optee_msg_arg *arg) -+ { -++#ifndef CONFIG_ARCH_BSP -+ if (arg->num_params != 1) -+ goto bad; -++#endif -+ -+ if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) != -+ OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) -+@@ -196,11 +217,35 @@ static void handle_rpc_func_cmd_wq(struct optee *optee, -+ -+ switch (arg->params[0].u.value.a) { -+ case OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP: -++#ifdef CONFIG_ARCH_BSP -++ if (arg->num_params != 1) { -++ goto bad; -++ } -++#endif -+ wq_sleep(&optee->wait_queue, arg->params[0].u.value.b); -+ break; -+ case OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP: -++#ifdef CONFIG_ARCH_BSP -++ if (arg->num_params != 1) { -++ goto bad; -++ } -++#endif -+ wq_wakeup(&optee->wait_queue, arg->params[0].u.value.b); -++ -+ break; -++#ifdef CONFIG_ARCH_BSP -++ case OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP_TIMEOUT: -++ if (arg->num_params != 2) { -++ goto bad; -++ } -++ if ((arg->params[1].attr & OPTEE_MSG_ATTR_TYPE_MASK) != -++ OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT) { -++ goto bad; -++ } -++ arg->params[1].u.value.a = wq_sleep_timeout(&optee->wait_queue, -++ arg->params[0].u.value.b, arg->params[0].u.value.c); -++ break; -++#endif -+ default: -+ goto bad; -+ } -+diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c -+index e95707312..b0cd5c815 100644 -+--- a/drivers/tee/tee_core.c -++++ b/drivers/tee/tee_core.c -+@@ -17,6 +17,10 @@ -+ #include -+ #include "tee_private.h" -+ -++#ifdef CONFIG_ARCH_BSP -++static phys_addr_t (*smmz_parameter_conversion_hook)(int, pid_t) = NULL; -++#endif -++ -+ #define TEE_NUM_DEVICES 32 -+ -+ #define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x)) -+@@ -267,6 +271,25 @@ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method, -+ } -+ EXPORT_SYMBOL_GPL(tee_session_calc_client_uuid); -+ -++#ifdef CONFIG_ARCH_BSP -++static DEFINE_SPINLOCK(conversion_hook_lock); -++void regist_smmz_parameter_conversion_hook(phys_addr_t (*hook)(int, pid_t)) -++{ -++ spin_lock(&conversion_hook_lock); -++ smmz_parameter_conversion_hook = hook; -++ spin_unlock(&conversion_hook_lock); -++} -++EXPORT_SYMBOL_GPL(regist_smmz_parameter_conversion_hook); -++ -++void unregist_smmz_parameter_conversion_hook(void) -++{ -++ spin_lock(&conversion_hook_lock); -++ smmz_parameter_conversion_hook = NULL; -++ spin_unlock(&conversion_hook_lock); -++} -++EXPORT_SYMBOL_GPL(unregist_smmz_parameter_conversion_hook); -++#endif -++ -+ static int tee_ioctl_version(struct tee_context *ctx, -+ struct tee_ioctl_version_data __user *uvers) -+ { -+@@ -430,6 +453,20 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, -+ params[n].u.memref.size = ip.b; -+ params[n].u.memref.shm = shm; -+ break; -++#ifdef CONFIG_ARCH_BSP -++ case TEE_IOCTL_PARAM_ATTR_TYPE_MMZ_INPUT: -++ case TEE_IOCTL_PARAM_ATTR_TYPE_MMZ_OUTPUT: -++ case TEE_IOCTL_PARAM_ATTR_TYPE_MMZ_INOUT: -++ spin_lock(&conversion_hook_lock); -++ if (smmz_parameter_conversion_hook != NULL) { -++ params[n].u.value.a = smmz_parameter_conversion_hook(ip.a, current->pid); -++ spin_unlock(&conversion_hook_lock); -++ params[n].u.value.b = ip.b; -++ params[n].u.value.c = ip.c; -++ break; -++ } -++ spin_unlock(&conversion_hook_lock); -++#endif -+ default: -+ /* Unknown attribute */ -+ return -EINVAL; -+diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h -+index e55204df3..816fb9065 100644 -+--- a/drivers/tee/tee_private.h -++++ b/drivers/tee/tee_private.h -+@@ -12,6 +12,13 @@ -+ #include -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#define TEE_TYPE_MMZ_MASK (1 << 4) -++#define TEE_IOCTL_PARAM_ATTR_TYPE_MMZ_INPUT (TEE_TYPE_MMZ_MASK | TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT) -++#define TEE_IOCTL_PARAM_ATTR_TYPE_MMZ_OUTPUT (TEE_TYPE_MMZ_MASK | TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT) -++#define TEE_IOCTL_PARAM_ATTR_TYPE_MMZ_INOUT (TEE_TYPE_MMZ_MASK | TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) -++#endif -++ -+ /** -+ * struct tee_shm_pool - shared memory pool -+ * @private_mgr: pool manager for shared memory only between kernel -+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -+index 638255a0e..4a211fcb2 100644 -+--- a/drivers/tty/serial/amba-pl011.c -++++ b/drivers/tty/serial/amba-pl011.c -+@@ -45,6 +45,10 @@ -+ -+ #include "amba-pl011.h" -+ -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -++ -+ #define UART_NR 14 -+ -+ #define SERIAL_AMBA_MAJOR 204 -+@@ -2717,6 +2721,19 @@ static int pl011_register_port(struct uart_amba_port *uap) -+ return ret; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static void try_deassert_uart_reset(struct amba_device *adev) -++{ -++ struct reset_control *uart_rst = NULL; -++ uart_rst = devm_reset_control_get(&adev->dev, "bsp_uart_rst"); -++ if (IS_ERR_OR_NULL(uart_rst)) -++ return; -++ /* deassert reset if "resets" property is set */ -++ dev_info(&adev->dev, "deassert reset\n"); -++ reset_control_deassert(uart_rst); -++} -++#endif -++ -+ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) -+ { -+ struct uart_amba_port *uap; -+@@ -2740,17 +2757,12 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) -+ uap->vendor = vendor; -+ uap->fifosize = vendor->get_fifosize(dev); -+ uap->port.iotype = vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; -++ uap->port.irq = dev->irq[0]; -+ uap->port.ops = &amba_pl011_pops; -+ -+- /* if no irq domain found, irq number is 0, try again */ -+- if (!dev->irq[0] && dev->dev.of_node) { -+- ret = of_irq_get(dev->dev.of_node, 0); -+- if (ret < 0) -+- return ret; -+- dev->irq[0] = ret; -+- } -+- -+- uap->port.irq = dev->irq[0]; -++#ifdef CONFIG_ARCH_BSP -++ try_deassert_uart_reset(dev); -++#endif -+ -+ snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); -+ -+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h -+index 291893d27..dcea12a91 100644 -+--- a/drivers/usb/dwc3/core.h -++++ b/drivers/usb/dwc3/core.h -+@@ -30,7 +30,9 @@ -+ #include -+ -+ #include -+- -++#ifdef CONFIG_ARCH_BSP -++#define STATUS_PHASE_APPEND_SETUP -++#endif -+ #define DWC3_MSG_MAX 500 -+ -+ /* Global constants */ -+@@ -474,7 +476,9 @@ -+ #define DWC3_DSTS_USBLNKST(n) (((n) & DWC3_DSTS_USBLNKST_MASK) >> 18) -+ -+ #define DWC3_DSTS_RXFIFOEMPTY BIT(17) -+- -++#ifdef CONFIG_ARCH_BSP -++#define DWC3_EVENT_PRAM_MAX_SOFFN 0x3fff -++#endif -+ #define DWC3_DSTS_SOFFN_MASK (0x3fff << 3) -+ #define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3) -+ -+@@ -654,8 +658,11 @@ struct dwc3_event_buffer { -+ -+ #define DWC3_EP_DIRECTION_TX true -+ #define DWC3_EP_DIRECTION_RX false -+- -++#ifdef CONFIG_ARCH_BSP -++#define DWC3_TRB_NUM 4096 -++#else -+ #define DWC3_TRB_NUM 256 -++#endif -+ -+ /** -+ * struct dwc3_ep - device side endpoint representation -+@@ -713,7 +720,19 @@ struct dwc3_ep { -+ -+ /* This last one is specific to EP0 */ -+ #define DWC3_EP0_DIR_IN BIT(31) -+- -++#ifdef CONFIG_ARCH_BSP -++ /* -++ * IMPORTANT: we *know* we have 4096 TRBs in our @trb_pool, so we will -++ * use a u16 type here. If anybody decides to increase number of TRBs to -++ * anything larger than 4096 - I can't see why people would want to do -++ * this though - then this type needs to be changed. -++ * -++ * By using u16 types we ensure that our % operator when incrementing -++ * enqueue and dequeue get optimized away by the compiler. -++ */ -++ u16 trb_enqueue; -++ u16 trb_dequeue; -++#else -+ /* -+ * IMPORTANT: we *know* we have 256 TRBs in our @trb_pool, so we will -+ * use a u8 type here. If anybody decides to increase number of TRBs to -+@@ -725,7 +744,7 @@ struct dwc3_ep { -+ */ -+ u8 trb_enqueue; -+ u8 trb_dequeue; -+- -++#endif // CONFIG_ARCH_BSP -+ u8 number; -+ u8 type; -+ u8 resource_index; -+@@ -1259,6 +1278,11 @@ struct dwc3 { -+ unsigned dis_metastability_quirk:1; -+ -+ unsigned dis_split_quirk:1; -++#ifdef CONFIG_ARCH_BSP -++#ifdef STATUS_PHASE_APPEND_SETUP -++ unsigned is_status_append_setup:1; -++#endif -++#endif // CONFIG_ARCH_BSP -+ -+ u16 imod_interval; -+ }; -+diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c -+index 3cd294264..cb7e2742e 100644 -+--- a/drivers/usb/dwc3/ep0.c -++++ b/drivers/usb/dwc3/ep0.c -+@@ -22,6 +22,10 @@ -+ #include -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -++ -+ #include "core.h" -+ #include "debug.h" -+ #include "gadget.h" -+@@ -56,7 +60,21 @@ static void dwc3_ep0_prepare_one_trb(struct dwc3_ep *dep, -+ else -+ trb->ctrl |= (DWC3_TRB_CTRL_IOC -+ | DWC3_TRB_CTRL_LST); -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("EP0 Prepare TRB:%d raw[%x %x %x %x] BUFSIZE:%d %s%s%s%s | %s%s%s%s%s CTL:0x%x", -++ dep->trb_enqueue, trb->bpl, trb->bph, trb->size, trb->ctrl, -++ trb->size & DWC3_TRB_SIZE_MASK, -++ (type == DWC3_TRBCTL_CONTROL_SETUP)?" setup" : "", -++ (type == DWC3_TRBCTL_CONTROL_STATUS3)?" status3" : "", -++ (type == DWC3_TRBCTL_CONTROL_STATUS2)?" status2" : "", -++ (type == DWC3_TRBCTL_CONTROL_DATA)?" data" : "", -++ (trb->ctrl & DWC3_TRB_CTRL_IOC) ? "IOC " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CSP) ? "CSP " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CHN) ? "CHN " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_LST) ? "LST " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_HWO) ? "HWO " : "", -++ ((trb->ctrl >> 4) & 0x3f)); -++#endif -+ trace_dwc3_prepare_trb(dep, trb); -+ } -+ -+@@ -83,6 +101,150 @@ static int dwc3_ep0_start_trans(struct dwc3_ep *dep) -+ -+ return 0; -+ } -++#ifdef CONFIG_ARCH_BSP -++#ifdef STATUS_PHASE_APPEND_SETUP -++static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl); -++static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl); -++static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc); -++ -++static void dwc3_ep0_prepare_setup_trb(struct dwc3_ep *dep) -++{ -++ struct dwc3_trb *trb; -++ struct dwc3 *dwc; -++ -++ dwc = dep->dwc; -++ trb = &dwc->ep0_trb[1]; -++ -++ trb->bpl = lower_32_bits(dwc->ep0_trb_addr + sizeof(*dwc->ep0_trb)); -++ trb->bph = upper_32_bits(dwc->ep0_trb_addr + sizeof(*dwc->ep0_trb)); -++ trb->size = 8; /* SETUP PACKET is 8 byte length */ -++ trb->ctrl = DWC3_TRBCTL_CONTROL_SETUP; -++ -++ trb->ctrl |= (DWC3_TRB_CTRL_HWO | DWC3_TRB_CTRL_ISP_IMI | -++ DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_LST); -++ -++ iprec("EP0[%s] Prepare Setup TRB(%#x) raw[%x %x %x %x] BUFSIZE:%d | %s%s%s%s%s%s CTL:0x%x", -++ dep->name, trb, trb->bpl, trb->bph, trb->size, trb->ctrl, -++ trb->size & DWC3_TRB_SIZE_MASK, -++ (trb->ctrl & DWC3_TRB_CTRL_ISP_IMI) ? "ISP " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_IOC) ? "IOC " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CSP) ? "CSP " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CHN) ? "CHN " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_LST) ? "LST " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_HWO) ? "HWO " : "", -++ ((trb->ctrl >> 4) & 0x3f)); /* bit[9:4] means TRBCTL */ -++} -++ -++static int dwc3_ep0_start_trans_append_setup(struct dwc3_ep *dep) -++{ -++ struct dwc3_gadget_ep_cmd_params params; -++ struct dwc3 *dwc; -++ int ret; -++ -++ dwc = dep->dwc; -++ -++ memset(¶ms, 0, sizeof(params)); -++ params.param0 = upper_32_bits(dwc->ep0_trb_addr + sizeof(*dwc->ep0_trb)); -++ params.param1 = lower_32_bits(dwc->ep0_trb_addr + sizeof(*dwc->ep0_trb)); -++ -++ ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, ¶ms); -++ if (ret < 0) -++ return ret; -++ -++ dwc->ep0_next_event = DWC3_EP0_COMPLETE; -++ -++ return 0; -++} -++ -++static int dwc3_ep0_check_status_complete(struct dwc3_ep *dep) -++{ -++ struct dwc3 *dwc = dep->dwc; -++ int timeout = 1000; -++ struct dwc3_trb *trb; -++ -++ if (dwc->ep0state != EP0_STATUS_PHASE) -++ return 0; -++ -++ trb = dwc->ep0_trb; -++ while (timeout > 0) { -++ iprec(" Check Status TRB.HWO:%d --- %d", trb->ctrl & DWC3_TRB_CTRL_HWO, timeout); -++ if ((trb->ctrl & DWC3_TRB_CTRL_HWO) != DWC3_TRB_CTRL_HWO) -++ return 0; -++ udelay(1); -++ timeout--; -++ } -++ return -1; -++} -++ -++static int dwc3_ep0_start_control_status_append_next_setup(struct dwc3_ep *dep) -++{ -++ int ret; -++ struct dwc3 *dwc = dep->dwc; -++ unsigned int direction = !dwc->ep0_expect_in; -++ struct dwc3_ep *dep_out = dwc->eps[0]; -++ u32 type; -++ -++ type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 -++ : DWC3_TRBCTL_CONTROL_STATUS2; -++ -++ iprec(""); -++ iprec(" Status-%s + Setup TRBs ", direction ? "In" : "Out"); -++ -++ dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 0, type, false); -++ ret = dwc3_ep0_start_trans(dep); -++ if (ret < 0) -++ return ret; -++ -++ if (!direction) -++ dwc3_ep0_check_status_complete(dep); -++ -++ dwc3_ep0_prepare_setup_trb(dep_out); -++ ret = dwc3_ep0_start_trans_append_setup(dep_out); -++ dwc->is_status_append_setup = 1; -++ return ret; -++} -++ -++static void dwc3_ep0_append_inspect_setup(struct dwc3 *dwc, -++ const struct dwc3_event_depevt *event) -++{ -++ struct usb_ctrlrequest *ctrl = (void *) &dwc->ep0_trb[1]; -++ int ret = -EINVAL; -++ u32 len; -++ -++ if (!dwc->gadget_driver) -++ goto out; -++ -++ trace_dwc3_ctrl_req(ctrl); -++ -++ iprec("EP0 Inspect setup: request_type:0x%02x request:0x%02x val:0x%04x idx:0x%04x len:0x%04x", -++ ctrl->bRequestType, ctrl->bRequest, le16_to_cpu(ctrl->wValue), -++ le16_to_cpu(ctrl->wIndex), le16_to_cpu(ctrl->wLength)); -++ -++ len = le16_to_cpu(ctrl->wLength); -++ if (!len) { -++ dwc->three_stage_setup = false; -++ dwc->ep0_expect_in = false; -++ dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS; -++ } else { -++ dwc->three_stage_setup = true; -++ dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN); -++ dwc->ep0_next_event = DWC3_EP0_NRDY_DATA; -++ } -++ -++ if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) -++ ret = dwc3_ep0_std_request(dwc, ctrl); -++ else -++ ret = dwc3_ep0_delegate_req(dwc, ctrl); -++ -++ if (ret == USB_GADGET_DELAYED_STATUS) -++ dwc->delayed_status = true; -++ -++out: -++ if (ret < 0) -++ dwc3_ep0_stall_and_restart(dwc); -++} -++#endif -++#endif // CONFIG_ARCH_BSP -+ -+ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, -+ struct dwc3_request *req) -+@@ -240,7 +402,20 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) -+ } -+ -+ dwc->ep0state = EP0_SETUP_PHASE; -++#ifdef CONFIG_ARCH_BSP -++#ifdef STATUS_PHASE_APPEND_SETUP -++ if (dwc->is_status_append_setup) { -++ dwc3_ep0_prepare_setup_trb(dep); -++ dwc3_ep0_start_trans_append_setup(dep); -++ } else { -++ dwc3_ep0_out_start(dwc); -++ } -++#else -+ dwc3_ep0_out_start(dwc); -++#endif -++#else // CONFIG_ARCH_BSP -++ dwc3_ep0_out_start(dwc); -++#endif // CONFIG_ARCH_BSP -+ } -+ -+ int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value) -+@@ -799,7 +974,11 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, -+ goto out; -+ -+ trace_dwc3_ctrl_req(ctrl); -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("EP0 Inspect setup: request_type:0x%02x request:0x%02x val:0x%04x idx:0x%04x len:0x%04x", -++ ctrl->bRequestType, ctrl->bRequest, le16_to_cpu(ctrl->wValue), -++ le16_to_cpu(ctrl->wIndex), le16_to_cpu(ctrl->wLength)); -++#endif -+ len = le16_to_cpu(ctrl->wLength); -+ if (!len) { -+ dwc->three_stage_setup = false; -+@@ -894,7 +1073,18 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc, -+ trb = dwc->ep0_trb; -+ -+ trace_dwc3_complete_trb(dep, trb); -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("EP0 TRB Complete:%d raw[%x %x %x %x]BUFSIZE:%d STATUS:0x%x %s%s%s%s CTL:0x%x", -++ dep->trb_enqueue, -++ trb->bpl, trb->bph, trb->size, trb->ctrl, -++ trb->size & DWC3_TRB_SIZE_MASK, -++ DWC3_TRB_SIZE_TRBSTS(trb->size), -++ (trb->ctrl & DWC3_TRB_CTRL_IOC) ? "IOC " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CSP) ? "CSP " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CHN) ? "CHN " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_LST) ? "LST " : "", -++ ((trb->ctrl >> 4) & 0x3f)); -++#endif -+ if (!list_empty(&dep->pending_list)) { -+ r = next_request(&dep->pending_list); -+ -+@@ -918,7 +1108,19 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc, -+ dwc->setup_packet_pending = true; -+ -+ dwc->ep0state = EP0_SETUP_PHASE; -++#ifdef CONFIG_ARCH_BSP -++#ifdef STATUS_PHASE_APPEND_SETUP -++ if (dwc->is_status_append_setup) { -++ iprec(" == skip prepare next SETUP packet =="); -++ } else { -++ dwc3_ep0_out_start(dwc); -++ } -++#else -++ dwc3_ep0_out_start(dwc); -++#endif -++#else // CONFIG_ARCH_BSP -+ dwc3_ep0_out_start(dwc); -++#endif // CONFIG_ARCH_BSP -+ } -+ -+ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, -+@@ -932,7 +1134,19 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc, -+ -+ switch (dwc->ep0state) { -+ case EP0_SETUP_PHASE: -++#ifdef CONFIG_ARCH_BSP -++#ifdef STATUS_PHASE_APPEND_SETUP -++ if (dwc->is_status_append_setup) { -++ dwc3_ep0_append_inspect_setup(dwc, event); -++ } else { -++ dwc3_ep0_inspect_setup(dwc, event); -++ } -++#else -++ dwc3_ep0_inspect_setup(dwc, event); -++#endif -++#else // CONFIG_ARCH_BSP -+ dwc3_ep0_inspect_setup(dwc, event); -++#endif // CONFIG_ARCH_BSP -+ break; -+ -+ case EP0_DATA_PHASE: -+@@ -1032,6 +1246,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, -+ WARN_ON(ret < 0); -+ } -+ -++#ifndef CONFIG_ARCH_BSP -++#ifndef STATUS_PHASE_APPEND_SETUP -+ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) -+ { -+ struct dwc3 *dwc = dep->dwc; -+@@ -1043,10 +1259,20 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) -+ dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 0, type, false); -+ return dwc3_ep0_start_trans(dep); -+ } -++#endif -++#endif // CONFIG_ARCH_BSP -+ -+ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep) -+ { -++#ifdef CONFIG_ARCH_BSP -++#ifdef STATUS_PHASE_APPEND_SETUP -++ WARN_ON(dwc3_ep0_start_control_status_append_next_setup(dep)); -++#else -++ WARN_ON(dwc3_ep0_start_control_status(dep)); -++#endif -++#else // CONFIG_ARCH_BSP -+ WARN_ON(dwc3_ep0_start_control_status(dep)); -++#endif // CONFIG_ARCH_BSP -+ } -+ -+ static void dwc3_ep0_do_control_status(struct dwc3 *dwc, -+@@ -1090,6 +1316,16 @@ static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep) -+ static void dwc3_ep0_xfernotready(struct dwc3 *dwc, -+ const struct dwc3_event_depevt *event) -+ { -++#ifdef CONFIG_ARCH_BSP -++ iprec("ep0xfernotready event:0x%x params:0x%x[%d] status:0x%x ev_type:0x%x ep0stage:%s ep:%d SOFFN=0x%04X", -++ *event, event->parameters, event->parameters, -++ event->status, event->endpoint_event, -++ (dwc->ep0state == EP0_SETUP_PHASE) ? " Setup" : -++ (dwc->ep0state == EP0_DATA_PHASE) ? " Data" : -++ (dwc->ep0state == EP0_STATUS_PHASE) ? " Status" : " Unknown", -++ event->endpoint_number, -++ DWC3_DSTS_SOFFN(dwc3_readl(dwc->regs, DWC3_DSTS))); -++#endif -+ switch (event->status) { -+ case DEPEVT_STATUS_CONTROL_DATA: -+ /* -+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c -+index 565397c41..6e55c42b2 100644 -+--- a/drivers/usb/dwc3/gadget.c -++++ b/drivers/usb/dwc3/gadget.c -+@@ -22,6 +22,10 @@ -+ #include -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -++ -+ #include "debug.h" -+ #include "core.h" -+ #include "gadget.h" -+@@ -147,7 +151,11 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) -+ * if it is point to the link TRB, wrap around to the beginning. The -+ * link TRB is always at the last TRB entry. -+ */ -++#ifdef CONFIG_ARCH_BSP -++static void dwc3_ep_inc_trb(u16 *index) -++#else -+ static void dwc3_ep_inc_trb(u8 *index) -++#endif -+ { -+ (*index)++; -+ if (*index == (DWC3_TRB_NUM - 1)) -+@@ -255,7 +263,9 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd, -+ } -+ -+ trace_dwc3_gadget_generic_cmd(cmd, param, status); -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("Generic Cmd:0x%x parms:0x%x status: %d ret: %d", cmd, param, status, ret); -++#endif -+ return ret; -+ } -+ -+@@ -415,6 +425,11 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, -+ reg |= saved_config; -+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); -+ } -++#ifdef CONFIG_ARCH_BSP -++ iprec(" --> EP%d Cmd:0x%x p0:0x%x p1:0x%x p2:0x%x flag:0x%x ret:%d", -++ dep->number, cmd, params->param0, params->param1, -++ params->param2, dep->flags, ret); -++#endif -+ -+ return ret; -+ } -+@@ -676,7 +691,9 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) -+ -+ dep->type = usb_endpoint_type(desc); -+ dep->flags |= DWC3_EP_ENABLED; -+- -++#ifdef CONFIG_ARCH_BSP -++ dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; -++#endif -+ reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); -+ reg |= DWC3_DALEPENA_EP(dep->number); -+ dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); -+@@ -757,8 +774,11 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) -+ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status) -+ { -+ struct dwc3_request *req; -+- -++#ifdef CONFIG_ARCH_BSP -++ dwc3_stop_active_transfer(dep, true, true); -++#else -+ dwc3_stop_active_transfer(dep, true, false); -++#endif -+ -+ /* - giveback all requests to gadget driver */ -+ while (!list_empty(&dep->started_list)) { -+@@ -933,10 +953,17 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, -+ * index is 0, we will wrap backwards, skip the link TRB, and return -+ * the one just before that. -+ */ -++#ifdef CONFIG_ARCH_BSP -++static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u16 index) -++#else -+ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) -++#endif -+ { -++#ifdef CONFIG_ARCH_BSP -++ u16 tmp = index; -++#else -+ u8 tmp = index; -+- -++#endif -+ if (!tmp) -+ tmp = DWC3_TRB_NUM - 1; -+ -+@@ -945,8 +972,11 @@ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index) -+ -+ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) -+ { -++#ifdef CONFIG_ARCH_BSP -++ u16 trbs_left; -++#else -+ u8 trbs_left; -+- -++#endif -+ /* -+ * If the enqueue & dequeue are equal then the TRB ring is either full -+ * or empty. It's considered full when there are DWC3_TRB_NUM-1 of TRBs -+@@ -996,7 +1026,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, -+ struct dwc3 *dwc = dep->dwc; -+ struct usb_gadget *gadget = dwc->gadget; -+ enum usb_device_speed speed = gadget->speed; -+- -++#ifdef CONFIG_ARCH_BSP -++ unsigned int chain_skip = 0; -++#endif -+ if (use_bounce_buffer) -+ dma = dep->dwc->bounce_addr; -+ else if (req->request.num_sgs > 0) -+@@ -1024,6 +1056,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, -+ break; -+ -+ case USB_ENDPOINT_XFER_ISOC: -++#ifndef CONFIG_ARCH_BSP -+ if (!node) { -+ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; -+ -+@@ -1065,6 +1098,30 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, -+ } else { -+ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; -+ } -++#else -++ if (!node) { -++ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; -++ if (speed == USB_SPEED_HIGH) { -++ struct usb_ep *ep = &dep->endpoint; -++ unsigned int mult = 2; -++ unsigned int maxp = usb_endpoint_maxp(ep->desc); -++ -++ if (trb_length <= (2 * maxp)) // at most 2 packets in high-speed -++ mult--; -++ -++ if (trb_length <= maxp) -++ mult--; -++ -++ trb->size |= DWC3_TRB_SIZE_PCM1(mult); -++ chain_skip = 1; -++ } -++ if (speed == USB_SPEED_SUPER) -++ chain_skip = 1; -++ } else { -++ chain_skip = 1; -++ trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; -++ } -++#endif -+ -+ if (!no_interrupt && !chain) -+ trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; -+@@ -1098,7 +1155,11 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, -+ if ((!no_interrupt && !chain) || must_interrupt) -+ trb->ctrl |= DWC3_TRB_CTRL_IOC; -+ -++#ifdef CONFIG_ARCH_BSP -++ if ((!chain_skip) && chain) -++#else -+ if (chain) -++#endif -+ trb->ctrl |= DWC3_TRB_CTRL_CHN; -+ else if (dep->stream_capable && is_last) -+ trb->ctrl |= DWC3_TRB_CTRL_LST; -+@@ -1165,9 +1226,20 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, -+ req->needs_extra_trb = num_trbs > 1; -+ -+ /* Prepare a normal TRB */ -++#ifdef CONFIG_ARCH_BSP -++ if (req->direction || req->request.length) { -++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) -++ dwc3_prepare_one_trb(dep, req, entry_length, -++ req->needs_extra_trb, 0, false, false); -++ else -++ dwc3_prepare_one_trb(dep, req, entry_length, -++ req->needs_extra_trb, node, false, false); -++ } -++#else -+ if (req->direction || req->request.length) -+ dwc3_prepare_one_trb(dep, req, entry_length, -+ req->needs_extra_trb, node, false, false); -++#endif -+ -+ /* Prepare extra TRBs for ZLP and MPS OUT transfer alignment */ -+ if ((!req->direction && !req->request.length) || req->needs_extra_trb) -+@@ -1234,9 +1306,17 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, -+ num_trbs_left <= 2 && -+ sg_dma_len(sg_next(s)) >= length)) -+ must_interrupt = true; -+- -++#ifdef CONFIG_ARCH_BSP -++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) -++ dwc3_prepare_one_trb(dep, req, trb_length, 1, 0, false, -++ must_interrupt); -++ else -++ dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false, -++ must_interrupt); -++#else -+ dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false, -+ must_interrupt); -++#endif -+ } -+ -+ /* -+@@ -1357,6 +1437,90 @@ static int dwc3_prepare_trbs(struct dwc3_ep *dep) -+ return ret; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static int __dwc3_gadget_get_frame(struct dwc3 *dwc); -++static void __dwc3_dwc3_iprec_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, -++ int index, int sof_number, char *data) -++{ -++ if (data != NULL) { -++ iprec(" %s Prepare TRB:%04d [%x %x %x %x] [%02x%02x %02x%02x %02x%02x %02x%02x] %d length:%d %s%s%s%sHWO CTL%d " -++ "SOFFN:0x%04X", -++ dep->name, index, trb->bpl, trb->bph, trb->size, trb->ctrl, -++ data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], -++ (trb->size >> 24) & 0x3, trb->size & DWC3_TRB_SIZE_MASK, -++ (trb->ctrl & DWC3_TRB_CTRL_IOC) ? "IOC " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CSP) ? "CSP " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CHN) ? "CHN " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_LST) ? "LST " : "", -++ ((trb->ctrl >> 4) & 0x3f), -++ sof_number); -++ } else { -++ iprec(" %s Prepare TRB:%04d [%x %x %x %x] %d length:%d %s%s%s%sHWO CTL%d SOFFN:0x%04X", -++ dep->name, index, trb->bpl, trb->bph, trb->size, trb->ctrl, -++ (trb->size >> 24) & 0x3, trb->size & DWC3_TRB_SIZE_MASK, -++ (trb->ctrl & DWC3_TRB_CTRL_IOC) ? "IOC " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CSP) ? "CSP " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_CHN) ? "CHN " : "", -++ (trb->ctrl & DWC3_TRB_CTRL_LST) ? "LST " : "", -++ ((trb->ctrl >> 4) & 0x3f), -++ sof_number); -++ } -++ return; -++} -++ -++static int __dwc3_iprec_preparing_trbs(struct dwc3_ep *dep, int from, int start_sof) -++{ -++ struct dwc3_trb *trb; -++ char *data = NULL; -++ phys_addr_t buffer_pointer_phy_addr; -++ void *buffer_pointer_virt_addr; -++ int end_trb_index = dep->trb_enqueue; -++ -++ /* Record First trb */ -++ trb = &dep->trb_pool[from]; -++ buffer_pointer_phy_addr = (((u64)trb->bph << 32) | trb->bpl); // shift for higher 32 bit address -++ buffer_pointer_virt_addr = phys_to_virt(buffer_pointer_phy_addr); -++ data = buffer_pointer_virt_addr; -++ if ((trb->size & DWC3_TRB_SIZE_MASK) >= 8) { // just record 8 byte -++ __dwc3_dwc3_iprec_prepare_one_trb(dep, trb, from, start_sof, data); -++ } else { -++ __dwc3_dwc3_iprec_prepare_one_trb(dep, trb, from, start_sof, NULL); -++ } -++ -++ /* Record Last trb */ -++ if ((end_trb_index - from) == 1) -++ return 0; -++ if ((from - end_trb_index) == (DWC3_TRB_NUM - 1)) -++ return 0; -++ -++ trb = dwc3_ep_prev_trb(dep, end_trb_index); -++ buffer_pointer_phy_addr = (((u64)trb->bph << 32) | trb->bpl); // shift for higher 32 bit address -++ buffer_pointer_virt_addr = phys_to_virt(buffer_pointer_phy_addr); -++ data = buffer_pointer_virt_addr; -++ if ((trb->size & DWC3_TRB_SIZE_MASK) >= 8) { // just record 8 byte -++ __dwc3_dwc3_iprec_prepare_one_trb(dep, trb, end_trb_index - 1, -++ __dwc3_gadget_get_frame(dep->dwc), data); -++ } else { -++ __dwc3_dwc3_iprec_prepare_one_trb(dep, trb, end_trb_index - 1, -++ __dwc3_gadget_get_frame(dep->dwc), NULL); -++ } -++ -++ return 0; -++} -++ -++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_MAX_SOFFN; -++ -++ if (eframe == cframe) -++ return true; -++ -++ return (((eframe - cframe) & DWC3_EVENT_PRAM_MAX_SOFFN) -++ > DWC3_EVENT_PRAM_MAX_SOFFN / 2); -++} -++#endif -++ -+ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep); -+ -+ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) -+@@ -1366,7 +1530,13 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) -+ int starting; -+ int ret; -+ u32 cmd; -++#ifdef CONFIG_ARCH_BSP -++ int current_trb_enqueue; -++ int frame_number = __dwc3_gadget_get_frame(dep->dwc); -++ struct dwc3 *dwc = dep->dwc; -+ -++ current_trb_enqueue = dep->trb_enqueue; -++#endif -+ /* -+ * Note that it's normal to have no new TRBs prepared (i.e. ret == 0). -+ * This happens when we need to stop and restart a transfer such as in -+@@ -1384,9 +1554,14 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) -+ */ -+ if (!ret && !starting) -+ return ret; -+- -++#ifdef CONFIG_ARCH_BSP -++ __dwc3_iprec_preparing_trbs(dep, current_trb_enqueue, frame_number); -++#endif -+ req = next_request(&dep->started_list); -+ if (!req) { -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s dep->started_list is empty! epnum:%d", __func__, dep->number); -++#endif -+ dep->flags |= DWC3_EP_PENDING_REQUEST; -+ return 0; -+ } -+@@ -1396,6 +1571,18 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) -+ if (starting) { -+ params.param0 = upper_32_bits(req->trb_dma); -+ params.param1 = lower_32_bits(req->trb_dma); -++#ifdef CONFIG_ARCH_BSP -++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -++ while (__dwc3_gadget_target_frame_elapsed(dep)) -++ dep->frame_number = DWC3_ALIGN_FRAME(dep, 1); -++ -++ // For FPGA, need more time, so set 5 interval advanced. -++ if (dwc->is_fpga) -++ dep->frame_number = DWC3_ALIGN_FRAME(dep, 5); -++ else -++ dep->frame_number = DWC3_ALIGN_FRAME(dep, 1); -++ } -++#endif -+ cmd = DWC3_DEPCMD_STARTTRANSFER; -+ -+ if (dep->stream_capable) -+@@ -1403,15 +1590,25 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) -+ -+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) -+ cmd |= DWC3_DEPCMD_PARAM(dep->frame_number); -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s StartXfer TRB:0x%llx cmd:0x%08x sof:(0x%04x)0x%04x current SOFFN:0x%04X", -++ dep->name, req->trb_dma, cmd, dep->frame_number, dep->frame_number & 0x3fff, __dwc3_gadget_get_frame(dep->dwc)); -++#endif -+ } else { -+ cmd = DWC3_DEPCMD_UPDATETRANSFER | -+ DWC3_DEPCMD_PARAM(dep->resource_index); -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s UpdateXfer cmd:0x%x", dep->name, cmd); -++#endif -+ } -+ -+ ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); -+ if (ret < 0) { -+ struct dwc3_request *tmp; -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s Send cmd fail ret:%d cmd:0x%x SOFFN:0x%X", dep->name, ret, -++ dwc3_readl(dep->regs, DWC3_DEPCMD), __dwc3_gadget_get_frame(dep->dwc)); -++#endif -+ if (ret == -EAGAIN) -+ return ret; -+ -+@@ -1603,6 +1800,9 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) -+ -+ if (list_empty(&dep->pending_list) && -+ list_empty(&dep->started_list)) { -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s %s ran out of requests!", __func__, dep->name); -++#endif -+ dep->flags |= DWC3_EP_PENDING_REQUEST; -+ return -EAGAIN; -+ } -+@@ -1634,7 +1834,12 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) -+ if (rollover) -+ dep->frame_number += BIT(14); -+ } -++#ifdef CONFIG_ARCH_BSP -++ while (__dwc3_gadget_target_frame_elapsed(dep)) -++ dep->frame_number = DWC3_ALIGN_FRAME(dep, 1); -+ -++ dep->frame_number = DWC3_ALIGN_FRAME(dep, 1); -++#endif -+ for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) { -+ dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1); -+ -+@@ -1650,6 +1855,11 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) -+ */ -+ if (ret == -EAGAIN) -+ ret = __dwc3_stop_active_transfer(dep, false, true); -++#ifdef CONFIG_ARCH_BSP -++ if (ret == 0) { -++ dep->flags &= ~DWC3_EP_PENDING_REQUEST; -++ } -++#endif -+ -+ return ret; -+ } -+@@ -1705,6 +1915,35 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) -+ * Without this trick, we are very, very likely gonna get Bus Expiry -+ * errors which will force us issue EndTransfer command. -+ */ -++#ifdef CONFIG_ARCH_BSP -++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -++ if (!(dep->flags & DWC3_EP_PENDING_REQUEST) && -++ !(dep->flags & DWC3_EP_TRANSFER_STARTED)) -++ return 0; -++ if (req->request.num_sgs) { // UVC -++ if (dep->resource_index && list_empty(&dep->started_list)) { -++ iprec(" %s Pending EndXfer idx: %d flag: 0x%x", -++ dep->name, dep->resource_index, dep->flags); -++ dwc3_stop_active_transfer(dep, true, true); -++ return 0; -++ } -++ } else { // UAC -++ if (!(dep->flags & DWC3_EP_PENDING_REQUEST) && -++ !(dep->flags & DWC3_EP_TRANSFER_STARTED)) { -++ return 0; -++ } -++ } -++ -++ if ((dep->flags & DWC3_EP_PENDING_REQUEST)) { -++ if (!(dep->flags & DWC3_EP_TRANSFER_STARTED)) { -++ iprec("%s calling start isoc %s flag:%x", __func__, dep->name, dep->flags); -++ return __dwc3_gadget_start_isoc(dep); -++ } -++ } -++ if (req->request.num_sgs) -++ return 0; -++ } -++#else -+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -+ if (!(dep->flags & DWC3_EP_PENDING_REQUEST) && -+ !(dep->flags & DWC3_EP_TRANSFER_STARTED)) -+@@ -1715,6 +1954,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) -+ return __dwc3_gadget_start_isoc(dep); -+ } -+ } -++#endif // CONFIG_ARCH_BSP -+ -+ __dwc3_gadget_kick_transfer(dep); -+ -+@@ -2374,6 +2614,11 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) -+ } -+ -+ /* begin to receive SETUP packets */ -++#ifdef CONFIG_ARCH_BSP -++#ifdef STATUS_PHASE_APPEND_SETUP -++ dwc->is_status_append_setup = 0; -++#endif -++#endif -+ dwc->ep0state = EP0_SETUP_PHASE; -+ dwc->link_state = DWC3_LINK_STATE_SS_DIS; -+ dwc->delayed_status = false; -+@@ -3087,6 +3332,9 @@ static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep, -+ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep, -+ const struct dwc3_event_depevt *event) -+ { -++#ifdef CONFIG_ARCH_BSP -++ u32 reg; -++#endif -+ u8 cmd = DEPEVT_PARAMETER_CMD(event->parameters); -+ -+ if (cmd != DWC3_DEPCMD_ENDTRANSFER) -+@@ -3100,8 +3348,22 @@ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep, -+ if (dep->stream_capable) -+ dep->flags |= DWC3_EP_IGNORE_NEXT_NOSTREAM; -+ -++#ifdef CONFIG_ARCH_BSP -++ /* -++ * Ensure that the current state of the endpoint is END_TRANSFER. -++ * If it is in any other state, do not clear the DWC3_EP_END_TRANSFER_PENDING -++ * and DWC3_EP_TRANSFER_STARTED flags to avoid modifying the flags -++ * and affecting the current transfer. -++ */ -++ reg = dwc3_readl(dep->regs, DWC3_DEPCMD); -++ if (DWC3_DEPCMD_CMD(reg) == DWC3_DEPCMD_ENDTRANSFER) { -++ dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; -++ dep->flags &= ~DWC3_EP_TRANSFER_STARTED; -++ } -++#else -+ dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; -+ dep->flags &= ~DWC3_EP_TRANSFER_STARTED; -++#endif -+ dwc3_gadget_ep_cleanup_cancelled_requests(dep); -+ -+ if (dep->flags & DWC3_EP_PENDING_CLEAR_STALL) { -+@@ -3198,7 +3460,21 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, -+ { -+ struct dwc3_ep *dep; -+ u8 epnum = event->endpoint_number; -+- -++#ifdef CONFIG_ARCH_BSP -++ if ((event->endpoint_event == DWC3_DEPEVT_XFERINPROGRESS) && (event->status & DEPEVT_STATUS_MISSED_ISOC)) { -++ iprec("event:0x%x params:0x%x[%d] status:0x%x ev_type:0x%x ep%d miss_isoc", *(u32 *)event, -++ event->parameters, event->parameters, event->status, event->endpoint_event, event->endpoint_number); -++ } else { -++ iprec("event:0x%x params:0x%x[%d] status:0x%x ev_type:0x%x ep%d %s SOFFN=0x%04X", *(u32 *)event, -++ event->parameters, event->parameters, event->status, -++ event->endpoint_event, event->endpoint_number, -++ (event->endpoint_event == 1) ? " XferComplt" : -++ (event->endpoint_event == 2) ? " XferInProg" : -++ (event->endpoint_event == 3) ? " XferNotRdy" : -++ (event->endpoint_event == 7) ? " EpCmdCompt" : "", -++ __dwc3_gadget_get_frame(dwc)); -++ } -++#endif -+ dep = dwc->eps[epnum]; -+ -+ if (!(dep->flags & DWC3_EP_ENABLED)) { -+@@ -3422,6 +3698,12 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) -+ reg = dwc3_readl(dwc->regs, DWC3_DCFG); -+ reg &= ~(DWC3_DCFG_DEVADDR_MASK); -+ dwc3_writel(dwc->regs, DWC3_DCFG, reg); -++ -++#ifdef CONFIG_ARCH_BSP -++ if (dwc->ep0state != EP0_SETUP_PHASE) { -++ __dwc3_gadget_ep0_set_halt(&dwc->eps[0]->endpoint, 1); -++ } -++#endif -+ } -+ -+ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) -+@@ -3701,9 +3983,56 @@ static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc, -+ /* enter hibernation here */ -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static void __dwc3_iprec_gadget_interrupt(u32 event_type) -++{ -++ switch (event_type) { -++ case DWC3_DEVICE_EVENT_DISCONNECT: -++ iprec("DWC3_DEVICE_EVENT_DISCONNECT"); -++ break; -++ case DWC3_DEVICE_EVENT_RESET: -++ iprec("DWC3_DEVICE_EVENT_RESET"); -++ break; -++ case DWC3_DEVICE_EVENT_CONNECT_DONE: -++ iprec("DWC3_DEVICE_EVENT_CONNECT_DONE"); -++ break; -++ case DWC3_DEVICE_EVENT_WAKEUP: -++ iprec("DWC3_DEVICE_EVENT_WAKEUP"); -++ break; -++ case DWC3_DEVICE_EVENT_HIBER_REQ: -++ iprec("DWC3_DEVICE_EVENT_HIBER_REQ"); -++ break; -++ case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: -++ iprec("DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE"); -++ break; -++ case DWC3_DEVICE_EVENT_EOPF: -++ iprec("DWC3_DEVICE_EVENT_EOPF"); -++ break; -++ case DWC3_DEVICE_EVENT_SOF: -++ iprec("DWC3_DEVICE_EVENT_SOF"); -++ break; -++ case DWC3_DEVICE_EVENT_ERRATIC_ERROR: -++ iprec("DWC3_DEVICE_EVENT_ERRATIC_ERROR"); -++ break; -++ case DWC3_DEVICE_EVENT_CMD_CMPL: -++ iprec("DWC3_DEVICE_EVENT_CMD_CMPL"); -++ break; -++ case DWC3_DEVICE_EVENT_OVERFLOW: -++ iprec("DWC3_DEVICE_EVENT_OVERFLOW"); -++ break; -++ default: -++ iprec("Unknown event 0x%x", event_type); -++ break; -++ } -++} -++#endif -++ -+ static void dwc3_gadget_interrupt(struct dwc3 *dwc, -+ const struct dwc3_event_devt *event) -+ { -++#ifdef CONFIG_ARCH_BSP -++ __dwc3_iprec_gadget_interrupt(event->type); -++#endif -+ switch (event->type) { -+ case DWC3_DEVICE_EVENT_DISCONNECT: -+ dwc3_gadget_disconnect_interrupt(dwc); -+@@ -3854,7 +4183,9 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) -+ count &= DWC3_GEVNTCOUNT_MASK; -+ if (!count) -+ return IRQ_NONE; -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s, count: %d SOFFN=0x%04X", __func__, count, __dwc3_gadget_get_frame(dwc)); -++#endif -+ evt->count = count; -+ evt->flags |= DWC3_EVENT_PENDING; -+ -+diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig -+index 2d152571a..955a424d1 100644 -+--- a/drivers/usb/gadget/Kconfig -++++ b/drivers/usb/gadget/Kconfig -+@@ -487,4 +487,13 @@ config USB_CONFIGFS_F_TCM -+ -+ source "drivers/usb/gadget/legacy/Kconfig" -+ -++if USB_F_UVC -++config MPP_TO_GADGET_UVC -++ bool "USB Gadget Webcam Data from MPP" -++ default n -++ depends on ARCH_BSP -++ help -++ Let Webcam function gets streaming data from mpp directly. -++endif -++ -+ endif # USB_GADGET -+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c -+index a98079990..567b0f744 100644 -+--- a/drivers/usb/gadget/composite.c -++++ b/drivers/usb/gadget/composite.c -+@@ -705,8 +705,12 @@ static int bos_desc(struct usb_composite_dev *cdev) -+ usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE; -+ usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY; -+ usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT; -++#ifdef CONFIG_ARCH_BSP -++ usb_ext->bmAttributes = 0x0; -++#else -+ usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT | -+ USB_BESL_SUPPORT | besl); -++#endif -+ -+ /* -+ * The Superspeed USB Capability descriptor shall be implemented by all -+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c -+index d51ea1c05..f46c292c3 100644 -+--- a/drivers/usb/gadget/configfs.c -++++ b/drivers/usb/gadget/configfs.c -+@@ -1262,7 +1262,10 @@ static void purge_configs_funcs(struct gadget_info *gi) -+ cfg = container_of(c, struct config_usb_cfg, c); -+ -+ list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) { -+- -++#ifdef CONFIG_ARCH_BSP -++ if (f->disable) -++ f->disable(f); -++#endif -+ list_move(&f->list, &cfg->func_list); -+ if (f->unbind) { -+ dev_dbg(&gi->cdev.gadget->dev, -+@@ -1270,6 +1273,10 @@ static void purge_configs_funcs(struct gadget_info *gi) -+ f->name, f); -+ f->unbind(c, f); -+ } -++#ifdef CONFIG_ARCH_BSP -++ if (f->bind_deactivated) -++ usb_function_activate(f); -++#endif -+ } -+ c->next_interface_id = 0; -+ memset(c->interface, 0, sizeof(c->interface)); -+diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c -+index 1eb4fa2e6..b2c1cd111 100644 -+--- a/drivers/usb/gadget/epautoconf.c -++++ b/drivers/usb/gadget/epautoconf.c -+@@ -67,18 +67,37 @@ struct usb_ep *usb_ep_autoconfig_ss( -+ ) -+ { -+ struct usb_ep *ep; -+- -++#ifdef CONFIG_ARCH_BSP -++ u8 type; -++#endif -+ if (gadget->ops->match_ep) { -+ ep = gadget->ops->match_ep(gadget, desc, ep_comp); -+ if (ep) -+ goto found_ep; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++ type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; -++ /* Second, look at endpoints until an unclaimed one looks usable */ -++ /* Match all the endpoints of the project that do not match the driver */ -++ 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; -++ } -++ } -++#else -+ /* 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; -+ } -++#endif // CONFIG_ARCH_BSP -+ -+ /* Fail */ -+ return NULL; -+diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c -+index 553547f12..1df70ca0f 100644 -+--- a/drivers/usb/gadget/function/f_mass_storage.c -++++ b/drivers/usb/gadget/function/f_mass_storage.c -+@@ -307,7 +307,9 @@ struct fsg_common { -+ unsigned int bad_lun_okay:1; -+ unsigned int running:1; -+ unsigned int sysfs:1; -+- -++#ifdef CONFIG_ARCH_BSP -++ unsigned int actived:1; -++#endif -+ struct completion thread_notifier; -+ struct task_struct *thread_task; -+ -+@@ -1338,7 +1340,11 @@ static int do_start_stop(struct fsg_common *common) -+ -+ up_read(&common->filesem); -+ down_write(&common->filesem); -++#ifdef CONFIG_ARCH_BSP -++ common->actived = 0; -++#else -+ fsg_lun_close(curlun); -++#endif -+ up_write(&common->filesem); -+ down_read(&common->filesem); -+ -+@@ -1775,7 +1781,11 @@ static int check_command(struct fsg_common *common, int cmnd_size, -+ -+ /* If the medium isn't mounted and the command needs to access -+ * it, return an error. */ -++#ifdef CONFIG_ARCH_BSP -++ if (curlun && !common->actived && needs_medium) { -++#else -+ if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { -++#endif -+ curlun->sense_data = SS_MEDIUM_NOT_PRESENT; -+ return -EINVAL; -+ } -+@@ -2234,6 +2244,9 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) -+ } -+ -+ common->running = 0; -++#ifdef CONFIG_ARCH_BSP -++ common->actived = 0; -++#endif -+ if (!new_fsg || rc) -+ return rc; -+ -+@@ -2277,7 +2290,9 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) -+ bh->inreq->complete = bulk_in_complete; -+ bh->outreq->complete = bulk_out_complete; -+ } -+- -++#ifdef CONFIG_ARCH_BSP -++ common->actived = 1; -++#endif -+ common->running = 1; -+ for (i = 0; i < ARRAY_SIZE(common->luns); ++i) -+ if (common->luns[i]) -+diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c -+index e65f474ad..47699b276 100644 -+--- a/drivers/usb/gadget/function/f_uac1.c -++++ b/drivers/usb/gadget/function/f_uac1.c -+@@ -55,6 +55,19 @@ static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio) -+ #define F_AUDIO_AS_IN_INTERFACE 2 -+ /* Number of streaming interfaces */ -+ #define F_AUDIO_NUM_INTERFACES 2 -++#ifdef CONFIG_ARCH_BSP -++#define F_AUDIO_ALL_INTERFACES_COUNT 3 -++ -++static struct usb_interface_assoc_descriptor uac_iad = { -++ .bLength = sizeof(uac_iad), -++ .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, -++ .bFirstInterface = 0, -++ .bInterfaceCount = F_AUDIO_ALL_INTERFACES_COUNT, -++ .bFunctionClass = USB_CLASS_AUDIO, -++ .bFunctionSubClass = 0, -++ .bFunctionProtocol = UAC_VERSION_1, -++}; -++#endif -+ -+ /* B.3.1 Standard AC Interface Descriptor */ -+ static struct usb_interface_descriptor ac_interface_desc = { -+@@ -254,7 +267,51 @@ static struct uac_iso_endpoint_descriptor as_iso_in_desc = { -+ .wLockDelay = 0, -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++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), -++}; -++#endif -++ -+ static struct usb_descriptor_header *f_audio_desc[] = { -++#ifdef CONFIG_ARCH_BSP -++ (struct usb_descriptor_header *)&uac_iad, -++#endif -++ (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, -++}; -++ -++#ifdef CONFIG_ARCH_BSP -++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, -+ -+@@ -270,6 +327,7 @@ static struct usb_descriptor_header *f_audio_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, -+@@ -279,9 +337,11 @@ static struct usb_descriptor_header *f_audio_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, -+ }; -++#endif -+ -+ enum { -+ STR_AC_IF, -+@@ -567,6 +627,9 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) -+ us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); -+ if (IS_ERR(us)) -+ return PTR_ERR(us); -++#ifdef CONFIG_ARCH_BSP -++ uac_iad.iFunction = us[STR_AC_IF].id; -++#endif -+ ac_interface_desc.iInterface = us[STR_AC_IF].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; -+@@ -603,6 +666,9 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) -+ status = usb_interface_id(c, f); -+ if (status < 0) -+ goto fail; -++#ifdef CONFIG_ARCH_BSP -++ uac_iad.bFirstInterface = status; -++#endif -+ ac_interface_desc.bInterfaceNumber = status; -+ uac1->ac_intf = status; -+ uac1->ac_alt = 0; -+@@ -643,8 +709,13 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) -+ audio->in_ep->desc = &as_in_ep_desc; -+ -+ /* copy descriptors, and track endpoint copies */ -++#ifdef CONFIG_ARCH_BSP -++ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, -++ f_audio_ss_desc, NULL); -++#else -+ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, -+ NULL); -++#endif -+ if (status) -+ goto fail; -+ -+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c -+index 5d39aff26..9d4cca85e 100644 -+--- a/drivers/usb/gadget/function/f_uvc.c -++++ b/drivers/usb/gadget/function/f_uvc.c -+@@ -14,6 +14,9 @@ -+ #include -+ #include -+ #include -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -+ #include -+ #include -+ #include -+@@ -23,6 +26,9 @@ -+ -+ #include -+ #include -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -+ -+ #include "u_uvc.h" -+ #include "uvc.h" -+@@ -42,6 +48,30 @@ MODULE_PARM_DESC(trace, "Trace level bitmask"); -+ -+ #define UVC_STRING_CONTROL_IDX 0 -+ #define UVC_STRING_STREAMING_IDX 1 -++#ifdef CONFIG_ARCH_BSP -++#define SS_EP_BURST 0 -++#define SS_EP_ATTRIBUTES 0 -++#define SS_EP_MAX_PACKET_SIZE 1024 -++ -++#define SS_EP1_BURST 1 -++#define SS_EP1_ATTRIBUTES 0 -++#define SS_EP1_MAX_PACKET_SIZE 1024 -++ -++#define SS_EP2_BURST 8 -++#define SS_EP2_ATTRIBUTES 1 -++#define SS_EP2_MAX_PACKET_SIZE 1024 -++ -++#define SS_EP3_BURST 15 -++#define SS_EP3_ATTRIBUTES 1 -++#define SS_EP3_MAX_PACKET_SIZE 1024 -++ -++#define HS_EP_MAX_PACKET_SIZE 0x320 -++#define HS_EP1_MAX_PACKET_SIZE 0xBE0 -++#define HS_EP2_MAX_PACKET_SIZE 0x1380 -++#define HS_EP3_MAX_PACKET_SIZE 0x1400 -++ -++#define USB_ENDPOINT_MAXP_MASK 0x07ff -++#endif -+ -+ static struct usb_string uvc_en_us_strings[] = { -+ [UVC_STRING_CONTROL_IDX].s = "UVC Camera", -+@@ -116,7 +146,11 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt0 = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bInterfaceNumber = UVC_INTF_VIDEO_STREAMING, -++#ifdef CONFIG_ARCH_BSP -++ .bAlternateSetting = ALT_SETTING_0, -++#else -+ .bAlternateSetting = 0, -++#endif -+ .bNumEndpoints = 0, -+ .bInterfaceClass = USB_CLASS_VIDEO, -+ .bInterfaceSubClass = UVC_SC_VIDEOSTREAMING, -+@@ -128,13 +162,55 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bInterfaceNumber = UVC_INTF_VIDEO_STREAMING, -++#ifdef CONFIG_ARCH_BSP -++ .bAlternateSetting = ALT_SETTING_1, -++#else -+ .bAlternateSetting = 1, -++#endif -++ .bNumEndpoints = 1, -++ .bInterfaceClass = USB_CLASS_VIDEO, -++ .bInterfaceSubClass = UVC_SC_VIDEOSTREAMING, -++ .bInterfaceProtocol = 0x00, -++ .iInterface = 0, -++}; -++ -++#ifdef CONFIG_ARCH_BSP -++static struct usb_interface_descriptor uvc_streaming_intf_alt2 = { -++ .bLength = USB_DT_INTERFACE_SIZE, -++ .bDescriptorType = USB_DT_INTERFACE, -++ .bInterfaceNumber = UVC_INTF_VIDEO_STREAMING, -++ .bAlternateSetting = ALT_SETTING_2, -++ .bNumEndpoints = 1, -++ .bInterfaceClass = USB_CLASS_VIDEO, -++ .bInterfaceSubClass = UVC_SC_VIDEOSTREAMING, -++ .bInterfaceProtocol = 0x00, -++ .iInterface = 0, -++}; -++ -++static struct usb_interface_descriptor uvc_streaming_intf_alt3 = { -++ .bLength = USB_DT_INTERFACE_SIZE, -++ .bDescriptorType = USB_DT_INTERFACE, -++ .bInterfaceNumber = UVC_INTF_VIDEO_STREAMING, -++ .bAlternateSetting = ALT_SETTING_3, -++ .bNumEndpoints = 1, -++ .bInterfaceClass = USB_CLASS_VIDEO, -++ .bInterfaceSubClass = UVC_SC_VIDEOSTREAMING, -++ .bInterfaceProtocol = 0x00, -++ .iInterface = 0, -++}; -++ -++static struct usb_interface_descriptor uvc_streaming_intf_alt4 = { -++ .bLength = USB_DT_INTERFACE_SIZE, -++ .bDescriptorType = USB_DT_INTERFACE, -++ .bInterfaceNumber = UVC_INTF_VIDEO_STREAMING, -++ .bAlternateSetting = ALT_SETTING_4, -+ .bNumEndpoints = 1, -+ .bInterfaceClass = USB_CLASS_VIDEO, -+ .bInterfaceSubClass = UVC_SC_VIDEOSTREAMING, -+ .bInterfaceProtocol = 0x00, -+ .iInterface = 0, -+ }; -++#endif -+ -+ static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+@@ -146,6 +222,40 @@ static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { -+ * module parameters. -+ */ -+ }; -++#ifdef CONFIG_ARCH_BSP -++static struct usb_endpoint_descriptor uvc_fs_streaming_ep1 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++ -++static struct usb_endpoint_descriptor uvc_fs_streaming_ep2 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++ -++static struct usb_endpoint_descriptor uvc_fs_streaming_ep3 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++#endif -+ -+ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+@@ -158,6 +268,41 @@ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { -+ */ -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++static struct usb_endpoint_descriptor uvc_hs_streaming_ep1 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++ -++static struct usb_endpoint_descriptor uvc_hs_streaming_ep2 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++ -++static struct usb_endpoint_descriptor uvc_hs_streaming_ep3 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++#endif -++ -+ static struct usb_endpoint_descriptor uvc_ss_streaming_ep = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+@@ -170,6 +315,43 @@ static struct usb_endpoint_descriptor uvc_ss_streaming_ep = { -+ */ -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++static struct usb_endpoint_descriptor uvc_ss_streaming_ep1 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++ -++static struct usb_endpoint_descriptor uvc_ss_streaming_ep2 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++ -++static struct usb_endpoint_descriptor uvc_ss_streaming_ep3 = { -++ .bLength = USB_DT_ENDPOINT_SIZE, -++ .bDescriptorType = USB_DT_ENDPOINT, -++ -++ .bEndpointAddress = USB_DIR_IN, -++ .bmAttributes = USB_ENDPOINT_SYNC_ASYNC -++ | USB_ENDPOINT_XFER_ISOC, -++ /* The wMaxPacketSize and bInterval values will be initialized from -++ * module parameters. -++ */ -++}; -++#endif -+ static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { -+ .bLength = sizeof(uvc_ss_streaming_comp), -+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -+@@ -178,15 +360,48 @@ static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { -+ */ -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp1 = { -++ .bLength = sizeof(uvc_ss_streaming_comp1), -++ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -++}; -++ -++static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp2 = { -++ .bLength = sizeof(uvc_ss_streaming_comp2), -++ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -++}; -++ -++static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp3 = { -++ .bLength = sizeof(uvc_ss_streaming_comp3), -++ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, -++}; -++#endif -++ -+ static const struct usb_descriptor_header * const uvc_fs_streaming[] = { -+ (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, -+ (struct usb_descriptor_header *) &uvc_fs_streaming_ep, -++#ifdef CONFIG_ARCH_BSP -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt2, -++ (struct usb_descriptor_header *)&uvc_fs_streaming_ep1, -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt3, -++ (struct usb_descriptor_header *)&uvc_fs_streaming_ep2, -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt4, -++ (struct usb_descriptor_header *)&uvc_fs_streaming_ep3, -++#endif -+ NULL, -+ }; -+ -+ static const struct usb_descriptor_header * const uvc_hs_streaming[] = { -+ (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, -+ (struct usb_descriptor_header *) &uvc_hs_streaming_ep, -++#ifdef CONFIG_ARCH_BSP -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt2, -++ (struct usb_descriptor_header *)&uvc_hs_streaming_ep1, -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt3, -++ (struct usb_descriptor_header *)&uvc_hs_streaming_ep2, -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt4, -++ (struct usb_descriptor_header *)&uvc_hs_streaming_ep3, -++#endif -+ NULL, -+ }; -+ -+@@ -194,6 +409,17 @@ static const struct usb_descriptor_header * const uvc_ss_streaming[] = { -+ (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, -+ (struct usb_descriptor_header *) &uvc_ss_streaming_ep, -+ (struct usb_descriptor_header *) &uvc_ss_streaming_comp, -++#ifdef CONFIG_ARCH_BSP -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt2, -++ (struct usb_descriptor_header *)&uvc_ss_streaming_ep1, -++ (struct usb_descriptor_header *)&uvc_ss_streaming_comp1, -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt3, -++ (struct usb_descriptor_header *)&uvc_ss_streaming_ep2, -++ (struct usb_descriptor_header *)&uvc_ss_streaming_comp2, -++ (struct usb_descriptor_header *)&uvc_streaming_intf_alt4, -++ (struct usb_descriptor_header *)&uvc_ss_streaming_ep3, -++ (struct usb_descriptor_header *)&uvc_ss_streaming_comp3, -++#endif -+ NULL, -+ }; -+ -+@@ -217,6 +443,9 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req) -+ sizeof(uvc_event->data.data)); -+ memcpy(&uvc_event->data.data, req->buf, uvc_event->data.length); -+ v4l2_event_queue(&uvc->vdev, &v4l2_event); -++#ifdef CONFIG_ARCH_BSP -++ iprec("v4l2 queue UVC_EVENT_DATA"); -++#endif -+ } -+ } -+ -+@@ -226,6 +455,11 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) -+ struct uvc_device *uvc = to_uvc(f); -+ struct v4l2_event v4l2_event; -+ struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s setup request 0x%02x 0x%02x value 0x%04x index 0x%04x length 0x%04x", -++ __func__, ctrl->bRequestType, ctrl->bRequest, le16_to_cpu(ctrl->wValue), -++ le16_to_cpu(ctrl->wIndex), le16_to_cpu(ctrl->wLength)); -++#endif -+ -+ if ((ctrl->bRequestType & USB_TYPE_MASK) != USB_TYPE_CLASS) { -+ uvcg_info(f, "invalid request type\n"); -+@@ -246,6 +480,9 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) -+ v4l2_event.type = UVC_EVENT_SETUP; -+ memcpy(&uvc_event->req, ctrl, sizeof(uvc_event->req)); -+ v4l2_event_queue(&uvc->vdev, &v4l2_event); -++#ifdef CONFIG_ARCH_BSP -++ iprec("v4l2 queue UVC_EVENT_SETUP"); -++#endif -+ -+ return 0; -+ } -+@@ -261,17 +498,86 @@ static int -+ uvc_function_get_alt(struct usb_function *f, unsigned interface) -+ { -+ struct uvc_device *uvc = to_uvc(f); -+- -++#ifdef CONFIG_ARCH_BSP -++ uvcg_info(f, "%s(%u)\n", __func__, uvc->alt); -++#else -+ uvcg_info(f, "%s(%u)\n", __func__, interface); -+- -++#endif -+ if (interface == uvc->control_intf) -+ return 0; -+ else if (interface != uvc->streaming_intf) -+ return -EINVAL; -+ else -++#ifdef CONFIG_ARCH_BSP -++ return uvc->video.ep->enabled ? uvc->alt : 0; -++#else -+ return uvc->video.ep->enabled ? 1 : 0; -++#endif -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static int uvc_function_set_appropriate_ep(struct usb_function *f, unsigned alt) -++{ -++ struct uvc_device *uvc = to_uvc(f); -++ switch (alt) { -++ case ALT_SETTING_1: -++ if (f->config->cdev->gadget->speed == USB_SPEED_SUPER) { -++ uvc->video.ep->maxpacket = SS_EP_MAX_PACKET_SIZE; -++ uvc->video.ep->desc = &uvc_ss_streaming_ep; -++ uvc->video.ep->mult = SS_EP_ATTRIBUTES + 1; -++ uvc->video.ep->maxburst = SS_EP_BURST + 1; -++ uvc->video.ep->comp_desc = &uvc_ss_streaming_comp; -++ } else { -++ uvc->video.ep->desc = &uvc_hs_streaming_ep; -++ uvc->video.ep->maxpacket = uvc->video.ep->desc->wMaxPacketSize & USB_ENDPOINT_MAXP_MASK; -++ uvc->video.ep->mult = USB_EP_MAXP_MULT(uvc->video.ep->desc->wMaxPacketSize) + 1; -++ } -++ return 0; -++ case ALT_SETTING_2: -++ if (f->config->cdev->gadget->speed == USB_SPEED_SUPER) { -++ uvc->video.ep->maxpacket = SS_EP1_MAX_PACKET_SIZE; -++ uvc->video.ep->desc = &uvc_ss_streaming_ep1; -++ uvc->video.ep->mult = SS_EP1_ATTRIBUTES + 1; -++ uvc->video.ep->maxburst = SS_EP1_BURST + 1; -++ uvc->video.ep->comp_desc = &uvc_ss_streaming_comp1; -++ } else { -++ uvc->video.ep->desc = &uvc_hs_streaming_ep1; -++ uvc->video.ep->maxpacket = uvc->video.ep->desc->wMaxPacketSize & USB_ENDPOINT_MAXP_MASK; -++ uvc->video.ep->mult = USB_EP_MAXP_MULT(uvc->video.ep->desc->wMaxPacketSize) + 1; -++ } -++ return 0; -++ case ALT_SETTING_3: -++ if (f->config->cdev->gadget->speed == USB_SPEED_SUPER) { -++ uvc->video.ep->maxpacket = SS_EP2_MAX_PACKET_SIZE; -++ uvc->video.ep->desc = &uvc_ss_streaming_ep2; -++ uvc->video.ep->mult = SS_EP2_ATTRIBUTES + 1; -++ uvc->video.ep->maxburst = SS_EP2_BURST + 1; -++ uvc->video.ep->comp_desc = &uvc_ss_streaming_comp2; -++ } else { -++ uvc->video.ep->desc = &uvc_hs_streaming_ep2; -++ uvc->video.ep->maxpacket = uvc->video.ep->desc->wMaxPacketSize & USB_ENDPOINT_MAXP_MASK; -++ uvc->video.ep->mult = USB_EP_MAXP_MULT(uvc->video.ep->desc->wMaxPacketSize) + 1; -++ } -++ return 0; -++ case ALT_SETTING_4: -++ if (f->config->cdev->gadget->speed == USB_SPEED_SUPER) { -++ uvc->video.ep->maxpacket = SS_EP3_MAX_PACKET_SIZE; -++ uvc->video.ep->desc = &uvc_ss_streaming_ep3; -++ uvc->video.ep->mult = SS_EP3_ATTRIBUTES + 1; -++ uvc->video.ep->maxburst = SS_EP3_BURST + 1; -++ uvc->video.ep->comp_desc = &uvc_ss_streaming_comp3; -++ } else { -++ uvc->video.ep->desc = &uvc_hs_streaming_ep3; -++ uvc->video.ep->maxpacket = uvc->video.ep->desc->wMaxPacketSize & USB_ENDPOINT_MAXP_MASK; -++ uvc->video.ep->mult = USB_EP_MAXP_MULT(uvc->video.ep->desc->wMaxPacketSize) + 1; -++ } -++ return 0; -++ default: -++ return -EINVAL; -++ } -++} -++#endif -++ -+ static int -+ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) -+ { -+@@ -282,7 +588,9 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) -+ int ret; -+ -+ uvcg_info(f, "%s(%u, %u)\n", __func__, interface, alt); -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s(%u, %u)", __func__, interface, alt); -++#endif -+ if (interface == uvc->control_intf) { -+ if (alt) -+ return -EINVAL; -+@@ -301,7 +609,9 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) -+ v4l2_event.type = UVC_EVENT_CONNECT; -+ uvc_event->speed = cdev->gadget->speed; -+ v4l2_event_queue(&uvc->vdev, &v4l2_event); -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("v4l2 queue UVC_EVENT_CONNECT"); -++#endif -+ uvc->state = UVC_STATE_CONNECTED; -+ } -+ -+@@ -311,11 +621,60 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) -+ if (interface != uvc->streaming_intf) -+ return -EINVAL; -+ -++#ifdef CONFIG_ARCH_BSP -++ uvc->alt = alt; -++#endif -+ /* TODO -+ if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep)) -+ return alt ? -EINVAL : 0; -+ */ -++#ifdef CONFIG_ARCH_BSP -++ if (alt == ALT_SETTING_0) { -++ if (uvc->state != UVC_STATE_STREAMING) -++ return 0; -++ -++ if (uvc->video.ep) -++ usb_ep_disable(uvc->video.ep); -++ -++ if (memset_s(&v4l2_event, sizeof(v4l2_event), 0, sizeof(v4l2_event)) != 0) -++ return -EINVAL; -++ v4l2_event.type = UVC_EVENT_STREAMOFF; -++ v4l2_event_queue(&uvc->vdev, &v4l2_event); -++ iprec("v4l2 queue UVC_EVENT_STREAMOFF"); -++ uvc->state = UVC_STATE_CONNECTED; -++ return 0; -++ } -++ -++ if (alt > ALT_SETTING_4) -++ return -EINVAL; -++ -++ if (uvc->state != UVC_STATE_CONNECTED) -++ return 0; -++ -++ if (!uvc->video.ep) -++ return -EINVAL; -++ -++ INFO(cdev, "reset UVC\n"); -++ usb_ep_disable(uvc->video.ep); -++ -++ ret = config_ep_by_speed(f->config->cdev->gadget, -++ &(uvc->func), uvc->video.ep); -++ if (ret) -++ return ret; -++ -++ ret = uvc_function_set_appropriate_ep(f, alt); -++ if (ret) -++ return ret; -++ -++ usb_ep_enable(uvc->video.ep); -+ -++ if (memset_s(&v4l2_event, sizeof(v4l2_event), 0, sizeof(v4l2_event)) != 0) -++ return -EINVAL; -++ v4l2_event.type = UVC_EVENT_STREAMON; -++ v4l2_event_queue(&uvc->vdev, &v4l2_event); -++ iprec("v4l2 queue UVC_EVENT_STREAMON"); -++ return USB_GADGET_DELAYED_STATUS; -++#else // CONFIG_ARCH_BSP -+ switch (alt) { -+ case 0: -+ if (uvc->state != UVC_STATE_STREAMING) -+@@ -355,8 +714,28 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) -+ default: -+ return -EINVAL; -+ } -++#endif // CONFIG_ARCH_BSP -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static void -++uvc_ep_recover(struct uvc_device *uvc, struct usb_function *f) -++{ -++ if (uvc->video.ep->enabled == false) -++ return; -++ -++ if (f->config->cdev->gadget->speed == USB_SPEED_SUPER) { -++ uvc->video.ep->desc = &uvc_ss_streaming_ep; -++ uvc->video.ep->mult = SS_EP_ATTRIBUTES + 1; -++ uvc->video.ep->maxburst = SS_EP_BURST + 1; -++ uvc->video.ep->comp_desc = &uvc_ss_streaming_comp; -++ } else { -++ uvc->video.ep->desc = &uvc_hs_streaming_ep; -++ uvc->video.ep->maxpacket = uvc->video.ep->desc->wMaxPacketSize & USB_ENDPOINT_MAXP_MASK; -++ uvc->video.ep->mult = USB_EP_MAXP_MULT(uvc->video.ep->desc->wMaxPacketSize) + 1; -++ } -++} -++#endif -+ static void -+ uvc_function_disable(struct usb_function *f) -+ { -+@@ -370,7 +749,9 @@ uvc_function_disable(struct usb_function *f) -+ v4l2_event_queue(&uvc->vdev, &v4l2_event); -+ -+ uvc->state = UVC_STATE_DISCONNECTED; -+- -++#ifdef CONFIG_ARCH_BSP -++ uvc_ep_recover(uvc, f); -++#endif -+ usb_ep_disable(uvc->video.ep); -+ usb_ep_disable(uvc->control_ep); -+ } -+@@ -628,6 +1009,73 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) -+ max_packet_size = opts->streaming_maxpacket / 3; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++ uvc_fs_streaming_ep.wMaxPacketSize = 0x100; -++ uvc_fs_streaming_ep.bInterval = opts->streaming_interval; -++ -++ uvc_fs_streaming_ep1.wMaxPacketSize = 0x200; -++ uvc_fs_streaming_ep1.bInterval = opts->streaming_interval; -++ -++ uvc_fs_streaming_ep2.wMaxPacketSize = 0x300; -++ uvc_fs_streaming_ep2.bInterval = opts->streaming_interval; -++ -++ uvc_fs_streaming_ep3.wMaxPacketSize = 0x3ff; -++ uvc_fs_streaming_ep3.bInterval = opts->streaming_interval; -++ -++ uvc_hs_streaming_ep.wMaxPacketSize = HS_EP_MAX_PACKET_SIZE; -++ /* A high-bandwidth endpoint must specify a bInterval value of 1 */ -++ if (max_packet_mult > 1) -++ uvc_hs_streaming_ep.bInterval = 1; -++ else -++ uvc_hs_streaming_ep.bInterval = opts->streaming_interval; -++ -++ uvc_hs_streaming_ep1.wMaxPacketSize = HS_EP1_MAX_PACKET_SIZE; -++ uvc_hs_streaming_ep1.bInterval = opts->streaming_interval; -++ -++ uvc_hs_streaming_ep2.wMaxPacketSize = HS_EP2_MAX_PACKET_SIZE; -++ uvc_hs_streaming_ep2.bInterval = opts->streaming_interval; -++ -++ uvc_hs_streaming_ep3.wMaxPacketSize = HS_EP3_MAX_PACKET_SIZE; -++ uvc_hs_streaming_ep3.bInterval = opts->streaming_interval; -++ -++ uvc_ss_streaming_ep.wMaxPacketSize = SS_EP_MAX_PACKET_SIZE; -++ uvc_ss_streaming_ep.bInterval = opts->streaming_interval; -++ -++ uvc_ss_streaming_ep1.wMaxPacketSize = SS_EP1_MAX_PACKET_SIZE; -++ uvc_ss_streaming_ep1.bInterval = opts->streaming_interval; -++ -++ uvc_ss_streaming_ep2.wMaxPacketSize = SS_EP2_MAX_PACKET_SIZE; -++ uvc_ss_streaming_ep2.bInterval = opts->streaming_interval; -++ -++ uvc_ss_streaming_ep3.wMaxPacketSize = SS_EP3_MAX_PACKET_SIZE; -++ uvc_ss_streaming_ep3.bInterval = opts->streaming_interval; -++ -++ uvc_ss_streaming_comp.bmAttributes = SS_EP_ATTRIBUTES; -++ uvc_ss_streaming_comp.bMaxBurst = SS_EP_BURST; -++ -++ uvc_ss_streaming_comp.wBytesPerInterval = -++ cpu_to_le16(uvc_ss_streaming_ep.wMaxPacketSize * (uvc_ss_streaming_comp.bmAttributes + 1) -++ * (uvc_ss_streaming_comp.bMaxBurst + 1)); -++ -++ uvc_ss_streaming_comp1.bmAttributes = SS_EP1_ATTRIBUTES; -++ uvc_ss_streaming_comp1.bMaxBurst = SS_EP1_BURST; -++ uvc_ss_streaming_comp1.wBytesPerInterval = -++ cpu_to_le16(uvc_ss_streaming_ep1.wMaxPacketSize * (uvc_ss_streaming_comp1.bmAttributes + 1) -++ * (uvc_ss_streaming_comp1.bMaxBurst + 1)); -++ -++ uvc_ss_streaming_comp2.bmAttributes = SS_EP2_ATTRIBUTES; -++ uvc_ss_streaming_comp2.bMaxBurst = SS_EP2_BURST; -++ uvc_ss_streaming_comp2.wBytesPerInterval = -++ cpu_to_le16(uvc_ss_streaming_ep2.wMaxPacketSize * (uvc_ss_streaming_comp2.bmAttributes + 1) -++ * (uvc_ss_streaming_comp2.bMaxBurst + 1)); -++ -++ uvc_ss_streaming_comp3.bmAttributes = SS_EP3_ATTRIBUTES; -++ uvc_ss_streaming_comp3.bMaxBurst = SS_EP3_BURST; -++ uvc_ss_streaming_comp3.wBytesPerInterval = -++ cpu_to_le16(uvc_ss_streaming_ep3.wMaxPacketSize * (uvc_ss_streaming_comp3.bmAttributes + 1) -++ * (uvc_ss_streaming_comp3.bMaxBurst + 1)); -++ -++#else // CONFIG_ARCH_BSP -+ uvc_fs_streaming_ep.wMaxPacketSize = -+ cpu_to_le16(min(opts->streaming_maxpacket, 1023U)); -+ uvc_fs_streaming_ep.bInterval = opts->streaming_interval; -+@@ -648,6 +1096,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) -+ uvc_ss_streaming_comp.wBytesPerInterval = -+ cpu_to_le16(max_packet_size * max_packet_mult * -+ (opts->streaming_maxburst + 1)); -++#endif // CONFIG_ARCH_BSP -+ -+ /* Allocate endpoints. */ -+ ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); -+@@ -675,6 +1124,19 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) -+ uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; -+ uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address; -+ -++#ifdef CONFIG_ARCH_BSP -++ uvc_fs_streaming_ep1.bEndpointAddress = uvc->video.ep->address; -++ uvc_hs_streaming_ep1.bEndpointAddress = uvc->video.ep->address; -++ uvc_ss_streaming_ep1.bEndpointAddress = uvc->video.ep->address; -++ -++ uvc_fs_streaming_ep2.bEndpointAddress = uvc->video.ep->address; -++ uvc_hs_streaming_ep2.bEndpointAddress = uvc->video.ep->address; -++ uvc_ss_streaming_ep2.bEndpointAddress = uvc->video.ep->address; -++ -++ uvc_fs_streaming_ep3.bEndpointAddress = uvc->video.ep->address; -++ uvc_hs_streaming_ep3.bEndpointAddress = uvc->video.ep->address; -++ uvc_ss_streaming_ep3.bEndpointAddress = uvc->video.ep->address; -++#endif -+ us = usb_gstrings_attach(cdev, uvc_function_strings, -+ ARRAY_SIZE(uvc_en_us_strings)); -+ if (IS_ERR(us)) { -+@@ -686,6 +1148,11 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) -+ ret = us[UVC_STRING_STREAMING_IDX].id; -+ uvc_streaming_intf_alt0.iInterface = ret; -+ uvc_streaming_intf_alt1.iInterface = ret; -++#ifdef CONFIG_ARCH_BSP -++ uvc_streaming_intf_alt2.iInterface = ret; -++ uvc_streaming_intf_alt3.iInterface = ret; -++ uvc_streaming_intf_alt4.iInterface = ret; -++#endif -+ -+ /* Allocate interface IDs. */ -+ if ((ret = usb_interface_id(c, f)) < 0) -+@@ -699,6 +1166,11 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) -+ goto error; -+ uvc_streaming_intf_alt0.bInterfaceNumber = ret; -+ uvc_streaming_intf_alt1.bInterfaceNumber = ret; -++#ifdef CONFIG_ARCH_BSP -++ uvc_streaming_intf_alt2.bInterfaceNumber = ret; -++ uvc_streaming_intf_alt3.bInterfaceNumber = ret; -++ uvc_streaming_intf_alt4.bInterfaceNumber = ret; -++#endif -+ uvc->streaming_intf = ret; -+ opts->streaming_interface = ret; -+ -+@@ -790,6 +1262,12 @@ static struct usb_function_instance *uvc_alloc_inst(void) -+ struct uvc_descriptor_header **ctl_cls; -+ int ret; -+ -++#ifdef CONFIG_ARCH_BSP -++ 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}; -++#endif -+ opts = kzalloc(sizeof(*opts), GFP_KERNEL); -+ if (!opts) -+ return ERR_PTR(-ENOMEM); -+@@ -825,6 +1303,25 @@ static struct usb_function_instance *uvc_alloc_inst(void) -+ pd->iProcessing = 0; -+ pd->bmVideoStandards = 0; -+ -++#ifdef CONFIG_ARCH_BSP -++ 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; -++ if (memcpy_s(ed->guidExtensionCode, sizeof(extension_guid), extension_guid, sizeof(extension_guid)) != 0) { -++ kfree(opts); -++ opts = NULL; -++ return NULL; -++ } -++ ed->bNrInPins = 1; -++ ed->baSourceID[0] = 2; -++ ed->bNumControls = 15; -++ ed->bControlSize = 2; -++ ed->bmControls[0] = 1; -++ ed->bmControls[1] = 0; -++ ed->iExtension = 0; -++#endif -+ od = &opts->uvc_output_terminal; -+ od->bLength = UVC_DT_OUTPUT_TERMINAL_SIZE; -+ od->bDescriptorType = USB_DT_CS_INTERFACE; -+@@ -843,6 +1340,29 @@ static struct usb_function_instance *uvc_alloc_inst(void) -+ md->bTransferCharacteristics = 1; -+ md->bMatrixCoefficients = 4; -+ -++#ifdef CONFIG_ARCH_BSP -++ /* Prepare fs control class descriptors for configfs-based gadgets */ -++ ctl_cls = opts->uvc_fs_control_cls; -++ 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 *)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; -++ -++ /* Prepare hs control class descriptors for configfs-based gadgets */ -++ ctl_cls = opts->uvc_ss_control_cls; -++ 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 *)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; -++#else // CONFIG_ARCH_BSP -+ /* Prepare fs control class descriptors for configfs-based gadgets */ -+ ctl_cls = opts->uvc_fs_control_cls; -+ ctl_cls[0] = NULL; /* assigned elsewhere by configfs */ -+@@ -862,6 +1382,7 @@ static struct usb_function_instance *uvc_alloc_inst(void) -+ ctl_cls[4] = NULL; /* NULL-terminate */ -+ opts->ss_control = -+ (const struct uvc_descriptor_header * const *)ctl_cls; -++#endif // CONFIG_ARCH_BSP -+ -+ opts->streaming_interval = 1; -+ opts->streaming_maxpacket = 1024; -+diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h -+index 9a01a7d4f..e3ce1c8ed 100644 -+--- a/drivers/usb/gadget/function/u_uvc.h -++++ b/drivers/usb/gadget/function/u_uvc.h -+@@ -53,6 +53,9 @@ struct f_uvc_opts { -+ struct uvc_output_terminal_descriptor uvc_output_terminal; -+ struct uvc_color_matching_descriptor uvc_color_matching; -+ -++#ifdef CONFIG_ARCH_BSP -++ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) uvc_extension; -++#endif -+ /* -+ * Control descriptors pointers arrays for full-/high-speed and -+ * super-speed. The first element is a configurable control header -+@@ -60,8 +63,13 @@ struct f_uvc_opts { -+ * descriptors. Used by configfs only, must not be touched by legacy -+ * gadgets. -+ */ -++#ifdef CONFIG_ARCH_BSP -++ struct uvc_descriptor_header *uvc_fs_control_cls[6]; -++ struct uvc_descriptor_header *uvc_ss_control_cls[6]; -++#else -+ struct uvc_descriptor_header *uvc_fs_control_cls[5]; -+ struct uvc_descriptor_header *uvc_ss_control_cls[5]; -++#endif -+ -+ /* -+ * Streaming descriptors for full-speed, high-speed and super-speed. -+diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h -+index 6c4fc4913..a4f44ff8f 100644 -+--- a/drivers/usb/gadget/function/uvc.h -++++ b/drivers/usb/gadget/function/uvc.h -+@@ -45,6 +45,14 @@ struct uvc_device; -+ #define UVC_WARN_MINMAX 0 -+ #define UVC_WARN_PROBE_DEF 1 -+ -++#ifdef CONFIG_ARCH_BSP -++#define ALT_SETTING_0 0 -++#define ALT_SETTING_1 1 -++#define ALT_SETTING_2 2 -++#define ALT_SETTING_3 3 -++#define ALT_SETTING_4 4 -++#endif -++ -+ extern unsigned int uvc_gadget_trace_param; -+ -+ #define uvc_trace(flag, msg...) \ -+@@ -65,11 +73,40 @@ extern unsigned int uvc_gadget_trace_param; -+ /* ------------------------------------------------------------------------ -+ * Driver specific constants -+ */ -++#ifdef CONFIG_ARCH_BSP -++#define UVC_SG_REQ -++#endif -+ -++#if defined(CONFIG_ARCH_BSP) && defined(UVC_SG_REQ) -++#define UVC_NUM_REQUESTS 1 -++#else -+ #define UVC_NUM_REQUESTS 4 -++#endif -+ #define UVC_MAX_REQUEST_SIZE 64 -+ #define UVC_MAX_EVENTS 4 -+ -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++/* ------------------------------------------------------------------------ -++ * UVC packet operation -++ */ -++struct uvc_video; -++struct uvc_pack_trans { -++ struct list_head list; -++ -++ uint64_t addr; -++ unsigned int len; -++ unsigned int buf_used; -++ -++ bool is_frame_end; -++ bool need_free; -++ -++ struct uvc_pack *pack; -++ int frame_cnts; -++ struct uvc_video *video; -++ spinlock_t lock; -++}; -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -++ -+ /* ------------------------------------------------------------------------ -+ * Structures -+ */ -+@@ -88,6 +125,10 @@ struct uvc_video { -+ unsigned int imagesize; -+ struct mutex mutex; /* protects frame parameters */ -+ -++#if defined(CONFIG_ARCH_BSP) && defined(UVC_SG_REQ) -++ unsigned int num_sgs; /* record base */ -++ __u8 *sg_buf; -++#endif -+ /* Requests */ -+ unsigned int req_size; -+ struct usb_request *req[UVC_NUM_REQUESTS]; -+@@ -95,8 +136,13 @@ struct uvc_video { -+ struct list_head req_free; -+ spinlock_t req_lock; -+ -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ void (*encode) (struct usb_request *req, struct uvc_video *video, -++ struct uvc_pack_trans *pack); -++#else -+ void (*encode) (struct usb_request *req, struct uvc_video *video, -+ struct uvc_buffer *buf); -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -+ -+ /* Context data used by the completion handler */ -+ __u32 payload_size; -+@@ -104,6 +150,9 @@ struct uvc_video { -+ -+ struct uvc_video_queue queue; -+ unsigned int fid; -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ volatile bool is_streaming; -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -+ }; -+ -+ enum uvc_state { -+@@ -136,6 +185,9 @@ struct uvc_device { -+ void *control_buf; -+ -+ unsigned int streaming_intf; -++#ifdef CONFIG_ARCH_BSP -++ unsigned int alt; -++#endif -+ -+ /* Events */ -+ unsigned int event_length; -+diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c -+index 2db01170d..019cfe486 100644 -+--- a/drivers/usb/gadget/function/uvc_configfs.c -++++ b/drivers/usb/gadget/function/uvc_configfs.c -+@@ -11,6 +11,9 @@ -+ */ -+ -+ #include -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -+ -+ #include "u_uvc.h" -+ #include "uvc_configfs.h" -+@@ -319,7 +322,53 @@ static ssize_t uvcg_default_processing_bm_controls_show( -+ return result; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static ssize_t uvcg_default_processing_bm_controls_store( -++ struct config_item *item, const char *page, size_t len) -++{ -++ struct config_group *group = to_config_group(item); -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct mutex *su_mutex = &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 = 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); -++#else // CONFIG_ARCH_BSP -+ UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls); -++#endif // CONFIG_ARCH_BSP -+ -+ static struct configfs_attribute *uvcg_default_processing_attrs[] = { -+ &uvcg_default_processing_attr_b_unit_id, -+@@ -355,6 +404,112 @@ static const struct uvcg_config_group_type uvcg_processing_grp_type = { -+ }, -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++/* ----------------------------------------------------------------------------- -++ * control/extension/default -++ */ -++ -++#define UVCG_DEFAULT_EXTENSION_ATTR(cname, aname, bits) \ -++static ssize_t uvcg_default_extension_##cname##_show( \ -++ struct config_item *item, char *page) \ -++{ \ -++ struct config_group *group = to_config_group(item); \ -++ struct f_uvc_opts *opts; \ -++ struct config_item *opts_item; \ -++ struct mutex *su_mutex = &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 = 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_s(page, PAGE_SIZE, "%u\n", le##bits##_to_cpu(ed->aname)); \ -++ mutex_unlock(&opts->lock); \ -++ \ -++ mutex_unlock(su_mutex); \ -++ return result; \ -++} \ -++ \ -++UVC_ATTR_RO(uvcg_default_extension_, cname, aname) -++ -++UVCG_DEFAULT_EXTENSION_ATTR(b_unit_id, bUnitID, 8); -++UVCG_DEFAULT_EXTENSION_ATTR(b_num_input_pins, bNrInPins, 8); -++UVCG_DEFAULT_EXTENSION_ATTR(i_extension, iExtension, 8); -++ -++#undef UVCG_DEFAULT_EXTENSION_ATTR -++ -++static ssize_t uvcg_default_extension_bm_controls_show( -++ struct config_item *item, char *page) -++{ -++ struct config_group *group = to_config_group(item); -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct mutex *su_mutex = &group->cg_subsys->su_mutex; -++ struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed; -++ int result, pg_state, i; -++ int max_size = PAGE_SIZE; -++ char *pg = page; -++ -++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -++ -++ opts_item = 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) && (max_size > 0); ++i) { -++ pg_state = sprintf_s(pg, max_size, "%d\n", ed->bmControls[i]); -++ if (pg_state < 0) -++ break; -++ result += pg_state; -++ pg = page + result; -++ max_size = PAGE_SIZE - 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 const struct uvcg_config_group_type uvcg_default_extension_type = { -++ .type = { -++ .ct_item_ops = &uvcg_config_item_ops, -++ .ct_attrs = uvcg_default_extension_attrs, -++ .ct_owner = THIS_MODULE, -++ }, -++ .name = "default", -++}; -++ -++/* ----------------------------------------------------------------------------- -++ * control/extension -++ */ -++static const struct uvcg_config_group_type uvcg_extension_grp_type = { -++ .type = { -++ .ct_item_ops = &uvcg_config_item_ops, -++ .ct_owner = THIS_MODULE, -++ }, -++ .name = "extension", -++ .children = (const struct uvcg_config_group_type*[]) { -++ &uvcg_default_extension_type, -++ NULL, -++ }, -++}; -++#endif -+ /* ----------------------------------------------------------------------------- -+ * control/terminal/camera/default -+ */ -+@@ -430,7 +585,54 @@ static ssize_t uvcg_default_camera_bm_controls_show( -+ return result; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++static ssize_t uvcg_default_camera_bm_controls_store( -++ struct config_item *item, const char *page, size_t len) -++{ -++ struct config_group *group = to_config_group(item); -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct mutex *su_mutex = &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 = 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); -++#else -+ UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls); -++#endif -+ -+ static struct configfs_attribute *uvcg_default_camera_attrs[] = { -+ &uvcg_default_camera_attr_b_terminal_id, -+@@ -810,6 +1012,9 @@ static const struct uvcg_config_group_type uvcg_control_grp_type = { -+ .children = (const struct uvcg_config_group_type*[]) { -+ &uvcg_control_header_grp_type, -+ &uvcg_processing_grp_type, -++#ifdef CONFIG_ARCH_BSP -++ &uvcg_extension_grp_type, -++#endif -+ &uvcg_terminal_grp_type, -+ &uvcg_control_class_grp_type, -+ NULL, -+@@ -824,11 +1029,17 @@ static const struct uvcg_config_group_type uvcg_control_grp_type = { -+ static const char * const uvcg_format_names[] = { -+ "uncompressed", -+ "mjpeg", -++#ifdef CONFIG_ARCH_BSP -++ "framebased" -++#endif -+ }; -+ -+ enum uvcg_format_type { -+ UVCG_UNCOMPRESSED = 0, -+ UVCG_MJPEG, -++#ifdef CONFIG_ARCH_BSP -++ UVCG_FRAME_FRAME_BASED, -++#endif -+ }; -+ -+ struct uvcg_format { -+@@ -1438,6 +1649,9 @@ static struct config_item *uvcg_frame_make(struct config_group *group, -+ return ERR_PTR(-EINVAL); -+ } -+ ++fmt->num_frames; -++#ifdef CONFIG_ARCH_BSP -++ h->frame.b_frame_index = fmt->num_frames; -++#endif -+ mutex_unlock(&opts->lock); -+ -+ config_item_init_type_name(&h->item, name, &uvcg_frame_type); -+@@ -1478,124 +1692,422 @@ static void uvcg_format_set_indices(struct config_group *fmt) -+ } -+ } -+ -++#ifdef CONFIG_ARCH_BSP -+ /* ----------------------------------------------------------------------------- -+- * streaming/uncompressed/ -++ * frame_based -+ */ -+- -+-struct uvcg_uncompressed { -+- struct uvcg_format fmt; -+- struct uvc_format_uncompressed desc; -+-}; -+- -+-static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) -+-{ -+- return container_of( -+- container_of(to_config_group(item), struct uvcg_format, group), -+- struct uvcg_uncompressed, fmt); -+-} -+- -+-static struct configfs_group_operations uvcg_uncompressed_group_ops = { -+- .make_item = uvcg_frame_make, -+- .drop_item = uvcg_frame_drop, -++struct uvcg_frame_based_frame { -++ struct config_item item; -++ enum uvcg_format_type fmt_type; -++ 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; -+ }; -+ -+-static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, -+- char *page) -+-{ -+- struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); -+- struct f_uvc_opts *opts; -+- struct config_item *opts_item; -+- struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; -+- -+- mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -+- -+- opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; -+- opts = to_f_uvc_opts(opts_item); -+- -+- mutex_lock(&opts->lock); -+- memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); -+- mutex_unlock(&opts->lock); -+- -+- mutex_unlock(su_mutex); -+- -+- return sizeof(ch->desc.guidFormat); -+-} -+- -+-static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, -+- const char *page, size_t len) -++static struct uvcg_frame_based_frame *to_uvcg_frame_based_frame(struct config_item *item) -+ { -+- struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); -+- struct f_uvc_opts *opts; -+- struct config_item *opts_item; -+- struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; -+- int ret; -+- -+- mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -+- -+- opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; -+- opts = to_f_uvc_opts(opts_item); -+- -+- mutex_lock(&opts->lock); -+- if (ch->fmt.linked || opts->refcnt) { -+- ret = -EBUSY; -+- goto end; -+- } -+- -+- memcpy(ch->desc.guidFormat, page, -+- min(sizeof(ch->desc.guidFormat), len)); -+- ret = sizeof(ch->desc.guidFormat); -+- -+-end: -+- mutex_unlock(&opts->lock); -+- mutex_unlock(su_mutex); -+- return ret; -++ return container_of(item, struct uvcg_frame_based_frame, item); -+ } -+ -+-UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); -+- -+-#define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits) \ -+-static ssize_t uvcg_uncompressed_##cname##_show( \ -+- struct config_item *item, char *page) \ -++#define UVCG_FRAME_BASED_FRAME_ATTR(cname, aname, bits) \ -++static ssize_t uvcg_frame_based_frame_##cname##_show(struct config_item *item, char *page)\ -+ { \ -+- struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ -++ 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 = &u->fmt.group.cg_subsys->su_mutex; \ -++ struct mutex *su_mutex = &f->item.ci_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_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, "%u\n", le##bits##_to_cpu(u->desc.aname));\ -++ result = sprintf_s(page, PAGE_SIZE, "%d\n", f->frame.cname); \ -+ mutex_unlock(&opts->lock); \ -+ \ -+ mutex_unlock(su_mutex); \ -+ return result; \ -+ } \ -+ \ -+-UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); -+- -+-#define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits) \ -+-static ssize_t uvcg_uncompressed_##cname##_show( \ -+- struct config_item *item, char *page) \ -++static ssize_t uvcg_frame_based_frame_##cname##_store(struct config_item *item, \ -++ const char *page, size_t len)\ -+ { \ -+- struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ -++ 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 = &u->fmt.group.cg_subsys->su_mutex; \ -+- int result; \ -++ struct uvcg_format *fmt; \ -++ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ -++ int ret; \ -++ typeof(f->frame.cname) num; \ -++ \ -++ ret = kstrtou##bits(page, 0, &num); \ -++ if (ret) \ -++ return ret; \ -+ \ -+ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ -+ \ -+- opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ -++ 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); \ -+- result = sprintf(page, "%u\n", le##bits##_to_cpu(u->desc.aname));\ -+- mutex_unlock(&opts->lock); \ -++ if (fmt->linked || opts->refcnt) { \ -++ ret = -EBUSY; \ -++ goto end; \ -++ } \ -++ \ -++ f->frame.cname = num; \ -++ ret = len; \ -++end: \ -++ mutex_unlock(&opts->lock); \ -++ mutex_unlock(su_mutex); \ -++ return ret; \ -++} \ -++ \ -++UVC_ATTR(uvcg_frame_based_frame_, cname, aname); -++ -++static ssize_t uvcg_frame_based_frame_b_frame_index_show(struct config_item *item, -++ char *page) -++{ -++ struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item); -++ struct uvcg_format *fmt; -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct config_item *fmt_item; -++ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex; -++ int result; -++ -++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -++ -++ fmt_item = f->item.ci_parent; -++ fmt = to_uvcg_format(fmt_item); -++ -++ if (!fmt->linked) { -++ result = -EBUSY; -++ goto out; -++ } -++ -++ opts_item = fmt_item->ci_parent->ci_parent->ci_parent; -++ opts = to_f_uvc_opts(opts_item); -++ -++ mutex_lock(&opts->lock); -++ result = sprintf_s(page, PAGE_SIZE, "%u\n", f->frame.b_frame_index); -++ mutex_unlock(&opts->lock); -++ -++out: -++ mutex_unlock(su_mutex); -++ return result; -++} -++ -++UVC_ATTR_RO(uvcg_frame_based_frame_, b_frame_index, bFrameIndex); -++ -++UVCG_FRAME_BASED_FRAME_ATTR(bm_capabilities, bmCapabilities, 8); -++UVCG_FRAME_BASED_FRAME_ATTR(w_width, wWidth, 16); -++UVCG_FRAME_BASED_FRAME_ATTR(w_height, wHeight, 16); -++UVCG_FRAME_BASED_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32); -++UVCG_FRAME_BASED_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32); -++UVCG_FRAME_BASED_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32); -++UVCG_FRAME_BASED_FRAME_ATTR(dw_bytes_per_line, dwBytesPerLine, 32); -++ -++#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, pg_state, i; -++ int max_size = PAGE_SIZE; -++ 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) && (max_size > 0); ++i) { -++ pg_state = sprintf_s(pg, max_size, "%u\n", frm->dw_frame_interval[i]); -++ if (pg_state < 0) -++ break; -++ result += pg_state; -++ pg = page + result; -++ max_size = PAGE_SIZE - 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; -++ sort(ch->dw_frame_interval, n, sizeof(*ch->dw_frame_interval), -++ uvcg_config_compare_u32, NULL); -++ 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_b_frame_index, -++ &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 const struct config_item_type uvcg_frame_based_frame_type = { -++ .ct_item_ops = &uvcg_config_item_ops, -++ .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 = 640; -++ h->frame.w_height = 360; -++ h->frame.dw_min_bit_rate = 18432000; -++ h->frame.dw_max_bit_rate = 55296000; -++ h->frame.dw_default_frame_interval = 333333; -++ h->frame.dw_bytes_per_line = 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); -++} -++#endif -++ -++/* ----------------------------------------------------------------------------- -++ * streaming/uncompressed/ -++ */ -++ -++struct uvcg_uncompressed { -++ struct uvcg_format fmt; -++ struct uvc_format_uncompressed desc; -++}; -++ -++static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) -++{ -++ return container_of( -++ container_of(to_config_group(item), struct uvcg_format, group), -++ struct uvcg_uncompressed, fmt); -++} -++ -++static struct configfs_group_operations uvcg_uncompressed_group_ops = { -++ .make_item = uvcg_frame_make, -++ .drop_item = uvcg_frame_drop, -++}; -++ -++static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, -++ char *page) -++{ -++ struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; -++ -++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -++ -++ opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; -++ opts = to_f_uvc_opts(opts_item); -++ -++ mutex_lock(&opts->lock); -++ memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); -++ mutex_unlock(&opts->lock); -++ -++ mutex_unlock(su_mutex); -++ -++ return sizeof(ch->desc.guidFormat); -++} -++ -++static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, -++ const char *page, size_t len) -++{ -++ struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; -++ int ret; -++ -++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -++ -++ opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; -++ opts = to_f_uvc_opts(opts_item); -++ -++ mutex_lock(&opts->lock); -++ if (ch->fmt.linked || opts->refcnt) { -++ ret = -EBUSY; -++ goto end; -++ } -++ -++ memcpy(ch->desc.guidFormat, page, -++ min(sizeof(ch->desc.guidFormat), len)); -++ ret = sizeof(ch->desc.guidFormat); -++ -++end: -++ mutex_unlock(&opts->lock); -++ mutex_unlock(su_mutex); -++ return ret; -++} -++ -++UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); -++ -++#define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, bits) \ -++static ssize_t uvcg_uncompressed_##cname##_show( \ -++ struct config_item *item, char *page) \ -++{ \ -++ struct uvcg_uncompressed *u = to_uvcg_uncompressed(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, "%u\n", le##bits##_to_cpu(u->desc.aname));\ -++ mutex_unlock(&opts->lock); \ -++ \ -++ mutex_unlock(su_mutex); \ -++ return result; \ -++} \ -++ \ -++UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); -++ -++#define UVCG_UNCOMPRESSED_ATTR(cname, aname, bits) \ -++static ssize_t uvcg_uncompressed_##cname##_show( \ -++ struct config_item *item, char *page) \ -++{ \ -++ struct uvcg_uncompressed *u = to_uvcg_uncompressed(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, "%u\n", le##bits##_to_cpu(u->desc.aname));\ -++ mutex_unlock(&opts->lock); \ -+ \ -+ mutex_unlock(su_mutex); \ -+ return result; \ -+@@ -1913,6 +2425,264 @@ static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { -+ .name = "mjpeg", -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++/* ----------------------------------------------------------------------------- -++ * 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, -++}; -++ -++static ssize_t uvcg_frame_based_guid_format_show(struct config_item *item, -++ char *page) -++{ -++ struct uvcg_frame_based_format *ch = to_uvcg_frame_based_format(item); -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; -++ int result; -++ -++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -++ -++ opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; -++ opts = to_f_uvc_opts(opts_item); -++ -++ mutex_lock(&opts->lock); -++ result = memcpy_s(page, PAGE_SIZE, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); -++ mutex_unlock(&opts->lock); -++ -++ mutex_unlock(su_mutex); -++ -++ if (result != 0) -++ return 0; -++ return sizeof(ch->desc.guidFormat); -++} -++ -++static ssize_t uvcg_frame_based_guid_format_store(struct config_item *item, -++ const char *page, size_t len) -++{ -++ struct uvcg_frame_based_format *ch = to_uvcg_frame_based_format(item); -++ struct f_uvc_opts *opts; -++ struct config_item *opts_item; -++ struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; -++ int ret, rc; -++ -++ mutex_lock(su_mutex); /* for navigating configfs hierarchy */ -++ -++ opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; -++ opts = to_f_uvc_opts(opts_item); -++ -++ mutex_lock(&opts->lock); -++ if (ch->fmt.linked || opts->refcnt) { -++ ret = -EBUSY; -++ goto end; -++ } -++ -++ rc = memcpy_s(ch->desc.guidFormat, sizeof(ch->desc.guidFormat), page, -++ min(sizeof(ch->desc.guidFormat), len)); -++ if (rc != 0) { -++ ret = 0; -++ goto end; -++ } -++ ret = sizeof(ch->desc.guidFormat); -++ -++end: -++ mutex_unlock(&opts->lock); -++ mutex_unlock(su_mutex); -++ return ret; -++} -++ -++UVC_ATTR(uvcg_frame_based_, guid_format, guidFormat); -++ -++#define UVCG_FRAME_BASED_FORMAT_ATTR_RO(cname, aname, bits) \ -++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_s(page, PAGE_SIZE, "%u\n", le##bits##_to_cpu(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, bits) \ -++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_s(page, PAGE_SIZE, "%u\n", le##bits##_to_cpu(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; \ -++ \ -++ 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) -++ -++UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_format_index, bFormatIndex, 8); -++UVCG_FRAME_BASED_FORMAT_ATTR(b_default_frame_index, bDefaultFrameIndex, 8); -++UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8); -++UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8); -++UVCG_FRAME_BASED_FORMAT_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8); -++ -++#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_format_index, -++ &uvcg_frame_based_attr_guid_format, -++ &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_item_ops = &uvcg_config_item_ops, -++ .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; -++ int result; -++ -++ 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; -++ result = memcpy_s(h->desc.guidFormat, sizeof(h->desc.guidFormat), guid, sizeof(guid)); -++ if (result != 0) -++ return NULL; -++ 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 struct configfs_group_operations uvcg_frame_based_format_grp_ops = { -++ .make_group = uvcg_frame_based_format_make, -++}; -++ -++static const struct uvcg_config_group_type uvcg_frame_based_format_grp_type = { -++ .type = { -++ .ct_item_ops = &uvcg_config_item_ops, -++ .ct_group_ops = &uvcg_frame_based_format_grp_ops, -++ .ct_owner = THIS_MODULE, -++ }, -++ .name = "framebased", -++}; -++#endif -++ -+ /* ----------------------------------------------------------------------------- -+ * streaming/color_matching/default -+ */ -+@@ -2106,6 +2876,13 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, -+ container_of(fmt, struct uvcg_mjpeg, fmt); -+ -+ *size += sizeof(m->desc); -++#ifdef CONFIG_ARCH_BSP -++ } 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); -++#endif -+ } else { -+ return -EINVAL; -+ } -+@@ -2114,7 +2891,16 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, -+ case UVCG_FRAME: { -+ struct uvcg_frame *frm = priv1; -+ int sz = sizeof(frm->dw_frame_interval); -+- -++#ifdef CONFIG_ARCH_BSP -++ 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; -++ } -++#endif -+ *size += sizeof(frm->frame); -+ *size += frm->frame.b_frame_interval_type * sz; -+ } -+@@ -2180,6 +2966,18 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, -+ m->desc.bNumFrameDescriptors = fmt->num_frames; -+ memcpy(*dest, &m->desc, sizeof(m->desc)); -+ *dest += sizeof(m->desc); -++#ifdef CONFIG_ARCH_BSP -++ } 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); -++ -++ if (memcpy_s(*dest, sizeof(h->desc), &h->desc, sizeof(h->desc)) != 0) -++ return -EINVAL; -++ *dest += sizeof(h->desc); -++ ffb->bNumFrameDescriptors = fmt->num_frames; -++ ffb->bFormatIndex = n + 1; -++#endif -+ } else { -+ return -EINVAL; -+ } -+@@ -2189,12 +2987,39 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, -+ struct uvcg_frame *frm = priv1; -+ struct uvc_descriptor_header *h = *dest; -+ -++#ifdef CONFIG_ARCH_BSP -++ if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) { -++ struct uvcg_frame_based_frame *fb_frm = priv1; -++ sz = sizeof(fb_frm->frame); -++ if (memcpy_s(*dest, sz, &fb_frm->frame, sz) != 0) -++ return -EINVAL; -++ *dest += sz; -++ sz = fb_frm->frame.b_frame_interval_type * -++ sizeof(*fb_frm->dw_frame_interval); -++ if (memcpy_s(*dest, sz, fb_frm->dw_frame_interval, sz) != 0) -++ return -EINVAL; -++ *dest += sz; -++ h->bLength = UVC_DT_FRAME_BASED_FRAME_SIZE( -++ fb_frm->frame.b_frame_interval_type); -++ return 0; -++ } -++#endif -+ sz = sizeof(frm->frame); -++#ifdef CONFIG_ARCH_BSP -++ if (memcpy_s(*dest, sz, &frm->frame, sz) != 0) -++ return -EINVAL; -++#else -+ memcpy(*dest, &frm->frame, sz); -++#endif -+ *dest += sz; -+ sz = frm->frame.b_frame_interval_type * -+ sizeof(*frm->dw_frame_interval); -++#ifdef CONFIG_ARCH_BSP -++ if (memcpy_s(*dest, sz, frm->dw_frame_interval, sz) != 0) -++ return -EINVAL; -++#else -+ memcpy(*dest, frm->dw_frame_interval, sz); -++#endif -+ *dest += sz; -+ if (frm->fmt_type == UVCG_UNCOMPRESSED) -+ h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE( -+@@ -2414,6 +3239,9 @@ static const struct uvcg_config_group_type uvcg_streaming_grp_type = { -+ &uvcg_streaming_header_grp_type, -+ &uvcg_uncompressed_grp_type, -+ &uvcg_mjpeg_grp_type, -++#ifdef CONFIG_ARCH_BSP -++ &uvcg_frame_based_format_grp_type, -++#endif -+ &uvcg_color_matching_grp_type, -+ &uvcg_streaming_class_grp_type, -+ NULL, -+diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c -+index 65abd55ce..d0a4c21b3 100644 -+--- a/drivers/usb/gadget/function/uvc_v4l2.c -++++ b/drivers/usb/gadget/function/uvc_v4l2.c -+@@ -19,6 +19,10 @@ -+ #include -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -++ -+ #include "f_uvc.h" -+ #include "uvc.h" -+ #include "uvc_queue.h" -+@@ -34,7 +38,9 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) -+ { -+ struct usb_composite_dev *cdev = uvc->func.config->cdev; -+ struct usb_request *req = uvc->control_req; -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s", __func__); -++#endif -+ if (data->length < 0) -+ return usb_ep_set_halt(cdev->gadget->ep0); -+ -+@@ -55,10 +61,21 @@ struct uvc_format { -+ u32 fcc; -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++static struct uvc_format uvc_formats[] = { -++ { 16, V4L2_PIX_FMT_YUYV }, -++ { 12, V4L2_PIX_FMT_NV21 }, -++ { 12, V4L2_PIX_FMT_NV12 }, -++ { 0, V4L2_PIX_FMT_MJPEG }, -++ { 0, V4L2_PIX_FMT_H264 }, -++ { 0, V4L2_PIX_FMT_H265 }, -++}; -++#else -+ static struct uvc_format uvc_formats[] = { -+ { 16, V4L2_PIX_FMT_YUYV }, -+ { 0, V4L2_PIX_FMT_MJPEG }, -+ }; -++#endif -+ -+ static int -+ uvc_v4l2_querycap(struct file *file, void *fh, struct v4l2_capability *cap) -+@@ -163,6 +180,7 @@ uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) -+ struct video_device *vdev = video_devdata(file); -+ struct uvc_device *uvc = video_get_drvdata(vdev); -+ struct uvc_video *video = &uvc->video; -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ int ret; -+ -+ ret = uvcg_queue_buffer(&video->queue, b); -+@@ -172,16 +190,24 @@ uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) -+ schedule_work(&video->pump); -+ -+ return ret; -++#else /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -++ schedule_work(&video->pump); -++ return 0; -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -+ } -+ -+ static int -+ uvc_v4l2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) -+ { -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ return 0; -++#else -+ struct video_device *vdev = video_devdata(file); -+ struct uvc_device *uvc = video_get_drvdata(vdev); -+ struct uvc_video *video = &uvc->video; -+ -+ return uvcg_dequeue_buffer(&video->queue, b, file->f_flags & O_NONBLOCK); -++#endif -+ } -+ -+ static int -+@@ -191,15 +217,20 @@ uvc_v4l2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) -+ struct uvc_device *uvc = video_get_drvdata(vdev); -+ struct uvc_video *video = &uvc->video; -+ int ret; -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("[%s] before uvcg_video_enable", __func__); -++#endif -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ if (type != video->queue.queue.type) -+ return -EINVAL; -+- -++#endif -+ /* Enable UVC video. */ -+ ret = uvcg_video_enable(video, 1); -+ if (ret < 0) -+ return ret; -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("[%s] uvcg_video_enable return: %d", __func__, ret); -++#endif -+ /* -+ * Complete the alternate setting selection setup phase now that -+ * userspace is ready to provide video frames. -+@@ -216,10 +247,13 @@ uvc_v4l2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) -+ struct video_device *vdev = video_devdata(file); -+ struct uvc_device *uvc = video_get_drvdata(vdev); -+ struct uvc_video *video = &uvc->video; -+- -++#ifdef CONFIG_ARCH_BSP -++ iprec("%s", __func__); -++#endif -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ if (type != video->queue.queue.type) -+ return -EINVAL; -+- -++#endif -+ return uvcg_video_enable(video, 0); -+ } -+ -+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c -+index 5ce548c23..b15edc822 100644 -+--- a/drivers/usb/gadget/function/uvc_video.c -++++ b/drivers/usb/gadget/function/uvc_video.c -+@@ -9,19 +9,315 @@ -+ #include -+ #include -+ #include -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -+ #include -+ #include -+ #include -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -+ -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#include -++#endif -+ #include "uvc.h" -+ #include "uvc_queue.h" -+ #include "uvc_video.h" -+ -++#ifdef CONFIG_ARCH_BSP -++#include -++#include -++#include -++#endif -++ -++/*************************************************************/ -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++#define MAX_FRAME 1 -++static struct uvc_pack_trans g_uvc_pack; -++ -++/* the caller shoulud hold g_uvc_pack.lock */ -++static void clean_untrans_frame(bool need_clean_all) -++{ -++ struct uvc_pack_trans *p; -++ -++ int rem = MAX_FRAME; -++ if (need_clean_all == 1) -++ rem = 0; -++ -++ while ((g_uvc_pack.frame_cnts > rem) && !list_empty(&g_uvc_pack.list)) { -++ p = list_first_entry(&g_uvc_pack.list, struct uvc_pack_trans, list); -++ list_del(&p->list); -++ -++ if (p->need_free) -++ p->pack->callback_func(p->pack); -++ if (p->is_frame_end) -++ g_uvc_pack.frame_cnts--; -++ -++ kfree(p->pack); -++ kfree(p); -++ } -++} -++ -++/* the caller shoulud hold g_uvc_pack.lock */ -++static void pack_save_to_list(struct uvc_pack_trans *ptr, -++ struct uvc_pack *pack, bool is_frame_end, bool free) -++{ -++ ptr->pack = (struct uvc_pack *)kmalloc(sizeof(struct uvc_pack), GFP_KERNEL); -++ if (ptr->pack == NULL) -++ return; -++ if (memcpy_s(ptr->pack, sizeof(struct uvc_pack), pack, sizeof(struct uvc_pack)) != 0) { -++ kfree(ptr->pack); -++ ptr->pack = NULL; -++ return; -++ } -++ -++ ptr->is_frame_end = is_frame_end; -++ ptr->need_free = free; -++ ptr->buf_used = 0; -++ -++ list_add_tail(&ptr->list, &g_uvc_pack.list); -++ -++ if (is_frame_end) { -++ g_uvc_pack.frame_cnts++; -++ if (g_uvc_pack.frame_cnts > MAX_FRAME) { -++ clean_untrans_frame(0); -++ } -++ if (unlikely(g_uvc_pack.video->is_streaming == false)) { -++ clean_untrans_frame(1); -++ } -++ } -++} -++ -++int uvc_recv_pack(struct uvc_pack *pack) -++{ -++ struct uvc_pack_trans *p = NULL; -++ struct uvc_pack_trans *q = NULL; -++ uint64_t end_virt_addr; -++ unsigned long flags; -++ -++ if (g_uvc_pack.list.next == NULL || g_uvc_pack.list.prev == NULL) { -++ printk(KERN_EMERG"[Error][uvc_recv_pack] UVC video has not been initialized!"); -++ return -1; -++ } -++ -++ if (pack->buf_vir_addr == 0 || pack->pack_vir_addr == 0 || pack->pack_len == 0) { -++ printk(KERN_EMERG"[Error][uvc_recv_pack] Get NULL pointer addr or illegal length!"); -++ -++ goto cleanup; -++ } -++ -++ end_virt_addr = pack->buf_vir_addr + pack->buf_size; -++ -++ if ((pack->pack_vir_addr < pack->buf_vir_addr) || (pack->pack_vir_addr > end_virt_addr)) { -++ printk(KERN_EMERG"[Error][uvc_recv_pack] Get illegal pack_vir_addr!"); -++ -++ goto cleanup; -++ } -++ -++ p = (struct uvc_pack_trans *)kmalloc(sizeof(struct uvc_pack_trans), GFP_KERNEL); -++ if (p == NULL) { -++ printk("[Warning][uvc_recv_pack]Can not alloc uvc_pack_trans!"); -++ return -1; -++ } -++ spin_lock_irqsave(&g_uvc_pack.lock, flags); -++ if (pack->pack_vir_addr + pack->pack_len > end_virt_addr) { -++ p->len = end_virt_addr - pack->pack_vir_addr; -++ p->addr = pack->pack_vir_addr; -++ pack_save_to_list(p, pack, false, false); -++ -++ q = (struct uvc_pack_trans *)kmalloc(sizeof(struct uvc_pack_trans), GFP_KERNEL); -++ if (q == NULL) { -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++ printk("[Warning][uvc_recv_pack]Can not alloc uvc_pack_trans!"); -++ return -1; -++ } -++ q->len = pack->pack_len - (end_virt_addr - pack->pack_vir_addr); -++ q->addr = pack->buf_vir_addr; -++ pack_save_to_list(q, pack, pack->is_frame_end, true); -++ } else { -++ p->len = pack->pack_len; -++ p->addr = pack->pack_vir_addr; -++ pack_save_to_list(p, pack, pack->is_frame_end, true); -++ } -++ -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++ -++ return 0; -++ -++cleanup: -++ spin_lock_irqsave(&g_uvc_pack.lock, flags); -++ clean_untrans_frame(1); -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++ -++ if (pack->callback_func != NULL) -++ pack->callback_func(pack); -++ -++ return 0; -++} -++EXPORT_SYMBOL(uvc_recv_pack); -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -++ -+ /* -------------------------------------------------------------------------- -+ * Video codecs -+ */ -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++static int -++uvc_video_encode_header(struct uvc_video *video, struct uvc_pack_trans *pack, -++ u8 *data, int len) -++{ -++ data[0] = 2; -++ data[1] = UVC_STREAM_EOH | video->fid; -++ -++ if ((pack->len - pack->buf_used <= len - 2) && pack->is_frame_end) -++ data[1] |= UVC_STREAM_EOF; -++ -++ return 2; -++} -++ -++static int -++uvc_video_encode_data(struct uvc_video *video, struct uvc_pack_trans *pack, -++ u8 *data, int len) -++{ -++ unsigned int nbytes; -++ void *mem; -++ -++ /* Copy video data to the USB buffer. */ -++ mem = (void *)(uintptr_t)pack->addr + pack->buf_used; -++ nbytes = min((unsigned int)len, pack->len - pack->buf_used); -++ -++ if (memcpy_s(data, len, mem, nbytes) != 0) -++ return 0; -++ pack->buf_used += nbytes; -++ -++ return nbytes; -++} -++ -++static void -++uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video, -++ struct uvc_pack_trans *pack) -++{ -++ void *mem = req->buf; -++ int len = video->req_size; -++ int ret; -++ -++ /* Add a header at the beginning of the payload. */ -++ if (video->payload_size == 0) { -++ ret = uvc_video_encode_header(video, pack, mem, len); -++ video->payload_size += ret; -++ mem += ret; -++ len -= ret; -++ } -++ -++ /* Process video data. */ -++ len = min((int)(video->max_payload_size - video->payload_size), len); -++ ret = uvc_video_encode_data(video, pack, mem, len); -++ -++ video->payload_size += ret; -++ len -= ret; -++ -++ req->length = video->req_size - len; -++ req->zero = video->payload_size == video->max_payload_size; -++ -++ if (pack->len == pack->buf_used) { -++ pack->buf_used = 0; -++ video->fid ^= UVC_STREAM_FID; -++ -++ video->payload_size = 0; -++ } -++ -++ if (video->payload_size == video->max_payload_size || -++ pack->len == pack->buf_used) -++ video->payload_size = 0; -++} -++ -++/* the caller shoulud hold g_uvc_pack.lock */ -++static void -++uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, -++ struct uvc_pack_trans *g_pack) -++{ -++ int ret; -++ struct uvc_pack_trans *pack = NULL; -++#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++) { -++ if (unlikely(list_empty(&g_pack->list) || (g_pack->frame_cnts == 0))) -++ break; -++ -++ pack = list_first_entry(&g_pack->list, struct uvc_pack_trans, list); -++ -++ mem = sg_virt(&req->sg[sg_idx]); -++ len = video->req_size; -++ -++ /* Add the header. */ -++ ret = uvc_video_encode_header(video, pack, mem, len); -++ mem += ret; -++ len -= ret; -++ -++ /* Process video data. */ -++ ret = uvc_video_encode_data(video, pack, 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 (pack->len == pack->buf_used) { -++ pack->buf_used = 0; -++ -++ list_del(&pack->list); -++ if (pack->need_free) -++ pack->pack->callback_func(pack->pack); -++ -++ if (pack->is_frame_end) { -++ g_pack->frame_cnts--; -++ video->fid ^= UVC_STREAM_FID; -++ kfree(pack->pack); -++ kfree(pack); -++ break; -++ } -++ -++ kfree(pack->pack); -++ kfree(pack); -++ } -++ } -++ req->num_sgs = sg_idx + 1; -++ if (req->num_sgs > video->num_sgs) -++ req->num_sgs = video->num_sgs; -++ sg_mark_end(&req->sg[sg_idx]); -++ req->length = ttllen; -++#else /* UVC_SG_REQ */ -++ void *mem = req->buf; -++ int len = video->req_size; -++ -++ /* Add the header. */ -++ ret = uvc_video_encode_header(video, pack, mem, len); -++ mem += ret; -++ len -= ret; -++ -++ /* Process video data. */ -++ ret = uvc_video_encode_data(video, pack, mem, len); -++ len -= ret; -++ -++ req->length = video->req_size - len; -++ -++ if (pack->len == pack->buf_used) { -++ pack->buf_used = 0; -++ if (pack->is_frame_end) -++ video->fid ^= UVC_STREAM_FID; -++ } -++#endif /* UVC_SG_REQ */ -++} -++ -++#else /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -+ -+ static int -+ uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf, -+@@ -98,6 +394,43 @@ static void -+ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, -+ struct uvc_buffer *buf) -+ { -++ int ret; -++#if defined(CONFIG_ARCH_BSP) && defined(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 /* UVC_SG_REQ */ -+ void *mem = req->buf; -+ int len = video->req_size; -+ int ret; -+@@ -119,7 +452,9 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, -+ uvcg_queue_next_buffer(&video->queue, buf); -+ video->fid ^= UVC_STREAM_FID; -+ } -++#endif /* UVC_SG_REQ */ -+ } -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -+ -+ /* -------------------------------------------------------------------------- -+ * Request handling -+@@ -128,15 +463,34 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, -+ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req) -+ { -+ int ret; -++#ifdef CONFIG_ARCH_BSP -++ /* -++ * 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; -++#endif -+ -+ ret = usb_ep_queue(video->ep, req, GFP_ATOMIC); -+ if (ret < 0) { -+ uvcg_err(&video->uvc->func, "Failed to queue request (%d).\n", -+ ret); -+ -++#ifdef CONFIG_ARCH_BSP -++ /* If the endpoint is disabled the descriptor may be NULL. */ -++ if (video->ep->desc) { -++ /* Isochronous endpoints can't be halted. */ -++ if (usb_endpoint_xfer_bulk(video->ep->desc)) -++ usb_ep_set_halt(video->ep); -++ } -++#else -+ /* Isochronous endpoints can't be halted. */ -+ if (usb_endpoint_xfer_bulk(video->ep->desc)) -+ usb_ep_set_halt(video->ep); -++#endif -+ } -+ -+ return ret; -+@@ -146,7 +500,9 @@ static void -+ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) -+ { -+ struct uvc_video *video = req->context; -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ struct uvc_video_queue *queue = &video->queue; -++#endif -+ unsigned long flags; -+ -+ switch (req->status) { -+@@ -155,14 +511,18 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) -+ -+ case -ESHUTDOWN: /* disconnect from host. */ -+ uvcg_dbg(&video->uvc->func, "VS request cancelled.\n"); -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ uvcg_queue_cancel(queue, 1); -++#endif -+ break; -+ -+ default: -+ uvcg_warn(&video->uvc->func, -+ "VS request completed with status %d.\n", -+ req->status); -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ uvcg_queue_cancel(queue, 0); -++#endif -+ } -+ -+ spin_lock_irqsave(&video->req_lock, flags); -+@@ -176,9 +536,27 @@ static int -+ uvc_video_free_requests(struct uvc_video *video) -+ { -+ unsigned int i; -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ unsigned long flags; -++#endif -++#if defined(CONFIG_ARCH_BSP) && defined(UVC_SG_REQ) -++ unsigned int sg_idx; -++#endif -+ -+ for (i = 0; i < UVC_NUM_REQUESTS; ++i) { -+ if (video->req[i]) { -++#if defined(CONFIG_ARCH_BSP) && defined(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])); -++ video->req[i]->num_mapped_sgs = 0; -++ } -++ -++ 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; -+ } -+@@ -189,6 +567,14 @@ uvc_video_free_requests(struct uvc_video *video) -+ } -+ } -+ -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ spin_lock_irqsave(&g_uvc_pack.lock, flags); -++ clean_untrans_frame(1); -++ g_uvc_pack.video->is_streaming = false; -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++ -++#endif -++ -+ INIT_LIST_HEAD(&video->req_free); -+ video->req_size = 0; -+ return 0; -+@@ -200,6 +586,11 @@ uvc_video_alloc_requests(struct uvc_video *video) -+ unsigned int req_size; -+ unsigned int i; -+ int ret = -ENOMEM; -++#if defined(CONFIG_ARCH_BSP) && defined(UVC_SG_REQ) -++ struct scatterlist *sg; -++ unsigned int num_sgs; -++ unsigned int sg_idx; -++#endif -+ -+ BUG_ON(video->req_size); -+ -+@@ -207,6 +598,35 @@ uvc_video_alloc_requests(struct uvc_video *video) -+ * max_t(unsigned int, video->ep->maxburst, 1) -+ * (video->ep->mult); -+ -++#if defined(CONFIG_ARCH_BSP) && defined(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) -+@@ -223,7 +643,7 @@ uvc_video_alloc_requests(struct uvc_video *video) -+ -+ list_add_tail(&video->req[i]->list, &video->req_free); -+ } -+- -++#endif -+ video->req_size = req_size; -+ -+ return 0; -+@@ -243,9 +663,69 @@ uvc_video_alloc_requests(struct uvc_video *video) -+ * This function fills the available USB requests (listed in req_free) with -+ * video data from the queued buffers. -+ */ -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -+ static void uvcg_video_pump(struct work_struct *work) -+ { -+ struct uvc_video *video = container_of(work, struct uvc_video, pump); -++ struct usb_request *req; -++ unsigned long flags; -++ int ret; -++ -++ if (g_uvc_pack.video->is_streaming == false) -++ return; -++ -++ while (1) { -++ /* Retrieve the first available USB request, protected by the -++ * request lock. -++ */ -++ spin_lock_irqsave(&video->req_lock, flags); -++ if (list_empty(&video->req_free)) { -++ spin_unlock_irqrestore(&video->req_lock, flags); -++ return; -++ } -++ req = list_first_entry(&video->req_free, struct usb_request, -++ list); -++ list_del(&req->list); -++ spin_unlock_irqrestore(&video->req_lock, flags); -++ -++ /* Retrieve the first available video buffer and fill the -++ * request, protected by the video queue irqlock. -++ */ -++ spin_lock_irqsave(&g_uvc_pack.lock, flags); -++ if (list_empty(&g_uvc_pack.list) || (g_uvc_pack.frame_cnts == 0)) { -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++ break; -++ } -++ -++#ifdef UVC_SG_REQ -++ sg_unmark_end(&req->sg[req->num_sgs - 1]); -++#endif -++ -++ video->encode(req, video, &g_uvc_pack); -++ -++ /* Queue the USB request */ -++ ret = uvcg_video_ep_queue(video, req); -++ if (ret < 0) { -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++ break; -++ } -++ -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++ } -++ -++ 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); -++ return; -++} -++#else /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -++static void uvcg_video_pump(struct work_struct *work) -++{ -++ struct uvc_video *video = container_of(work, struct uvc_video, pump); -++ -+ struct uvc_video_queue *queue = &video->queue; -+ struct usb_request *req; -+ struct uvc_buffer *buf; -+@@ -276,6 +756,10 @@ static void uvcg_video_pump(struct work_struct *work) -+ break; -+ } -+ -++#if defined(CONFIG_ARCH_BSP) && defined(UVC_SG_REQ) -++ sg_unmark_end(&req->sg[req->num_sgs - 1]); -++#endif -++ -+ video->encode(req, video, buf); -+ -+ /* Queue the USB request */ -+@@ -289,10 +773,14 @@ static void uvcg_video_pump(struct work_struct *work) -+ } -+ -+ spin_lock_irqsave(&video->req_lock, flags); -++#if defined(CONFIG_ARCH_BSP) && defined(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); -+ return; -+ } -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -+ -+ /* -+ * Enable or disable the video stream. -+@@ -301,6 +789,13 @@ int uvcg_video_enable(struct uvc_video *video, int enable) -+ { -+ unsigned int i; -+ int ret; -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ unsigned long flags; -++#endif -++ -++#ifdef CONFIG_ARCH_BSP -++ iprec("[%s] %d", __func__, enable); -++#endif -+ -+ if (video->ep == NULL) { -+ uvcg_info(&video->uvc->func, -+@@ -317,12 +812,16 @@ int uvcg_video_enable(struct uvc_video *video, int enable) -+ usb_ep_dequeue(video->ep, video->req[i]); -+ -+ uvc_video_free_requests(video); -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ uvcg_queue_enable(&video->queue, 0); -++#endif -+ return 0; -+ } -+ -++#if defined(CONFIG_ARCH_BSP) && !(IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC)) -+ if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0) -+ return ret; -++#endif -+ -+ if ((ret = uvc_video_alloc_requests(video)) < 0) -+ return ret; -+@@ -333,6 +832,12 @@ int uvcg_video_enable(struct uvc_video *video, int enable) -+ } else -+ video->encode = uvc_video_encode_isoc; -+ -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ spin_lock_irqsave(&g_uvc_pack.lock, flags); -++ g_uvc_pack.video->is_streaming = true; -++ spin_unlock_irqrestore(&g_uvc_pack.lock, flags); -++#endif -++ -+ schedule_work(&video->pump); -+ -+ return ret; -+@@ -343,6 +848,13 @@ int uvcg_video_enable(struct uvc_video *video, int enable) -+ */ -+ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc) -+ { -++#if defined(CONFIG_ARCH_BSP) && IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++ INIT_LIST_HEAD(&g_uvc_pack.list); -++ spin_lock_init(&g_uvc_pack.lock); -++ g_uvc_pack.frame_cnts = 0; -++ video->is_streaming = false; -++ g_uvc_pack.video = video; -++#endif -+ INIT_LIST_HEAD(&video->req_free); -+ spin_lock_init(&video->req_lock); -+ INIT_WORK(&video->pump, uvcg_video_pump); -+diff --git a/drivers/vdmav100/Kconfig b/drivers/vdmav100/Kconfig -+new file mode 100755 -+index 000000000..5756a0004 -+--- /dev/null -++++ b/drivers/vdmav100/Kconfig -+@@ -0,0 +1,30 @@ -++if ARCH_BSP -++ -++menuconfig VDMA_V100 -++ tristate "Vendor VDMA Controller V100" -++ depends on ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100 -++ default n if ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100 -++ help -++ This is the driver for Vendor VDMA controoller -++ IP. -++ -++if VDMA_V100 -++ -++config VDMA_CHN_NUM -++ int "VDMAV100 max channel number" -++ default 32 -++ -++config VDMA_TRANSFER_THRESHOLD -++ int "VDMA data transfer threshold KBytes" -++ range 4 16384 -++ default "128" if (ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100) -++ -++config VDMA_MISC_DEV -++ bool "VDMAV100 misc dev" -++ default y if (ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100) -++ depends on VDMA_V100 -++ -++ -++endif -++ -++endif # ARCH_BSP -+diff --git a/drivers/vdmav100/Makefile b/drivers/vdmav100/Makefile -+new file mode 100755 -+index 000000000..7d3392900 -+--- /dev/null -++++ b/drivers/vdmav100/Makefile -+@@ -0,0 +1,4 @@ -++ifdef CONFIG_ARCH_BSP -++obj-$(CONFIG_VDMA_V100) += vdmav100.o -++obj-$(CONFIG_VDMA_MISC_DEV) += vdmav100_misc.o -++endif -+diff --git a/drivers/vdmav100/vdma.h b/drivers/vdmav100/vdma.h -+new file mode 100755 -+index 000000000..f4db0184c -+--- /dev/null -++++ b/drivers/vdmav100/vdma.h -+@@ -0,0 +1,28 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __VDMA_USER_H__ -++#define __VDMA_USER_H__ -++ -++struct vdmac_host { -++ struct device *dev; -++ struct clk *clk; -++ struct reset_control *rstc; -++ void __iomem *regbase; -++ -++ int irq; -++}; -++ -++#define VDMA_DATA_CMD 0x6 -++ -++struct dmac_user_para { -++ uintptr_t src; -++ uintptr_t dst; -++ unsigned int size; -++}; -++ -++extern int vdma_m2m_copy(void *dst, const void *src, size_t count); -++ -++ -++#endif -+diff --git a/drivers/vdmav100/vdmav100.c b/drivers/vdmav100/vdmav100.c -+new file mode 100755 -+index 000000000..c7d5be63c -+--- /dev/null -++++ b/drivers/vdmav100/vdmav100.c -+@@ -0,0 +1,444 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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 -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "vdmav100.h" -++#include "vdma.h" -++ -++#define user_addr(ptr) (((uintptr_t)(ptr) < TASK_SIZE) \ -++ && ((uintptr_t)(ptr) > 0)) -++ -++int vdma_flag = 0; -++EXPORT_SYMBOL(vdma_flag); -++ -++void __iomem *reg_vdma_base_va; -++ -++spinlock_t my_lock; -++spinlock_t reg_lock; -++ -++unsigned int irq_flag; -++ -++unsigned int wake_channel_flag[DMAC_MAX_CHANNELS]; -++ -++wait_queue_head_t dmac_wait_queue[DMAC_MAX_CHANNELS]; -++ -++int g_channel_status[DMAC_MAX_CHANNELS]; -++ -++/* -++ * allocate channel. -++ */ -++int vdma_channel_allocate(const void *pisr) -++{ -++ unsigned int i, channelinfo, tmp, channel_intr; -++ unsigned long flags; -++ -++ spin_lock_irqsave(&my_lock, flags); -++ -++ if (reg_vdma_base_va == NULL) -++ return 0; -++ dmac_readw(reg_vdma_base_va + DMAC_CHANNEL_STATUS, channelinfo); -++ -++ for (i = 0; i < CHANNEL_NUM; i++) { -++ if (g_channel_status[i] == DMAC_CHN_VACANCY) { -++ dmac_readw(reg_vdma_base_va + dmac_cxintr_raw(i), -++ channel_intr); -++ tmp = channelinfo >> i; -++ /* check the vdma channel data transfer is finished ? */ -++ if (((tmp & 0x01) == 0x00) && (channel_intr == 0x00)) { -++ g_channel_status[i] = DMAC_CHN_ALLOCAT; -++ spin_unlock_irqrestore(&my_lock, flags); -++ return i; /* return channel number */ -++ } -++ } -++ } -++ -++ spin_unlock_irqrestore(&my_lock, flags); -++ return DMAC_CHANNEL_INVALID; -++} -++ -++/* -++ * free channel -++ */ -++int vdma_channel_free(unsigned int channel) -++{ -++ g_channel_status[channel] = DMAC_CHN_VACANCY; -++ -++ return 0; -++} -++ -++/* -++ * channel enable -++ * start a vdma transfer immediately -++ */ -++int vdma_channelstart(unsigned int channel, -++ const unsigned int *src, const unsigned int *dest) -++{ -++ struct mm_struct *mm = NULL; -++ unsigned int reg[DMAC_MAX_CHANNELS]; -++ -++ if (channel >= DMAC_MAX_CHANNELS) { -++ pr_err("channel number is out of scope<%d>.\n", -++ DMAC_MAX_CHANNELS); -++ return -EINVAL; -++ } -++ -++ g_channel_status[channel] = DMAC_NOT_FINISHED; -++ -++ mm = current->mm; -++ if (!mm) -++ mm = &init_mm; -++ -++ if (mm->pgd == NULL) -++ return -EINVAL; -++ /* set ttbr */ -++ /* get TTBR from the page */ -++ reg[channel] = __pa(mm->pgd); -++ -++ /* only [31:10] is the ttbr */ -++ reg[channel] &= 0xfffffc00; -++ -++ /* set the RGN,AFE,AFFD,TRE */ -++ reg[channel] |= TTB_RGN | AFE | TRE; -++ -++ if (user_addr(dest)) -++ reg[channel] &= ~DEST_IS_KERNEL; -++ else -++ reg[channel] |= DEST_IS_KERNEL; -++ -++ if (user_addr(src)) -++ reg[channel] &= ~SRC_IS_KERNEL; -++ else -++ reg[channel] |= SRC_IS_KERNEL; -++ -++ if (in_atomic() || in_interrupt()) { -++ /* disable the channel interrupt */ -++ reg[channel] &= ~DMAC_INTR_ENABLE; -++ } else { -++ /* enable the channel interrupt */ -++ reg[channel] |= DMAC_INTR_ENABLE; -++ } -++ -++ reg[channel] |= DMAC_CHANNEL_ENABLE; -++ -++ if (reg_vdma_base_va == NULL) -++ return 0; -++ /* set the TTBR register */ -++ dmac_writew(reg_vdma_base_va + dmac_cxttbr(channel), -++ reg[channel]); -++ return 0; -++} -++ -++/* -++ * Apply VDMA interrupt resource -++ * init channel state -++ */ -++int vdma_driver_init(const struct vdmac_host *dma) -++{ -++ unsigned int i; -++ unsigned int tmp_reg = 0; -++ -++ if (reg_vdma_base_va == NULL) -++ return 0; -++ dmac_readw(reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg); -++ tmp_reg |= AUTO_CLK_GT_EN; -++ dmac_writew(reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg); -++ -++ /* set rd dust address is ram 0 */ -++ dmac_writew(reg_vdma_base_va + DMAC_RD_DUSTB_ADDR, 0x04c11000); -++ -++ /* set wr dust address is ram 0x1000 */ -++ dmac_writew(reg_vdma_base_va + DMAC_WR_DUSTB_ADDR, 0x04c11000); -++ -++ /* set prrr register */ -++ dmac_writew(reg_vdma_base_va + DMAC_MMU_PRRR, PRRR); -++ /* set nmrr register */ -++ dmac_writew(reg_vdma_base_va + DMAC_MMU_NMRR, NMRR); -++ -++ /* config global reg for VDMA */ -++ tmp_reg |= EVENT_BROADCAST_EN | WR_CMD_NUM_PER_ARB | -++ RD_CMD_NUM_PER_ARB | WR_OTD_NUM | RD_OTD_NUM | WFE_EN; -++ dmac_writew(reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg); -++ -++ for (i = 0; i < CHANNEL_NUM; i++) { -++ g_channel_status[i] = DMAC_CHN_VACANCY; -++ init_waitqueue_head(&dmac_wait_queue[i]); -++ } -++ -++ spin_lock_init(&my_lock); -++ spin_lock_init(®_lock); -++ -++ return 0; -++} -++ -++/* -++ * wait for transfer end -++ */ -++int vdma_wait(unsigned int channel) -++{ -++ unsigned long data_jiffies_timeout = jiffies + DMA_TIMEOUT_HZ; -++ -++ while (1) { -++ unsigned int channel_intr_raw; -++ if (reg_vdma_base_va == NULL) -++ return 0; -++ /* read the status of current interrupt */ -++ dmac_readw(reg_vdma_base_va + dmac_cxintr_raw(channel), -++ channel_intr_raw); -++ -++ /* clear the interrupt */ -++ dmac_writew(reg_vdma_base_va -++ + dmac_cxintr_raw(channel), -++ channel_intr_raw); -++ -++ if (channel >= DMAC_MAX_CHANNELS) -++ return 0; -++ /* save the current channel transfer status to * -++ * g_channel_status[i] */ -++ if ((channel_intr_raw & CX_INT_STAT) == CX_INT_STAT) { -++ /* transfer finish interrupt */ -++ if ((channel_intr_raw & CX_INT_TC_RAW) == -++ CX_INT_TC_RAW) { -++ g_channel_status[channel] = DMAC_CHN_SUCCESS; -++ return DMAC_CHN_SUCCESS; -++ } -++ -++ /* transfer abort interrupt */ -++ pr_debug("data transfer error in VDMA %x channel!", -++ channel); -++ pr_debug("intr_raw=%x\n", channel_intr_raw); -++ g_channel_status[channel] = -++ -DMAC_CHN_CONFIG_ERROR; -++ return -DMAC_CHN_CONFIG_ERROR; -++ } -++ -++ if (!time_before(jiffies, data_jiffies_timeout)) { /* timeout */ -++ pr_err("wait interrupt timeout, channel=%d, func:%s, line:%d\n", -++ channel, __func__, __LINE__); -++ return -1; -++ } -++ } -++ -++ return -1; -++} -++ -++/* -++ * execute memory to memory vdma transfer -++ */ -++static int vdma_m2m_transfer(const unsigned int *psource, -++ const unsigned int *pdest, -++ unsigned int uwtransfersize) -++{ -++ unsigned int ulchnn; -++ int ret = 0; -++ -++ ulchnn = (unsigned int)vdma_channel_allocate(NULL); -++ if (ulchnn == DMAC_CHANNEL_INVALID) { -++ pr_err("DMAC_CHANNEL_INVALID.\n"); -++ -++ return -1; -++ } -++ -++ wake_channel_flag[ulchnn] = 0; -++ -++ dmac_writew(reg_vdma_base_va + dmac_cxlength(ulchnn), -++ uwtransfersize); -++ dmac_writew(reg_vdma_base_va + dmac_cxsrcaddr(ulchnn), -++ (uintptr_t)psource); -++ dmac_writew(reg_vdma_base_va + dmac_cxdestaddr(ulchnn), -++ (uintptr_t)pdest); -++ -++ if (vdma_channelstart(ulchnn, psource, pdest) != 0) { -++ ret = -1; -++ goto exit; -++ } -++ -++ if (vdma_wait(ulchnn) != DMAC_CHN_SUCCESS) { -++ ret = -1; -++ goto exit; -++ } -++ -++exit: -++ vdma_channel_free(ulchnn); -++ -++ return ret; -++} -++EXPORT_SYMBOL(vdma_m2m_transfer); -++ -++int vdma_m2m_copy(void *dst, const void *src, size_t count) -++{ -++ int ret; -++ -++ if (((uintptr_t)dst & 0xff) || ((uintptr_t)src & 0xff)) -++ return -1; -++ -++ if (((uintptr_t)src < (uintptr_t)dst) && -++ (((uintptr_t)src + count) > (uintptr_t)dst)) -++ return -1; -++ -++ if (((uintptr_t)src >= (uintptr_t)dst) && -++ ((uintptr_t)src < ((uintptr_t)dst + count))) -++ return -1; -++ -++ if (abs((uintptr_t)dst - (uintptr_t)src) < PAGE_SIZE) -++ return -1; -++ -++ ret = vdma_m2m_transfer((unsigned int *)src, dst, count); -++ if (ret < 0) -++ return ret; -++ else -++ return 0; -++} -++EXPORT_SYMBOL(vdma_m2m_copy); -++ -++static int vdmac_probe(struct platform_device *platdev) -++{ -++ unsigned int i; -++ struct vdmac_host *dma = NULL; -++ struct resource *res = NULL; -++ int ret; -++ dma = devm_kzalloc(&platdev->dev, sizeof(*dma), GFP_KERNEL); -++ if (!dma) -++ return -ENOMEM; -++ -++ res = platform_get_resource(platdev, IORESOURCE_MEM, 0); -++ if (!res) { -++ dev_err(&platdev->dev, "no mmio resource\n"); -++ return -ENODEV; -++ } -++ -++ dma->regbase = devm_ioremap_resource(&platdev->dev, res); -++ if (IS_ERR(dma->regbase)) -++ return PTR_ERR(dma->regbase); -++ -++ dma->clk = devm_clk_get(&platdev->dev, NULL); -++ if (IS_ERR(dma->clk)) -++ return PTR_ERR(dma->clk); -++ -++ clk_prepare_enable(dma->clk); -++ -++ dma->rstc = devm_reset_control_get(&platdev->dev, "dma-reset"); -++ if (IS_ERR(dma->rstc)) -++ return PTR_ERR(dma->rstc); -++ -++ dma->irq = platform_get_irq(platdev, 0); -++ if (unlikely(dma->irq < 0)) -++ return -ENODEV; -++ -++ reg_vdma_base_va = dma->regbase; -++ pr_debug("vdma reg base is %p\n", reg_vdma_base_va); -++ dma->dev = &platdev->dev; -++ -++ ret = vdma_driver_init(dma); -++ if (ret) -++ return -ENODEV; -++ -++ platform_set_drvdata(platdev, dma); -++ -++ for (i = 0; i < CONFIG_VDMA_CHN_NUM; i++) -++ g_channel_status[i] = DMAC_CHN_VACANCY; -++ -++ vdma_flag = 1; -++ printk("vdmav100 driver inited.\n"); -++ return ret; -++} -++ -++static int vdmac_remove(struct platform_device *platdev) -++{ -++ int i; -++ struct vdmac_host *dma = platform_get_drvdata(platdev); -++ -++ clk_disable_unprepare(dma->clk); -++ -++ for (i = 0; i < CONFIG_VDMA_CHN_NUM; i++) -++ g_channel_status[i] = DMAC_CHN_VACANCY; -++ -++ vdma_flag = 0; -++ printk("vdmav100 driver deinited.\n"); -++ -++ return 0; -++} -++ -++static int vdmac_suspend(struct platform_device *platdev, -++ pm_message_t state) -++{ -++ int i; -++ struct vdmac_host *dma = platform_get_drvdata(platdev); -++ -++ clk_prepare_enable(dma->clk); -++ -++ for (i = 0; i < CONFIG_VDMA_CHN_NUM; i++) -++ g_channel_status[i] = DMAC_CHN_VACANCY; -++ -++ clk_disable_unprepare(dma->clk); -++ -++ vdma_flag = 0; -++ -++ return 0; -++} -++ -++static int vdmac_resume(struct platform_device *platdev) -++{ -++ int i; -++ struct vdmac_host *dma = platform_get_drvdata(platdev); -++ -++ vdma_driver_init(dma); -++ -++ for (i = 0; i < CONFIG_VDMA_CHN_NUM; i++) -++ g_channel_status[i] = DMAC_CHN_VACANCY; -++ -++ vdma_flag = 1; -++ -++ return 0; -++} -++ -++static const struct of_device_id vdmac_dt_ids[] = { -++ {.compatible = "vendor,vdmac"}, -++ { }, -++}; -++MODULE_DEVICE_TABLE(of, vdmac_dt_ids); -++ -++static struct platform_driver vdmac_driver = { -++ .driver = { -++ .name = "vdma", -++ .of_match_table = vdmac_dt_ids, -++ }, -++ .probe = vdmac_probe, -++ .remove = vdmac_remove, -++ .suspend = vdmac_suspend, -++ .resume = vdmac_resume, -++}; -++ -++module_platform_driver(vdmac_driver); -++ -++MODULE_LICENSE("GPL"); -+diff --git a/drivers/vdmav100/vdmav100.h b/drivers/vdmav100/vdmav100.h -+new file mode 100755 -+index 000000000..1b5ab4ee2 -+--- /dev/null -++++ b/drivers/vdmav100/vdmav100.h -+@@ -0,0 +1,114 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#ifndef __VDMA_H__ -++#define __VDMA_H__ -++ -++#define dmac_writew(addr, value) \ -++ ((*(volatile unsigned int *)(addr)) = (value)) -++ -++#define dmac_readw(addr, v) \ -++ ((v) = (*(volatile unsigned int *)(addr))) -++ -++/**************************************************** -++ *for vdma -++ ****************************************************/ -++/*global control register define*/ -++#define DMAC_GLOBLE_CTRL 0x000 -++#define WFE_EN (0x1 << 23) -++#define EVENT_BROADCAST_EN (0x1 << 21) -++#define AUTO_CLK_GT_EN (0x1 << 17) -++#define AUTO_PRI_EN (0x1 << 16) -++#define WR_CMD_NUM_PER_ARB (0x4 << 12) -++#define RD_CMD_NUM_PER_ARB (0x4 << 8) -++#define WR_OTD_NUM (0xF << 4) -++#define RD_OTD_NUM (0xF) -++ -++#define DMAC_PRI_THRESHOLD 0x004 -++/*PRRR and NMRR define*/ -++#define DMAC_MMU_NMRR 0x008 -++#define DMAC_MMU_PRRR 0x00C -++/*read and write dustb address register define*/ -++#define DMAC_RD_DUSTB_ADDR 0x010 -++#define DMAC_WR_DUSTB_ADDR 0x014 -++/*channel status register define*/ -++#define DMAC_CHANNEL_STATUS 0x01c -++#define DMAC_WORK_DURATION 0x020 -++#define DMAC_INT_STATUS 0x02c -++/*the definition for DMAC channel register*/ -++#define DMAC_CHANNEL_BASE 0x100 -++#define dmac_cxsrcaddr(i) (DMAC_CHANNEL_BASE + 0x00 + 0x20 * (i)) -++#define dmac_cxdestaddr(i) (DMAC_CHANNEL_BASE + 0x04 + 0x20 * (i)) -++#define dmac_cxlength(i) (DMAC_CHANNEL_BASE + 0x08 + 0x20 * (i)) -++#define dmac_cxttbr(i) (DMAC_CHANNEL_BASE + 0x0C + 0x20 * (i)) -++#define dmac_cxmisc(i) (DMAC_CHANNEL_BASE + 0x10 + 0x20 * (i)) -++#define dmac_cxintr_raw(i) (DMAC_CHANNEL_BASE + 0x14 + 0x20 * (i)) -++#define CX_INT_STAT (0x1 << 4) -++#define CX_INT_TC_RAW (0x1 << 3) -++#define CX_INT_TE_RAW (0x1 << 2) -++#define CX_INT_TM_RAW (0x1 << 1) -++#define CX_INT_AP_RAW (0x1 << 0) -++ -++#define DMAC_INTR_ENABLE (0x1 << 8) -++ -++/* channel enable */ -++#define DMAC_CHANNEL_ENABLE (0x1 << 9) -++ -++/* access flag enable */ -++#define AFE (0x1 << 6) -++ -++/*user and kernel define*/ -++#define DEST_IS_KERNEL (0x1 << 2) -++#define SRC_IS_KERNEL (0x1 << 1) -++ -++/*for TTBR*/ -++#define TTB_RGN (0x1 << 3) /*outer cache write back allocate*/ -++ -++ -++/*for ap and cache remap*/ -++ -++/*remap enable,ap access check enable*/ -++#define TRE 0x001 -++ -++#define PRRR 0xff0a81a8 -++#define NMRR 0x40e040e0 -++ -++#define DMAC_SYNC_VAL 0x0 -++ -++/*definition for the return value*/ -++#define DMAC_ERROR_BASE 100 -++#define DMAC_CHANNEL_INVALID (DMAC_ERROR_BASE + 1) -++ -++#define DMAC_TRXFERSIZE_INVALID (DMAC_ERROR_BASE + 2) -++#define DMAC_SOURCE_ADDRESS_INVALID (DMAC_ERROR_BASE + 3) -++#define DMAC_DESTINATION_ADDRESS_INVALID (DMAC_ERROR_BASE + 4) -++#define DMAC_MEMORY_ADDRESS_INVALID (DMAC_ERROR_BASE + 5) -++#define DMAC_PERIPHERAL_ID_INVALID (DMAC_ERROR_BASE + 6) -++#define DMAC_DIRECTION_ERROR (DMAC_ERROR_BASE + 7) -++#define DMAC_TRXFER_ERROR (DMAC_ERROR_BASE + 8) -++#define DMAC_LLIHEAD_ERROR (DMAC_ERROR_BASE + 9) -++#define DMAC_SWIDTH_ERROR (DMAC_ERROR_BASE + 0xa) -++#define DMAC_LLI_ADDRESS_INVALID (DMAC_ERROR_BASE + 0xb) -++#define DMAC_TRANS_CONTROL_INVALID (DMAC_ERROR_BASE + 0xc) -++#define DMAC_MEMORY_ALLOCATE_ERROR (DMAC_ERROR_BASE + 0xd) -++#define DMAC_NOT_FINISHED (DMAC_ERROR_BASE + 0xe) -++ -++#define DMAC_TIMEOUT (DMAC_ERROR_BASE + 0xf) -++#define DMAC_CHN_SUCCESS (DMAC_ERROR_BASE + 0x10) -++#define DMAC_CHN_CONFIG_ERROR (DMAC_ERROR_BASE + 0x11) -++#define DMAC_CHN_DATA_ERROR (DMAC_ERROR_BASE + 0x12) -++#define DMAC_CHN_TIMEOUT (DMAC_ERROR_BASE + 0x13) -++#define DMAC_CHN_ALLOCAT (DMAC_ERROR_BASE + 0x14) -++#define DMAC_CHN_VACANCY (DMAC_ERROR_BASE + 0x15) -++ -++#define DMAC_MAX_CHANNELS CONFIG_VDMA_CHN_NUM -++ -++#define CHANNEL_NUM DMAC_MAX_CHANNELS -++ -++#define DMA_TRANS_OK 0x1 -++#define DMA_PAGE_FAULT 0x2 -++#define DMA_TRANS_FAULT 0x3 -++#define DMA_TIMEOUT_HZ (3 * HZ) -++ -++extern int g_channel_status[DMAC_MAX_CHANNELS]; -++#endif -+diff --git a/drivers/vdmav100/vdmav100_misc.c b/drivers/vdmav100/vdmav100_misc.c -+new file mode 100755 -+index 000000000..f7f7e9d80 -+--- /dev/null -++++ b/drivers/vdmav100/vdmav100_misc.c -+@@ -0,0 +1,94 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "vdma.h" -++ -++#define hidmac_error(s...) do { \ -++ pr_err("hidmac:%s:%d: ", __func__, __LINE__); \ -++ printk(s); \ -++ printk("\n"); \ -++} while (0) -++ -++static long vdma_ioctl(struct file *filep, unsigned int cmd, -++ unsigned long arg) -++{ -++ long ret; -++ struct dmac_user_para para; -++ -++ if (copy_from_user((void *)¶, (void *)(uintptr_t)arg, sizeof(para))) -++ return -EINVAL; -++ -++ switch (cmd) { -++ case VDMA_DATA_CMD: -++ ret = vdma_m2m_copy((void *)para.dst, (void *)para.src, para.size); -++ break; -++ default: -++ hidmac_error("unknown command :%x\n", cmd); -++ ret = -1; -++ break; -++ } -++ -++ return ret; -++} -++ -++static int vdma_open(struct inode *inode, struct file *file) -++{ -++ return 0; -++} -++ -++static int vdma_release(struct inode *inode, struct file *file) -++{ -++ return 0; -++} -++ -++static const struct file_operations vdma_fops = { -++ .owner = THIS_MODULE, -++ .unlocked_ioctl = vdma_ioctl, -++ .open = vdma_open, -++ .release = vdma_release, -++}; -++ -++static struct miscdevice vdma_misc_device = { -++ .minor = MISC_DYNAMIC_MINOR, -++ .name = "vdma", -++ .fops = &vdma_fops, -++}; -++ -++static int __init vdma_init(void) -++{ -++ int ret; -++ -++ ret = misc_register(&vdma_misc_device); -++ -++ return ret; -++} -++ -++static void __exit vdma_exit(void) -++{ -++ misc_deregister(&vdma_misc_device); -++} -++ -++module_init(vdma_init); -++module_exit(vdma_exit); -++MODULE_LICENSE("GPL"); -++MODULE_DESCRIPTION("Vendor VDMA MISC Driver"); -+diff --git a/drivers/vendor/Kconfig b/drivers/vendor/Kconfig -+new file mode 100755 -+index 000000000..40607fc00 -+--- /dev/null -++++ b/drivers/vendor/Kconfig -+@@ -0,0 +1,9 @@ -++menu "Vendor driver support" -++ -++source "drivers/vendor/cma/Kconfig" -++source "drivers/vendor/usb/Kconfig" -++source "drivers/vendor/ups_phy/Kconfig" -++source "drivers/vendor/basedrv_clk/Kconfig" -++source "drivers/vendor/mmc/Kconfig" -++ -++endmenu -+diff --git a/drivers/vendor/Makefile b/drivers/vendor/Makefile -+new file mode 100755 -+index 000000000..b743891e7 -+--- /dev/null -++++ b/drivers/vendor/Makefile -+@@ -0,0 +1,5 @@ -++obj-$(CONFIG_CMA) += cma/ -++obj-$(CONFIG_USB_WING) += usb/ -++obj-$(CONFIG_WING_UPS_PHY) += ups_phy/ -++obj-$(CONFIG_BASEDRV_CLK) += basedrv_clk/ -++obj-$(CONFIG_MMC) += mmc/ -+diff --git a/drivers/vendor/basedrv_clk/Kconfig b/drivers/vendor/basedrv_clk/Kconfig -+new file mode 100755 -+index 000000000..7fbbbbc69 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/Kconfig -+@@ -0,0 +1,3 @@ -++config BASEDRV_CLK -++ bool "Basedrv IP Clock" -++ default y -+diff --git a/drivers/vendor/basedrv_clk/Makefile b/drivers/vendor/basedrv_clk/Makefile -+new file mode 100755 -+index 000000000..51b0bb726 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/Makefile -+@@ -0,0 +1,7 @@ -++KBUILD_CFLAGS += -Werror -++ -++obj-$(CONFIG_ARCH_HI3519DV500_FAMILY) += hi3519dv500/ -++obj-$(CONFIG_ARCH_HI3516CV610_FAMILY) += hi3516cv610/ -++ -++obj-$(CONFIG_BASEDRV_CLK) += basedrv-clk.o -++basedrv-clk-y += basedrv_clk.o -+diff --git a/drivers/vendor/basedrv_clk/basedrv-clock.h b/drivers/vendor/basedrv_clk/basedrv-clock.h -+new file mode 100755 -+index 000000000..c9c265717 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/basedrv-clock.h -+@@ -0,0 +1,17 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __DT_BINDINGS_UPS_CLOCK_H -++#define __DT_BINDINGS_UPS_CLOCK_H -++ -++#define PERI_CRG3664_USB30_CTRL0 0x0000 -++#define PERI_CRG3672_USB30_CTRL1 0x0004 -++#define PERI_CRG3632_USB2_PHY0 0x0008 -++#define PERI_CRG3640_USB2_PHY1 0x000C -++#define PERI_CRG3665_COMBPHY0_CLK 0x0010 -++#define PERI_CRG3673_COMBPHY1_CLK 0x0014 -++ -++#define CLK_MAX 0x0800 -++ -++#endif /* __DT_BINDINGS_UPS_CLOCK_H */ -+diff --git a/drivers/vendor/basedrv_clk/basedrv_clk.c b/drivers/vendor/basedrv_clk/basedrv_clk.c -+new file mode 100755 -+index 000000000..e6d2de4fe -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/basedrv_clk.c -+@@ -0,0 +1,338 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "basedrv-clk" -++#define pr_fmt(fmt) DRVNAME ": " fmt -++ -++#include -++#include -++#include -++#include -++ -++#include "basedrv_clk.h" -++ -++static void ins_clk_enable(struct basedrv_clk_hw *clk) -++{ -++ if (clk->value) { -++ u32 val = readl(clk->peri_crgx); -++ val &= ~clk->mask; -++ val |= clk->value; -++ writel(val, clk->peri_crgx); -++ -++ val = readl(clk->peri_crgx); -++ if ((val & clk->mask) != clk->value) { -++ pr_warn("enable '%s' clock fail: want:%#x, real:%#x\n", -++ clk->name, clk->value, val); -++ } -++ } -++ -++ clk->flags |= CLKHW_ENABLE; -++} -++ -++static void ins_clk_disable(struct basedrv_clk_hw *clk) -++{ -++ if (clk->mask) { -++ u32 val = readl(clk->peri_crgx); -++ val &= ~clk->mask; -++ writel(val, clk->peri_crgx); -++ } -++ -++ clk->flags &= ~CLKHW_ENABLE; -++} -++ -++static void ins_clk_reset(struct basedrv_clk_hw *clk) -++{ -++ if (clk->rstbit) { -++ u32 val = readl(clk->peri_crgx); -++ val |= clk->rstbit; -++ writel(val, clk->peri_crgx); -++ } -++ -++ clk->flags |= CLKHW_RESET; -++} -++ -++static void ins_clk_unreset(struct basedrv_clk_hw *clk) -++{ -++ if (clk->rstbit) { -++ u32 val = readl(clk->peri_crgx); -++ val &= ~clk->rstbit; -++ writel(val, clk->peri_crgx); -++ } -++ -++ clk->flags &= ~CLKHW_RESET; -++} -++ -++int basedrv_clk_enable(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = NULL; -++ -++ if (hw == NULL) -++ return -1; -++ -++ clk = to_basedrv_clk_hw(hw); -++ -++ ins_clk_enable(clk); -++ -++ if (clk->flags & CLKHW_RESET) { -++ ins_clk_unreset(clk); -++ } -++ -++ return 0; -++} -++ -++void basedrv_clk_disable(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = NULL; -++ -++ if (hw == NULL) -++ return; -++ -++ clk = to_basedrv_clk_hw(hw); -++ -++ ins_clk_disable(clk); -++} -++ -++unsigned long basedrv_clk_recalc_rate(struct clk_hw *hw, -++ unsigned long parent_rate) -++{ -++ struct basedrv_clk_hw *clk = NULL; -++ -++ if (hw == NULL) -++ return parent_rate; -++ -++ clk = to_basedrv_clk_hw(hw); -++ -++ return clk->rate; -++} -++ -++static long basedrv_clk_round_rate(struct clk_hw *hw, unsigned long rate, -++ unsigned long *parent_rate) -++{ -++ return rate; -++} -++ -++int basedrv_clk_prepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = NULL; -++ -++ if (hw == NULL) -++ return -1; -++ -++ clk = to_basedrv_clk_hw(hw); -++ -++ ins_clk_enable(clk); -++ ins_clk_unreset(clk); -++ ins_clk_reset(clk); -++ -++ return 0; -++} -++ -++void basedrv_clk_unprepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = NULL; -++ -++ if (hw == NULL) -++ return; -++ -++ clk = to_basedrv_clk_hw(hw); -++ -++ clk->flags |= CLKHW_RESET; -++} -++ -++#if (LINUX_VERSION_CODE >=KERNEL_VERSION(5, 5, 0)) -++int basedrv_clk_init(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = NULL; -++ -++ if (hw == NULL) -++ return -1; -++ -++ clk = to_basedrv_clk_hw(hw); -++ -++ ins_clk_enable(clk); -++ ins_clk_reset(clk); -++ ins_clk_disable(clk); -++ -++ return 0; -++} -++#else -++void basedrv_clk_init(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = NULL; -++ -++ if (hw == NULL) -++ return; -++ -++ clk = to_basedrv_clk_hw(hw); -++ -++ ins_clk_enable(clk); -++ ins_clk_reset(clk); -++ ins_clk_disable(clk); -++} -++#endif -++ -++struct clk * __init basedrv_clk_register(struct basedrv_clk_hw *hw, -++ struct clk_ops *clkops) -++{ -++ struct clk *clk = NULL; -++ struct clk_init_data init; -++ -++ if (hw == NULL || clkops == NULL) -++ return NULL; -++ -++ init.name = hw->name; -++ init.flags = CLK_GET_RATE_NOCACHE; -++#ifdef CONFIG_ARCH_SHAOLINSWORD -++ init.flags |= CLK_IS_ROOT; -++#endif -++ init.parent_names = NULL; -++ init.num_parents = 0; -++ -++ if (hw->ops == NULL) -++ hw->ops = clkops; -++ -++ if (hw->ops->init == NULL) -++ hw->ops->init = basedrv_clk_init; -++ -++ if (hw->ops->prepare == NULL) -++ hw->ops->prepare = basedrv_clk_prepare; -++ -++ if (hw->ops->unprepare == NULL) -++ hw->ops->unprepare = basedrv_clk_unprepare; -++ -++ if (hw->ops->enable == NULL) -++ hw->ops->enable = basedrv_clk_enable; -++ -++ if (hw->ops->disable == NULL) -++ hw->ops->disable = basedrv_clk_disable; -++ -++ if (hw->ops->recalc_rate == NULL) -++ hw->ops->recalc_rate = basedrv_clk_recalc_rate; -++ -++ if (hw->ops->round_rate == NULL) -++ hw->ops->round_rate = basedrv_clk_round_rate; -++ -++ init.ops = hw->ops; -++ -++ hw->hw.init = &init; -++ -++ clk = clk_register(NULL, &hw->hw); -++ if (IS_ERR(clk)) { -++ pr_err("%s: register clock fail.\n", __func__); -++ return NULL; -++ } -++ -++ clk_register_clkdev(clk, hw->name, NULL); -++ -++ return clk; -++} -++ -++static struct clk *basedrv_clk_src_get(struct of_phandle_args *clkspec, void *data) -++{ -++ struct clk_onecell_data *clk_data = NULL; -++ unsigned int idx = 0; -++ -++ if ((data == NULL) || (clkspec == NULL)) { -++ return NULL; -++ } -++ -++ clk_data = data; -++ idx = clkspec->args[0]; -++ -++ if (idx >= (clk_data->clk_num << IDX_TO_CLK_NUM)) { -++ pr_err("%s: invalid clock index %d\n", __func__, idx); -++ return ERR_PTR(-EINVAL); -++ } -++ -++ return clk_data->clks[idx >> IDX_TO_CLK_NUM]; -++} -++ -++#define PERI_CRG_NODE_IDX 0 -++#define PERI_CTRL_NODE_IDX 1 -++ -++void __init basedrv_clocks_init(struct device_node *node, -++ struct basedrv_clk_hw *clks_hw, int nr_hw, unsigned int clk_num, -++ struct clk_ops *clkops) -++{ -++ int ix; -++ int ret; -++ void __iomem *peri_crg_base = NULL; -++ void __iomem *peri_ctrl_base = NULL; -++ struct clk_onecell_data *clk_data = NULL; -++ -++ if ((nr_hw > clk_num) || (clks_hw == NULL)) { -++ basedrv_clk_err("invalid argument\n"); -++ return; -++ } -++ -++ peri_crg_base = of_iomap(node, PERI_CRG_NODE_IDX); -++ if (peri_crg_base == NULL) { -++ basedrv_clk_err("failed to remap peri crg base\n"); -++ return; -++ } -++ -++ peri_ctrl_base = of_iomap(node, PERI_CTRL_NODE_IDX); -++ if (peri_ctrl_base == NULL) { -++ basedrv_clk_err("failed to remap peri ctrl base\n"); -++ goto exit; -++ } -++ -++ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); -++ if (clk_data == NULL) { -++ basedrv_clk_err("failed to allocate clk_data\n"); -++ goto exit; -++ } -++ -++ clk_data->clk_num = clk_num; -++ clk_data->clks = kzalloc(sizeof(struct clk *) * clk_num, GFP_KERNEL); -++ if (clk_data->clks == NULL) { -++ basedrv_clk_err("failed to allocate clks\n"); -++ goto exit; -++ } -++ -++ for (ix = 0; ix < nr_hw; ix++) { -++ struct basedrv_clk_hw *hw = &clks_hw[ix]; -++ -++ hw->peri_crg_base = peri_crg_base; -++ hw->peri_crgx = hw->peri_crg_base + hw->offset; -++ hw->peri_ctrl_base = peri_ctrl_base; -++ -++ if ((hw->id >> IDX_TO_CLK_NUM) >= clk_num) { -++ basedrv_clk_info("clk id is exceed CLK_MAX.\n"); -++ continue; -++ } -++ -++ clk_data->clks[hw->id >> IDX_TO_CLK_NUM] = basedrv_clk_register(hw, clkops); -++ } -++ -++ ret = of_clk_add_provider(node, basedrv_clk_src_get, clk_data); -++ if (ret != 0) { -++ basedrv_clk_err("add clk provider failed\n"); -++ goto exit; -++ } -++ -++ return; -++ -++exit: -++ if (peri_crg_base != NULL) { -++ iounmap(peri_crg_base); -++ peri_crg_base = NULL; -++ } -++ -++ if (peri_ctrl_base != NULL) { -++ iounmap(peri_ctrl_base); -++ peri_ctrl_base = NULL; -++ } -++ -++ if (clk_data != NULL && clk_data->clks != NULL) { -++ kfree(clk_data->clks); -++ clk_data->clks = NULL; -++ } -++ -++ if (clk_data != NULL) { -++ kfree(clk_data); -++ clk_data = NULL; -++ } -++} -++ -+diff --git a/drivers/vendor/basedrv_clk/basedrv_clk.h b/drivers/vendor/basedrv_clk/basedrv_clk.h -+new file mode 100755 -+index 000000000..2235a9ed0 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/basedrv_clk.h -+@@ -0,0 +1,103 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef BASEDRV_CLK_H -++#define BASEDRV_CLK_H -++ -++#include -++#include -++#include -++#include -++ -++#define BASEDRV_CLK_DEBUG 0 -++ -++#define basedrv_clk_dbg(format, arg...) \ -++ do { \ -++ if (BASEDRV_CLK_DEBUG) \ -++ printk(KERN_INFO "[UPS-CLK][%s]"format, __func__, ##arg); \ -++ } while (0) -++ -++#define basedrv_clk_info(format, arg...) \ -++ printk(KERN_INFO "[UPS-CLK][%s]"format, __func__, ##arg) -++ -++#define basedrv_clk_err(format, arg...) \ -++ printk(KERN_ERR "[UPS-CLK][%s]"format, __func__, ##arg) -++ -++struct clk_rate_reg { -++ unsigned long rate; -++ u32 regval; -++}; -++ -++struct basedrv_clk_hw { -++ unsigned int id; -++ const char *name; -++ u32 offset; -++ u32 mask; -++ u32 value; -++ u32 rstbit; -++ -++ unsigned long rate; -++ struct clk_ops *ops; -++ struct clk_hw hw; -++ void *__iomem peri_crgx; -++ void *__iomem peri_crg_base; -++ void *__iomem peri_ctrl_base; -++ -++#define CLKHW_RESET 0x01 -++#define CLKHW_ENABLE 0x02 -++ u32 flags; -++}; -++ -++/* clk id is 4bytes alignment, logical shift right 2 bits */ -++#define IDX_TO_CLK_NUM 2 -++ -++#define clk(_id, _mask, _value, _rstbit, _rate, _ops) { \ -++.id = (_id), \ -++.name = #_id, \ -++.offset = (_id), \ -++.mask = (_mask), \ -++.value = (_value), \ -++.rstbit = (_rstbit), \ -++.rate = (_rate), \ -++.ops = (_ops), \ -++} -++ -++#define clk_shared(_id, _off, _mask, _value, _rstbit, _rate, _ops) { \ -++.id = (_id), \ -++.name = #_id, \ -++.offset = (_off), \ -++.mask = (_mask), \ -++.value = (_value), \ -++.rstbit = (_rstbit), \ -++.rate = (_rate), \ -++.ops = (_ops), \ -++} -++ -++#define to_basedrv_clk_hw(_hw) container_of(_hw, struct basedrv_clk_hw, hw) -++ -++struct clk *basedrv_clk_register(struct basedrv_clk_hw *hw, struct clk_ops *clkops); -++ -++struct clk *basedrv_of_clk_src_get(struct of_phandle_args *clkspec, void *data); -++ -++void basedrv_clocks_init(struct device_node *node, struct basedrv_clk_hw *clks_hw, -++ int nr_hw, unsigned int clk_num, struct clk_ops *clkops); -++ -++int basedrv_clk_enable(struct clk_hw *hw); -++ -++void basedrv_clk_disable(struct clk_hw *hw); -++ -++unsigned long basedrv_clk_recalc_rate(struct clk_hw *hw, -++ unsigned long parent_rate); -++ -++int basedrv_clk_prepare(struct clk_hw *hw); -++ -++void basedrv_clk_unprepare(struct clk_hw *hw); -++ -++#if (LINUX_VERSION_CODE >=KERNEL_VERSION(5, 5, 0)) -++int basedrv_clk_init(struct clk_hw *hw); -++#else -++void basedrv_clk_init(struct clk_hw *hw); -++#endif -++ -++#endif /* BASEDRV_CLK_H */ -+diff --git a/drivers/vendor/basedrv_clk/hi3516cv610/Makefile b/drivers/vendor/basedrv_clk/hi3516cv610/Makefile -+new file mode 100755 -+index 000000000..e8b151bb6 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3516cv610/Makefile -+@@ -0,0 +1,4 @@ -++KBUILD_CFLAGS += -Werror -++ -++obj-$(CONFIG_ARCH_HI3516CV610_FAMILY) += soc_clk_hi3516cv610.o -++soc_clk_hi3516cv610-y += clk_hi3516cv610.o clk_ups.o -+diff --git a/drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.c b/drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.c -+new file mode 100755 -+index 000000000..8b601ca21 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.c -+@@ -0,0 +1,85 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "basedrv-clk" -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "../basedrv_clk.h" -++#include "clk_hi3516cv610.h" -++ -++static struct basedrv_clk_hw g_clks_hw[] = { -++ clk(PERI_CRG3664_USB30_CTRL0, 0x0, 0x0, 0x0, 0, &g_clk_ops_usb20_drd), -++ clk(PERI_CRG3632_USB2_PHY0, 0x0, 0x0, 0x0, 0, &g_clk_ops_xvpphy0), -++}; -++ -++static unsigned long hi3516cv610_basedrv_clk_recalc_rate(struct clk_hw *hw, -++ unsigned long parent_rate) -++{ -++ return 0; -++} -++ -++static int hi3516cv610_basedrv_clk_set_rate(struct clk_hw *hw, unsigned long drate, -++ unsigned long parent_rate) -++{ -++ return 0; -++} -++ -++static int hi3516cv610_basedrv_clk_get_phase(struct clk_hw *hw) -++{ -++ return 0; -++} -++ -++static int hi3516cv610_basedrv_clk_set_phase(struct clk_hw *hw, int degrees) -++{ -++ return 0; -++} -++ -++static int hi3516cv610_basedrv_clk_enable(struct clk_hw *hw) -++{ -++ basedrv_clk_enable(hw); -++ hi3516cv610_basedrv_clk_recalc_rate(hw, 0); -++ return 0; -++} -++ -++static struct clk_ops g_clk_ops = { -++ .enable = hi3516cv610_basedrv_clk_enable, -++ .recalc_rate = hi3516cv610_basedrv_clk_recalc_rate, -++ .set_rate = hi3516cv610_basedrv_clk_set_rate, -++ .get_phase = hi3516cv610_basedrv_clk_get_phase, -++ .set_phase = hi3516cv610_basedrv_clk_set_phase, -++}; -++ -++static void __init hi3516cv610_basedrv_clocks_init(struct device_node *np) -++{ -++ int ix; -++ for (ix = 0; ix < ARRAY_SIZE(g_clks_hw); ix++) { -++ struct basedrv_clk_hw *hw = &g_clks_hw[ix]; -++ struct clk_ops *ops = hw->ops; -++ if (ops == NULL) { -++ continue; -++ } -++ -++ if (ops->enable == NULL) { -++ ops->enable = hi3516cv610_basedrv_clk_enable; -++ } -++ -++ if (ops->recalc_rate == NULL) { -++ ops->recalc_rate = hi3516cv610_basedrv_clk_recalc_rate; -++ } -++ } -++ -++ basedrv_clocks_init(np, g_clks_hw, ARRAY_SIZE(g_clks_hw), -++ CLK_MAX >> IDX_TO_CLK_NUM, &g_clk_ops); -++} -++CLK_OF_DECLARE(basedrv_clk, "basedrv-ip,clock", hi3516cv610_basedrv_clocks_init); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("huanglong"); -+diff --git a/drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.h b/drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.h -+new file mode 100755 -+index 000000000..e9ce987ac -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3516cv610/clk_hi3516cv610.h -+@@ -0,0 +1,13 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef CLK_HI3516CV610_H -++#define CLK_HI3516CV610_H -++#include -++ -++extern struct clk_ops g_clk_ops_xvpphy0; -++extern struct clk_ops g_clk_ops_usb20_drd; -++ -++#endif -++ -+diff --git a/drivers/vendor/basedrv_clk/hi3516cv610/clk_ups.c b/drivers/vendor/basedrv_clk/hi3516cv610/clk_ups.c -+new file mode 100755 -+index 000000000..9506c12ec -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3516cv610/clk_ups.c -+@@ -0,0 +1,221 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++ -++#include "../basedrv_clk.h" -++ -++#define REG_PERI_CRG3664_USB20_CTRL 0x38C8 -++#define REG_PERI_CRG3632_USB2_PHY0 0x38C0 -++ -++#define USB2_CTRL_CRG_DEFAULT_VALUE 0x10131 -++#define USB2_PHY_CRG_DEFAULT_VALUE 0x33 -++ -++#define USB2_CRG_SRST_REQ (0x1 << 0) -++ -++#define USB2_PHY_CRG_APB_SREQ (0x1 << 2) -++#define USB2_PHY_CRG_TREQ (0x1 << 1) -++#define USB2_PHY_CRG_REQ (0x1 << 0) -++ -++#define OTP_USB_SHADOW_ADDR 0x101E001C -++#define USB_VBUS_SEL_MASK (0x1 << 14) -++#define PINOUT_REG_BASE 0x10260060 -++#define PINOUT_USB_DEFAULT_VAL 0x1200 -++// VBUS_IN_PULL_UP_ENABLE_VAL is for QFN, no vbus pin, pull up internal -++#define VBUS_IN_PULL_UP_ENABLE_VAL 0x1131 -++// VBUS_IN_PULL_UP_DISABLE_VAL is for BGA, vbus pin exist -++#define VBUS_IN_PULL_UP_DISABLE_VAL 0x1031 -++ -++#define DELAY_TIME_10 10 -++#define DELAY_TIME_200 200 -++ -++static unsigned int basedrv_clk_readl(const void __iomem *addr) -++{ -++ unsigned int reg = readl(addr); -++ -++ basedrv_clk_dbg("readl(0x%lx) = %#08X\n", (uintptr_t)addr, reg); -++ return reg; -++} -++ -++static void basedrv_clk_writel(unsigned int v, void __iomem *addr) -++{ -++ writel(v, addr); -++ basedrv_clk_dbg("writel(0x%lx) = %#08X\n", (uintptr_t)addr, v); -++} -++ -++static void usb_pinout_cfg(void) -++{ -++ void __iomem *otp_addr = NULL; -++ void __iomem *pinout_addr = NULL; -++ unsigned int reg; -++ -++ otp_addr = ioremap(OTP_USB_SHADOW_ADDR, 0x4); -++ if (otp_addr == NULL) { -++ basedrv_clk_info("ioremap OTP_USB_SHADOW_ADDR registor failed\n"); -++ return; -++ } -++ -++ reg = basedrv_clk_readl(otp_addr) & USB_VBUS_SEL_MASK; -++ pinout_addr = ioremap(PINOUT_REG_BASE, 0x4); -++ if (pinout_addr == NULL) { -++ basedrv_clk_info("ioremap pinout registor failed\n"); -++ return; -++ } -++ -++ if (reg == USB_VBUS_SEL_MASK) { -++ basedrv_clk_writel(VBUS_IN_PULL_UP_DISABLE_VAL, pinout_addr); -++ } else { -++ basedrv_clk_writel(VBUS_IN_PULL_UP_ENABLE_VAL, pinout_addr); -++ } -++ -++ udelay(DELAY_TIME_200); /* delay 200 us to wait vbus stable */ -++ -++ iounmap(otp_addr); -++ iounmap(pinout_addr); -++ otp_addr = NULL; -++ pinout_addr = NULL; -++} -++ -++static int xvpphy0_clk_prepare(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ /* init phy step1 */ -++ basedrv_clk_writel(USB2_PHY_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ -++ /* init phy step2 */ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ val &= ~(USB2_PHY_CRG_REQ); -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void xvpphy0_clk_unprepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ basedrv_clk_writel(USB2_PHY_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ basedrv_clk_dbg("---"); -++} -++ -++static int xvpphy0_clk_enable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ /* init phy step6 */ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ val &= ~(USB2_PHY_CRG_TREQ); -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void xvpphy0_clk_disable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ /* unregister step3 */ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ val |= USB2_PHY_CRG_APB_SREQ; -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ udelay(DELAY_TIME_10); -++ -++ /* unregister step4 */ -++ basedrv_clk_writel(USB2_PHY_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ basedrv_clk_dbg("---"); -++} -++ -++static int usb20_drd_clk_prepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ /* init ctrl step0 */ -++ usb_pinout_cfg(); -++ -++ /* init ctrl step1 */ -++ basedrv_clk_writel(USB2_CTRL_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3664_USB20_CTRL); -++ udelay(DELAY_TIME_200); // delay 200 us -++ -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void usb20_drd_clk_unprepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ basedrv_clk_writel(USB2_CTRL_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3664_USB20_CTRL); -++ basedrv_clk_dbg("---"); -++} -++ -++static int usb20_drd_clk_enable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ /* init ctrl step2 */ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3664_USB20_CTRL); -++ val &= ~USB2_CRG_SRST_REQ; -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3664_USB20_CTRL); -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void usb20_drd_clk_disable(struct clk_hw *hw) -++{ -++ void __iomem *addr = NULL; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ basedrv_clk_dbg("+++"); -++ -++ /* unregister step 1 write default to Vbus pin_out */ -++ addr = ioremap(PINOUT_REG_BASE, 0x4); -++ if (addr == NULL) { -++ basedrv_clk_info("ioremap pinout registor failed\n"); -++ return; -++ } -++ basedrv_clk_writel(PINOUT_USB_DEFAULT_VAL, addr); -++ -++ /* unregister step 2 write default value to DRD ctrl */ -++ basedrv_clk_writel(USB2_CTRL_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3664_USB20_CTRL); -++ -++ iounmap(addr); -++ basedrv_clk_dbg("---"); -++} -++ -++struct clk_ops g_clk_ops_xvpphy0 = { -++ .prepare = xvpphy0_clk_prepare, -++ .unprepare = xvpphy0_clk_unprepare, -++ .enable = xvpphy0_clk_enable, -++ .disable = xvpphy0_clk_disable, -++}; -++ -++struct clk_ops g_clk_ops_usb20_drd = { -++ .prepare = usb20_drd_clk_prepare, -++ .unprepare = usb20_drd_clk_unprepare, -++ .enable = usb20_drd_clk_enable, -++ .disable = usb20_drd_clk_disable, -++}; -++ -+diff --git a/drivers/vendor/basedrv_clk/hi3519dv500/Makefile b/drivers/vendor/basedrv_clk/hi3519dv500/Makefile -+new file mode 100755 -+index 000000000..e7ea70a0a -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3519dv500/Makefile -+@@ -0,0 +1,4 @@ -++KBUILD_CFLAGS += -Werror -++ -++obj-$(CONFIG_ARCH_HI3519DV500_FAMILY) += soc_clk_hi3519dv500.o -++soc_clk_hi3519dv500-y += clk_hi3519dv500.o clk_ups.o -+diff --git a/drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.c b/drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.c -+new file mode 100755 -+index 000000000..db8dbda26 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.c -+@@ -0,0 +1,93 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "basedrv-clk" -++#define pr_fmt(fmt) DRVNAME ": " fmt -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "../basedrv_clk.h" -++#include "clk_hi3519dv500.h" -++ -++ -++#define REG_PERI_CRG3665_USB3_PHY0 0x3944 -++ -++static struct basedrv_clk_hw g_clks_hw[] = { -++ clk(PERI_CRG3664_USB30_CTRL0, 0x0, 0x0, 0x0, 0, &g_clk_ops_usb30_drd), -++ clk(PERI_CRG3632_USB2_PHY0, 0x0, 0x0, 0x0, 0, &g_clk_ops_xvpphy0), -++ clk_shared(PERI_CRG3665_COMBPHY0_CLK, REG_PERI_CRG3665_USB3_PHY0, 0x0, 0x0, -++ 0x0, 0, &g_clk_ops_combophy0), -++}; -++ -++static unsigned long hi3519dv500_basedrv_clk_recalc_rate(struct clk_hw *hw, -++ unsigned long parent_rate) -++{ -++ return 0; -++} -++ -++static int hi3519dv500_basedrv_clk_set_rate(struct clk_hw *hw, unsigned long drate, -++ unsigned long parent_rate) -++{ -++ return 0; -++} -++ -++static int hi3519dv500_basedrv_clk_get_phase(struct clk_hw *hw) -++{ -++ return 0; -++} -++ -++static int hi3519dv500_basedrv_clk_set_phase(struct clk_hw *hw, int degrees) -++{ -++ return 0; -++} -++ -++static int hi3519dv500_basedrv_clk_enable(struct clk_hw *hw) -++{ -++ basedrv_clk_enable(hw); -++ hi3519dv500_basedrv_clk_recalc_rate(hw, 0); -++ return 0; -++} -++ -++static struct clk_ops g_clk_ops = { -++ .enable = hi3519dv500_basedrv_clk_enable, -++ .recalc_rate = hi3519dv500_basedrv_clk_recalc_rate, -++ .set_rate = hi3519dv500_basedrv_clk_set_rate, -++ .get_phase = hi3519dv500_basedrv_clk_get_phase, -++ .set_phase = hi3519dv500_basedrv_clk_set_phase, -++}; -++ -++static void __init hi3519dv500_basedrv_clocks_init(struct device_node *np) -++{ -++ int ix; -++ -++ for (ix = 0; ix < ARRAY_SIZE(g_clks_hw); ix++) { -++ struct basedrv_clk_hw *hw = &g_clks_hw[ix]; -++ struct clk_ops *ops = hw->ops; -++ -++ if (ops == NULL) { -++ continue; -++ } -++ -++ if (ops->enable == NULL) { -++ ops->enable = hi3519dv500_basedrv_clk_enable; -++ } -++ -++ if (ops->recalc_rate == NULL) { -++ ops->recalc_rate = hi3519dv500_basedrv_clk_recalc_rate; -++ } -++ } -++ -++ basedrv_clocks_init(np, g_clks_hw, ARRAY_SIZE(g_clks_hw), -++ CLK_MAX >> IDX_TO_CLK_NUM, &g_clk_ops); -++} -++CLK_OF_DECLARE(basedrv_clk, "basedrv-ip,clock", hi3519dv500_basedrv_clocks_init); -++ -++MODULE_LICENSE("GPL"); -++MODULE_AUTHOR("huanglong"); -+diff --git a/drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.h b/drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.h -+new file mode 100755 -+index 000000000..669b498ef -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3519dv500/clk_hi3519dv500.h -+@@ -0,0 +1,14 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef CLK_HI3519DV100_H -++#define CLK_HI3519DV100_H -++#include -++ -++extern struct clk_ops g_clk_ops_xvpphy0; -++extern struct clk_ops g_clk_ops_combophy0; -++extern struct clk_ops g_clk_ops_usb30_drd; -++ -++#endif -++ -+diff --git a/drivers/vendor/basedrv_clk/hi3519dv500/clk_ups.c b/drivers/vendor/basedrv_clk/hi3519dv500/clk_ups.c -+new file mode 100755 -+index 000000000..f69b61c53 -+--- /dev/null -++++ b/drivers/vendor/basedrv_clk/hi3519dv500/clk_ups.c -+@@ -0,0 +1,283 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++ -++#include "../basedrv_clk.h" -++ -++#define REG_PERI_CRG3664_USB30_CTRL 0x3940 -++#define REG_PERI_CRG3632_USB2_PHY0 0x38C0 -++#define REG_PERI_CRG3665_USB3_PHY0 0x3944 -++ -++#define USB3_CTRL_CRG_DEFAULT_VALUE 0x10003 -++#define USB2_PHY_CRG_DEFAULT_VALUE 0x107 -++#define USB3_PHY_CRG_DEFAULT_VALUE 0x3 -++ -++#define USB3_CRG_PCLK_OCC_SEL (0x1 << 18) -++#define USB3_CRG_FREECLK_SEL (0x1 << 16) -++#define USB3_CRG_PIPE_CKEN (0x1 << 12) -++#define USB3_CRG_UTMI_CKEN (0x1 << 8) -++#define USB3_CRG_SUSPEND_CKEN (0x1 << 6) -++#define USB3_CRG_REF_CKEN (0x1 << 5) -++#define USB3_CRG_BUS_CKEN (0x1 << 4) -++#define USB3_CRG_SRST_REQ (0x1 << 0) -++ -++#define USB2_PHY_CRG_APB_CKEN (0x1 << 6) -++#define USB2_PHY_CRG_XTAL_CKEN (0x1 << 4) -++#define USB2_PHY_CRG_APB_SREQ (0x1 << 2) -++#define USB2_PHY_CRG_TREQ (0x1 << 1) -++#define USB2_PHY_CRG_REQ (0x1 << 0) -++ -++#define COMBPHY_REF_CKEN (0x1<< 24) -++#define COMBPHY_SRST_REQ (0x1<< 16) -++ -++#define USB3_PHY_CRG_REF_CKEN (0x1 << 4) -++#define USB3_PHY_CRG_APB_SREQ (0x1 << 2) -++#define USB3_PHY_CRG_SRST_REQ (0x1 << 1) -++#define USB3_PHY_CRG_REQ (0x1 << 0) -++ -++#define REG_USB3_CTRL_MISC 0x208 -++#define USB3_DISABLE_SUPER_SPEED (0x1 << 9) -++ -++#define PINOUT_REG_BASE 0x179F0010 -++#define PINOUT_USB_VAL 0x1201 -++ -++static unsigned int basedrv_clk_readl(const void __iomem *addr) -++{ -++ unsigned int reg = readl(addr); -++ -++ basedrv_clk_dbg("readl(0x%lx) = %#08X\n", (uintptr_t)addr, reg); -++ return reg; -++} -++ -++static void basedrv_clk_writel(unsigned int v, void __iomem *addr) -++{ -++ writel(v, addr); -++ basedrv_clk_dbg("writel(0x%lx) = %#08X\n", (uintptr_t)addr, v); -++} -++ -++static void usb_pinout_cfg(void) -++{ -++ void __iomem *addr = NULL; -++ -++ addr = ioremap(PINOUT_REG_BASE, 0x4); -++ if (addr == NULL) { -++ basedrv_clk_info("map pinout registor failed\n"); -++ return; -++ } -++ -++ basedrv_clk_writel(PINOUT_USB_VAL, addr); -++ udelay(200); /* delay 200 us to wait vbus stable */ -++ -++ iounmap(addr); -++ addr = NULL; -++} -++ -++static int xvpphy0_clk_prepare(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ basedrv_clk_writel(USB2_PHY_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ -++ udelay(200); // delay 200 us -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ val |= (USB2_PHY_CRG_APB_CKEN | USB2_PHY_CRG_XTAL_CKEN); -++ val &= ~(USB2_PHY_CRG_APB_SREQ | USB2_PHY_CRG_REQ); -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void xvpphy0_clk_unprepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ basedrv_clk_writel(USB2_PHY_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ -++ basedrv_clk_dbg("---"); -++} -++ -++static int xvpphy0_clk_enable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ val &= ~(USB2_PHY_CRG_TREQ); -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void xvpphy0_clk_disable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ val |= USB2_PHY_CRG_TREQ; -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3632_USB2_PHY0); -++ -++ basedrv_clk_dbg("---"); -++} -++ -++static int combophy0_clk_prepare(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ basedrv_clk_writel(USB3_PHY_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++ -++ udelay(200); // delay 200 us -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++ val |= (USB3_PHY_CRG_REF_CKEN | USB3_PHY_CRG_APB_SREQ); -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++ -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void combophy0_clk_unprepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ basedrv_clk_writel(USB3_PHY_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++ -++ basedrv_clk_dbg("---"); -++} -++ -++static int combophy0_clk_enable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++ val &= ~(USB3_PHY_CRG_SRST_REQ | USB3_PHY_CRG_REQ); -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++ -++ return 0; -++} -++ -++static void combophy0_clk_disable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++ val |= (USB3_PHY_CRG_SRST_REQ | USB3_PHY_CRG_REQ); -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3665_USB3_PHY0); -++} -++ -++static int usb30_drd_clk_prepare(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ usb_pinout_cfg(); -++ -++ basedrv_clk_writel(USB3_CTRL_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3664_USB30_CTRL); -++ -++ val = basedrv_clk_readl(clk->peri_ctrl_base + REG_USB3_CTRL_MISC); -++ val &= ~(USB3_DISABLE_SUPER_SPEED); -++ basedrv_clk_writel(val, clk->peri_ctrl_base + REG_USB3_CTRL_MISC); -++ udelay(200); // delay 200 us -++ -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void usb30_drd_clk_unprepare(struct clk_hw *hw) -++{ -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ basedrv_clk_writel(USB3_CTRL_CRG_DEFAULT_VALUE, -++ clk->peri_crg_base + REG_PERI_CRG3664_USB30_CTRL); -++ -++ basedrv_clk_dbg("---"); -++} -++ -++static int usb30_drd_clk_enable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3664_USB30_CTRL); -++ val |= (USB3_CRG_FREECLK_SEL | USB3_CRG_PIPE_CKEN | USB3_CRG_UTMI_CKEN | -++ USB3_CRG_SUSPEND_CKEN | USB3_CRG_REF_CKEN | USB3_CRG_BUS_CKEN); -++ val &= ~USB3_CRG_SRST_REQ; -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3664_USB30_CTRL); -++ -++ basedrv_clk_dbg("---"); -++ -++ return 0; -++} -++ -++static void usb30_drd_clk_disable(struct clk_hw *hw) -++{ -++ u32 val; -++ struct basedrv_clk_hw *clk = to_basedrv_clk_hw(hw); -++ -++ basedrv_clk_dbg("+++"); -++ -++ val = basedrv_clk_readl(clk->peri_crg_base + REG_PERI_CRG3664_USB30_CTRL); -++ val |= USB3_CRG_SRST_REQ; -++ basedrv_clk_writel(val, clk->peri_crg_base + REG_PERI_CRG3664_USB30_CTRL); -++ -++ basedrv_clk_dbg("---"); -++} -++ -++struct clk_ops g_clk_ops_xvpphy0 = { -++ .prepare = xvpphy0_clk_prepare, -++ .unprepare = xvpphy0_clk_unprepare, -++ .enable = xvpphy0_clk_enable, -++ .disable = xvpphy0_clk_disable, -++}; -++ -++struct clk_ops g_clk_ops_combophy0 = { -++ .prepare = combophy0_clk_prepare, -++ .unprepare = combophy0_clk_unprepare, -++ .enable = combophy0_clk_enable, -++ .disable = combophy0_clk_disable, -++}; -++ -++struct clk_ops g_clk_ops_usb30_drd = { -++ .prepare = usb30_drd_clk_prepare, -++ .unprepare = usb30_drd_clk_unprepare, -++ .enable = usb30_drd_clk_enable, -++ .disable = usb30_drd_clk_disable, -++}; -++ -+diff --git a/drivers/vendor/cma/Kconfig b/drivers/vendor/cma/Kconfig -+new file mode 100755 -+index 000000000..7472dccd8 -+--- /dev/null -++++ b/drivers/vendor/cma/Kconfig -+@@ -0,0 +1,16 @@ -++ -++config CMA_MEM_SHARED -++ bool "Support sharing CMA memory with the heap" -++ depends on CMA && DMA_CMA -++ default no -++ help -++ Support sharing CMA memory with the heap. -++ -++config CMA_ADVANCE_SHARE -++ bool "Support cma advance share" -++ depends on CMA && DMA_CMA -++ select CMA_MEM_SHARED -++ default no -++ help -++ Support advance sharing CMA memory with the heap. -++ CMA Multiplex Ratio will be improved when this macro defined. -+diff --git a/drivers/vendor/cma/Makefile b/drivers/vendor/cma/Makefile -+new file mode 100755 -+index 000000000..97d573979 -+--- /dev/null -++++ b/drivers/vendor/cma/Makefile -+@@ -0,0 +1,2 @@ -++ -++obj-$(CONFIG_CMA) += cma.o -+diff --git a/drivers/vendor/cma/cma.c b/drivers/vendor/cma/cma.c -+new file mode 100755 -+index 000000000..7900d87d8 -+--- /dev/null -++++ b/drivers/vendor/cma/cma.c -+@@ -0,0 +1,176 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++ -++static u32 num_zones; -++static struct cma_zone bsp_zone[ZONE_MAX]; -++static int use_bootargs; -++ -++unsigned int get_cma_size(void) -++{ -++ u32 i; -++ u64 total = 0; -++ -++ for (i = 0; i < num_zones; i++) -++ total += bsp_zone[i].nbytes; -++ -++ return (unsigned int)(total >> 20); /* unit M: shift right 20 bits */ -++} -++ -++int is_cma_address(phys_addr_t phys, unsigned long size) -++{ -++ phys_addr_t start, end; -++ u32 i; -++ -++ for (i = 0; i < num_zones; i++) { -++ start = bsp_zone[i].phys_start; -++ end = bsp_zone[i].phys_start + bsp_zone[i].nbytes; -++ -++ if ((phys >= start) && ((phys + size) <= end)) -++ return 1; /* Yes, found! */ -++ } -++ -++ return 0; -++} -++EXPORT_SYMBOL(is_cma_address); -++ -++static int __init bsp_mmz_parse_cmdline(char *s) -++{ -++ char *line = NULL, *tmp = NULL; -++ char tmpline[256]; -++ int ret; -++ -++ if (s == NULL) { -++ pr_info("There is no cma zone!\n"); -++ return 0; -++ } -++ ret = strncpy_s(tmpline, sizeof(tmpline), s, sizeof(tmpline) - 1); -++ if (ret) { -++ printk("%s:strncpy_s failed\n", __func__); -++ return ret; -++ } -++ -++ 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; -++ -++ if (num_zones >= ZONE_MAX) -++ return 0; -++ bsp_zone[num_zones].pdev.coherent_dma_mask = DMA_BIT_MASK(64); -++ if (i == 4) { -++ strlcpy(bsp_zone[num_zones].name, argv[0], NAME_LEN_MAX); -++ bsp_zone[num_zones].gfp = (uintptr_t)memparse(argv[1], NULL); -++ bsp_zone[num_zones].phys_start = (uintptr_t)memparse(argv[2], NULL); -++ bsp_zone[num_zones].nbytes = (uintptr_t)memparse(argv[3], NULL); -++ } -++ -++ else if (i == 6) { -++ strlcpy(bsp_zone[num_zones].name, argv[0], NAME_LEN_MAX); -++ bsp_zone[num_zones].gfp = (uintptr_t)memparse(argv[1], NULL); -++ bsp_zone[num_zones].phys_start = (uintptr_t)memparse(argv[2], NULL); -++ bsp_zone[num_zones].nbytes = (uintptr_t)memparse(argv[3], NULL); -++ bsp_zone[num_zones].alloc_type = (uintptr_t)memparse(argv[4], NULL); -++ bsp_zone[num_zones].block_align = (uintptr_t)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", bsp_mmz_parse_cmdline); -++ -++phys_addr_t get_zones_start(void) -++{ -++ u32 i; -++ phys_addr_t lowest_zone_base = memblock_end_of_DRAM(); -++ -++ for (i = 0; i < num_zones; i++) { -++ if (lowest_zone_base > bsp_zone[i].phys_start) -++ lowest_zone_base = bsp_zone[i].phys_start; -++ } -++ -++ return lowest_zone_base; -++} -++EXPORT_SYMBOL(get_zones_start); -++ -++struct cma_zone *get_cma_zone(const char *name) -++{ -++ u32 i; -++ -++ if (name == NULL) -++ return NULL; -++ for (i = 0; i < num_zones; i++) -++ if (strcmp(bsp_zone[i].name, name) == 0) -++ break; -++ -++ if (i == num_zones) -++ return NULL; -++ -++ return &bsp_zone[i]; -++} -++EXPORT_SYMBOL(get_cma_zone); -++ -++struct device *get_cma_device(const char *name) -++{ -++ u32 i; -++ -++ if (name == NULL) -++ return NULL; -++ -++ for (i = 0; i < num_zones; i++) -++ if (strcmp(bsp_zone[i].name, name) == 0) -++ break; -++ -++ if (i == num_zones) -++ return NULL; -++ -++ return &bsp_zone[i].pdev; -++} -++EXPORT_SYMBOL(get_cma_device); -++ -++int __init declare_heap_memory(void) -++{ -++ u32 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_contiguous_reserve_area(bsp_zone[i].nbytes, -++ bsp_zone[i].phys_start, 0, &bsp_zone[i].pdev.cma_area, true); -++ if (ret) -++ panic("declare cma zone %s base: 0x%lx size:%lu MB failed. ret:%d", -++ bsp_zone[i].name, (unsigned long)bsp_zone[i].phys_start, -++ (unsigned long)bsp_zone[i].nbytes >> 20, ret); -++ -++ bsp_zone[i].phys_start = cma_get_base(bsp_zone[i].pdev.cma_area); -++ bsp_zone[i].nbytes = cma_get_size(bsp_zone[i].pdev.cma_area); -++ } -++ -++ return ret; -++} -++ -++static int bsp_mmz_setup(struct reserved_mem *rmem) -++{ -++ return 0; -++} -++RESERVEDMEM_OF_DECLARE(cma, "bsp-mmz", bsp_mmz_setup); -++ -+diff --git a/drivers/vendor/mmc/ChangLog b/drivers/vendor/mmc/ChangLog -+new file mode 100755 -+index 000000000..1ea066b31 -+--- /dev/null -++++ b/drivers/vendor/mmc/ChangLog -+@@ -0,0 +1,7 @@ -++2023-02-01 -++ -++ * version 1.0.0 -++ * feature: 2023-03-03 support emmc quick boot up -++ * feature: 2023-01-31 add dfx support, support card status dump, card init command backtrace if init failed. -++ * feature: 2023-01-13 add command queuing support -++ * feature: 2022-11-15 support emmc, sdio basic function -+diff --git a/drivers/vendor/mmc/Kconfig b/drivers/vendor/mmc/Kconfig -+new file mode 100755 -+index 000000000..47076834c -+--- /dev/null -++++ b/drivers/vendor/mmc/Kconfig -+@@ -0,0 +1,23 @@ -++# -++# MMC/SD host controller drivers -++# -++ -++config MMC_SDHCI_NEBULA -++ tristate "SDHCI nebula support" -++ depends on MMC && MMC_SDHCI -++ help -++ This selects the SDHCI nebula support. -++ -++ If you have a controller with this interface, say Y or M here. -++ -++ If unsure, say N. -++ -++config MMC_QUICKBOOT -++ tristate "SDHCI support quick boot on the Vendor SoC" -++ depends on MMC_SDHCI_PLTFM && ((MMC_SDHCI_NEBULA = y) || (MMC_SDHCI_SOCT = y)) -++ help -++ This selects the SDHCI quick boot support for Vendor System-on-Chip devices. -++ -++ If you want to support this feature, say Y here. -++ -++ If unsure, say N. -+diff --git a/drivers/vendor/mmc/Makefile b/drivers/vendor/mmc/Makefile -+new file mode 100755 -+index 000000000..9c59c8799 -+--- /dev/null -++++ b/drivers/vendor/mmc/Makefile -+@@ -0,0 +1,42 @@ -++include $(src)/version.mak -++ccflags-y += -DSDHCI_NEBULA_KERNEL_VERSION=\"$(SDHCI_NEBULA_KERNEL_VERSION)\" -++ -++ccflags-y += -I$(src)/ -++ccflags-y += -I$(src)/dfx -++ccflags-y += -I$(srctree)/drivers/mmc/host -++ccflags-y += -I$(srctree)/drivers/mmc/core -++ccflags-y += -I$(srctree)/include/huanglong/utils/ -++ccflags-y += -I$(srctree)/include/huanglong/ -++ccflags-y += -I$(srctree)/../../huanglong/linux/include/generic/ -++ccflags-y += -I$(srctree)/drivers/drv/ext_inc/dftevent/ -++ -++mmc_src := sdhci_nebula.o \ -++ adapter/nebula_adapter.o \ -++ adapter/nebula_quick.o \ -++ dfx/nebula_dfx.o \ -++ platform/platform_comm.o \ -++ dfx/mci_proc.o \ -++ nebula_intf.o -++ -++mod_name := sdhcinebula -++ -++mmc_plat_src-$(CONFIG_ARCH_HI3519DV500_FAMILY) += platform/sdhci_hi3519dv500.o -++mmc_plat_src-$(CONFIG_ARCH_HI3516CV610_FAMILY) += platform/sdhci_hi3516cv610.o -++ -++ifeq ($(CONFIG_SOCT_DRV_BUILD_KO),y) -++CONFIG_MMC_SDHCI_SOCT := m -++endif -++ -++obj-$(CONFIG_MMC_SDHCI_NEBULA) += ${mod_name}.o -++obj-$(CONFIG_MMC_SDHCI_SOCT) += ${mod_name}.o -++obj-$(CONFIG_MMC_SDHCI_SHAOLINSWORD) += ${mod_name}.o -++ -++ifneq ($(CONFIG_MMC_SDHCI_SOCT)$(CONFIG_MMC_SDHCI_NEBULA),) -++${mod_name}-objs := ${mmc_src} ${mmc_plat_src-y} -++else -++ifneq ($(findstring $(CONFIG_SOCT_CHIP_REVERSION), "shaolinsword_c"),) -++${mod_name}-objs := ${mmc_src} ${mmc_plat_src-y} -++else -++${mod_name}-objs := platform/sdhci_shaolinsword.o adapter/nebula_fmea.o -++endif -++endif -+diff --git a/drivers/vendor/mmc/adapter/nebula_adapter.c b/drivers/vendor/mmc/adapter/nebula_adapter.c -+new file mode 100755 -+index 000000000..abb61eb93 -+--- /dev/null -++++ b/drivers/vendor/mmc/adapter/nebula_adapter.c -+@@ -0,0 +1,1141 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "cqhci.h" -++#include "nebula_quirk_ids.h" -++#include "nebula_quick.h" -++#include "sdhci_nebula.h" -++#include "core.h" -++#include "card.h" -++ -++static u32 __read_mostly g_mmc_flag = 0; -++ -++#define sdhci_nebula_dump(f, x...) \ -++ pr_err("%s: sdhci: " f, mmc_hostname(host->mmc), ## x) -++ -++void __maybe_unused sdhci_nebula_dump_vendor_regs(struct sdhci_host *host) -++{ -++ u32 reg0, reg1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ sdhci_nebula_dump("========= SDHCI NEBULA DEBUG DUMP ==========\n"); -++ sdhci_nebula_dump("Mshc ctl: 0x%08x | Ahb ctl: 0x%08x\n", -++ sdhci_readl(host, SDHCI_MSHC_CTRL_R), -++ sdhci_readl(host, SDHCI_AXI_MBIU_CTRL)); -++ sdhci_nebula_dump("Debug1: 0x%08x | Debug2: 0x%08x\n", -++ sdhci_readl(host, SDHCI_DEBUG1_PORT), -++ sdhci_readl(host, SDHCI_DEBUG2_PORT)); -++ sdhci_nebula_dump("eMMC ctl: 0x%08x | eMMC rst: 0x%08x\n", -++ sdhci_readl(host, SDHCI_EMMC_CTRL), -++ sdhci_readl(host, SDHCI_EMMC_HW_RESET)); -++ sdhci_nebula_dump("AT ctl: 0x%08x | AT stat: 0x%08x\n", -++ sdhci_readl(host, SDHCI_AT_CTRL), -++ sdhci_readl(host, SDHCI_AT_STAT)); -++ sdhci_nebula_dump("eMMC reg: 0x%08x | Mutl cyl: 0x%08x\n", -++ sdhci_readl(host, SDHCI_EMAX_R), -++ sdhci_readl(host, SDHCI_MUTLI_CYCLE_EN)); -++ -++ /* Crg */ -++ regmap_read(nebula->crg_regmap, nebula->info->crg_ofs[CRG_CLK_RST], ®0); -++ regmap_read(nebula->crg_regmap, nebula->info->crg_ofs[CRG_DLL_RST], ®1); -++ sdhci_nebula_dump("CRG ctl: 0x%08x | Dll rst: 0x%08x\n", reg0, reg1); -++ plat_dump_io_info(host); -++} -++ -++static int __maybe_unused __init nebula_mmc_setup(char *str) -++{ -++ /* cqe off */ -++ if (strcasecmp(str, "cqeoff") == 0) { -++ g_mmc_flag |= MMC_CMDQ_FORCE_OFF; -++ } -++ -++ /* no whitelist */ -++ if (strcasecmp(str, "nowhitelist") == 0) { -++ g_mmc_flag |= MMC_CMDQ_DIS_WHITELIST; -++ } -++ -++ return 1; -++} -++__setup("mmc=", nebula_mmc_setup); -++ -++static void nebula_set_emmc_card(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ unsigned int reg; -++ -++ reg = sdhci_readl(host, SDHCI_EMMC_CTRL); -++ reg |= SDHCI_CARD_IS_EMMC; -++ sdhci_writel(host, reg, SDHCI_EMMC_CTRL); -++ } -++} -++ -++static void nebula_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 nebula_set_sample_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 nebula_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 nebula_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 nebula_disable_internal_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 nebula_enable_internal_clk(struct sdhci_host *host) -++{ -++ u16 clk, timeout; -++ -++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -++ clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_PLL_EN; -++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -++ -++ /* Wait max 20 ms */ -++ timeout = 20; -++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -++ while ((clk & SDHCI_CLOCK_INT_STABLE) == 0) { -++ if (timeout == 0) { -++ pr_err("%s: Internal clock never stabilised.\n", mmc_hostname(host->mmc)); -++ return; -++ } -++ timeout--; -++ udelay(1000); /* delay 1000 us */ -++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -++ } -++} -++ -++void sdhci_nebula_set_clock(struct sdhci_host *host, unsigned int clk) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -++ -++ nebula_disable_card_clk(host); -++ udelay(25); /* delay 25 us */ -++ nebula_disable_internal_clk(host); -++ -++ host->mmc->actual_clock = clk; -++ if (clk == 0) -++ return; -++ -++ clk_set_rate(pltfm_host->clk, clk); -++ -++ host->mmc->actual_clock = (unsigned int)clk_get_rate(pltfm_host->clk); -++ -++ plat_get_drv_samp_phase(host); -++ plat_set_drv_phase(host, nebula->drv_phase); -++ nebula_enable_sample(host); -++ nebula_set_sample_phase(host, nebula->sample_phase); -++ udelay(5); /* delay 5 us */ -++ nebula_enable_internal_clk(host); -++ -++ if ((host->timing == MMC_TIMING_MMC_HS400) || -++ (host->timing == MMC_TIMING_MMC_HS200) || -++ (host->timing == MMC_TIMING_UHS_SDR104) || -++ (host->timing == MMC_TIMING_UHS_SDR50)) { -++ if (nebula->priv_cap & NEBULA_CAP_RST_IN_DRV) { -++ plat_dll_reset_assert(host); -++ plat_dll_reset_deassert(host); -++ } else { -++ reset_control_assert(nebula->dll_rst); -++ reset_control_deassert(nebula->dll_rst); -++ } -++ plat_wait_p4_dll_lock(host); -++ plat_wait_sample_dll_ready(host); -++ } -++ -++ if (host->timing == MMC_TIMING_MMC_HS400) -++ plat_wait_ds_dll_ready(host); -++ -++ nebula_enable_card_clk(host); -++ udelay(75); /* delay 75 us */ -++} -++ -++static void nebula_select_sample_phase(struct sdhci_host *host, unsigned int phase) -++{ -++ nebula_disable_card_clk(host); -++ nebula_set_sample_phase(host, phase); -++ plat_wait_sample_dll_ready(host); -++ nebula_enable_card_clk(host); -++ udelay(1); -++} -++ -++static int nebula_send_tuning(struct sdhci_host *host, u32 opcode) -++{ -++ int count, err; -++ -++ count = 0; -++ do { -++ err = mmc_send_tuning(host->mmc, opcode, NULL); -++ if (err) { -++ if (host->tuning_delay > 0) -++ mdelay(host->tuning_delay); -++ mmc_abort_tuning(host->mmc, MMC_SEND_TUNING_BLOCK_HS200); -++ break; -++ } -++ -++ count++; -++ } while (count < MAX_TUNING_NUM); -++ -++ return err; -++} -++ -++static void nebula_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); -++ -++ nebula_enable_sample(host); -++ host->is_tuning = 1; -++} -++ -++static void nebula_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; -++} -++ -++static int nebula_get_best_sample(u32 candidates) -++{ -++ int rise = NOT_FOUND; -++ int fall, i, win; -++ 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; -++ -++ for (i = 0; i < PHASE_SCALE; i++) { -++ if ((candidates & WIN_MASK) == WIN_RISE) -++ rise = (i + 1) % PHASE_SCALE; -++ -++ if ((candidates & WIN_MASK) == WIN_FALL) { -++ fall = i; -++ win = fall - rise + 1; -++ if (rise == NOT_FOUND) { -++ end_fall = fall; -++ } else if ((rise != NOT_FOUND) && (win > win_max)) { -++ win_max = win; -++ found = (fall + rise) / WIN_DIV; -++ win_max_r = rise; -++ win_max_f = fall; -++ rise = NOT_FOUND; -++ fall = NOT_FOUND; -++ } -++ } -++ 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 / WIN_DIV)) % PHASE_SCALE; -++ win_max_r = rise; -++ win_max_f = fall; -++ } -++ } -++ -++ if (found != NOT_FOUND) -++ pr_err("valid phase shift [%d, %d] Final Phase:%d\n", -++ win_max_r, win_max_f, found); -++ -++ return found; -++} -++ -++static int nebula_exec_sample_tuning(struct sdhci_host *host, u32 opcode) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ unsigned int sample; -++ int err, phase; -++ unsigned int candidates = 0; -++ -++ nebula_pre_tuning(host); -++ -++ for (sample = 0; sample < PHASE_SCALE; sample++) { -++ nebula_select_sample_phase(host, sample); -++ -++ err = nebula_send_tuning(host, opcode); -++ if (err) -++ pr_debug("%s: send tuning CMD%u fail! phase:%d err:%d\n", -++ mmc_hostname(host->mmc), opcode, sample, err); -++ else -++ candidates |= (0x1 << sample); -++ } -++ -++ pr_info("%s: tuning done! candidates 0x%X: ", -++ mmc_hostname(host->mmc), candidates); -++ -++ phase = nebula_get_best_sample(candidates); -++ if (phase == NOT_FOUND) { -++ phase = nebula->sample_phase; -++ pr_err("%s: no valid phase shift! use default %d\n", mmc_hostname(host->mmc), phase); -++ } -++ -++ nebula->tuning_phase = (unsigned int)phase; -++ nebula_select_sample_phase(host, nebula->tuning_phase); -++ nebula_post_tuning(host); -++ -++ return ERET_SUCCESS; -++} -++ -++static void nebula_enable_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 void nebula_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 nebula_get_best_edges(struct sdhci_host *host, u32 opcode, -++ unsigned int *edge_p2f_ptr, unsigned int *edge_f2p_ptr) -++{ -++ int err; -++ unsigned int index, val; -++ bool found = false; -++ bool prev_found = false; -++ unsigned int edge_p2f, edge_f2p, start, end; -++ -++ start = 0; -++ end = PHASE_SCALE / EDGE_TUNING_PHASE_STEP; -++ -++ edge_p2f = start; -++ edge_f2p = end; -++ for (index = 0; index <= end; index++) { -++ nebula_select_sample_phase(host, index * EDGE_TUNING_PHASE_STEP); -++ -++ err = nebula_send_tuning(host, opcode); -++ if (err == 0) { -++ val = sdhci_readl(host, SDHCI_MULTI_CYCLE); -++ found = ((val & SDHCI_FOUND_EDGE) != 0); -++ } else { -++ found = true; -++ } -++ -++ 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 = false; -++ } -++ -++ if ((edge_p2f == start) && (edge_f2p == end)) -++ return NOT_FOUND; -++ -++ *edge_p2f_ptr = edge_p2f; -++ *edge_f2p_ptr = edge_f2p; -++ -++ return ERET_SUCCESS; -++} -++ -++static unsigned int nebula_get_best_phase(struct sdhci_host *host, u32 opcode, -++ unsigned int *edge_p2f_ptr, unsigned int *edge_f2p_ptr) -++{ -++ unsigned int index, start, end; -++ unsigned int phase, fall, rise; -++ bool fall_updat_flag = false; -++ int err; -++ int prev_err = 0; -++ -++ start = *edge_p2f_ptr * EDGE_TUNING_PHASE_STEP; -++ end = *edge_f2p_ptr * EDGE_TUNING_PHASE_STEP; -++ if (end <= start) -++ end += PHASE_SCALE; -++ -++ fall = start; -++ rise = end; -++ for (index = start; index <= end; index++) { -++ nebula_select_sample_phase(host, index % PHASE_SCALE); -++ -++ err = nebula_send_tuning(host, opcode); -++ if (err) { -++ pr_debug("%s: send tuning CMD%u fail! phase:%d err:%d\n", -++ mmc_hostname(host->mmc), opcode, index, err); -++ } -++ -++ if ((err != 0) && (index == start)) { -++ if (!fall_updat_flag) { -++ fall_updat_flag = true; -++ fall = start; -++ } -++ } else if ((prev_err == 0) && (err != 0)) { -++ if (!fall_updat_flag) { -++ fall_updat_flag = true; -++ fall = index; -++ } -++ } -++ -++ if ((prev_err != 0) && (err == 0)) -++ rise = index; -++ -++ if ((err != 0) && (index == end)) { -++ rise = end; -++ } -++ -++ prev_err = err; -++ } -++ -++ /* Calculate the center value by devide 2 */ -++ phase = ((fall + rise) / 2 + PHASE_SCALE / 2) % PHASE_SCALE; -++ -++ 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); -++ -++ return phase; -++} -++ -++static int nebula_exec_edge_tuning(struct sdhci_host *host, u32 opcode) -++{ -++ int ret; -++ unsigned int phase, edge_p2f, edge_f2p; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ nebula_pre_tuning(host); -++ nebula_enable_edge_tuning(host); -++ -++ ret = nebula_get_best_edges(host, opcode, &edge_p2f, &edge_f2p); -++ if (ret == NOT_FOUND) { -++ pr_err("%s: tuning failed! can not found edge!\n", mmc_hostname(host->mmc)); -++ return ret; -++ } -++ -++ nebula_disable_edge_tuning(host); -++ -++ phase = nebula_get_best_phase(host, opcode, &edge_p2f, &edge_f2p); -++ -++ nebula->tuning_phase = phase; -++ nebula_select_sample_phase(host, phase); -++ nebula_post_tuning(host); -++ -++ return ERET_SUCCESS; -++} -++ -++int sdhci_nebula_execute_tuning(struct sdhci_host *host, u32 opcode) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->priv_quirk & NEBULA_QUIRK_FPGA) -++ return ERET_SUCCESS; -++ -++ if (nebula->priv_quirk & NEBULA_QUIRK_SAMPLE_TURNING) { -++ return nebula_exec_sample_tuning(host, opcode); -++ } else { -++ return nebula_exec_edge_tuning(host, opcode); -++ } -++} -++ -++static void nebula_parse_priv_cap(struct sdhci_host *host, -++ struct device_node *np) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (of_get_property(np, "reset_out_drv", NULL) == NULL) -++ nebula->priv_cap |= NEBULA_CAP_RST_IN_DRV; -++ -++ if (of_get_property(np, "pm_runtime_enable", NULL)) -++ nebula->priv_cap |= NEBULA_CAP_PM_RUNTIME; -++ -++ if (of_get_property(np, "nm_card", NULL)) -++ nebula->priv_cap |= NEBULA_CAP_NM_CARD; -++} -++ -++static void nebula_parse_priv_quirk(struct sdhci_host *host, -++ const struct device_node *np) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (of_get_property(np, "sample_turning", NULL)) -++ nebula->priv_quirk |= NEBULA_QUIRK_SAMPLE_TURNING; -++ -++ if (of_get_property(np, "fpga", NULL)) -++ nebula->priv_quirk |= NEBULA_QUIRK_FPGA; -++ -++ if (of_get_property(np, "cd_inverted", NULL)) -++ nebula->priv_quirk |= NEBULA_QUIRK_CD_INVERTED; -++ -++ if (of_get_property(np, "pwr_en_inverted", NULL)) -++ nebula->priv_quirk |= NEBULA_QUIRK_PWR_EN_INVERTED; -++} -++ -++static void nebula_of_parse(struct platform_device *pdev, -++ struct sdhci_host *host) -++{ -++ u32 bus_width; -++ struct device *dev = &pdev->dev; -++ -++ if (device_property_present(dev, "mmc-broken-cmd23")) -++ host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; -++ -++ if (device_property_present(dev, "sdhci,1-bit-only") || -++ (device_property_read_u32(dev, "bus-width", &bus_width) == 0 && -++ bus_width == 1)) -++ host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA; -++ -++ if (device_property_present(dev, "broken-cd")) -++ host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; -++} -++ -++static int nebula_parse_comm_dt(struct platform_device *pdev, -++ struct sdhci_host *host) -++{ -++ int ret; -++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ struct device_node *np = pdev->dev.of_node; -++ -++ ret = mmc_of_parse(host->mmc); -++ if (ret) { -++ dev_err(mmc_dev(host->mmc), "parse comm dt failed.\n"); -++ return ret; -++ } -++ -++ if ((of_property_read_u32(np, "devid", &nebula->devid) != 0) || -++ (nebula->devid >= MMC_DEV_TYPE_MAX)) { -++ return -EINVAL; -++ } -++ -++ if (of_property_read_bool(np, "fix-1v8")) -++ host->flags = (unsigned int)host->flags & ~SDHCI_SIGNALING_330; -++ -++ nebula_of_parse(pdev, host); -++ -++ nebula_parse_priv_cap(host, np); -++ -++ nebula_parse_priv_quirk(host, np); -++ -++#ifdef CONFIG_MMC_CQHCI -++ if (of_get_property(np, "mmc-cmdq", NULL)) -++ host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; -++#endif -++ -++ if (of_property_read_u32(np, "max-frequency", &host->mmc->f_max)) -++ host->mmc->f_max = MAX_FREQ; -++ -++ pltfm_host->clk = devm_clk_get(mmc_dev(host->mmc), "mmc_clk"); -++ if (IS_ERR_OR_NULL(pltfm_host->clk)) { -++ dev_err(mmc_dev(host->mmc), "get clk failed\n"); -++ return -EINVAL; -++ } -++ -++ nebula->hclk = devm_clk_get(mmc_dev(host->mmc), "mmc_hclk"); -++ if (IS_ERR_OR_NULL(nebula->hclk)) { -++ dev_warn(mmc_dev(host->mmc), "dts no hclk\n"); -++ } else { -++ ret = clk_prepare_enable(nebula->hclk); -++ if (ret) { -++ dev_err(mmc_dev(host->mmc), "enable hclk failed.\n"); -++ return -EINVAL; -++ } -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++static int nebula_parse_reset_dt(struct platform_device *pdev, -++ struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if ((nebula->priv_cap & NEBULA_CAP_RST_IN_DRV) == 0) { -++ nebula->crg_rst = devm_reset_control_get(&pdev->dev, "crg_reset"); -++ if (IS_ERR_OR_NULL(nebula->crg_rst)) { -++ dev_err(&pdev->dev, "get crg_rst failed. %ld\n", \ -++ PTR_ERR(nebula->crg_rst)); -++ return (int)PTR_ERR(nebula->crg_rst); -++ } -++ -++ nebula->dll_rst = devm_reset_control_get(&pdev->dev, "dll_reset"); -++ if (IS_ERR_OR_NULL(nebula->dll_rst)) { -++ dev_err(&pdev->dev, "get dll_reset failed. %ld\n", \ -++ PTR_ERR(nebula->dll_rst)); -++ return (int)PTR_ERR(nebula->dll_rst); -++ } -++ -++ /* below crg rst not must */ -++ nebula->crg_tx = devm_reset_control_get(&pdev->dev, "crg_tx"); -++ if (IS_ERR_OR_NULL(nebula->crg_tx)) { -++ dev_warn(&pdev->dev, "crg tx rst not found with dts\n"); -++ nebula->crg_tx = nebula->crg_rst; -++ } -++ -++ nebula->crg_rx = devm_reset_control_get(&pdev->dev, "crg_rx"); -++ if (IS_ERR_OR_NULL(nebula->crg_rx)) { -++ dev_warn(&pdev->dev, "crg rx rst not found with dts\n"); -++ nebula->crg_rx = nebula->crg_rst; -++ } -++ -++ nebula->samp_rst = devm_reset_control_get(&pdev->dev, "samp_rst"); -++ if (IS_ERR_OR_NULL(nebula->samp_rst)) { -++ dev_warn(&pdev->dev, "crg samp rst not found with dts\n"); -++ nebula->samp_rst = NULL; -++ } -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++static int nebula_parse_regmap_dt(struct platform_device *pdev, -++ struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ struct device_node *np = pdev->dev.of_node; -++ -++ nebula->crg_regmap = syscon_regmap_lookup_by_phandle(np, -++ "crg_regmap"); -++ if (IS_ERR(nebula->crg_regmap)) { -++ dev_err(&pdev->dev, "get crg regmap failed. %ld\n", \ -++ PTR_ERR(nebula->crg_regmap)); -++ return (int)PTR_ERR(nebula->crg_regmap); -++ } -++ -++ nebula->iocfg_regmap = syscon_regmap_lookup_by_phandle(np, -++ "iocfg_regmap"); -++ if (IS_ERR(nebula->iocfg_regmap)) { -++ dev_err(&pdev->dev, "get iocfg regmap failed. %ld\n", \ -++ PTR_ERR(nebula->iocfg_regmap)); -++ return (int)PTR_ERR(nebula->iocfg_regmap); -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++int sdhci_nebula_pltfm_init(struct platform_device *pdev, -++ struct sdhci_host *host) -++{ -++ int ret; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ ret = nebula_parse_comm_dt(pdev, host); -++ if (ret) { -++ dev_err(&pdev->dev, "parse comm dt failed\n"); -++ return ret; -++ } -++ -++ ret = plat_host_pre_init(pdev, host); -++ if (ret) { -++ dev_err(&pdev->dev, "pltfm pre init failed\n"); -++ return ret; -++ } -++ -++ /* check nebula *info and *mask valid? */ -++ if (nebula->info == NULL || nebula->mask == NULL) { -++ dev_err(&pdev->dev, "info or mask data invalid\n"); -++ return -EINVAL; -++ } -++ -++ ret = nebula_parse_reset_dt(pdev, host); -++ if (ret) -++ return ret; -++ -++ ret = nebula_parse_regmap_dt(pdev, host); -++ if (ret) -++ return ret; -++ -++#ifdef CONFIG_MMC_QUICKBOOT -++ ret = mmc_fast_boot_init(host); -++ if (ret) -++ return ret; -++#endif -++ -++ /* Do ZQ calibration */ -++ ret = plat_resistance_calibration(host); -++ if (ret) -++ return ret; -++ -++ ret = plat_crg_init(host); -++ if (ret) -++ return ret; -++ -++ host->tuning_delay = 1; -++ plat_caps_quirks_init(host); -++ host->mmc_host_ops.hs400_enhanced_strobe = plat_hs400_enhanced_strobe; -++ -++ return ERET_SUCCESS; -++} -++ -++void sdhci_nebula_set_uhs_signaling(struct sdhci_host *host, -++ unsigned int timing) -++{ -++ nebula_set_emmc_card(host); -++ sdhci_set_uhs_signaling(host, timing); -++ host->timing = timing; -++ plat_set_drv_cap(host); -++} -++ -++void sdhci_nebula_hw_reset(struct sdhci_host *host) -++{ -++ sdhci_writel(host, 0x0, SDHCI_EMMC_HW_RESET); -++ udelay(10); /* delay 10 us */ -++ sdhci_writel(host, 0x1, SDHCI_EMMC_HW_RESET); -++ udelay(200); /* delay 200 us */ -++} -++ -++int sdhci_nebula_runtime_suspend(struct device *dev) -++{ -++ struct sdhci_host *host = dev_get_drvdata(dev); -++ -++ nebula_disable_card_clk(host); -++ -++ return ERET_SUCCESS; -++} -++ -++int sdhci_nebula_runtime_resume(struct device *dev) -++{ -++ struct sdhci_host *host = dev_get_drvdata(dev); -++ -++ nebula_enable_card_clk(host); -++ -++ return ERET_SUCCESS; -++} -++ -++int sdhci_nebula_voltage_switch(struct sdhci_host *host, struct mmc_ios *ios) -++{ -++ return plat_voltage_switch(host, ios); -++} -++ -++void sdhci_nebula_extra_init(struct sdhci_host *host) -++{ -++ host->error_count = 0; -++ return plat_extra_init(host); -++} -++ -++#ifdef CONFIG_MMC_CQHCI -++static void nebula_init_card(struct mmc_host *host, struct mmc_card *card) -++{ -++ u32 idx; -++ /* eMMC spec: cid product name offset: 0, 7, 6, 5, 4, 11 */ -++ const u8 cid_pnm_offset[] = {0, 7, 6, 5, 4, 11}; -++ -++ if (host == NULL || card == NULL) { -++ pr_err("%s: null card or host\n", mmc_hostname(host)); -++ return; -++ } -++ -++ if ((card->type == MMC_TYPE_MMC) && (host->caps2 & MMC_CAP2_CQE)) { -++ u8 *raw_cid = (u8 *)card->raw_cid; -++ -++ /* Skip whitelist */ -++ if (g_mmc_flag & MMC_CMDQ_DIS_WHITELIST) { -++ return; -++ } -++ -++ /* Clear MMC CQE capblility */ -++ host->caps2 &= ~(MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); -++ -++ /* Manufacturer ID: b[127:120](eMMC v2.0 and upper), 0/24: idx/bit offset */ -++ card->cid.manfid = ((card->raw_cid[0] >> 24) & 0xFF); -++ -++ /* Decode CID with eMMC v2.0 and upper */ -++ for (idx = 0; idx < sizeof(cid_pnm_offset); idx++) { -++ card->cid.prod_name[idx] = raw_cid[cid_pnm_offset[idx]]; -++ } -++ card->cid.prod_name[++idx] = 0; -++ mmc_fixup_device(card, mmc_cmdq_whitelist); -++ } -++} -++ -++static void nebula_controller_v4_enable(struct sdhci_host *host, bool enable) -++{ -++ u16 ctrl; -++ -++ ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); -++ if (enable) -++ ctrl |= SDHCI_CTRL_V4_ENABLE; -++ else -++ ctrl &= ~SDHCI_CTRL_V4_ENABLE; -++ -++ if (host->flags & SDHCI_USE_64_BIT_DMA) -++ ctrl |= SDHCI_CTRL_64BIT_ADDR; -++ -++ sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); -++} -++ -++static void nebula_cqe_enable(struct mmc_host *mmc) -++{ -++ struct sdhci_host *host = mmc_priv(mmc); -++ u32 timeout = CQE_MAX_TIMEOUT; -++ u16 reg, clk; -++ u8 ctrl; -++ -++ /* SW_RST_DAT */ -++ sdhci_reset(host, SDHCI_RESET_DATA); -++ -++ nebula_controller_v4_enable(host, true); -++ -++ /* Set the DMA boundary value and block size */ -++ sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary, -++ MMC_BLOCK_SIZE), SDHCI_BLOCK_SIZE); -++ -++ /* need to set multitransfer for cmdq */ -++ reg = sdhci_readw(host, SDHCI_TRANSFER_MODE); -++ reg |= SDHCI_TRNS_MULTI; -++ reg |= SDHCI_TRNS_BLK_CNT_EN; -++ sdhci_writew(host, reg, SDHCI_TRANSFER_MODE); -++ -++ /* ADMA2 only */ -++ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); -++ ctrl &= ~SDHCI_CTRL_DMA_MASK; -++ ctrl |= SDHCI_CTRL_ADMA32; -++ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -++ -++ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -++ clk |= SDHCI_CLOCK_PLL_EN; -++ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -++ -++ while (mmc->ops->card_busy(mmc)) { -++ timeout--; -++ if (!timeout) { -++ pr_err("%s: cqe enable wait busy timeout\n", mmc_hostname(mmc)); -++ break; -++ } -++ udelay(1); -++ } -++ -++ sdhci_cqe_enable(mmc); -++} -++ -++static void nebula_cqe_disable(struct mmc_host *mmc, bool recovery) -++{ -++ u32 timeout = CQE_MAX_TIMEOUT; -++ -++ while (mmc->ops->card_busy(mmc)) { -++ timeout--; -++ if (!timeout) { -++ pr_err("%s: cqe disable wait busy timeout\n", mmc_hostname(mmc)); -++ break; -++ } -++ udelay(1); -++ } -++ -++ nebula_controller_v4_enable(mmc_priv(mmc), 0); -++ -++ sdhci_cqe_disable(mmc, recovery); -++} -++ -++static void nebula_dumpregs(struct mmc_host *mmc) -++{ -++ sdhci_dumpregs(mmc_priv(mmc)); -++} -++ -++static const struct cqhci_host_ops sdhci_nebula_cqe_ops = { -++ .enable = nebula_cqe_enable, -++ .disable = nebula_cqe_disable, -++ .dumpregs = nebula_dumpregs, -++}; -++ -++static int nebula_cqe_add_host(struct sdhci_host *host) -++{ -++ int ret; -++ struct cqhci_host *cq_host = NULL; -++ bool dma64 = false; -++ -++ if (g_mmc_flag & MMC_CMDQ_FORCE_OFF) { -++ /* force cmdq off by bootarges */ -++ host->mmc->caps2 &= ~(MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); -++ return sdhci_add_host(host); -++ } -++ -++ ret = sdhci_setup_host(host); -++ if (ret) -++ return ret; -++ -++ cq_host = devm_kzalloc(host->mmc->parent, sizeof(struct cqhci_host), GFP_KERNEL); -++ if (cq_host == NULL) { -++ pr_err("%s: allocate cqe host failed.\n", mmc_hostname(host->mmc)); -++ ret = -ENOMEM; -++ goto cleanup; -++ } -++ -++ cq_host->mmio = host->ioaddr + NEBULA_CQE_OFS; -++ cq_host->ops = &sdhci_nebula_cqe_ops; -++ -++ /* -++ * synopsys controller has dma 128M algin limit, -++ * may split the trans descriptors -++ */ -++ cq_host->quirks |= CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT; -++ host->mmc->max_segs *= CQHCI_MAX_SEGS_MUL; -++ -++ dma64 = host->flags & SDHCI_USE_64_BIT_DMA; -++ if (dma64) -++ cq_host->caps |= CQHCI_TASK_DESC_SZ_128; -++ -++ ret = cqhci_init(cq_host, host->mmc, dma64); -++ if (ret) { -++ pr_err("%s: cqe init fail\n", mmc_hostname(host->mmc)); -++ return ret; -++ } -++ -++ ret = __sdhci_add_host(host); -++ if (ret) -++ return ret; -++ -++ host->mmc_host_ops.init_card = nebula_init_card; -++ -++ return ERET_SUCCESS; -++ -++cleanup: -++ sdhci_cleanup_host(host); -++ return ret; -++} -++ -++static u32 nebula_cqe_irq(struct sdhci_host *host, u32 intmask) -++{ -++ int cmd_error = 0; -++ int data_error = 0; -++ -++ if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error)) -++ return intmask; -++ -++ cqhci_irq(host->mmc, intmask, cmd_error, data_error); -++ -++ return ERET_SUCCESS; -++} -++#else -++static int nebula_cqe_add_host(struct sdhci_host *host) -++{ -++ /* Rollback to no cqe mode */ -++ host->mmc->caps2 &= ~(MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); -++ -++ return sdhci_add_host(host); -++} -++ -++static u32 nebula_cqe_irq(struct sdhci_host *host, u32 intmask) -++{ -++ return intmask; -++} -++#endif -++ -++u32 sdhci_nebula_irq(struct sdhci_host *host, u32 intmask) -++{ -++#ifdef CONFIG_SDHCI_NEBULA_DFX -++ sdhci_nebula_dfx_irq(host, intmask); -++#endif -++ -++ if (host->mmc->caps2 & MMC_CAP2_CQE) -++ return nebula_cqe_irq(host, intmask); -++ -++ return intmask; -++} -++ -++int sdhci_nebula_add_host(struct sdhci_host *host) -++{ -++ int ret; -++ -++#ifdef CONFIG_MMC_QUICKBOOT -++ if (mmc_is_fast_boot(host)) { -++ host->mmc->rescan_entered = 1; -++ /* Do not do repowerup before scan */ -++ host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; -++ /* Skip reset device for fast boot */ -++ host->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; -++ sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); -++ } -++#endif -++ -++ if (host->mmc->caps2 & MMC_CAP2_CQE) { -++ ret = nebula_cqe_add_host(host); -++ } else { -++ ret = sdhci_add_host(host); -++ } -++ if (ret != ERET_SUCCESS) -++ return ret; -++ -++#ifdef CONFIG_MMC_QUICKBOOT -++ if (mmc_is_fast_boot(host)) { -++ /* Clear SDHCI_QUIRK_NO_CARD_NO_RESET for normal reset */ -++ host->quirks &= ~SDHCI_QUIRK_NO_CARD_NO_RESET; -++ -++ mmc_parameter_init(host->mmc); -++ ret = mmc_quick_init_card(host->mmc, mmc_get_rocr(host), NULL); -++ if (ret) { -++ host->mmc->rescan_entered = 0; -++ mmc_detect_change(host->mmc, 0); -++ } -++ host->mmc->card_status = MMC_CARD_INIT; -++ if (host->mmc->ops->card_info_save) -++ host->mmc->ops->card_info_save(host->mmc); -++ } -++#endif -++ return ret; -++} -++ -++void sdhci_nebula_set_bus_width(struct sdhci_host *host, int width) -++{ -++ u8 ctrl; -++ -++ if (width <= MMC_BUS_WIDTH_4) { -++ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); -++ ctrl &= ~SDHCI_CTRL_8BITBUS; -++ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -++ } -++ -++ return sdhci_set_bus_width(host, width); -++} -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -++void sdhci_nebula_adma_write_desc(struct sdhci_host *host, void **desc, -++ dma_addr_t addr, int len, unsigned int cmd) -++{ -++ int split_len; -++ -++ /* work around for buffer across 128M boundary, split the buffer */ -++ if (((addr & (SZ_128M - 1)) + len) > SZ_128M) { -++ split_len = SZ_128M - (int)(addr & (SZ_128M - 1)); -++ sdhci_adma_write_desc(host, desc, addr, split_len, ADMA2_TRAN_VALID); -++ addr += split_len; -++ len -= split_len; -++ } -++ -++ sdhci_adma_write_desc(host, desc, addr, len, cmd); -++} -++#endif -++ -++void sdhci_nebula_reset(struct sdhci_host *host, u8 mask) -++{ -++ u8 ctrl; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++#ifdef CONFIG_MMC_QUICKBOOT -++ /* eMMC quick boot up no need reset */ -++ if ((nebula->devid == MMC_DEV_TYPE_MMC_0) && \ -++ ((host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) != 0)) { -++ return; -++ } -++#endif -++ sdhci_reset(host, mask); -++ -++ ctrl = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); -++ -++ /* eMMC card detect inverted */ -++ if (nebula->priv_quirk & NEBULA_QUIRK_CD_INVERTED) -++ ctrl |= SDHCI_DETECT_POLARITY; -++ -++ /* eMMC power en inverted */ -++ if (nebula->priv_quirk & NEBULA_QUIRK_PWR_EN_INVERTED) -++ ctrl &= ~SDHCI_PWR_EN_POLARITY; -++ -++ sdhci_writeb(host, ctrl, SDHCI_WAKE_UP_CONTROL); -++} -++ -++#ifdef CONFIG_PM -++int sdhci_nebula_pltfm_suspend(struct device *dev) -++{ -++ int ret; -++ struct sdhci_host *host = dev_get_drvdata(dev); -++ struct sdhci_nebula *nebula = nebula_priv(host); -++#ifdef CONFIG_MMC_QUICKBOOT -++ struct mmc_card *card = host->mmc->card; -++ -++ if (mmc_is_fast_boot(host)) { -++ if ((card != NULL) && (mmc_card_suspended(card) != 0)) -++ mmc_set_cur_mode(host, SLEEP_MODE); -++ } -++#endif -++ ret = sdhci_pltfm_suspend(dev); -++ if (ret != 0) { -++ pr_err("%s: pltfm suspend fail\n", mmc_hostname(host->mmc)); -++ return ret; -++ } -++ -++ if (!IS_ERR_OR_NULL(nebula->hclk)) -++ clk_disable_unprepare(nebula->hclk); -++ -++ return ERET_SUCCESS; -++} -++ -++int sdhci_nebula_pltfm_resume(struct device *dev) -++{ -++ int ret; -++ struct sdhci_host *host = dev_get_drvdata(dev); -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++#ifdef CONFIG_MMC_QUICKBOOT -++ struct mmc_card *card = host->mmc->card; -++ -++ if (mmc_is_fast_boot(host)) { -++ if ((card != NULL) && (mmc_card_suspended(card) == 0)) -++ mmc_set_cur_mode(host, INIT_MODE); -++ } -++#endif -++ if (!IS_ERR_OR_NULL(nebula->hclk)) { -++ ret = clk_prepare_enable(nebula->hclk); -++ if (ret != 0) { -++ pr_err("%s: resume hclk enable fail\n", mmc_hostname(host->mmc)); -++ return ret; -++ } -++ } -++ -++ return sdhci_pltfm_resume(dev); -++} -++#endif -+diff --git a/drivers/vendor/mmc/adapter/nebula_fmea.c b/drivers/vendor/mmc/adapter/nebula_fmea.c -+new file mode 100755 -+index 000000000..75cf9c729 -+--- /dev/null -++++ b/drivers/vendor/mmc/adapter/nebula_fmea.c -+@@ -0,0 +1,123 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include "core.h" -++#include "mmc_ops.h" -++#include "drv_dft_event.h" -++#include "nebula_fmea.h" -++ -++#ifndef CONFIG_LINUX_PRODUCT -++ -++static int g_check_immediately = 0; -++module_param(g_check_immediately, int, 0644); -++ -++static int nebula_fmea_update_extcsd(struct mmc_card *card) -++{ -++ int ret; -++ u8 *ext_csd; -++ -++ mmc_claim_host(card->host); -++ ret = mmc_get_ext_csd(card, &ext_csd); -++ mmc_release_host(card->host); -++ if (ret) -++ return ret; -++ -++ card->ext_csd.device_life_time_est_typ_a = ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]; -++ card->ext_csd.device_life_time_est_typ_b = ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]; -++ kfree(ext_csd); -++ -++ return 0; -++} -++ -++static noinline bool nebula_fmea_lifettime_exceed(struct mmc_card *card) -++{ -++ u8 type_a, type_b; -++ -++ type_a = card->ext_csd.device_life_time_est_typ_a; -++ type_b = card->ext_csd.device_life_time_est_typ_b; -++ -++ if ((type_a >= DEVICE_LIFE_TIME_EST_VAL) || (type_b >= DEVICE_LIFE_TIME_EST_VAL)) { -++ return true; -++ } -++ -++ return false; -++} -++ -++static void nebula_fmea_check_lifetime(struct work_struct *work) -++{ -++ int ret; -++ td_handle handle; -++ nebula_fmea *fmea = -++ container_of(work, struct sdhci_nebula_fmea, mmc_lifecheck_work.work); -++ struct mmc_card *card = fmea->host->mmc->card; -++ -++ if ((card == NULL) || (card->type != MMC_TYPE_MMC)) { -++ goto out; -++ } -++ -++ if ((fmea->life_check_interval > 0) && (g_check_immediately == 0)) { -++ fmea->life_check_interval--; -++ goto out; -++ } -++ -++ fmea->life_check_interval = DEVICE_LIFE_CHECK_INTERVAL; -++ ret = nebula_fmea_update_extcsd(card); -++ if (ret != 0) { -++ goto out; -++ } -++ -++ if (nebula_fmea_lifettime_exceed(card)) { -++ ret = dft_drv_event_create(SDHCI_FMEA_LIFE_TIME_EXCEED, &handle); -++ if (ret == TD_SUCCESS) { -++ dft_drv_event_put_string(handle, "PNAME", current->comm); -++ dft_drv_event_put_string(handle, "F1NAME", __func__); -++ dft_drv_event_put_string(handle, "FLASH_TYPE", "EMMC"); -++ dft_drv_event_put_integral(handle, "DEVICE_LIFE_TIME_EST_TYP_A", \ -++ card->ext_csd.device_life_time_est_typ_a); -++ dft_drv_event_put_integral(handle, "DEVICE_LIFE_TIME_EST_TYP_B", \ -++ card->ext_csd.device_life_time_est_typ_b); -++ dft_drv_event_report(handle); -++ dft_drv_event_destroy(handle); -++ } -++ } -++ -++out: -++ queue_delayed_work(system_freezable_wq, (struct delayed_work *)work, HZ); -++} -++ -++int sdhci_nebula_fmea_init(struct sdhci_host *host, nebula_fmea *fmea) -++{ -++ struct delayed_work *work = &fmea->mmc_lifecheck_work; -++ -++ fmea->host = host; -++ fmea->life_check_interval = DEVICE_LIFE_CHECK_INTERVAL; -++ INIT_DELAYED_WORK(work, nebula_fmea_check_lifetime); -++ queue_delayed_work(system_freezable_wq, work, HZ); -++ -++ return 0; -++} -++ -++int sdhci_nebula_fmea_deinit(nebula_fmea *fmea) -++{ -++ cancel_delayed_work(&fmea->mmc_lifecheck_work); -++ -++ return 0; -++} -++#else -++int sdhci_nebula_fmea_init(struct sdhci_host *host, nebula_fmea *fmea) -++{ -++ return 0; -++} -++ -++int sdhci_nebula_fmea_deinit(nebula_fmea *fmea) -++{ -++ return 0; -++} -++#endif -++ -+diff --git a/drivers/vendor/mmc/adapter/nebula_quick.c b/drivers/vendor/mmc/adapter/nebula_quick.c -+new file mode 100755 -+index 000000000..f32730865 -+--- /dev/null -++++ b/drivers/vendor/mmc/adapter/nebula_quick.c -+@@ -0,0 +1,252 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#ifdef CONFIG_MMC_QUICKBOOT -++#include -++#include -++ -++#include "sdhci.h" -++#include "sdhci_nebula.h" -++#include "nebula_quick.h" -++ -++static emmc_qboot_u mmc_get_qboot_mode(struct sdhci_host *host) -++{ -++ u32 param1_offset; -++ emmc_param_gen1_u param1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ BUG_ON(nebula->qboot_virt_addr == NULL); -++ param1_offset = nebula->info->qboot_param1_ofs; -++ param1.u32 = readl(nebula->qboot_virt_addr + param1_offset); -++ return (emmc_qboot_u)param1.bits.emmc_qboot_mode; -++ } -++ -++ return QUICK_BOOT_DIS; -++} -++ -++bool mmc_is_fast_boot(struct sdhci_host *host) -++{ -++ return (mmc_get_qboot_mode(host) != QUICK_BOOT_DIS); -++} -++EXPORT_SYMBOL(mmc_is_fast_boot); -++ -++int mmc_fast_boot_init(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ if (nebula->info->qboot_phy_addr == INVALID_DATA) { -++ pr_err("%s: invalid quick phy addr.\n", mmc_hostname(host->mmc)); -++ return -EINVAL; -++ } -++ -++ nebula->qboot_virt_addr = ioremap(nebula->info->qboot_phy_addr, PAGE_SIZE); -++ if (nebula->qboot_virt_addr == NULL) { -++ pr_err("%s: quick boot remap failed.\n", mmc_hostname(host->mmc)); -++ return -ENOMEM; -++ } -++ -++ if (mmc_is_fast_boot(host)) { -++ nebula->priv_cap |= NEBULA_CAP_QUICK_BOOT; -++ } -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++static emmc_mode_u mmc_get_cur_mode(struct sdhci_host *host) -++{ -++ u32 param1_offset; -++ emmc_param_gen1_u param1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0 && -++ (mmc_get_qboot_mode(host) == QUICK_BOOT_WARM)) { -++ param1_offset = nebula->info->qboot_param1_ofs; -++ param1.u32 = readl(nebula->qboot_virt_addr + param1_offset); -++ return (emmc_mode_u)param1.bits.emmc_cur_mode; -++ } -++ -++ return INIT_MODE; -++} -++ -++void mmc_set_cur_mode(struct sdhci_host *host, emmc_mode_u mode) -++{ -++ u32 param1_offset; -++ emmc_param_gen1_u param1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0 && -++ (mmc_get_qboot_mode(host) == QUICK_BOOT_WARM)) { -++ BUG_ON(nebula->qboot_virt_addr == NULL); -++ param1_offset = nebula->info->qboot_param1_ofs; -++ param1.u32 = readl(nebula->qboot_virt_addr + param1_offset); -++ param1.bits.emmc_cur_mode = mode; -++ writel(param1.u32, nebula->qboot_virt_addr + param1_offset); -++ } -++} -++ -++void mmc_reset_init_mode(struct sdhci_host *host) -++{ -++ return mmc_set_cur_mode(host, INIT_MODE); -++} -++EXPORT_SYMBOL(mmc_reset_init_mode); -++ -++int mmc_save_cid(struct mmc_host *host, struct mmc_card *card, u32 *cid) -++{ -++ if (mmc_is_fast_boot(mmc_priv(host)) && (card->raw_cid[0] == MMC_CID_MAGIC)) -++ return memcpy_s(card->raw_cid, sizeof(card->raw_cid), cid, sizeof(card->raw_cid)); -++ return 0; -++} -++EXPORT_SYMBOL(mmc_save_cid); -++ -++void mmc_parameter_init(struct mmc_host *mmc) -++{ -++ u8 reg8; -++ u32 param1_offset; -++ emmc_param_gen1_u param1; -++ struct sdhci_host *host = mmc_priv(mmc); -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const u8 bus_width[] = {MMC_BUS_WIDTH_1, MMC_BUS_WIDTH_4, \ -++ MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_1}; -++ const u8 uhs_mode[] = {MMC_TIMING_LEGACY, MMC_TIMING_MMC_HS, 0, \ -++ MMC_TIMING_MMC_HS200, MMC_TIMING_MMC_DDR52, 0, 0, MMC_TIMING_MMC_HS400}; -++ -++ if (nebula->devid != MMC_DEV_TYPE_MMC_0) { -++ return; -++ } -++ -++ BUG_ON(nebula->qboot_virt_addr == NULL); -++ param1_offset = nebula->info->qboot_param1_ofs; -++ param1.u32 = readl(nebula->qboot_virt_addr + param1_offset); -++ -++ if (mmc_get_qboot_mode(host) == QUICK_BOOT_COLD) { -++ /* Cold boot choice from host controller */ -++ param1.bits.emmc_uhs_mode_sel = \ -++ sdhci_readb(host, SDHCI_HOST_CONTROL2) & SDHCI_CTRL_UHS_MASK; -++ param1.bits.emmc_enh_strobe = \ -++ ((sdhci_readw(host, SDHCI_EMMC_CTRL) & SDHCI_ENH_STROBE_EN) != 0); -++ reg8 = sdhci_readb(host, SDHCI_HOST_CONTROL); -++ param1.bits.emmc_bus_width = ((reg8 & SDHCI_CTRL_8BITBUS) != 0) ? BUS_8BIT_IDX : \ -++ (((reg8 & SDHCI_CTRL_4BITBUS) != 0) ? BUS_4BIT_IDX : BUS_1BIT_IDX); -++ } -++ -++ mmc->ios.bus_width = bus_width[param1.bits.emmc_bus_width]; -++ mmc->ios.timing = uhs_mode[param1.bits.emmc_uhs_mode_sel]; -++ host->timing = mmc->ios.timing; -++ nebula->tuning_phase = sdhci_readl(host, SDHCI_AT_STAT) & SDHCI_PHASE_SEL_MASK; -++ mmc->ios.enhanced_strobe = param1.bits.emmc_enh_strobe; -++ -++ mmc->ios.vdd = (unsigned short)fls(mmc->ocr_avail) - 1; -++ mmc->ios.power_mode = MMC_POWER_ON; -++ /* OPENDRAIN: Identify process, PUSHPULL: Transfer */ -++ mmc->ios.bus_mode = MMC_BUSMODE_PUSHPULL; -++ mmc->ios.drv_type = 0; -++ mmc->ios.clock = mmc->f_max; -++ mmc->actual_clock = mmc->f_max; -++} -++ -++u32 mmc_get_rocr(struct sdhci_host *host) -++{ -++ u32 rocr = 0; -++ u32 param1_offset; -++ emmc_param_gen1_u param1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ BUG_ON(nebula->qboot_virt_addr == NULL); -++ param1_offset = nebula->info->qboot_param1_ofs; -++ param1.u32 = readl(nebula->qboot_virt_addr + param1_offset); -++ rocr = MMC_VDD_165_195; -++ rocr |= MMC_VDD_32_33 | MMC_VDD_33_34; -++ /* for >= 2GiB Device, hcs mode assign from ext csd */ -++ rocr |= (param1.bits.emmc_hcs_mode << HCS_BIT); -++ } -++ -++ return rocr; -++} -++ -++static u32 mmc_get_io_info(struct sdhci_host *host) -++{ -++ u32 timing; -++ emmc_param_gen0_u param0; -++ nebula_timing *timing_data = NULL; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const nebula_info *info = nebula->info; -++ -++ param0.u32 = 0; -++ -++ /* choice host timing data */ -++ timing_data = info->timing + host->timing; -++ if (!timing_data->data_valid) { -++ /* choice legacy mode timing */ -++ timing_data = info->timing; -++ } -++ -++ timing = timing_data->timing[IO_TYPE_CMD]; -++ param0.bits.emmc_cmd_drv = \ -++ (timing & info->io_drv_str_mask) >> info->io_drv_str_bit_ofs; -++ param0.bits.emmc_cmd_sl = \ -++ (timing & info->io_drv_str_mask) >> info->io_drv_str_bit_ofs; -++ -++ timing = timing_data->timing[IO_TYPE_CLK]; -++ param0.bits.emmc_clk_drv = \ -++ (timing & info->io_drv_str_mask) >> info->io_drv_str_bit_ofs; -++ param0.bits.emmc_clk_sl = \ -++ (timing & info->io_drv_str_mask) >> info->io_drv_str_bit_ofs; -++ -++ timing = timing_data->timing[IO_TYPE_DATA]; -++ param0.bits.emmc_data_drv = \ -++ (timing & info->io_drv_str_mask) >> info->io_drv_str_bit_ofs; -++ param0.bits.emmc_data_sl = \ -++ (timing & info->io_drv_str_mask) >> info->io_drv_str_bit_ofs; -++ -++ return param0.u32; -++} -++ -++int mmc_save_parameters(struct mmc_host *mmc) -++{ -++ unsigned int reg; -++ emmc_param_gen0_u param0; -++ emmc_param_gen1_u param1; -++ struct sdhci_host *host = mmc_priv(mmc); -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const nebula_info *info = nebula->info; -++ -++ /* eMMC work parameters store by uboot, only eMMC support, cold boot no need */ -++ if ((nebula->devid != MMC_DEV_TYPE_MMC_0) || \ -++ mmc_get_qboot_mode(host) == QUICK_BOOT_COLD || \ -++ (mmc_get_cur_mode(host) == TRAN_MODE)) { -++ return ERET_SUCCESS; -++ } -++ -++ BUG_ON(nebula->qboot_virt_addr == NULL); -++ param0.u32 = readl(nebula->qboot_virt_addr); -++ -++ regmap_read(nebula->crg_regmap, info->crg_ofs[CRG_CLK_RST], ®); -++ param0.bits.emmc_clk_sel = \ -++ ((reg & nebula->mask->crg_clk_sel_mask) >> nebula->mask->crg_clk_sel_ofs); -++ param0.bits.emmc_clk_ph_sel = nebula->drv_phase; -++ param0.bits.emmc_sw_clk_ph = sdhci_readb(host, SDHCI_AT_STAT); -++ -++ /* eMMC IO info */ -++ param0.u32 |= mmc_get_io_info(host); -++ -++ writel(param0.u32, nebula->qboot_virt_addr); -++ -++ param1.u32 = readl(nebula->qboot_virt_addr + info->qboot_param1_ofs); -++ param1.bits.emmc_uhs_mode_sel = \ -++ sdhci_readb(host, SDHCI_HOST_CONTROL2) & SDHCI_CTRL_UHS_MASK; -++ param1.bits.emmc_enh_strobe = mmc->ios.enhanced_strobe; -++ param1.bits.emmc_bus_width = (mmc->ios.bus_width == MMC_BUS_WIDTH_8) ? BUS_8BIT_IDX : \ -++ ((mmc->ios.bus_width == MMC_BUS_WIDTH_4) ? BUS_4BIT_IDX : BUS_1BIT_IDX); -++ param1.bits.emmc_hcs_mode = mmc_card_is_blockaddr(mmc->card); -++ writel(param1.u32, nebula->qboot_virt_addr + info->qboot_param1_ofs); -++ -++ mmc_set_cur_mode(host, TRAN_MODE); -++ -++ return ERET_SUCCESS; -++} -++EXPORT_SYMBOL(mmc_save_parameters); -++#endif -+diff --git a/drivers/vendor/mmc/adapter/nebula_quick.h b/drivers/vendor/mmc/adapter/nebula_quick.h -+new file mode 100755 -+index 000000000..e4882c15c -+--- /dev/null -++++ b/drivers/vendor/mmc/adapter/nebula_quick.h -+@@ -0,0 +1,86 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _MMC_NEBULA_QUICK_H_ -++#define _MMC_NEBULA_QUICK_H_ -++ -++#include -++ -++#include "nebula_quick.h" -++ -++typedef enum { -++ BUS_1BIT_IDX = 0, -++ BUS_4BIT_IDX, -++ BUS_8BIT_IDX, -++} emmc_bus_idx_u; -++ -++#define MMC_CMD_SLEEP_AWAKE 5 -++#define MMC_SAWAKE_SHIFT_BIT 15 -++#define MMC_RCA_SHIFT_BIT 16 -++ -++#define HCS_BIT 30 -++ -++#define MMC_CID_MAGIC 0x45239867 -++ -++/* emmc parameters type */ -++typedef union { -++ struct { -++ u32 emmc_clk_ph_sel : 5; // [4:0] -++ u32 emmc_clk_sel : 3; // [7:5] -++ u32 emmc_sw_clk_ph : 8; // [15:8] -++ u32 emmc_cmd_drv : 4; // [19:16] -++ u32 emmc_cmd_sl : 1; // [20] -++ u32 emmc_clk_drv : 4; // [24:21] -++ u32 emmc_clk_sl : 1; // [25] -++ u32 emmc_data_drv : 4; // [29:26] -++ u32 emmc_data_sl : 1; // [30] -++ u32 reserved_0 : 1; // [31] -++ } bits; -++ u32 u32; -++} emmc_param_gen0_u; -++ -++/* emmc parameters type */ -++typedef union { -++ struct { -++ u32 emmc_uhs_mode_sel : 3; // [2:0] -++ u32 emmc_enh_strobe : 1; // [3] -++ u32 emmc_bus_width : 2; // [5:4] -++ u32 emmc_hcs_mode : 1; // [6] -++ u32 emmc_spec_ver : 4; // [10:7] -++ u32 emmc_chip_size : 11; // [21:11] -++ u32 emmc_qboot_mode : 2; // [23:22] -++ u32 emmc_cur_mode : 8; // [31:24] -++ } bits; -++ u32 u32; -++} emmc_param_gen1_u; -++ -++typedef enum { -++ INIT_MODE = 0x0, -++ SLEEP_MODE = 0x5A, -++ BOOT_MODE, -++ DS_MODE, -++ TRAN_MODE -++} emmc_mode_u; -++ -++typedef enum { -++ QUICK_BOOT_DIS = 0x0, -++ QUICK_BOOT_WARM, -++ QUICK_BOOT_COLD, -++ QUICK_BOOT_MAX -++} emmc_qboot_u; -++ -++struct mmc_host; -++struct sdhci_host; -++struct mmc_card; -++int mmc_fast_boot_init(struct sdhci_host *host); -++void mmc_parameter_init(struct mmc_host *mmc); -++void mmc_set_cur_mode(struct sdhci_host *host, emmc_mode_u mode); -++u32 mmc_get_rocr(struct sdhci_host *host); -++ -++int mmc_save_parameters(struct mmc_host *mmc); -++void mmc_reset_init_mode(struct sdhci_host *host); -++bool mmc_is_fast_boot(struct sdhci_host *host); -++int mmc_save_cid(struct mmc_host *host, struct mmc_card *card, u32 *cid); -++ -++#endif /* _MMC_NEBULA_QUICK_H_ */ -+diff --git a/drivers/vendor/mmc/adapter/nebula_quirk_ids.h b/drivers/vendor/mmc/adapter/nebula_quirk_ids.h -+new file mode 100755 -+index 000000000..40787ede2 -+--- /dev/null -++++ b/drivers/vendor/mmc/adapter/nebula_quirk_ids.h -+@@ -0,0 +1,54 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _DRIVERS_MMC_NEBULA_QUIRK_IDS_H -++#define _DRIVERS_MMC_NEBULA_QUIRK_IDS_H -++ -++#define MMC_CMDQ_FORCE_OFF 0x1 -++#define MMC_CMDQ_DIS_WHITELIST 0x2 -++ -++#ifdef CONFIG_MMC_CQHCI -++#include "card.h" -++#include "host.h" -++#include "quirks.h" -++ -++#define CID_MANFID_SANDISK_F 0x45 -++/* -++ * Quirk cmdq for MMC products. -++ */ -++static inline void __maybe_unused nebula_cmdq_quirk_mmc(struct mmc_card *card, int data) -++{ -++ struct mmc_host *host = card->host; -++ -++ if (host != NULL) { -++ host->caps2 |= (MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD); -++ pr_debug("Whitelist: match device %s\n", card->cid.prod_name); -++ } -++} -++ -++static const struct mmc_fixup mmc_cmdq_whitelist[] = { -++ /* Toshiba */ -++ MMC_FIXUP("008GB0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("016G30", CID_MANFID_TOSHIBA, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("016GB0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("008G30", CID_MANFID_TOSHIBA, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ /* Samsung */ -++ MMC_FIXUP("BJTD4R", CID_MANFID_SAMSUNG, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("CKTA42", CID_MANFID_SAMSUNG, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("8GTF4R", CID_MANFID_SAMSUNG, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("AJTD4R", CID_MANFID_SAMSUNG, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ /* Sandisk */ -++ MMC_FIXUP("DF4032", CID_MANFID_SANDISK_F, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("DG4016", CID_MANFID_SANDISK_F, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("DF4128", CID_MANFID_SANDISK_F, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ MMC_FIXUP("DG4008", CID_MANFID_SANDISK_F, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ /* Kingston */ -++ MMC_FIXUP("TB2816", CID_MANFID_KINGSTON, CID_OEMID_ANY, nebula_cmdq_quirk_mmc, 0), -++ /* null, no remove */ -++ END_FIXUP -++}; -++ -++#endif /* CONFIG_MMC_CQHCI */ -++ -++#endif /* _DRIVERS_MMC_BSP_QUIRK_IDS_H */ -+diff --git a/drivers/vendor/mmc/dfx/mci_proc.c b/drivers/vendor/mmc/dfx/mci_proc.c -+new file mode 100755 -+index 000000000..e7c359ec3 -+--- /dev/null -++++ b/drivers/vendor/mmc/dfx/mci_proc.c -+@@ -0,0 +1,304 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++#include -++#include -++#include "card.h" -++#include "core.h" -++#include "sdhci_nebula.h" -++#include "mci_proc.h" -++ -++#define MCI_PARENT "mci" -++#define MCI_STATS_PROC "mci_info" -++#define MAX_CLOCK_SCALE 4 -++ -++static struct proc_dir_entry *g_proc_mci_dir; -++ -++static char *g_card_type[MAX_CARD_TYPE + 1] = { -++ "MMC card", -++ "SD card", -++ "SDIO card", -++ "SD combo (IO+mem) card", -++ "unknown" -++}; -++static char *g_clock_unit[MAX_CLOCK_SCALE] = { -++ "Hz", -++ "KHz", -++ "MHz", -++ "GHz" -++}; -++ -++#define BIT_WIDTH 32 -++static unsigned int unstuff_bits(const u32 *resp, u32 start, u32 size) -++{ -++ const u32 mask = ((size < BIT_WIDTH) ? 1 << size : 0) - 1; -++ const u32 off = 0x3 - ((start) / BIT_WIDTH); -++ const u32 shft = (start) & 31; /* max shift value 31 */ -++ u32 res; -++ -++ res = resp[off] >> shft; -++ if (size + shft > BIT_WIDTH) -++ res |= resp[off - 1] << ((BIT_WIDTH - shft) % BIT_WIDTH); -++ res = res & mask; -++ -++ return res; -++} -++ -++static char *mci_get_card_type(unsigned int sd_type) -++{ -++ if (sd_type >= MAX_CARD_TYPE) -++ return g_card_type[MAX_CARD_TYPE]; -++ else -++ return g_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; /* Cal freq by dividing 1000 */ -++ 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_speed(struct seq_file *s, struct mmc_host *mmc) -++{ -++ unsigned int speed_class, grade_speed_uhs; -++ struct mmc_card *card = mmc->card; -++ const char *uhs_bus_speed_mode = ""; -++ static const char * const 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 ", -++ }; -++ -++ if (is_card_uhs(mmc->ios.timing) && -++ card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)) -++ uhs_bus_speed_mode = -++ uhs_speeds[card->sd_bus_speed]; -++ -++ seq_printf(s, "\tMode: %s %s\n", -++ is_card_uhs(mmc->ios.timing) ? "UHS" : -++ is_card_hs(mmc->ios.timing) ? "HS" : -++ (mmc->ios.enhanced_strobe == true) ? "HS400ES" : -++ (mmc->ios.timing == MMC_TIMING_MMC_HS400) ? "HS400" : -++ (mmc->ios.timing == MMC_TIMING_MMC_HS200) ? "HS200" : -++ (mmc->ios.timing == MMC_TIMING_MMC_DDR52) ? "DDR" : -++ "DS", uhs_bus_speed_mode); -++ -++ speed_class = unstuff_bits(card->raw_ssr, 56, 8); /* 56 = 440 - 384 */ -++ grade_speed_uhs = unstuff_bits(card->raw_ssr, 12, 4); /* 12 = 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"); -++} -++ -++static void mci_stats_seq_clock(struct seq_file *s, struct mmc_host *mmc) -++{ -++ unsigned int clock, clock_scale; -++ unsigned int clock_value = 0; -++ -++ clock = mmc->ios.clock; -++ clock_scale = analyze_clock_scale(clock, &clock_value); -++ seq_printf(s, "\tHost work clock: %d%s\n", -++ clock_value, g_clock_unit[clock_scale]); -++ -++ clock = mmc->ios.clock; -++ clock_scale = analyze_clock_scale(clock, &clock_value); -++ seq_printf(s, "\tCard support clock: %d%s\n", -++ clock_value, g_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, g_clock_unit[clock_scale]); -++} -++ -++static void mci_stats_seq_printout(struct seq_file *s) -++{ -++ unsigned int index_mci; -++ const char *type = NULL; -++ struct mmc_host *mmc = NULL; -++ struct mmc_card *card = NULL; -++ int present; -++ struct sdhci_host *host = NULL; -++ struct sdhci_nebula *priv = NULL; -++ -++ for (index_mci = 0; index_mci < MCI_SLOT_NUM; index_mci++) { -++ mmc = g_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); -++ } -++ -++ mmc_claim_host(mmc); -++ host = mmc_priv(mmc); -++ priv = nebula_priv(host); -++ -++ present = host->mmc->ops->get_cd(host->mmc); -++ if (present != 0) -++ seq_puts(s, ": pluged"); -++ else -++ seq_puts(s, ": unplugged"); -++ -++ card = host->mmc->card; -++ if (present == 0) { -++ seq_puts(s, "_disconnected\n"); -++ } else if ((present != 0) && (card == NULL)) { -++ seq_puts(s, "_init_failed\n"); -++ } else if (card != NULL) { -++ seq_puts(s, "_connected\n"); -++ -++ seq_printf(s, "\tType: %s", -++ mci_get_card_type(card->type)); -++ -++ if (card->state & MMC_STATE_BLOCKADDR) { -++ type = ((card->state & MMC_CARD_SDXC) != 0) ? -++ "SDXC" : "SDHC"; -++ seq_printf(s, "(%s)\n", type); -++ } -++ -++ mci_stats_seq_speed(s, mmc); -++ mci_stats_seq_clock(s, mmc); -++ -++ /* add card read/write error count */ -++ seq_printf(s, "\tCard error count: %d\n", host->error_count); -++ } -++ mmc_release_host(mmc); -++ } -++} -++ -++/* 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; -++ -++ return NULL; -++} -++ -++/* proc interface next */ -++static void *mci_seq_next(struct seq_file *s, void *v, loff_t *pos) -++{ -++ (*pos)++; -++ -++ return mci_seq_start(s, pos); -++} -++ -++/* 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 */ -++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0) -++static const struct file_operations mci_stats_proc_ops = { -++ .open = mci_stats_proc_open, -++ .read = seq_read, -++ .release = seq_release -++}; -++#else -++static const struct proc_ops mci_stats_proc_ops = { -++ .proc_open = mci_stats_proc_open, -++ .proc_read = seq_read, -++ .proc_release = seq_release -++}; -++#endif -++ -++int mci_proc_init(void) -++{ -++ struct proc_dir_entry *proc_stats_entry = NULL; -++ -++ g_proc_mci_dir = proc_mkdir(MCI_PARENT, NULL); -++ if (g_proc_mci_dir == NULL) { -++ pr_err("%s: failed to create proc file %s\n", -++ __func__, MCI_PARENT); -++ return 1; -++ } -++ -++ proc_stats_entry = proc_create(MCI_STATS_PROC, -++ 0, g_proc_mci_dir, &mci_stats_proc_ops); -++ if (proc_stats_entry == NULL) { -++ pr_err("%s: failed to create proc file %s\n", -++ __func__, MCI_STATS_PROC); -++ remove_proc_entry(MCI_PARENT, NULL); -++ return 1; -++ } -++ -++ return 0; -++} -++ -++int mci_proc_shutdown(void) -++{ -++ if (g_proc_mci_dir != NULL) { -++ remove_proc_entry(MCI_STATS_PROC, g_proc_mci_dir); -++ remove_proc_entry(MCI_PARENT, NULL); -++ g_proc_mci_dir = NULL; -++ } -++ -++ return 0; -++} -+diff --git a/drivers/vendor/mmc/dfx/mci_proc.h b/drivers/vendor/mmc/dfx/mci_proc.h -+new file mode 100755 -+index 000000000..65a9237a9 -+--- /dev/null -++++ b/drivers/vendor/mmc/dfx/mci_proc.h -+@@ -0,0 +1,16 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __MCI_PROC_H__ -++#define __MCI_PROC_H__ -++ -++#include "mci_proc.h" -++ -++#define MAX_CARD_TYPE 4 -++#define MAX_SPEED_MODE 5 -++ -++int mci_proc_init(void); -++int mci_proc_shutdown(void); -++ -++#endif /* __MCI_PROC_H__ */ -+diff --git a/drivers/vendor/mmc/dfx/nebula_dfx.c b/drivers/vendor/mmc/dfx/nebula_dfx.c -+new file mode 100755 -+index 000000000..6a1e038c2 -+--- /dev/null -++++ b/drivers/vendor/mmc/dfx/nebula_dfx.c -+@@ -0,0 +1,493 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "card.h" -++#include "core.h" -++#include "sdhci_nebula.h" -++#include "nebula_dfx.h" -++ -++#ifdef CONFIG_SDHCI_NEBULA_DFX -++ -++#define BITS_PER_U32 32 -++#define BYTES_PER_U32 4 -++ -++#define SD_SSR_BITS_OFFSET 384 -++#define SD_SSR_SPEED_CLASS_WIDTH 8 -++#define SD_SSR_SPEED_CLASS_OFS (440 - SD_SSR_BITS_OFFSET) -++#define SD_SSR_UHS_SPEED_GRADE_WIDTH 4 -++#define SD_SSR_UHS_SPEED_GRADE_OFS (396 - SD_SSR_BITS_OFFSET) -++ -++/** -++ * 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 -++ */ -++#define CMD_R1_ERRORS \ -++ (R1_OUT_OF_RANGE | R1_ADDRESS_ERROR | \ -++ R1_BLOCK_LEN_ERROR | R1_WP_VIOLATION | \ -++ R1_CC_ERROR | R1_ERROR) -++ -++static char *g_card_type_string[] = { -++ "MMC card", -++ "SD card", -++ "SDIO card", -++ "SD combo (IO+mem) card", -++ "unknown" -++}; -++ -++static void nebula_show_str(struct seq_file *m, const char *key, const char *val) -++{ -++ seq_printf(m, "%-25s:%-35s|\n", key, val); -++} -++ -++static void nebula_show_u32(struct seq_file *m, const char *key, u32 val) -++{ -++ seq_printf(m, "%-25s:%-35u|\n", key, val); -++} -++ -++static void nebula_show_hex(struct seq_file *m, const char *key, u32 val) -++{ -++ seq_printf(m, "%-25s:0x%-33x|\n", key, val); -++} -++ -++static u32 unstuff_bits(const u32 *resp, u32 start, u32 size) -++{ -++ const u32 mask = ((size < BITS_PER_U32) ? (1 << size) : 0) - 1; -++ const u32 off = (BYTES_PER_U32 - 1) - ((start) / BITS_PER_U32); -++ const u32 shft = (start) & (BITS_PER_U32 - 1); -++ u32 res; -++ -++ res = resp[off] >> shft; -++ if ((size + shft) > BITS_PER_U32) -++ res |= resp[off - 1] << ((BITS_PER_U32 - shft) % BITS_PER_U32); -++ res = res & mask; -++ -++ return res; -++} -++ -++static char *nebula_get_card_type(u32 card_type) -++{ -++ if (card_type >= ARRAY_SIZE(g_card_type_string)) -++ return g_card_type_string[ARRAY_SIZE(g_card_type_string) - 1]; -++ else -++ return g_card_type_string[card_type]; -++} -++ -++static void nebula_help_show(struct seq_file *m) -++{ -++ seq_puts(m, "#\n" -++ "# echo \"help \" > /proc/mmc[x]/status\n" -++ "# echo \"rescan \" > /proc/mmc[x]/status\n" -++ "# mode format: ,; example: \"hs200,4\"\n" -++ "# speed: ds, hs, hs200, hs400, hs400es, sdr12, sdr25, sdr50, sdr104\n" -++ "# bus_width: 1, 4, 8\n" -++ "# echo \"lvl=\" > /proc/mmc[x]/status\n" -++ "# log_level: 0, 1, 2\n" -++ "#\n"); -++} -++ -++static inline bool is_card_uhs(unsigned char timing) -++{ -++ return (timing >= MMC_TIMING_UHS_SDR12) && -++ (timing <= MMC_TIMING_UHS_DDR50); -++}; -++ -++static inline bool is_card_hs(unsigned char timing) -++{ -++ return (timing == MMC_TIMING_SD_HS) || (timing == MMC_TIMING_MMC_HS); -++}; -++ -++static void nebula_seq_sd_info(struct seq_file *m) -++{ -++ struct sdhci_host *host = (struct sdhci_host *)m->private; -++ struct card_info *info = &host->c_info; -++ const char *uhs_bus_speed_mode = "DS"; -++ u32 speed_class, grade_speed_uhs; -++ static const char * const uhs_speeds[] = { -++ [UHS_SDR12_BUS_SPEED] = "UHS SDR12", -++ [UHS_SDR25_BUS_SPEED] = "UHS SDR25", -++ [UHS_SDR50_BUS_SPEED] = "UHS SDR50", -++ [UHS_SDR104_BUS_SPEED] = "UHS SDR104", -++ [UHS_DDR50_BUS_SPEED] = "UHS DDR50", -++ }; -++ -++ if (is_card_uhs(info->timing) && info->sd_bus_speed < ARRAY_SIZE(uhs_speeds)) { -++ uhs_bus_speed_mode = uhs_speeds[info->sd_bus_speed]; -++ } -++ -++ nebula_show_str(m, " work_mode", (is_card_hs(info->timing)) ? "HS" : uhs_bus_speed_mode); -++ -++ nebula_show_str(m, " capacity_type", -++ ((info->card_state & MMC_STATE_BLOCKADDR) == 0) ? "SD (<=2GB)" : -++ ((info->card_state & MMC_CARD_SDXC) != 0) ? "SDXC (<=2TB)" : "SDHC (<=32GB)"); -++ -++ speed_class = unstuff_bits(info->ssr, SD_SSR_SPEED_CLASS_OFS, -++ SD_SSR_SPEED_CLASS_WIDTH); -++ nebula_show_str(m, " speed_class", -++ (speed_class == SD_SPEED_CLASS0) ? "0" : -++ (speed_class == SD_SPEED_CLASS1) ? "2" : -++ (speed_class == SD_SPEED_CLASS2) ? "4" : -++ (speed_class == SD_SPEED_CLASS3) ? "6" : -++ (speed_class == SD_SPEED_CLASS4) ? "10" : -++ "Reserved"); -++ -++ grade_speed_uhs = unstuff_bits(info->ssr, SD_SSR_UHS_SPEED_GRADE_OFS, -++ SD_SSR_UHS_SPEED_GRADE_WIDTH); -++ nebula_show_str(m, " uhs_speed_grade", -++ (grade_speed_uhs == SD_SPEED_GRADE0) ? -++ "Less than 10MB/sec(0h)" : -++ (grade_speed_uhs == SD_SPEED_GRADE1) ? -++ "10MB/sec and above(1h)" : -++ "Reserved"); -++} -++ -++static void nebula_seq_emmc_info(struct seq_file *m) -++{ -++ struct sdhci_host *host = (struct sdhci_host *)m->private; -++ struct mmc_host *mmc = host->mmc; -++ -++ nebula_show_str(m, " work_mode", -++ (mmc->ios.enhanced_strobe) ? "HS400ES" : -++ (mmc->ios.timing == MMC_TIMING_MMC_HS400) ? "HS400" : -++ (mmc->ios.timing == MMC_TIMING_MMC_HS200) ? "HS200" : -++ (mmc->ios.timing == MMC_TIMING_MMC_DDR52) ? "DDR" : -++ (mmc->ios.timing == MMC_TIMING_MMC_HS) ? "HS" : "DS"); -++} -++ -++static void nebula_cmd_backtrace_show(struct seq_file *m) -++{ -++ int idx, sp; -++ struct sdhci_host *host = (struct sdhci_host *)m->private; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ nebula_show_str(m, "command_trace", "idx command"); -++ sp = (nebula->cmd_bt.sp % NEBULA_DFX_BT_MAX_NUM) + 1; -++ for (idx = 0; idx < NEBULA_DFX_BT_MAX_NUM; idx++) { -++ seq_printf(m, "%-25s: %d CMD%-27u|\n", "", idx, -++ nebula->cmd_bt.opcode[sp++]); -++ sp %= NEBULA_DFX_BT_MAX_NUM; -++ } -++} -++ -++static int nebula_stats_show(struct seq_file *m, void *v) -++{ -++ bool card_insert = true; -++ struct sdhci_host *host = (struct sdhci_host *)m->private; -++ struct card_info *info = &host->c_info; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->dfx_cap.help) { -++ nebula_help_show(m); -++ nebula->dfx_cap.help = false; -++ return 0; -++ } -++ -++ if (nebula->dfx_cap.log_level >= DEBUG_LVL_VERBOSE) -++ sdhci_dumpregs(host); -++ -++ seq_printf(m, "========================%s=================================\n", -++ mmc_hostname(host->mmc)); -++ nebula_show_str(m, "version", SDHCI_NEBULA_KERNEL_VERSION); -++ nebula_show_str(m, "mmc_device", host->hw_name); -++ -++ if ((mmc_card_is_removable(host->mmc) != 0) && host->mmc->ops->get_cd != NULL) -++ card_insert = host->mmc->ops->get_cd(host->mmc); -++ -++ if (card_insert && (info->card_connect != CARD_CONNECT) && (host->mmc->card_status == MMC_CARD_INIT_FAIL)) { -++ nebula_show_str(m, "card_status", "pluged_init_failed"); -++ nebula_cmd_backtrace_show(m); -++ } else if (card_insert && (info->card_connect == CARD_CONNECT)) { -++ nebula_show_str(m, "card_status", "plugged"); -++ } else { -++ nebula_show_str(m, "card_status", "unplugged"); -++ } -++ -++ if (card_insert && (info->card_connect == CARD_CONNECT)) { -++ nebula_show_str(m, " card_type", nebula_get_card_type(info->card_type)); -++ if (info->card_type == MMC_TYPE_MMC) -++ nebula_seq_emmc_info(m); -++ else -++ nebula_seq_sd_info(m); -++ -++ nebula_show_str(m, " cmdq_enable", (host->cqe_on) ? "true" : "false"); -++ nebula_show_u32(m, " bus_width", (1 << host->mmc->ios.bus_width)); -++ nebula_show_u32(m, " host_work_clock", info->card_support_clock); -++ nebula_show_u32(m, " card_work_clock", host->mmc->actual_clock); -++ } -++ -++ nebula_show_hex(m, "host_caps1", host->mmc->caps); -++ nebula_show_hex(m, "host_caps2", host->mmc->caps2); -++ nebula_show_u32(m, "error_count", host->error_count); -++ -++ seq_puts(m, "=============================================================\n"); -++ -++ return 0; -++} -++ -++/* proc file open */ -++static int nebula_stats_proc_open(struct inode *inode, struct file *file) -++{ -++ return single_open(file, nebula_stats_show, PDE_DATA(inode)); -++}; -++ -++static void nebula_parse_bus_width(struct sdhci_host *host, const char *mode) -++{ -++ host->mmc->caps &= ~(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA); -++ -++ if (strstr(mode, ",4") != NULL) { -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA; -++ } else if (strstr(mode, ",8") != NULL) { -++ host->mmc->caps |= MMC_CAP_8_BIT_DATA; -++ } -++} -++ -++static void nebula_parse_mmc_mode(struct sdhci_host *host, const char *mode) -++{ -++ u32 avail_type = 0; -++ struct mmc_card *card = host->mmc->card; -++ -++ if (mmc_card_is_removable(card->host)) { -++ return; -++ } -++ -++ nebula_parse_bus_width(host, mode); -++ -++ if (strstr(mode, "hs400es") != NULL) { -++ avail_type |= EXT_CSD_CARD_TYPE_HS400ES | EXT_CSD_CARD_TYPE_HS400 | \ -++ EXT_CSD_CARD_TYPE_HS200 | EXT_CSD_CARD_TYPE_HS; -++ host->mmc->caps |= MMC_CAP_8_BIT_DATA; -++ } else if (strstr(mode, "hs400") != NULL) { -++ avail_type |= EXT_CSD_CARD_TYPE_HS400 | EXT_CSD_CARD_TYPE_HS200 | \ -++ EXT_CSD_CARD_TYPE_HS; -++ host->mmc->caps |= MMC_CAP_8_BIT_DATA; -++ } else if (strstr(mode, "hs200") != NULL) { -++ avail_type |= EXT_CSD_CARD_TYPE_HS200 | EXT_CSD_CARD_TYPE_HS; -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA; -++ } else if (strstr(mode, "hs") != NULL) { -++ avail_type |= EXT_CSD_CARD_TYPE_HS; -++ } -++ -++ card->mmc_avail_type = avail_type; -++} -++ -++static void nebula_parse_sd_mode(struct sdhci_host *host, const char *mode) -++{ -++ u32 sd_bus_speed = 0; -++ -++ host->mmc->caps &= ~(MMC_CAP_UHS | MMC_CAP_SD_HIGHSPEED); -++ -++ nebula_parse_bus_width(host, mode); -++ -++ if (strstr(mode, "sdr12")) { -++ sd_bus_speed |= MMC_CAP_UHS_SDR12; -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA; -++ } else if (strstr(mode, "sdr25") != NULL) { -++ sd_bus_speed |= MMC_CAP_UHS_SDR25; -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA; -++ } else if (strstr(mode, "sdr50") != NULL) { -++ sd_bus_speed |= MMC_CAP_UHS_SDR50; -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA; -++ } else if (strstr(mode, "sdr104") != NULL) { -++ sd_bus_speed |= MMC_CAP_UHS_SDR104; -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA; -++ } else if (strstr(mode, "hs") != NULL) { -++ sd_bus_speed |= MMC_CAP_SD_HIGHSPEED; -++ } -++ -++ host->mmc->caps |= sd_bus_speed; -++} -++ -++static void nebula_trigger_rescan(struct sdhci_host *host, const char *mode) -++{ -++ int ret; -++ struct mmc_host *mmc = host->mmc; -++ struct mmc_card *card = mmc->card; -++ -++ if (card != NULL) { -++ mmc_claim_host(mmc); -++ nebula_parse_mmc_mode(host, mode); -++ nebula_parse_sd_mode(host, mode); -++ mmc->card_status = MMC_CARD_UNINIT; -++ ret = mmc_hw_reset(mmc); -++ mmc->card_status = (ret == 0) ? MMC_CARD_INIT : MMC_CARD_INIT_FAIL; -++ if (mmc->ops->card_info_save) -++ mmc->ops->card_info_save(mmc); -++ mmc_release_host(mmc); -++ } -++} -++ -++static void nebula_trigger_detect(struct sdhci_host *host, const char *mode) -++{ -++ u8 val; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid != MMC_DEV_TYPE_MMC_0) { -++ val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); -++ val |= SDHCI_DETECT_POLARITY; -++ sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); -++ } -++} -++ -++static void nebula_trigger_help(struct sdhci_host *host, const char *mode) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (strstr(mode, "on") != NULL) { -++ nebula->dfx_cap.help = true; -++ } else if (strstr(mode, "off") != NULL) { -++ nebula->dfx_cap.help = false; -++ } -++} -++ -++static void nebula_trigger_log_level(struct sdhci_host *host, const char *mode) -++{ -++ u32 lvl = DEBUG_LVL_INFO; -++ char *ptr = NULL; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ ptr = strstr(mode, "="); -++ if (ptr == NULL) { -++ return; -++ } -++ -++ ptr++; -++ -++ if (get_option(&ptr, &lvl) == 0) { -++ return; -++ } -++ -++ if (lvl >= DEBUG_LVL_INFO && lvl < DEBUG_LVL_MAX) { -++ nebula->dfx_cap.log_level = lvl; -++ } -++} -++ -++static ssize_t nebula_proc_write(struct file *file, const char __user *buf, -++ size_t count, loff_t *pos) -++{ -++ char kbuf[MAX_STR_LEN] = {0}; -++ struct sdhci_host *host = (struct sdhci_host *)PDE_DATA(file_inode(file)); -++ -++ if (count == 0) -++ return -EINVAL; -++ -++ if (count > sizeof(kbuf)) -++ count = sizeof(kbuf) - 1; -++ -++ if (copy_from_user(kbuf, buf, count)) -++ return -EFAULT; -++ -++ /* Strip trailing '\n' and terminate string */ -++ kbuf[count - 1] = 0; -++ -++ if (strstr(kbuf, "rescan") != NULL) { -++ nebula_trigger_rescan(host, kbuf); -++ } else if (strstr(kbuf, "help") != NULL) { -++ nebula_trigger_help(host, kbuf); -++ } else if (strstr(kbuf, "lvl") != NULL) { -++ nebula_trigger_log_level(host, kbuf); -++ } else if (strstr(kbuf, "detect") != NULL) { -++ nebula_trigger_detect(host, kbuf); -++ } -++ -++ return (ssize_t)count; -++} -++/* proc file operation */ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++static const struct proc_ops nebula_stats_proc_ops = { -++ .proc_open = nebula_stats_proc_open, -++ .proc_read = seq_read, -++ .proc_write = nebula_proc_write, -++ .proc_release = single_release, -++}; -++#else -++static const struct file_operations nebula_stats_proc_ops = { -++ .owner = THIS_MODULE, -++ .open = nebula_stats_proc_open, -++ .read = seq_read, -++ .release = single_release, -++ .write = nebula_proc_write, -++}; -++#endif -++ -++void sdhci_nebula_dfx_irq(struct sdhci_host *host, u32 intmask) -++{ -++ struct mmc_command *cmd = host->cmd; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (cmd == NULL || ((intmask & SDHCI_INT_CMD_MASK) == 0)) { -++ return; -++ } -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -++ if (host->mmc->doing_init_tune != 0) { -++ return; -++ } -++#endif -++ -++ nebula->cmd_bt.sp++; -++ nebula->cmd_bt.sp %= NEBULA_DFX_BT_MAX_NUM; -++ nebula->cmd_bt.opcode[nebula->cmd_bt.sp] = cmd->opcode; -++} -++ -++int sdhci_nebula_proc_init(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ nebula->proc_root = proc_mkdir(mmc_hostname(host->mmc), NULL); -++ if (nebula->proc_root == NULL) { -++ pr_err("%s: create proc file failed\n", mmc_hostname(host->mmc)); -++ return -ENOMEM; -++ } -++ -++ nebula->proc_stat = proc_create_data("status", 0, nebula->proc_root, -++ &nebula_stats_proc_ops, (void *)host); -++ if (nebula->proc_stat == NULL) { -++ pr_err("%s: create status file failed\n", mmc_hostname(host->mmc)); -++ remove_proc_entry(mmc_hostname(host->mmc), NULL); -++ nebula->proc_root = NULL; -++ return -ENOMEM; -++ } -++ -++ nebula->dfx_cap.log_level = DEBUG_LVL_INFO; -++ nebula->dfx_cap.help = false; -++ -++ return ERET_SUCCESS; -++} -++ -++int sdhci_nebula_proc_shutdown(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->proc_root != NULL) { -++ if (nebula->proc_stat != NULL) { -++ remove_proc_entry("status", nebula->proc_root); -++ nebula->proc_stat = NULL; -++ } -++ remove_proc_entry(mmc_hostname(host->mmc), NULL); -++ nebula->proc_root = NULL; -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++#else -++int sdhci_nebula_proc_init(struct sdhci_host *host) -++{ -++ return ERET_SUCCESS; -++} -++ -++int sdhci_nebula_proc_shutdown(struct sdhci_host *host) -++{ -++ return ERET_SUCCESS; -++}; -++#endif -+diff --git a/drivers/vendor/mmc/dfx/nebula_dfx.h b/drivers/vendor/mmc/dfx/nebula_dfx.h -+new file mode 100755 -+index 000000000..2e8571667 -+--- /dev/null -++++ b/drivers/vendor/mmc/dfx/nebula_dfx.h -+@@ -0,0 +1,36 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __NEBULA_DFX_H__ -++#define __NEBULA_DFX_H__ -++ -++#include "nebula_dfx.h" -++ -++typedef enum { -++ DEBUG_LVL_INFO = 0, -++ DEBUG_LVL_NOTICE, -++ DEBUG_LVL_VERBOSE, -++ DEBUG_LVL_MAX, -++} nebula_dfx_log_lvl; -++ -++#define MAX_STR_LEN 20 -++#define MAX_NAMELEN 10 -++#define CLOCK_KHZ 1000 -++ -++enum sd_speed_class { -++ SD_SPEED_CLASS0 = 0, -++ SD_SPEED_CLASS1, -++ SD_SPEED_CLASS2, -++ SD_SPEED_CLASS3, -++ SD_SPEED_CLASS4, -++ SD_SPEED_CLASS_MAX, -++}; -++ -++enum sd_uhs_speed_grade { -++ SD_SPEED_GRADE0 = 0, -++ SD_SPEED_GRADE1, -++ SD_SPEED_GRADE_MAX, -++}; -++ -++#endif -+diff --git a/drivers/vendor/mmc/driver_obj.mk b/drivers/vendor/mmc/driver_obj.mk -+new file mode 100755 -+index 000000000..f11fa4c3a -+--- /dev/null -++++ b/drivers/vendor/mmc/driver_obj.mk -+@@ -0,0 +1,3 @@ -++obj-$(CONFIG_MMC_SDHCI_SOCT) += huanglong/mmc/ -++obj-$(CONFIG_MMC_SDHCI_SHAOLINSWORD) += huanglong/mmc/ -++ -+diff --git a/drivers/vendor/mmc/dtsi_usage.txt b/drivers/vendor/mmc/dtsi_usage.txt -+new file mode 100755 -+index 000000000..a6faf8569 -+--- /dev/null -++++ b/drivers/vendor/mmc/dtsi_usage.txt -+@@ -0,0 +1,58 @@ -++* Nebula SDHCI Controller -++ -++The Nebula SDHCI Controller act as a MMC controller -++to support MMC, SD, and SDIO types of memory cards. -++ -++This file documents differences between the core properties in mmc.txt -++and the properties used by the nebula driver. -++ -++Refer to mmc.txt for standard MMC bindings. -++ -++Required properties: -++- compatible: value should be "nebula,sdhci" for nebula controllers -++ -++- reg: physical base address of the controller and length -++- interrupts: Should contain MSDC interrupt number -++- clocks: Should contain phandle for the clock feeding the MMC controller -++- clock-names: Should contain the following: -++ "mmc_clk" - source clock (required) -++- resets: Array of clocks required for Nebula Host. -++- resets-names: Array of clocks required for Nebula Host. Should contain the following: -++ "crg_reset" - source reset (mandatory) -++ "dll_reset" - source reset (mandatory) -++ "crg_tx" - crg tx reset (Optional) -++ "crg_rx" - crg rx reset (Optional) -++ "samp_rst" - sample reset (Optional) -++ -++Optional properties: -++- devid: device id(emmc:0, sdio0:1, sdio1:2). -++- fpga: nebula driver go fpga branch, no turning, no iocfg -++- reset_out_drv: reset host out of driver, by resets node. -++- pm_runtime_enable: deivce support power mangerment runtime. -++- sample_turning: if device not support edge turning, enable sample_turning -++- crg_regmap: crg register handle. -++- iocfg_regmap: iocfg register handle. -++ -++Examples: -++emmc:emmc@0x01710000 { -++ compatible = "nebula,sdhci"; -++ reg = <0x01710000 0x1000>; -++ interrupts = <0 221 4>; -++ clocks = <&huanglong_clock PERI_CRG426_EMMC>; -++ clock-names = "mmc_clk"; -++ resets = <&clock 0x34c0 16>, <&clock 0x34c0 17>, <&clock 0x34c0 18>, <&clock 0x34c4 1>; -++ reset-names = "crg_reset", "crg_tx", "crg_rx", "dll_reset"; -++ crg_regmap = <&huanglong_clock>; -++ iocfg_regmap = <&huanglong_iocfg>; -++ max-frequency = <196000000>; -++ disable-wp; -++ non-removable; -++ bus-width = <8>; -++ mmc-hs200-1_8v; -++ mmc-hs400-1_8v; -++ mmc-hs400-enhanced-strobe; -++ cap-mmc-highspeed; -++ cap-mmc-hw-reset; -++ devid = <0>; -++ status = "okay"; -++}; -+\ No newline at end of file -+diff --git a/drivers/vendor/mmc/nebula_fmea.h b/drivers/vendor/mmc/nebula_fmea.h -+new file mode 100755 -+index 000000000..96985a11d -+--- /dev/null -++++ b/drivers/vendor/mmc/nebula_fmea.h -+@@ -0,0 +1,25 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __SDHCI_FMEA_H__ -++#define __SDHCI_FMEA_H__ -++ -++#include "sdhci.h" -++ -++#include "nebula_fmea.h" -++ -++#define SDHCI_FMEA_LIFE_TIME_EXCEED 955465100 -++ -++#define DEVICE_LIFE_CHECK_INTERVAL (3600) -++#define DEVICE_LIFE_TIME_EST_VAL (0x5) -++ -++typedef struct sdhci_nebula_fmea { -++ struct sdhci_host *host; -++ struct delayed_work mmc_lifecheck_work; -++ int life_check_interval; -++} nebula_fmea; -++ -++int sdhci_nebula_fmea_init(struct sdhci_host *host, nebula_fmea *fmea); -++int sdhci_nebula_fmea_deinit(nebula_fmea *fmea); -++#endif -+diff --git a/drivers/vendor/mmc/nebula_intf.c b/drivers/vendor/mmc/nebula_intf.c -+new file mode 100755 -+index 000000000..d3a759dee -+--- /dev/null -++++ b/drivers/vendor/mmc/nebula_intf.c -+@@ -0,0 +1,93 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include "core.h" -++#include "sdhci_nebula.h" -++#include "nebula_intf.h" -++ -++/* -++ * This api is for wifi driver rescan the sdio device -++ */ -++int bsp_sdio_rescan(int slot) -++{ -++ struct mmc_host *mmc = NULL; -++ -++ if ((slot >= MCI_SLOT_NUM) || (slot < 0)) { -++ pr_err("invalid mmc slot, please check the argument\n"); -++ return -EINVAL; -++ } -++ -++ mmc = g_mci_host[slot]; -++ if (mmc == NULL) { -++ pr_err("invalid mmc, please check the argument\n"); -++ return -EINVAL; -++ } -++ -++ mmc->rescan_entered = 0; -++ mmc_detect_change(mmc, 0); -++ return 0; -++} -++EXPORT_SYMBOL_GPL(bsp_sdio_rescan); -++ -++int hl_drv_sdio_rescan(int index) -++{ -++ struct mmc_host *mmc = NULL; -++ int i; -++ -++ if ((index < 0) || (index >= MCI_SLOT_NUM)) { -++ pr_err("invalid mmc_host index for sdio %d\n", index); -++ return -EINVAL; -++ } -++ -++ for (i = MMC_DEV_TYPE_SDIO_0; i <= MMC_DEV_TYPE_SDIO_1; i++) { -++ mmc = g_mmc_host[i]; -++ -++ if ((mmc == NULL) || (mmc->card != NULL)) { -++ continue; -++ } -++ printk("Trigger sdio%d scanning card successfully\n", i); -++ mmc_detect_change(mmc, 0); -++ } -++ -++ return 0; -++} -++EXPORT_SYMBOL_GPL(hl_drv_sdio_rescan); -++ -++int sdhci_nebula_sdio_rescan(int index) -++{ -++ int ret = 0; -++ struct mmc_host *mmc = NULL; -++ -++ if ((index < 0) || (index >= MCI_SLOT_NUM)) { -++ pr_err("invalid mmc_host index for sdio %d\n", index); -++ return -EINVAL; -++ } -++ -++ mmc = g_mmc_host[index]; -++ if (mmc == NULL) { -++ pr_err("sdio %d not init\n", index); -++ return -EINVAL; -++ } -++ -++ pr_info("Trigger sdio%d rescan\n", index); -++ if (mmc->card == NULL) { -++ mmc->rescan_entered = 0; -++ mmc_detect_change(mmc, 0); -++ } else { -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -++ mmc_claim_host(mmc); -++ ret = mmc_hw_reset(mmc); -++ mmc_release_host(mmc); -++#else -++ ret = mmc_hw_reset(mmc); -++#endif -++ } -++ -++ return ret; -++} -++EXPORT_SYMBOL_GPL(sdhci_nebula_sdio_rescan); -+diff --git a/drivers/vendor/mmc/nebula_intf.h b/drivers/vendor/mmc/nebula_intf.h -+new file mode 100755 -+index 000000000..f5d3d7e10 -+--- /dev/null -++++ b/drivers/vendor/mmc/nebula_intf.h -+@@ -0,0 +1,14 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef NEBULA_INTF_H -++#define NEBULA_INTF_H -++ -++#include "nebula_intf.h" -++ -++int bsp_sdio_rescan(int slot); -++int hl_drv_sdio_rescan(int index); -++int sdhci_nebula_sdio_rescan(int index); -++ -++#endif -+diff --git a/drivers/vendor/mmc/platform/platform_comm.c b/drivers/vendor/mmc/platform/platform_comm.c -+new file mode 100755 -+index 000000000..fb59e1308 -+--- /dev/null -++++ b/drivers/vendor/mmc/platform/platform_comm.c -+@@ -0,0 +1,501 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include "sdhci_nebula.h" -++#include "platform_priv.h" -++ -++#define sdhci_nebula_dump(f, x...) \ -++ pr_err("%s: sdhci: " f, mmc_hostname(host->mmc), ## x) -++ -++static void comm_set_regmap(struct regmap *regmap, -++ u32 offset, u32 mask, u32 data) -++{ -++ u32 reg; -++ -++ regmap_read(regmap, offset, ®); -++ reg &= ~mask; -++ data &= mask; -++ reg |= data; -++ regmap_write(regmap, offset, reg); -++} -++ -++static int comm_wait_dll_timeout(struct sdhci_host *host, -++ u32 offset, u32 mask, u32 timeout) -++{ -++ u32 reg, save_timeout; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ save_timeout = timeout; -++ -++ do { -++ reg = 0; -++ regmap_read(nebula->crg_regmap, offset, ®); -++ if (reg & mask) -++ return ERET_SUCCESS; -++ -++ mdelay(1); -++ timeout--; -++ } while (timeout > 0); -++ -++ pr_err("%s: wait ofs 0x%x mask 0x%x timeout after %d ms\n", -++ mmc_hostname(host->mmc), offset, mask, save_timeout); -++ return -ETIMEDOUT; -++} -++ -++int plat_wait_sample_dll_ready(struct sdhci_host *host) -++{ -++ unsigned int offset, mask; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_DLL_STA]; -++ mask = nebula->mask->samp_ready_mask; -++ return comm_wait_dll_timeout(host, offset, mask, WAIT_MAX_TIMEOUT); -++} -++ -++int plat_wait_p4_dll_lock(struct sdhci_host *host) -++{ -++ unsigned int offset, mask; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_DLL_STA]; -++ mask = nebula->mask->p4_lock_mask; -++ return comm_wait_dll_timeout(host, offset, mask, WAIT_MAX_TIMEOUT); -++} -++ -++int plat_wait_ds_dll_ready(struct sdhci_host *host) -++{ -++ unsigned int offset, mask; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_DLL_STA]; -++ mask = nebula->mask->dll_ready_mask; -++ return comm_wait_dll_timeout(host, offset, mask, WAIT_MAX_TIMEOUT); -++} -++ -++void plat_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) -++{ -++ u16 ctrl; -++ struct sdhci_host *host = mmc_priv(mmc); -++ -++ ctrl = sdhci_readw(host, SDHCI_EMMC_CTRL); -++ if (ios->enhanced_strobe) -++ ctrl |= SDHCI_ENH_STROBE_EN; -++ else -++ ctrl &= ~SDHCI_ENH_STROBE_EN; -++ -++ sdhci_writew(host, ctrl, SDHCI_EMMC_CTRL); -++} -++ -++void plat_get_drv_samp_phase(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const nebula_info *info = nebula->info; -++ nebula_timing *timing_data = NULL; -++ -++ if ((info->timing_size == 0) || host->timing > info->timing_size) { -++ pr_err("%s: warning: check fixed timing %d\n", -++ mmc_hostname(host->mmc), host->timing); -++ return; -++ } -++ -++ /* choice host timing data */ -++ timing_data = info->timing + host->timing; -++ if (timing_data->data_valid == false) { -++ /* choice legacy mode timing */ -++ timing_data = info->timing; -++ } -++ -++ if (timing_data->data_valid == true) { -++ nebula->drv_phase = (timing_data->phase[DRV_PHASE] & TIMING_MASK); -++ if (is_timing_valid(timing_data->phase[SAMP_PHASE])) { -++ nebula->sample_phase = (timing_data->phase[SAMP_PHASE] & TIMING_MASK); -++ } else { -++ nebula->sample_phase = nebula->tuning_phase; -++ } -++ } else { -++ pr_err("%s: warning: check default timing valid?\n", -++ mmc_hostname(host->mmc)); -++ } -++} -++ -++void plat_set_drv_phase(struct sdhci_host *host, u32 phase) -++{ -++ unsigned int reg, offset; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_DRV_DLL]; -++ regmap_read(nebula->crg_regmap, offset, ®); -++ reg &= ~(nebula->mask->drv_phase_mask); -++ reg |= phase; -++ regmap_write(nebula->crg_regmap, offset, reg); -++} -++ -++void plat_set_drv_cap(struct sdhci_host *host) -++{ -++ int idx, bus_width; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const nebula_info *info = nebula->info; -++ nebula_timing *timing_data = NULL; -++ struct mmc_ios *ios = &host->mmc->ios; -++ -++ if (nebula->priv_quirk & NEBULA_QUIRK_FPGA) { -++ return; -++ } -++ -++ if ((info->timing_size == 0) || host->timing > info->timing_size) { -++ pr_err("%s: warning: check fixed timing %d\n", -++ mmc_hostname(host->mmc), host->timing); -++ return; -++ } -++ -++ /* choice host timing data */ -++ timing_data = info->timing + host->timing; -++ if (timing_data->data_valid == false) { -++ /* choice legacy mode timing */ -++ timing_data = info->timing; -++ } -++ -++ /* clk cmd rst timing setting */ -++ for (idx = 0; idx < IO_TYPE_MAX; idx++) { -++ if (is_timing_valid(timing_data->timing[idx])) { -++ comm_set_regmap(nebula->iocfg_regmap, info->io_offset[idx], \ -++ info->io_drv_mask, timing_data->timing[idx] & TIMING_MASK); -++ } -++ } -++ -++ /* data line drv valid? fixed bus width */ -++ if (is_timing_valid(timing_data->timing[IO_TYPE_DATA])) { -++ /* data0 line set already */ -++ bus_width = (1 << ios->bus_width) - 1; -++ for (idx = IO_TYPE_D1; (idx < IO_TYPE_DMAX) && (bus_width != 0); idx++) { -++ bus_width--; -++ comm_set_regmap(nebula->iocfg_regmap, info->io_offset[idx], \ -++ info->io_drv_mask, timing_data->timing[IO_TYPE_DATA] & TIMING_MASK); -++ } -++ } -++} -++ -++void plat_dll_reset_assert(struct sdhci_host *host) -++{ -++ unsigned int reg, offset; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_DLL_RST]; -++ regmap_read(nebula->crg_regmap, offset, ®); -++ reg |= nebula->mask->dll_srst_mask; -++ regmap_write(nebula->crg_regmap, offset, reg); -++} -++ -++void plat_dll_reset_deassert(struct sdhci_host *host) -++{ -++ unsigned int reg, offset; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_DLL_RST]; -++ regmap_read(nebula->crg_regmap, offset, ®); -++ reg &= ~nebula->mask->dll_srst_mask; -++ regmap_write(nebula->crg_regmap, offset, reg); -++} -++ -++static void comm_crg_enable_clock(struct sdhci_host *host) -++{ -++ unsigned int reg, offset; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_CLK_RST]; -++ regmap_read(nebula->crg_regmap, offset, ®); -++ reg |= nebula->mask->crg_cken_mask; -++ regmap_write(nebula->crg_regmap, offset, reg); -++} -++ -++static void comm_crg_reset_assert(struct sdhci_host *host) -++{ -++ unsigned int reg, offset; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_CLK_RST]; -++ regmap_read(nebula->crg_regmap, offset, ®); -++ reg |= nebula->mask->crg_srst_mask; -++ regmap_write(nebula->crg_regmap, offset, reg); -++} -++ -++static void comm_crg_reset_deassert(struct sdhci_host *host) -++{ -++ unsigned int reg, offset; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ offset = nebula->info->crg_ofs[CRG_CLK_RST]; -++ regmap_read(nebula->crg_regmap, offset, ®); -++ reg &= ~nebula->mask->crg_srst_mask; -++ regmap_write(nebula->crg_regmap, offset, reg); -++} -++ -++int plat_crg_init(struct sdhci_host *host) -++{ -++ int ret; -++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ ret = clk_prepare_enable(pltfm_host->clk); -++ if (ret) { -++ pr_err("%s: enable mmc clk failed\n", mmc_hostname(host->mmc)); -++ return ret; -++ } -++ -++ if ((nebula->priv_cap & NEBULA_CAP_QUICK_BOOT) != 0) { -++ return ERET_SUCCESS; -++ } -++ -++ if (nebula->priv_cap & NEBULA_CAP_RST_IN_DRV) { -++ comm_crg_enable_clock(host); -++ comm_crg_reset_assert(host); -++ plat_dll_reset_assert(host); -++ -++ udelay(25); /* delay 25 us */ -++ comm_crg_reset_deassert(host); -++ udelay(10); /* delay 10 us */ -++ } else { -++ reset_control_assert(nebula->crg_rst); -++ reset_control_assert(nebula->crg_tx); -++ reset_control_assert(nebula->crg_rx); -++ -++ reset_control_assert(nebula->dll_rst); -++ -++ udelay(25); /* delay 25 us */ -++ reset_control_deassert(nebula->crg_rst); -++ reset_control_deassert(nebula->crg_tx); -++ reset_control_deassert(nebula->crg_rx); -++ -++ udelay(10); /* delay 10 us */ -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++/* Do ZQ resistance calibration for eMMC PHY IO */ -++static int comm_resistance_calibration(struct sdhci_host *host) -++{ -++ int i; -++ u32 reg_val; -++ void __iomem *viraddr = NULL; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->info->zq_phy_addr == 0) { -++ pr_err("%s: zq_phy_addr is invalid.\n", mmc_hostname(host->mmc)); -++ return -EINVAL; -++ } -++ -++ viraddr = ioremap(nebula->info->zq_phy_addr, sizeof(u32)); -++ if (viraddr == NULL) { -++ pr_err("%s: io calibration ioremap error.\n", mmc_hostname(host->mmc)); -++ return -ENOMEM; -++ } -++ -++ reg_val = readl(viraddr); -++ reg_val |= EMMC_ZQ_INIT_EN | EMMC_ZQ_ZCAL_EN; -++ writel(reg_val, viraddr); -++ -++ for (i = 0; i < EMMC_ZQ_CHECK_TIMES; i++) { -++ reg_val = readl(viraddr); -++ if ((reg_val & (EMMC_ZQ_INIT_EN | EMMC_ZQ_ZCAL_EN)) == 0) { -++ iounmap(viraddr); -++ return ERET_SUCCESS; -++ } -++ udelay(10); /* delay 10 us */ -++ } -++ -++ iounmap(viraddr); -++ return -ETIMEDOUT; -++} -++ -++int plat_resistance_calibration(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if ((nebula->priv_cap & NEBULA_CAP_QUICK_BOOT) != 0) { -++ return ERET_SUCCESS; -++ } -++ -++ if (nebula->priv_cap & NEBULA_CAP_ZQ_CALB) { -++ return comm_resistance_calibration(host); -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++static int comm_voltage_switch(struct sdhci_host *host, const struct mmc_ios *ios) -++{ -++ u32 ctrl; -++ void __iomem *viraddr; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (ios == NULL || nebula->info->volt_sw_phy_addr == 0) { -++ pr_err("%s: ios or volt_sw_phy_addr is invalid.\n", -++ mmc_hostname(host->mmc)); -++ return -EINVAL; -++ } -++ -++ viraddr = ioremap(nebula->info->volt_sw_phy_addr, sizeof(u32)); -++ if (viraddr == NULL) { -++ pr_err("%s: volt switch ioremap error.\n", mmc_hostname(host->mmc)); -++ return -ENOMEM; -++ } -++ -++ ctrl = readl(viraddr); -++ ctrl |= nebula->mask->volt_sw_en_mask; -++ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) -++ ctrl |= nebula->mask->volt_sw_1v8_mask; -++ else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) -++ ctrl &= ~nebula->mask->volt_sw_1v8_mask; -++ -++ writel(ctrl, viraddr); -++ -++ usleep_range(1000, 2000); /* Sleep between 1000 and 2000us */ -++ -++ iounmap(viraddr); -++ -++ return ERET_SUCCESS; -++} -++ -++int plat_voltage_switch(struct sdhci_host *host, struct mmc_ios *ios) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->priv_cap & NEBULA_CAP_VOLT_SW) { -++ return comm_voltage_switch(host, ios); -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++void __weak plat_caps_quirks_init(struct sdhci_host *host) -++{ -++} -++ -++void __weak plat_extra_init(struct sdhci_host *host) -++{ -++} -++ -++void __weak plat_dump_io_info(struct sdhci_host *host) -++{ -++ int idx, bus_width; -++ u32 reg0, reg1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const nebula_info *info = nebula->info; -++ -++ /* Cmd Clk */ -++ regmap_read(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CLK], ®0); -++ regmap_read(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CMD], ®1); -++ sdhci_nebula_dump("Clk io: 0x%08x | Cmd io: 0x%08x\n", reg0, reg1); -++ -++ if (info->io_offset[IO_TYPE_RST] != INVALID_DATA && \ -++ info->io_offset[IO_TYPE_DQS] != INVALID_DATA) { -++ /* Rst/Detect Dqs/Power_en */ -++ regmap_read(nebula->iocfg_regmap, info->io_offset[IO_TYPE_RST], ®0); -++ regmap_read(nebula->iocfg_regmap, info->io_offset[IO_TYPE_DQS], ®1); -++ sdhci_nebula_dump("Rst/Det: 0x%08x | Dqs/Pwen: 0x%08x\n", reg0, reg1); -++ } -++ -++ if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_1) { -++ regmap_read(nebula->iocfg_regmap, info->io_offset[IO_TYPE_D0], ®0); -++ sdhci_nebula_dump("Data0 io: 0x%08x\n", reg0); -++ return; -++ } -++ -++ bus_width = (1 << host->mmc->ios.bus_width); -++ for (idx = 0; idx < bus_width; idx += DUMP_DATA_IO_STEP) { -++ regmap_read(nebula->iocfg_regmap, info->io_offset[idx + IO_TYPE_D0], ®0); -++ regmap_read(nebula->iocfg_regmap, info->io_offset[idx + IO_TYPE_D0 + 1], ®1); -++ sdhci_nebula_dump("Data%d io: 0x%08x | Data%d io: 0x%08x\n", -++ idx, reg0, idx + 1, reg1); -++ } -++} -++ -++static u32 comm_get_mmc_bus_width(struct sdhci_host *host) -++{ -++ void __iomem *sys_stat_reg; -++ unsigned int sys_stat; -++ unsigned int bus_width; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->info->bus_width_phy_addr == 0) { -++ pr_err("%s: bus_width_phy_addr is invalid.\n", mmc_hostname(host->mmc)); -++ return -EINVAL; -++ } -++ -++ sys_stat_reg = ioremap(nebula->info->bus_width_phy_addr, sizeof(u32)); -++ if (sys_stat_reg == NULL) { -++ pr_err("%s: bus width ioremap error.\n", mmc_hostname(host->mmc)); -++ return -ENOMEM; -++ } -++ -++ sys_stat = readl(sys_stat_reg); -++ iounmap(sys_stat_reg); -++ -++ if ((sys_stat & BOOT_FLAG_MASK) == BOOT_MEDIA_EMMC) { -++ bus_width = ((sys_stat & EMMC_BOOT_8BIT) != 0) ? -++ MMC_BUS_WIDTH_8 : MMC_BUS_WIDTH_4; -++ } else { -++ /* up to 4 bit mode support when spi nand start up */ -++ bus_width = MMC_BUS_WIDTH_4; -++ } -++ -++ return bus_width; -++} -++ -++void __maybe_unused plat_set_mmc_bus_width(struct sdhci_host *host) -++{ -++ u32 bus_width; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ /* for eMMC devices only */ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ bus_width = comm_get_mmc_bus_width(host); -++ if (bus_width == MMC_BUS_WIDTH_8) { -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; -++ } else { -++ host->mmc->caps |= MMC_CAP_4_BIT_DATA; -++ host->mmc->caps &= ~MMC_CAP_8_BIT_DATA; -++ } -++ } -++} -++ -++void __maybe_unused plat_comm_caps_quirks_init(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ /* -++ * only eMMC has a hw reset, eMMC and NM card is fixed 1.8V voltage -++ */ -++ if ((host->mmc->caps & MMC_CAP_HW_RESET) -++ || (nebula->priv_cap & NEBULA_CAP_NM_CARD)) { -++ 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->quirks2 &= ~SDHCI_QUIRK2_ACMD23_BROKEN; -++} -++ -++void plat_set_emmc_type(struct sdhci_host *host) -++{ -++ u32 ctrl; -++ -++ ctrl = sdhci_readl(host, SDHCI_EMMC_CTRL); -++ ctrl |= SDHCI_CARD_IS_EMMC; -++ sdhci_writel(host, ctrl, SDHCI_EMMC_CTRL); -++} -+diff --git a/drivers/vendor/mmc/platform/platform_priv.h b/drivers/vendor/mmc/platform/platform_priv.h -+new file mode 100755 -+index 000000000..250c83cb7 -+--- /dev/null -++++ b/drivers/vendor/mmc/platform/platform_priv.h -+@@ -0,0 +1,221 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _DRIVERS_MMC_NEBULA_PLATFOMR_H -++#define _DRIVERS_MMC_NEBULA_PLATFOMR_H -++ -++#include "platform_priv.h" -++ -++#define DUMP_DATA_IO_STEP 2 -++ -++#define WAIT_MAX_TIMEOUT 20 -++ -++/* ZQ resistance calibration confiuration */ -++#define EMMC_ZQ_INIT_EN 0x1 -++#define EMMC_ZQ_ZCAL_EN (0x1 << 3) -++#define EMMC_ZQ_CHECK_TIMES 100 -++ -++/* Voltage switch configure */ -++#ifdef NEBULA_VOLT_SW_BVT -++#define PWR_CTRL_BY_MISC BIT(0) -++#define PWR_CTRL_BY_MISC_EN BIT(4) -++#define PWR_CRTL_EN (PWR_CTRL_BY_MISC | PWR_CTRL_BY_MISC_EN) -++#define IO_MODE_SEL_1V8 BIT(1) -++#define PWRSW_SEL_1V8 BIT(5) -++#define PWR_CRTL_1V8 (IO_MODE_SEL_1V8 | PWRSW_SEL_1V8) -++#else -++#define PWR_CRTL_EN BIT(0) -++#define PWR_CRTL_1V8 BIT(2) -++#endif -++ -++#define BOOT_MEDIA_EMMC 0xC -++#define EMMC_BOOT_8BIT BIT(11) -++#define BOOT_FLAG_MASK (0x3 << 2) -++ -++#ifndef CRG_CLK_BIT_OFS -++#define CRG_CLK_BIT_OFS INVALID_DATA -++#define CRG_CLK_SEL_MASK INVALID_DATA -++#endif -++ -++/* Help macro for create nebula crg mask info struct */ -++#if defined(CRG_SRST_REQ) && defined(CRG_DLL_SRST_REQ) -++#define NEBULA_CRG_MASK_DESC \ -++{ \ -++ .crg_srst_mask = CRG_SRST_REQ, \ -++ .crg_clk_sel_ofs = CRG_CLK_BIT_OFS, \ -++ .crg_clk_sel_mask = CRG_CLK_SEL_MASK, \ -++ .crg_cken_mask = CRG_CLK_EN_MASK, \ -++ .dll_srst_mask = CRG_DLL_SRST_REQ, \ -++ .p4_lock_mask = CRG_P4_DLL_LOCKED, \ -++ .dll_ready_mask = CRG_DS_DLL_READY, \ -++ .samp_ready_mask = CRG_SAM_DLL_READY, \ -++ .drv_phase_mask = CRG_DRV_PHASE_MASK, \ -++ .volt_sw_en_mask = PWR_CRTL_EN, \ -++ .volt_sw_1v8_mask = PWR_CRTL_1V8, \ -++} -++#endif -++ -++#ifndef EMMC_ZQ_CTRL_PHY_ADDR -++#define EMMC_ZQ_CTRL_PHY_ADDR 0x0 -++#endif -++#ifndef EMMC_VOLT_SW_PHY_ADDR -++#define EMMC_VOLT_SW_PHY_ADDR 0x0 -++#endif -++#ifndef EMMC_BUS_WIDTH_PHY_ADDR -++#define EMMC_BUS_WIDTH_PHY_ADDR 0x0 -++#endif -++ -++#ifndef EMMC_QUICK_BOOT_PHY_ADDR -++#define EMMC_QUICK_BOOT_PHY_ADDR INVALID_DATA -++#define EMMC_QUICK_BOOT_PARAM1_OFS INVALID_DATA -++#endif -++ -++/* Help macro for create nebula emmc info description struct */ -++#if defined(EMMC_CRG_CLK_OFS) && defined(EMMC_D7_GPIO_OFS) -++#define nebula_emmc_info_desc(_timing) \ -++{ \ -++ .io_offset = {EMMC_CLK_GPIO_OFS, EMMC_CMD_GPIO_OFS, \ -++ EMMC_RSTN_GPIO_OFS, EMMC_DQS_GPIO_OFS, \ -++ EMMC_D0_GPIO_OFS, EMMC_D1_GPIO_OFS, \ -++ EMMC_D2_GPIO_OFS, EMMC_D3_GPIO_OFS, \ -++ EMMC_D4_GPIO_OFS, EMMC_D5_GPIO_OFS, \ -++ EMMC_D6_GPIO_OFS, EMMC_D7_GPIO_OFS}, \ -++ .io_drv_mask = DRV_STR_MASK_GPIO | SR_STR_MASK_GPIO, \ -++ .io_drv_str_bit_ofs = DRV_STR_SHIFT, \ -++ .io_drv_str_mask = DRV_STR_MASK_GPIO, \ -++ .io_drv_sr_bit_ofs = SR_STR_SHIFT, \ -++ .io_drv_sr_mask = SR_STR_MASK_GPIO, \ -++ .crg_ofs = {EMMC_CRG_CLK_OFS, EMMC_DLL_RST_OFS, EMMC_DRV_DLL_OFS, EMMC_DLL_STA_OFS}, \ -++ .zq_phy_addr = EMMC_ZQ_CTRL_PHY_ADDR, \ -++ .volt_sw_phy_addr = EMMC_VOLT_SW_PHY_ADDR, \ -++ .bus_width_phy_addr = EMMC_BUS_WIDTH_PHY_ADDR, \ -++ .qboot_phy_addr = EMMC_QUICK_BOOT_PHY_ADDR, \ -++ .qboot_param1_ofs = EMMC_QUICK_BOOT_PARAM1_OFS, \ -++ .timing_size = ARRAY_SIZE(_timing), \ -++ .timing = (_timing), \ -++} -++#endif -++ -++#ifndef SDIO0_ZQ_CTRL_PHY_ADDR -++#define SDIO0_ZQ_CTRL_PHY_ADDR 0x0 -++#endif -++ -++#ifndef SDIO0_VOLT_SW_PHY_ADDR -++#define SDIO0_VOLT_SW_PHY_ADDR 0x0 -++#endif -++ -++#ifndef SDIO0_DETECT_OFS -++#define SDIO0_DETECT_OFS INVALID_DATA -++#endif -++ -++#ifndef SDIO0_PWEN_OFS -++#define SDIO0_PWEN_OFS INVALID_DATA -++#endif -++ -++/* Help macro for create nebula sdio0 info description struct */ -++#if defined(SDIO0_CLK_OFS) && defined(SDIO0_CRG_CLK_OFS) -++#define nebula_sdio0_info_desc(_timing) \ -++{ \ -++ .io_offset = {SDIO0_CLK_OFS, SDIO0_CMD_OFS, SDIO0_DETECT_OFS, \ -++ SDIO0_PWEN_OFS, SDIO0_D0_OFS, \ -++ SDIO0_D1_OFS, SDIO0_D2_OFS, SDIO0_D3_OFS}, \ -++ .io_drv_mask = DRV_STR_MASK_GPIO | SR_STR_MASK_GPIO, \ -++ .crg_ofs = {SDIO0_CRG_CLK_OFS, SDIO0_DLL_RST_OFS, SDIO0_DRV_DLL_OFS, SDIO0_DLL_STA_OFS}, \ -++ .zq_phy_addr = SDIO0_ZQ_CTRL_PHY_ADDR, \ -++ .volt_sw_phy_addr = SDIO0_VOLT_SW_PHY_ADDR, \ -++ .timing_size = ARRAY_SIZE(_timing), \ -++ .timing = (_timing), \ -++} -++#endif -++ -++#ifndef SDIO1_ZQ_CTRL_PHY_ADDR -++#define SDIO1_ZQ_CTRL_PHY_ADDR 0x0 -++#endif -++ -++#ifndef SDIO1_VOLT_SW_PHY_ADDR -++#define SDIO1_VOLT_SW_PHY_ADDR 0x0 -++#endif -++ -++#ifndef SDIO1_DETECT_OFS -++#define SDIO1_DETECT_OFS INVALID_DATA -++#endif -++ -++#ifndef SDIO1_PWEN_OFS -++#define SDIO1_PWEN_OFS INVALID_DATA -++#endif -++ -++/* Help macro for create nebula sdio1 info description struct */ -++#if defined(SDIO0_CLK_OFS) && defined(SDIO0_CRG_CLK_OFS) -++#define nebula_sdio1_info_desc(_timing) \ -++{ \ -++ .io_offset = {SDIO1_CLK_OFS, SDIO1_CMD_OFS, SDIO1_DETECT_OFS, \ -++ SDIO1_PWEN_OFS, SDIO1_D0_OFS, \ -++ SDIO1_D1_OFS, SDIO1_D2_OFS, SDIO1_D3_OFS}, \ -++ .io_drv_mask = DRV_STR_MASK_GPIO | SR_STR_MASK_GPIO, \ -++ .crg_ofs = {SDIO1_CRG_CLK_OFS, SDIO1_DLL_RST_OFS, SDIO1_DRV_DLL_OFS, SDIO1_DLL_STA_OFS}, \ -++ .zq_phy_addr = SDIO1_ZQ_CTRL_PHY_ADDR, \ -++ .volt_sw_phy_addr = SDIO1_VOLT_SW_PHY_ADDR, \ -++ .timing_size = ARRAY_SIZE(_timing), \ -++ .timing = (_timing), \ -++} -++#endif -++ -++/* Help macro for create nebula emmc high speed info description struct */ -++#if defined(EMMC_D0_IO_OFS) && defined(EMMC_CRG_CLK_OFS) -++#define nebula_emmc_hsio_info_desc(_timing) \ -++{ \ -++ .io_offset = {EMMC_CLK_IO_OFS, EMMC_CMD_IO_OFS, \ -++ EMMC_RSTN_IO_OFS, EMMC_DQS_IO_OFS, \ -++ EMMC_D0_IO_OFS, EMMC_D1_IO_OFS, \ -++ EMMC_D2_IO_OFS, EMMC_D3_IO_OFS, \ -++ EMMC_D4_IO_OFS, EMMC_D5_IO_OFS, \ -++ EMMC_D6_IO_OFS, EMMC_D7_IO_OFS}, \ -++ .io_drv_mask = DRV_STR_MASK_IO, \ -++ .io_drv_str_bit_ofs = DRV_STR_SHIFT, \ -++ .io_drv_str_mask = DRV_STR_MASK_IO, \ -++ .io_drv_sr_bit_ofs = SR_STR_SHIFT, \ -++ .io_drv_sr_mask = SR_STR_MASK_GPIO, \ -++ .crg_ofs = {EMMC_CRG_CLK_OFS, EMMC_DLL_RST_OFS, EMMC_DRV_DLL_OFS, EMMC_DLL_STA_OFS}, \ -++ .zq_phy_addr = EMMC_ZQ_CTRL_PHY_ADDR, \ -++ .volt_sw_phy_addr = EMMC_VOLT_SW_PHY_ADDR, \ -++ .qboot_phy_addr = EMMC_QUICK_BOOT_PHY_ADDR, \ -++ .qboot_param1_ofs = EMMC_QUICK_BOOT_PARAM1_OFS, \ -++ .timing_size = ARRAY_SIZE(_timing), \ -++ .timing = (_timing), \ -++} -++#endif -++ -++#define TIMING_MASK 0x7FFFFFFF -++#define TIMING_VALID 0x80000000 -++#define is_timing_valid(x) (((x) & TIMING_VALID) == TIMING_VALID) -++ -++/* Generial GPIO CFG */ -++#if defined(DRV_STR_SHIFT) && defined(SR_STR_SHIFT) -++#define gpio_drv_sel(str) ((str) << DRV_STR_SHIFT) -++#define gpio_sr_sel(sr) ((sr) << SR_STR_SHIFT) -++#define fixed_gpio_drv(drv_sel, sr_sel) \ -++ (TIMING_VALID | gpio_drv_sel(drv_sel) | gpio_sr_sel(sr_sel)) -++#endif -++ -++/* High speed IO CFG */ -++#if defined(DRV_STR_SHIFT) -++#define hsio_drv_sel(str) ((str) << DRV_STR_SHIFT) -++#define fixed_hsio_drv(drv_sel) (TIMING_VALID | hsio_drv_sel(drv_sel)) -++#endif -++ -++#ifdef CRG_DRV_PHASE_SHIFT -++/* Set drv phase only */ -++#define fixed_drv_phase_only(drv_phase) \ -++ .phase[DRV_PHASE] = (TIMING_VALID | ((drv_phase) << CRG_DRV_PHASE_SHIFT)) -++ -++/* Set drv and sample phase */ -++#define fixed_drv_samp_phase(drv_phase, samp_phase) \ -++ .phase[DRV_PHASE] = (TIMING_VALID | ((drv_phase) << CRG_DRV_PHASE_SHIFT)), \ -++ .phase[SAMP_PHASE] = (TIMING_VALID | (samp_phase)) -++#endif -++ -++struct sdhci_host; -++void plat_comm_caps_quirks_init(struct sdhci_host *host); -++ -++#endif /* _DRIVERS_MMC_NEBULA_ADAPTER_H */ -+diff --git a/drivers/vendor/mmc/platform/platform_timing.h b/drivers/vendor/mmc/platform/platform_timing.h -+new file mode 100755 -+index 000000000..bf2984614 -+--- /dev/null -++++ b/drivers/vendor/mmc/platform/platform_timing.h -+@@ -0,0 +1,71 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _DRIVERS_MMC_NEBULA_PLATFOMR_TIMING_H -++#define _DRIVERS_MMC_NEBULA_PLATFOMR_TIMING_H -++ -++enum drv_timing_lvl { -++ TM_LVL_0 = 0, -++ TM_LVL_1, -++ TM_LVL_2, -++ TM_LVL_3, -++ TM_LVL_4, -++ TM_LVL_5, -++ TM_LVL_6, -++ TM_LVL_7, -++ TM_LVL_8, -++ TM_LVL_9, -++ TM_LVL_10, -++ TM_LVL_11, -++ TM_LVL_12, -++ TM_LVL_13, -++ TM_LVL_14, -++ TM_LVL_15, -++ TM_LVL_MAX -++}; -++ -++enum sr_lvl { -++ SR_LVL_0 = 0, -++ SR_LVL_1, -++ SR_LVL_2, -++ SR_LVL_3, -++ SR_LVL_MAX -++}; -++ -++enum phase_lvl { -++ PHASE_LVL_0, /* 0 degree */ -++ PHASE_LVL_1, /* 11.25 degree */ -++ PHASE_LVL_2, /* 22.5 degree */ -++ PHASE_LVL_3, /* 33.75 degree */ -++ PHASE_LVL_4, /* 45 degree */ -++ PHASE_LVL_5, /* 56.25 degree */ -++ PHASE_LVL_6, /* 67.5 degree */ -++ PHASE_LVL_7, /* 78.75 degree */ -++ PHASE_LVL_8, /* 90 degree */ -++ PHASE_LVL_9, /* 101.25 degree */ -++ PHASE_LVL_10, /* 112.5 degree */ -++ PHASE_LVL_11, /* 123.75 degree */ -++ PHASE_LVL_12, /* 135 degree */ -++ PHASE_LVL_13, /* 146.25 degree */ -++ PHASE_LVL_14, /* 157.5 degree */ -++ PHASE_LVL_15, /* 168.75 degree */ -++ PHASE_LVL_16, /* 180 degree */ -++ PHASE_LVL_17, /* 191.25 degree */ -++ PHASE_LVL_18, /* 202.5 degree */ -++ PHASE_LVL_19, /* 213.75 degree */ -++ PHASE_LVL_20, /* 225 degree */ -++ PHASE_LVL_21, /* 236.25 degree */ -++ PHASE_LVL_22, /* 247.5 degree */ -++ PHASE_LVL_23, /* 258.75 degree */ -++ PHASE_LVL_24, /* 270 degree */ -++ PHASE_LVL_25, /* 281.25 degree */ -++ PHASE_LVL_26, /* 292.5 degree */ -++ PHASE_LVL_27, /* 303.75 degree */ -++ PHASE_LVL_28, /* 315 degree */ -++ PHASE_LVL_29, /* 326.25 degree */ -++ PHASE_LVL_30, /* 337.5 degree */ -++ PHASE_LVL_31, /* 348.75 degree */ -++}; -++ -++#endif -+diff --git a/drivers/vendor/mmc/platform/sdhci_hi3516cv610.c b/drivers/vendor/mmc/platform/sdhci_hi3516cv610.c -+new file mode 100755 -+index 000000000..4a5c5a78e -+--- /dev/null -++++ b/drivers/vendor/mmc/platform/sdhci_hi3516cv610.c -+@@ -0,0 +1,362 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++ -++#include "sdhci.h" -++ -++/* Host controller CRG */ -++#define EMMC_CRG_CLK_OFS 0x35c0 -++#define SDIO0_CRG_CLK_OFS 0x35c0 -++#define SDIO1_CRG_CLK_OFS 0x36c0 -++#define CRG_SRST_REQ (BIT(16) | BIT(17) | BIT(18)) -++#define CRG_CLK_EN_MASK (BIT(0) | BIT(1)) -++#define CRG_CLK_BIT_OFS 24 -++#define CRG_CLK_SEL_MASK (0x7 << CRG_CLK_BIT_OFS) -++ -++/* Host dll reset register */ -++#define EMMC_DLL_RST_OFS 0x35c4 -++#define SDIO0_DLL_RST_OFS 0x35c4 -++#define SDIO1_DLL_RST_OFS 0x36c4 -++#define CRG_DLL_SRST_REQ BIT(1) -++ -++/* Host dll phase register */ -++#define EMMC_DRV_DLL_OFS 0x35c8 -++#define SDIO0_DRV_DLL_OFS 0x35c8 -++#define SDIO1_DRV_DLL_OFS 0x36c8 -++#define CRG_DRV_PHASE_SHIFT 15 -++#define CRG_DRV_PHASE_MASK (0x1F << CRG_DRV_PHASE_SHIFT) -++ -++/* Host dll state register */ -++#define EMMC_DLL_STA_OFS 0x35d8 -++#define SDIO0_DLL_STA_OFS 0x35d8 -++#define SDIO1_DLL_STA_OFS 0x36d8 -++#define CRG_P4_DLL_LOCKED BIT(9) -++#define CRG_DS_DLL_READY BIT(10) -++#define CRG_SAM_DLL_READY BIT(12) -++ -++/* Host drv cap config */ -++#define DRV_STR_SHIFT 4 -++#define DRV_STR_MASK_GPIO (0xF << DRV_STR_SHIFT) -++#define SR_STR_SHIFT 10 -++#define SR_STR_MASK_GPIO (0x1 << SR_STR_SHIFT) -++#define NEBULA_VOLT_SW_BVT 1 -++ -++/* EMMC IO register offset */ -++#define EMMC_CLK_GPIO_OFS 0x34 -++#define EMMC_CMD_GPIO_OFS 0x4c -++#define EMMC_RSTN_GPIO_OFS 0x28 -++#define EMMC_DQS_GPIO_OFS 0x48 -++#define EMMC_D0_GPIO_OFS 0x2c -++#define EMMC_D1_GPIO_OFS 0x38 -++#define EMMC_D2_GPIO_OFS 0x30 -++#define EMMC_D3_GPIO_OFS 0x50 -++#define EMMC_D4_GPIO_OFS 0x44 -++#define EMMC_D5_GPIO_OFS 0x54 -++#define EMMC_D6_GPIO_OFS 0x3c -++#define EMMC_D7_GPIO_OFS 0x40 -++ -++/* EMMC QFN IO register offset */ -++#define EMMC_CLK_QFN_GPIO_OFS 0x34 -++#define EMMC_CMD_QFN_GPIO_OFS 0x38 -++#define EMMC_RSTN_QFN_GPIO_OFS 0x28 -++#define EMMC_D0_QFN_GPIO_OFS 0x30 -++#define EMMC_D1_QFN_GPIO_OFS 0x2c -++#define EMMC_D2_QFN_GPIO_OFS 0x40 -++#define EMMC_D3_QFN_GPIO_OFS 0x3c -++ -++#define EMMC_BUS_WIDTH_PHY_ADDR 0x11020018 -++#define EMMC_QUICK_BOOT_PHY_ADDR 0x11020138 -++#define EMMC_QUICK_BOOT_PARAM1_OFS 0x14 -++ -++/* SDIO0 IO register offset */ -++#define SDIO0_DETECT_OFS 0x28 -++#define SDIO0_PWEN_OFS 0x44 -++#define SDIO0_CLK_OFS 0x34 -++#define SDIO0_CMD_OFS 0x38 -++#define SDIO0_D0_OFS 0x30 -++#define SDIO0_D1_OFS 0x2c -++#define SDIO0_D2_OFS 0x40 -++#define SDIO0_D3_OFS 0x3c -++ -++/* QFN or BGA mode */ -++#define EMMC_OTP_STAT 0x101E001C -++#define EMMC_INPUT_SEL BIT(17) -++ -++/* SDIO1 IO register offset */ -++#define SDIO1_DETECT_OFS 0x50 -++#define SDIO1_PWEN_OFS 0x54 -++#define SDIO1_CLK_OFS 0x44 -++#define SDIO1_CMD_OFS 0x40 -++#define SDIO1_D0_OFS 0x48 -++#define SDIO1_D1_OFS 0x4c -++#define SDIO1_D2_OFS 0x38 -++#define SDIO1_D3_OFS 0x3c -++ -++#include "sdhci_nebula.h" -++#include "platform_priv.h" -++#include "platform_timing.h" -++ -++static const nebula_crg_mask g_crg_mask = NEBULA_CRG_MASK_DESC; -++ -++/* EMMC fixed timing parameter */ -++static nebula_timing g_timing_gpio_emmc[] = { -++ [MMC_TIMING_LEGACY] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_MMC_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_12, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_20, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_MMC_HS200] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_9, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_9, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_20), -++ }, -++ [MMC_TIMING_MMC_HS400] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DQS] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_8), -++ }, -++}; -++ -++static nebula_timing g_qfn_timing_gpio_emmc[] = { -++ [MMC_TIMING_LEGACY] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_MMC_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_10, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_10, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_MMC_HS200] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_20), -++ }, -++}; -++ -++/* EMMC info struct */ -++static nebula_info g_gpio_emmc_info = \ -++ nebula_emmc_info_desc(g_timing_gpio_emmc); -++ -++static nebula_info g_qfn_gpio_emmc_info = \ -++ nebula_emmc_info_desc(g_qfn_timing_gpio_emmc); -++ -++static u32 g_qfn_emmc_io_offset[IO_TYPE_DMAX] = { -++ EMMC_CLK_QFN_GPIO_OFS, EMMC_CMD_QFN_GPIO_OFS, \ -++ EMMC_RSTN_QFN_GPIO_OFS, 0, \ -++ EMMC_D0_QFN_GPIO_OFS, EMMC_D1_QFN_GPIO_OFS, \ -++ EMMC_D2_QFN_GPIO_OFS, EMMC_D3_QFN_GPIO_OFS, -++}; -++ -++/* SDIO0 fixed timing parameter */ -++static nebula_timing g_timing_gpio_sdio0[] = { -++ [MMC_TIMING_LEGACY] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_12, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_SD_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_10, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_14, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_20, PHASE_LVL_4), -++ }, -++}; -++ -++/* SDIO0 info struct */ -++static const nebula_info g_gpio_sdio0_info = \ -++ nebula_sdio0_info_desc(g_timing_gpio_sdio0); -++ -++/* SDIO1 fixed timing parameter */ -++static nebula_timing g_timing_gpio_sdio1[] = { -++ [MMC_TIMING_LEGACY] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_SD_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_24, PHASE_LVL_4), -++ }, -++}; -++ -++/* SDIO1 info struct */ -++static const nebula_info g_gpio_sdio1_info = \ -++ nebula_sdio1_info_desc(g_timing_gpio_sdio1); -++ -++static bool priv_is_bga_package(struct sdhci_host *host) -++{ -++ void __iomem *sys_stat_reg; -++ static unsigned int sys_stat; -++ static bool sys_stat_init = false; -++ -++ if (sys_stat_init) -++ return ((sys_stat & EMMC_INPUT_SEL) == EMMC_INPUT_SEL); -++ -++ sys_stat_reg = ioremap(EMMC_OTP_STAT, sizeof(u32)); -++ if (sys_stat_reg == NULL) { -++ pr_err("%s: mmc otp ioremap error.\n", mmc_hostname(host->mmc)); -++ return -ENOMEM; -++ } -++ -++ sys_stat = readl(sys_stat_reg); -++ iounmap(sys_stat_reg); -++ -++ sys_stat_init = true; -++ -++ return ((sys_stat & EMMC_INPUT_SEL) == EMMC_INPUT_SEL); -++} -++ -++int plat_host_pre_init(struct platform_device *pdev, struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ nebula->mask = &g_crg_mask; -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ if (priv_is_bga_package(host)) { -++ nebula->info = &g_gpio_emmc_info; -++ } else { -++ nebula->info = &g_qfn_gpio_emmc_info; -++ } -++ } else if (nebula->devid == MMC_DEV_TYPE_SDIO_0) { -++ nebula->info = &g_gpio_sdio0_info; -++ } else if (nebula->devid == MMC_DEV_TYPE_SDIO_1) { -++ nebula->info = &g_gpio_sdio1_info; -++ } else { -++ pr_err("error: invalid device\n"); -++ return -EINVAL; -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++void plat_extra_init(struct sdhci_host *host) -++{ -++ u32 ctrl; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ ctrl = sdhci_readl(host, SDHCI_AXI_MBIU_CTRL); -++ ctrl &= ~SDHCI_UNDEFL_INCR_EN; -++ sdhci_writel(host, ctrl, SDHCI_AXI_MBIU_CTRL); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ plat_set_emmc_type(host); -++ } -++} -++ -++static void priv_plat_mux_init(struct sdhci_host *host) -++{ -++ u32 i, pin_mux_val; -++ u32 bus_width = 1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const nebula_info *info = nebula->info; -++ -++ if (nebula->priv_quirk & NEBULA_QUIRK_FPGA) -++ return; -++ -++ if (host->mmc->caps & MMC_CAP_8_BIT_DATA) { -++ bus_width = (1 << MMC_BUS_WIDTH_8); -++ } else if (host->mmc->caps & MMC_CAP_4_BIT_DATA) { -++ bus_width = (1 << MMC_BUS_WIDTH_4); -++ } -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CLK], \ -++ 0x12B1); /* 0x12B1: pinmux value */ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CMD], \ -++ 0x11C1); /* 0x11C1: pinmux value */ -++ pin_mux_val = 0x11C1; /* 0x11C1: pinmux value */ -++ if (priv_is_bga_package(host)) { -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CMD], \ -++ 0x11C2); /* 0x11C2: pinmux value */ -++ pin_mux_val = 0x11C2; /* 0x11C2: pinmux value */ -++ } -++ for (i = IO_TYPE_D0; i < (IO_TYPE_D0 + bus_width); i++) -++ regmap_write(nebula->iocfg_regmap, info->io_offset[i], pin_mux_val); -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_RST], \ -++ 0x1132); /* 0x1132: pinmux value */ -++ if (host->mmc->caps & MMC_CAP_8_BIT_DATA) -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_DQS], \ -++ 0x12C2); /* 0x12C2: pinmux value */ -++ } else if (nebula->devid == MMC_DEV_TYPE_SDIO_0 || \ -++ nebula->devid == MMC_DEV_TYPE_SDIO_1) { -++ if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) == 0) -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_DET], \ -++ 0x1131); /* 0x1131: pinmux value */ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_PWE], \ -++ (nebula->devid == MMC_DEV_TYPE_SDIO_0) ? 0x11F1 : 0x1131); -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CLK], \ -++ 0x12F1); /* 0x12F1: pinmux value */ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CMD], \ -++ 0x11F1); /* 0x11F1: pinmux value */ -++ for (i = IO_TYPE_D0; i < (IO_TYPE_D0 + bus_width); i++) -++ regmap_write(nebula->iocfg_regmap, info->io_offset[i], \ -++ 0x11F1); /* 0x11F1: pinmux value */ -++ } -++} -++ -++static void plat_set_qfn_parameters(struct sdhci_host *host) -++{ -++ int idx; -++ -++ if (priv_is_bga_package(host)) -++ return; -++ -++ for (idx = 0; idx < IO_TYPE_DMAX; idx++) -++ g_qfn_gpio_emmc_info.io_offset[idx] = g_qfn_emmc_io_offset[idx]; -++ -++ /* only 4bits width */ -++ host->mmc->caps &= ~MMC_CAP_8_BIT_DATA; -++} -++ -++void plat_caps_quirks_init(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ plat_comm_caps_quirks_init(host); -++ -++ plat_set_mmc_bus_width(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) -++ plat_set_qfn_parameters(host); -++ -++ if ((nebula->priv_cap & NEBULA_CAP_QUICK_BOOT) == 0) -++ priv_plat_mux_init(host); -++} -+diff --git a/drivers/vendor/mmc/platform/sdhci_hi3519dv500.c b/drivers/vendor/mmc/platform/sdhci_hi3519dv500.c -+new file mode 100755 -+index 000000000..42f0d0bf7 -+--- /dev/null -++++ b/drivers/vendor/mmc/platform/sdhci_hi3519dv500.c -+@@ -0,0 +1,351 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++ -++#include "sdhci.h" -++ -++/* Host controller CRG */ -++#define EMMC_CRG_CLK_OFS 0x34c0 -++#define SDIO0_CRG_CLK_OFS 0x35c0 -++#define SDIO1_CRG_CLK_OFS 0x36c0 -++#define CRG_SRST_REQ (BIT(16) | BIT(17) | BIT(18)) -++#define CRG_CLK_EN_MASK (BIT(0) | BIT(1)) -++#define CRG_CLK_BIT_OFS 24 -++#define CRG_CLK_SEL_MASK (0x7 << CRG_CLK_BIT_OFS) -++ -++/* Host dll reset register */ -++#define EMMC_DLL_RST_OFS 0x34c4 -++#define SDIO0_DLL_RST_OFS 0x35c4 -++#define SDIO1_DLL_RST_OFS 0x36c4 -++#define CRG_DLL_SRST_REQ BIT(1) -++ -++/* Host dll phase register */ -++#define EMMC_DRV_DLL_OFS 0x34c8 -++#define SDIO0_DRV_DLL_OFS 0x35c8 -++#define SDIO1_DRV_DLL_OFS 0x36c8 -++#define CRG_DRV_PHASE_SHIFT 15 -++#define CRG_DRV_PHASE_MASK (0x1F << CRG_DRV_PHASE_SHIFT) -++ -++/* Host dll state register */ -++#define EMMC_DLL_STA_OFS 0x34d8 -++#define SDIO0_DLL_STA_OFS 0x35d8 -++#define SDIO1_DLL_STA_OFS 0x36d8 -++#define CRG_P4_DLL_LOCKED BIT(9) -++#define CRG_DS_DLL_READY BIT(10) -++#define CRG_SAM_DLL_READY BIT(12) -++ -++/* Host drv cap config */ -++#define DRV_STR_SHIFT 4 -++#define DRV_STR_MASK_GPIO (0xF << DRV_STR_SHIFT) -++#define SR_STR_SHIFT 10 -++#define SR_STR_MASK_GPIO (0x1 << SR_STR_SHIFT) -++#define NEBULA_VOLT_SW_BVT 1 -++ -++/* EMMC IO register offset */ -++#define EMMC_CLK_GPIO_OFS 0x34 -++#define EMMC_CMD_GPIO_OFS 0x38 -++#define EMMC_RSTN_GPIO_OFS 0x4c -++#define EMMC_DQS_GPIO_OFS 0x50 -++#define EMMC_D0_GPIO_OFS 0x3c -++#define EMMC_D1_GPIO_OFS 0x40 -++#define EMMC_D2_GPIO_OFS 0x44 -++#define EMMC_D3_GPIO_OFS 0x48 -++#define EMMC_D4_GPIO_OFS 0x24 -++#define EMMC_D5_GPIO_OFS 0x28 -++#define EMMC_D6_GPIO_OFS 0x2c -++#define EMMC_D7_GPIO_OFS 0x30 -++ -++#define EMMC_BUS_WIDTH_PHY_ADDR 0x11020018 -++#define EMMC_QUICK_BOOT_PHY_ADDR 0x11120020 -++#define EMMC_QUICK_BOOT_PARAM1_OFS 0x4 -++ -++/* SDIO0 IO register offset */ -++#define SDIO0_DETECT_OFS 0xd0 -++#define SDIO0_PWEN_OFS 0xd4 -++#define SDIO0_CLK_OFS 0xcc -++#define SDIO0_CMD_OFS 0xb8 -++#define SDIO0_D0_OFS 0xbc -++#define SDIO0_D1_OFS 0xc0 -++#define SDIO0_D2_OFS 0xc4 -++#define SDIO0_D3_OFS 0xc8 -++ -++/* Voltage switch physical address */ -++#define SDIO0_VOLT_SW_PHY_ADDR 0x11024700 -++ -++/* SDIO1 IO register offset */ -++#define SDIO1_CLK_OFS 0xb0 -++#define SDIO1_CMD_OFS 0xb4 -++#define SDIO1_D0_OFS 0xa0 -++#define SDIO1_D1_OFS 0xa4 -++#define SDIO1_D2_OFS 0xa8 -++#define SDIO1_D3_OFS 0xac -++ -++#include "sdhci_nebula.h" -++#include "platform_priv.h" -++#include "platform_timing.h" -++ -++static const nebula_crg_mask g_crg_mask = NEBULA_CRG_MASK_DESC; -++ -++/* EMMC fixed timing parameter */ -++static nebula_timing g_timing_gpio_emmc[] = { -++ [MMC_TIMING_LEGACY] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_2, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_2, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_MMC_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_4, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_MMC_HS200] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_12, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_DQS] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_12, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_18), -++ }, -++ [MMC_TIMING_MMC_HS400] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ .timing[IO_TYPE_RST] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_DQS] = fixed_gpio_drv(TM_LVL_0, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_9), -++ }, -++}; -++ -++/* EMMC info struct */ -++static const nebula_info g_gpio_emmc_info = \ -++ nebula_emmc_info_desc(g_timing_gpio_emmc); -++ -++/* SDIO0 fixed timing parameter */ -++static nebula_timing g_timing_gpio_sdio0[] = { -++ [MMC_TIMING_LEGACY] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_2, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_2, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_MMC_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_4, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_19, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_MMC_HS200] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_8, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_6, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_6, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_20), -++ }, -++ [MMC_TIMING_SD_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_4, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_UHS_SDR12] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_9, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_UHS_SDR25] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_9, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_UHS_SDR50] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_12, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_10, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_10, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_20), -++ }, -++ [MMC_TIMING_UHS_SDR104] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_8, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_6, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_6, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_20), -++ }, -++}; -++ -++/* SDIO0 info struct */ -++static const nebula_info g_gpio_sdio0_info = \ -++ nebula_sdio0_info_desc(g_timing_gpio_sdio0); -++ -++/* SDIO1 fixed timing parameter */ -++static nebula_timing g_timing_gpio_sdio1[] = { -++ [MMC_TIMING_LEGACY] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_2, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_2, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_MMC_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_4, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_MMC_HS200] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_11, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_11, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_20), -++ }, -++ [MMC_TIMING_SD_HS] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_4, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_3, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_UHS_SDR12] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_9, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_0), -++ }, -++ [MMC_TIMING_UHS_SDR25] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_9, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_7, SR_LVL_0), -++ fixed_drv_samp_phase(PHASE_LVL_16, PHASE_LVL_4), -++ }, -++ [MMC_TIMING_UHS_SDR50] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_12, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_10, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_10, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_20), -++ }, -++ [MMC_TIMING_UHS_SDR104] = { -++ .data_valid = true, -++ .timing[IO_TYPE_CLK] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ .timing[IO_TYPE_CMD] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ .timing[IO_TYPE_DATA] = fixed_gpio_drv(TM_LVL_15, SR_LVL_0), -++ fixed_drv_phase_only(PHASE_LVL_19), -++ }, -++}; -++ -++/* SDIO1 info struct */ -++static const nebula_info g_gpio_sdio1_info = \ -++ nebula_sdio1_info_desc(g_timing_gpio_sdio1); -++ -++int plat_host_pre_init(struct platform_device *pdev, struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ nebula->mask = &g_crg_mask; -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ nebula->info = &g_gpio_emmc_info; -++ } else if (nebula->devid == MMC_DEV_TYPE_SDIO_0) { -++ nebula->info = &g_gpio_sdio0_info; -++ nebula->priv_cap |= NEBULA_CAP_VOLT_SW; -++ } else if (nebula->devid == MMC_DEV_TYPE_SDIO_1) { -++ nebula->info = &g_gpio_sdio1_info; -++ } else { -++ pr_err("error: invalid device\n"); -++ return -EINVAL; -++ } -++ -++ return ERET_SUCCESS; -++} -++ -++void plat_extra_init(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ plat_set_emmc_type(host); -++ } -++} -++ -++static void priv_plat_mux_init(struct sdhci_host *host) -++{ -++ u32 i; -++ u32 bus_width = 1; -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ const nebula_info *info = nebula->info; -++ -++ if (host->mmc->caps & MMC_CAP_8_BIT_DATA) { -++ bus_width = (1 << MMC_BUS_WIDTH_8); -++ } else if (host->mmc->caps & MMC_CAP_4_BIT_DATA) { -++ bus_width = (1 << MMC_BUS_WIDTH_4); -++ } -++ -++ if (nebula->devid == MMC_DEV_TYPE_MMC_0) { -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CLK], \ -++ 0x11e1); /* 0x11e1: pinmux value */ -++ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CMD], \ -++ 0x1391); /* 0x1391: pinmux value */ -++ -++ for (i = IO_TYPE_D0; i < (IO_TYPE_D0 + bus_width); i++) -++ regmap_write(nebula->iocfg_regmap, info->io_offset[i], \ -++ (i < IO_TYPE_D4) ? 0x1391 : 0x1393); /* 0x1391, 0x1393: pinmux value */ -++ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_RST], \ -++ 0x1301); /* 0x1301: pinmux value */ -++ -++ if (host->mmc->caps & MMC_CAP_8_BIT_DATA) -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_DQS], \ -++ 0x1101); /* 0x1101: pinmux value */ -++ } else if (nebula->devid == MMC_DEV_TYPE_SDIO_0 || \ -++ nebula->devid == MMC_DEV_TYPE_SDIO_1) { -++ if (nebula->devid == MMC_DEV_TYPE_SDIO_0) { -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_DET], \ -++ 0x1901); /* 0x1901: pinmux value */ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_PWE], \ -++ 0x1501); /* 0x1501: pinmux value */ -++ } -++ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CLK], \ -++ 0x1101); /* 0x1101: pinmux value */ -++ regmap_write(nebula->iocfg_regmap, info->io_offset[IO_TYPE_CMD], \ -++ 0x1301); /* 0x1301: pinmux value */ -++ -++ for (i = IO_TYPE_D0; i < (IO_TYPE_D0 + bus_width); i++) -++ regmap_write(nebula->iocfg_regmap, info->io_offset[i], \ -++ 0x1301); /* 0x1301: pinmux value */ -++ } -++} -++ -++void plat_caps_quirks_init(struct sdhci_host *host) -++{ -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ plat_comm_caps_quirks_init(host); -++ -++ plat_set_mmc_bus_width(host); -++ if ((nebula->priv_cap & NEBULA_CAP_QUICK_BOOT) == 0) -++ priv_plat_mux_init(host); -++ -++ if ((host->mmc->caps2 & MMC_CAP2_NO_SDIO) == 0) -++ nebula->priv_cap |= NEBULA_CAP_PM_RUNTIME; -++} -+diff --git a/drivers/vendor/mmc/sdhci_nebula.c b/drivers/vendor/mmc/sdhci_nebula.c -+new file mode 100755 -+index 000000000..bc1b8e544 -+--- /dev/null -++++ b/drivers/vendor/mmc/sdhci_nebula.c -+@@ -0,0 +1,183 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#include -++#include -++#include -++ -++#include "dfx/mci_proc.h" -++#include "sdhci_nebula.h" -++ -++static unsigned int g_slot_index; -++struct mmc_host *g_mci_host[MCI_SLOT_NUM] = {NULL}; -++struct mmc_host *g_mmc_host[MCI_SLOT_NUM] = {NULL}; -++ -++static const struct of_device_id g_sdhci_nebula_match[] = { -++ { .compatible = "nebula,sdhci" }, -++ { .compatible = "huanglong,sdhci" }, -++ {}, -++}; -++ -++MODULE_DEVICE_TABLE(of, g_sdhci_nebula_match); -++ -++static struct sdhci_ops g_sdhci_nebula_ops = { -++ .platform_execute_tuning = sdhci_nebula_execute_tuning, -++ .reset = sdhci_nebula_reset, -++ .set_clock = sdhci_nebula_set_clock, -++ .irq = sdhci_nebula_irq, -++ .set_bus_width = sdhci_nebula_set_bus_width, -++ .set_uhs_signaling = sdhci_nebula_set_uhs_signaling, -++ .hw_reset = sdhci_nebula_hw_reset, -++ .signal_voltage_switch = sdhci_nebula_voltage_switch, -++ .init = sdhci_nebula_extra_init, -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) -++ .dump_vendor_regs = sdhci_nebula_dump_vendor_regs, -++#endif -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -++ .adma_write_desc = sdhci_nebula_adma_write_desc, -++#endif -++ -++}; -++ -++static const struct sdhci_pltfm_data g_sdhci_nebula_pdata = { -++ .ops = &g_sdhci_nebula_ops, -++ .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, -++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, -++}; -++ -++static int sdhci_nebula_probe(struct platform_device *pdev) -++{ -++ int ret; -++ struct sdhci_host *host; -++ struct sdhci_nebula *nebula = NULL; -++ -++ host = sdhci_pltfm_init(pdev, &g_sdhci_nebula_pdata, -++ sizeof(struct sdhci_nebula)); -++ if (IS_ERR(host)) -++ return (int)PTR_ERR(host); -++ -++ ret = sdhci_nebula_pltfm_init(pdev, host); -++ if (ret) -++ goto pltfm_free; -++ -++ nebula = nebula_priv(host); -++ if (nebula->priv_cap & NEBULA_CAP_PM_RUNTIME) { -++ pm_runtime_get_noresume(&pdev->dev); -++ pm_runtime_set_autosuspend_delay(&pdev->dev, -++ MMC_AUTOSUSPEND_DELAY_MS); -++ pm_runtime_use_autosuspend(&pdev->dev); -++ pm_runtime_set_active(&pdev->dev); -++ pm_runtime_enable(&pdev->dev); -++ } -++ -++ ret = sdhci_nebula_add_host(host); -++ if (ret) -++ goto pm_runtime_disable; -++ -++ if (nebula->priv_cap & NEBULA_CAP_PM_RUNTIME) { -++ pm_runtime_mark_last_busy(&pdev->dev); -++ pm_runtime_put_autosuspend(&pdev->dev); -++ } -++ -++ ret = sdhci_nebula_proc_init(host); -++ if (ret) -++ goto pm_runtime_disable; -++ -++ g_mci_host[g_slot_index++] = host->mmc; -++ -++ if ((nebula->devid >= 0) && (nebula->devid < MCI_SLOT_NUM)) -++ g_mmc_host[nebula->devid] = host->mmc; -++ -++ return ERET_SUCCESS; -++ -++pm_runtime_disable: -++ if (nebula->priv_cap & NEBULA_CAP_PM_RUNTIME) { -++ pm_runtime_disable(&pdev->dev); -++ pm_runtime_set_suspended(&pdev->dev); -++ pm_runtime_put_noidle(&pdev->dev); -++ } -++ -++pltfm_free: -++ sdhci_pltfm_free(pdev); -++ return ret; -++} -++ -++static int sdhci_nebula_remove(struct platform_device *pdev) -++{ -++ int ret; -++ struct sdhci_host *host = platform_get_drvdata(pdev); -++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); -++ struct sdhci_nebula *nebula = nebula_priv(host); -++ -++ if (nebula->priv_cap & NEBULA_CAP_PM_RUNTIME) { -++ pm_runtime_get_sync(&pdev->dev); -++ pm_runtime_disable(&pdev->dev); -++ pm_runtime_put_noidle(&pdev->dev); -++ } -++ -++ sdhci_remove_host(host, true); -++ -++ ret = sdhci_nebula_proc_shutdown(host); -++ if (ret != ERET_SUCCESS) { -++ pr_err("failed to shutdown proc.\n"); -++ return ret; -++ } -++ -++ if (!IS_ERR_OR_NULL(nebula->hclk)) -++ clk_disable_unprepare(nebula->hclk); -++ -++ clk_disable_unprepare(pltfm_host->clk); -++ -++ sdhci_pltfm_free(pdev); -++ -++ return ret; -++} -++ -++static const struct dev_pm_ops g_sdhci_nebula_pm_ops = { -++ SET_SYSTEM_SLEEP_PM_OPS(sdhci_nebula_pltfm_suspend, -++ sdhci_nebula_pltfm_resume) -++ SET_RUNTIME_PM_OPS(sdhci_nebula_runtime_suspend, -++ sdhci_nebula_runtime_resume, -++ NULL) -++}; -++ -++static struct platform_driver g_sdhci_nebula_driver = { -++ .probe = sdhci_nebula_probe, -++ .remove = sdhci_nebula_remove, -++ .driver = { -++ .name = "sdhci_nebula", -++ .of_match_table = g_sdhci_nebula_match, -++ .pm = &g_sdhci_nebula_pm_ops, -++ }, -++}; -++ -++static int __init sdhci_bsp_init(void) -++{ -++ int ret; -++ -++ ret = platform_driver_register(&g_sdhci_nebula_driver); -++ if (ret) { -++ pr_err("failed to register sdhci drv.\n"); -++ return ret; -++ } -++ -++ ret = mci_proc_init(); -++ if (ret) -++ platform_driver_unregister(&g_sdhci_nebula_driver); -++ -++ return ret; -++} -++ -++static void __exit sdhci_bsp_exit(void) -++{ -++ mci_proc_shutdown(); -++ -++ platform_driver_unregister(&g_sdhci_nebula_driver); -++} -++ -++module_init(sdhci_bsp_init); -++module_exit(sdhci_bsp_exit); -++ -++MODULE_DESCRIPTION("SDHCI driver for vendor"); -++MODULE_AUTHOR("CompanyNameMagicTag."); -++MODULE_LICENSE("GPL v2"); -+diff --git a/drivers/vendor/mmc/sdhci_nebula.h b/drivers/vendor/mmc/sdhci_nebula.h -+new file mode 100755 -+index 000000000..fb15fb6fd -+--- /dev/null -++++ b/drivers/vendor/mmc/sdhci_nebula.h -+@@ -0,0 +1,319 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _DRIVERS_MMC_SDHCI_NEBULA_H -++#define _DRIVERS_MMC_SDHCI_NEBULA_H -++ -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "sdhci-pltfm.h" -++#include "sdhci_nebula.h" -++ -++/* The operation completed successfully. */ -++#define ERET_SUCCESS 0 -++ -++#define SDHCI_HL_EDGE_TUNING /* enable edge tuning */ -++ -++#define PHASE_SCALE 32 -++#define EDGE_TUNING_PHASE_STEP 4 -++#define NOT_FOUND (-1) -++#define MAX_TUNING_NUM 1 -++#define WIN_DIV 2 -++#define WIN_MASK 0x3 -++#define WIN_RISE 0x2 -++#define WIN_FALL 0x1 -++ -++#define MAX_FREQ 200000000 -++#define MMC_BLOCK_SIZE 512 -++ -++#ifndef CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT -++#define CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT 0x2 -++#endif -++#define CQHCI_MAX_SEGS_MUL 2 -++#define SDHCI_CTRL_64BIT_ADDR 0x2000 -++#define SDHCI_CTRL_V4_ENABLE 0x1000 -++ -++#define CQE_MAX_TIMEOUT 10000 -++/* Software auto suspend delay */ -++#define MMC_AUTOSUSPEND_DELAY_MS 50 -++ -++/* -++ * Nebula extended host controller registers. -++ */ -++#define SDHCI_EMMC_CTRL 0x52C -++#define SDHCI_CARD_IS_EMMC 0x0001 -++#define SDHCI_ENH_STROBE_EN 0x0100 -++ -++#define SDHCI_EMMC_HW_RESET 0x534 -++ -++#define SDHCI_AT_CTRL 0x540 -++#define SDHCI_SAMPLE_EN 0x00000010 -++ -++#define SDHCI_AXI_MBIU_CTRL 0x510 -++#define SDHCI_UNDEFL_INCR_EN 0x1 -++ -++#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) -++ -++#define SDHCI_MSHC_CTRL_R 0x508 -++#define SDHCI_DEBUG1_PORT 0x520 -++#define SDHCI_DEBUG2_PORT 0x524 -++#define SDHCI_GP_OUT_R 0x534 -++#define SDHCI_EMAX_R 0x548 -++#define SDHCI_MUTLI_CYCLE_EN 0x54C -++ -++#define NEBULA_CQE_OFS 0x180 -++ -++#define SDHCI_DETECT_POLARITY BIT(3) -++#define SDHCI_PWR_EN_POLARITY BIT(5) -++ -++#define CONFIG_SDHCI_NEBULA_DFX -++#define NEBULA_DFX_BT_MAX_NUM 8 -++ -++#define INVALID_DATA 0xFFFFFFFF -++ -++#define MCI_SLOT_NUM 4 -++ -++enum mmc_crg_type { -++ CRG_CLK_RST = 0, -++ CRG_DLL_RST, -++ CRG_DRV_DLL, -++ CRG_DLL_STA, -++ CRG_TYPE_MAX, -++}; -++ -++enum phase_type { -++ DRV_PHASE = 0, -++ SAMP_PHASE, -++ PHASE_MAX, -++}; -++ -++enum mmc_io_type { -++ MMC_IO_TYPE_IO, -++ MMC_IO_TYPE_GPIO, -++ MMC_IO_TYPE_MAX, -++}; -++ -++enum mmc_dev_type { -++ MMC_DEV_TYPE_MMC_0 = 0, -++ MMC_DEV_TYPE_SDIO_0, -++ MMC_DEV_TYPE_SDIO_1, -++ MMC_DEV_TYPE_MAX, -++}; -++ -++/** -++ * mmc spec define 5 io types, -++ * data line with 8 bit width -++ */ -++enum io_type { -++ IO_TYPE_CLK = 0, -++ IO_TYPE_CMD, -++ IO_TYPE_RST, -++ IO_TYPE_DET = IO_TYPE_RST, -++ IO_TYPE_DQS, -++ IO_TYPE_PWE = IO_TYPE_DQS, -++ IO_TYPE_DATA, -++ IO_TYPE_MAX, -++ IO_TYPE_D0 = IO_TYPE_DATA, -++ IO_TYPE_D1 = IO_TYPE_MAX, -++ IO_TYPE_D2, -++ IO_TYPE_D3, -++ IO_TYPE_D4, -++ IO_TYPE_D5, -++ IO_TYPE_D6, -++ IO_TYPE_D7, -++ IO_TYPE_DMAX, -++}; -++ -++/** -++ * struct mmc_timing_s - nebula host timing data array -++ * @data_valid: this timing valid? -++ * @timing: io timing array -++ * @phase: phase timing array -++ */ -++typedef struct mmc_timing_s { -++ bool data_valid; -++ u32 timing[IO_TYPE_MAX]; -++ u32 phase[PHASE_MAX]; -++} nebula_timing; -++ -++/** -++ * struct nebula_info_s - nebula host info data array -++ * @io_offset: io pin register offset array -++ * @io_drv_mask: io pin driver cap configure mask -++ * @io_drv_str_bit_ofs: io pin driver cap bit offset -++ * @io_drv_str_mask: io pin driver cap mask -++ * @io_drv_sr_bit_ofs: io pin driver cap bit offset -++ * @io_drv_sr_mask: io pin driver cap mask -++ * @crg_ofs: host crg register offset array -++ * @zq_phy_addr: zq resistance calibration physical addr -++ * @volt_sw_phy_addr: voltage switch ctrl phisical addr -++ * @bus_width_phy_addr: get bus width phisical addr -++ * @qboot_phy_addr: emmc quick boot parameters phisical addr -++ * @qboot_param1_ofs: emmc quick boot parameter1 offset -++ * @timing_size: host fixed timing size -++ * @timing: host fixed timing point -++ */ -++typedef struct nebula_info_s { -++ u32 io_offset[IO_TYPE_DMAX]; -++ u32 io_drv_mask; -++ u32 io_drv_str_bit_ofs; -++ u32 io_drv_str_mask; -++ u32 io_drv_sr_bit_ofs; -++ u32 io_drv_sr_mask; -++ u32 crg_ofs[CRG_TYPE_MAX]; -++ phys_addr_t zq_phy_addr; -++ phys_addr_t volt_sw_phy_addr; -++ phys_addr_t bus_width_phy_addr; -++ phys_addr_t qboot_phy_addr; -++ u32 qboot_param1_ofs; -++ u32 timing_size; -++ nebula_timing *timing; -++}nebula_info; -++ -++/** -++ * struct nebula_crg_mask_s - nebula host crg mask info -++ * @crg_srst_mask: reset/unreset mmc controller mask -++ * @crg_cken_mask: mmc controller clock enable mask -++ * @crg_clk_sel_ofs: mmc controller clock select bit offset -++ * @crg_clk_sel_mask: mmc controller clock select mask -++ * @dll_srst_mask: dll reset/unreset mask -++ * @p4_lock_mask: wait p4 lock status mask -++ * @dll_ready_mask: wait dll ready mask -++ * @samp_ready_mask: wait sample ready mask -++ * @drv_phase_mask: driver phase setting mask -++ */ -++typedef struct nebula_crg_mask_s { -++ u32 crg_srst_mask; -++ u32 crg_clk_sel_ofs; -++ u32 crg_clk_sel_mask; -++ u32 crg_cken_mask; -++ u32 dll_srst_mask; -++ u32 p4_lock_mask; -++ u32 dll_ready_mask; -++ u32 samp_ready_mask; -++ u32 drv_phase_mask; -++ u32 volt_sw_en_mask; -++ u32 volt_sw_1v8_mask; -++} nebula_crg_mask; -++ -++typedef struct nebula_cmd_info { -++ u32 opcode[NEBULA_DFX_BT_MAX_NUM]; -++ u32 sp; -++} nebula_cmd_bt; -++ -++typedef struct nebula_cap_s { -++ u32 help : 1; // [0] -++ u32 log_level : 7; // [7:1] -++} nebula_cap; -++ -++struct sdhci_nebula { -++ enum mmc_io_type io_type; /* io type: gpio or high speed io */ -++ struct reset_control *crg_rst; /* reset handle for host controller */ -++ struct reset_control *crg_tx; -++ struct reset_control *crg_rx; -++ struct reset_control *dll_rst; -++ struct reset_control *samp_rst; -++ struct regmap *crg_regmap; /* regmap for host controller */ -++ struct regmap *iocfg_regmap; -++ const nebula_crg_mask *mask; -++ const nebula_info *info; /* io, timing, crg info */ -++ struct clk *hclk; /* AHB clock */ -++ -++ u32 priv_cap; -++#define NEBULA_CAP_PM_RUNTIME (1 << 0) /* Support PM runtime */ -++#define NEBULA_CAP_QUICK_BOOT (1 << 1) /* Support quick boot */ -++#define NEBULA_CAP_RST_IN_DRV (1 << 2) /* Support reset in driver */ -++#define NEBULA_CAP_VOLT_SW (1 << 3) /* Support voltage switch */ -++#define NEBULA_CAP_ZQ_CALB (1 << 4) /* Support ZQ resistance calibration */ -++#define NEBULA_CAP_NM_CARD (1 << 5) /* This controller plugged NM card */ -++ -++ u32 priv_quirk; /* Deviations from soc. */ -++#define NEBULA_QUIRK_FPGA (1 << 0) /* FPGA board */ -++#define NEBULA_QUIRK_SAMPLE_TURNING (1 << 1) /* for not support edge turning */ -++#define NEBULA_QUIRK_CD_INVERTED (1 << 2) /* This card detect inverted */ -++#define NEBULA_QUIRK_PWR_EN_INVERTED (1 << 3) /* This power en inverted */ -++ -++ unsigned int devid; /* device id, mapping to enum mmc_dev_type */ -++ unsigned int drv_phase; -++ unsigned int sample_phase; -++ unsigned int tuning_phase; -++ nebula_cmd_bt cmd_bt; -++ nebula_cap dfx_cap; -++ struct proc_dir_entry *proc_root; -++ struct proc_dir_entry *proc_stat; -++ void __iomem *qboot_virt_addr; -++}; -++ -++static inline void *nebula_priv(struct sdhci_host *host) -++{ -++ return sdhci_pltfm_priv(sdhci_priv(host)); -++} -++ -++extern struct mmc_host *g_mci_host[MCI_SLOT_NUM]; -++extern struct mmc_host *g_mmc_host[MCI_SLOT_NUM]; -++ -++/* Export api by platform */ -++void plat_extra_init(struct sdhci_host *host); -++void plat_set_drv_cap(struct sdhci_host *host); -++void plat_get_drv_samp_phase(struct sdhci_host *host); -++void plat_set_drv_phase(struct sdhci_host *host, u32 phase); -++void plat_dll_reset_assert(struct sdhci_host *host); -++void plat_dll_reset_deassert(struct sdhci_host *host); -++void plat_caps_quirks_init(struct sdhci_host *host); -++void plat_dump_io_info(struct sdhci_host *host); -++void plat_set_mmc_bus_width(struct sdhci_host *host); -++void plat_set_emmc_type(struct sdhci_host *host); -++void plat_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios); -++int plat_crg_init(struct sdhci_host *host); -++int plat_wait_sample_dll_ready(struct sdhci_host *host); -++int plat_wait_p4_dll_lock(struct sdhci_host *host); -++int plat_wait_ds_dll_ready(struct sdhci_host *host); -++int plat_host_init(struct platform_device *pdev, struct sdhci_host *host); -++int plat_voltage_switch(struct sdhci_host *host, struct mmc_ios *ios); -++int plat_host_pre_init(struct platform_device *pdev, struct sdhci_host *host); -++int plat_resistance_calibration(struct sdhci_host *host); -++ -++/* -++ * Export api for sdhci ops (by adapter) -++ */ -++void sdhci_nebula_extra_init(struct sdhci_host *host); -++void sdhci_nebula_set_uhs_signaling(struct sdhci_host *host, unsigned int timing); -++void sdhci_nebula_hw_reset(struct sdhci_host *host); -++void sdhci_nebula_set_clock(struct sdhci_host *host, unsigned int clk); -++int sdhci_nebula_execute_tuning(struct sdhci_host *host, u32 opcode); -++int sdhci_nebula_voltage_switch(struct sdhci_host *host, struct mmc_ios *ios); -++int sdhci_nebula_pltfm_init(struct platform_device *pdev, struct sdhci_host *host); -++int sdhci_nebula_runtime_suspend(struct device *dev); -++int sdhci_nebula_runtime_resume(struct device *dev); -++int sdhci_nebula_add_host(struct sdhci_host *host); -++int sdhci_nebula_pltfm_suspend(struct device *dev); -++int sdhci_nebula_pltfm_resume(struct device *dev); -++u32 sdhci_nebula_irq(struct sdhci_host *host, u32 intmask); -++void sdhci_nebula_dump_vendor_regs(struct sdhci_host *host); -++void sdhci_nebula_set_bus_width(struct sdhci_host *host, int width); -++void sdhci_nebula_adma_write_desc(struct sdhci_host *host, void **desc, -++ dma_addr_t addr, int len, unsigned int cmd); -++void sdhci_nebula_reset(struct sdhci_host *host, u8 mask); -++ -++/* -++ * Export api by dfx -++ */ -++int sdhci_nebula_proc_init(struct sdhci_host *host); -++int sdhci_nebula_proc_shutdown(struct sdhci_host *host); -++void sdhci_nebula_dfx_irq(struct sdhci_host *host, u32 intmask); -++ -++#endif /* _DRIVERS_MMC_SDHCI_NEBULA_H */ -+diff --git a/drivers/vendor/mmc/version.mak b/drivers/vendor/mmc/version.mak -+new file mode 100755 -+index 000000000..3109e00f2 -+--- /dev/null -++++ b/drivers/vendor/mmc/version.mak -+@@ -0,0 +1 @@ -++SDHCI_NEBULA_KERNEL_VERSION="MMC_KERNEL 1.0.0" -+diff --git a/drivers/vendor/ups_phy/Kconfig b/drivers/vendor/ups_phy/Kconfig -+new file mode 100755 -+index 000000000..acb646a8a -+--- /dev/null -++++ b/drivers/vendor/ups_phy/Kconfig -+@@ -0,0 +1,28 @@ -++menu "Wing UPS Phy" -++ -++config WING_UPS_PHY -++ tristate "Support Wing UPS Phy" -++ select GENERIC_PHY -++ help -++ Say Y or M here if you want support Wing UPS phy. -++ -++if WING_UPS_PHY -++config WING_UPS_XVP_PHY -++ bool "Support UPS Xvp Phy" -++ help -++ Say Y here if you want to support xvp phy. -++ -++config WING_UPS_NANO_PHY -++ bool "Support UPS Nano Phy" -++ help -++ Say Y here if you want to support nano phy. -++ -++config WING_UPS_MISSILE_PHY -++ bool "Support UPS Missile Phy" -++ help -++ Say Y here if you want to support missile phy. -++ -++endif #WING_UPS_PHY -++ -++endmenu -++ -+diff --git a/drivers/vendor/ups_phy/Makefile b/drivers/vendor/ups_phy/Makefile -+new file mode 100755 -+index 000000000..f8c95721f -+--- /dev/null -++++ b/drivers/vendor/ups_phy/Makefile -+@@ -0,0 +1,21 @@ -++KBUILD_CFLAGS += -Werror -++ -++ifneq ($(CONFIG_ARCH_SHAOLINSWORD),y) -++ -++obj-$(CONFIG_WING_UPS_PHY) = wing-ups-phy.o -++wing-ups-phy-y := phy.o common.o -++ -++ifeq ($(CONFIG_WING_UPS_XVP_PHY), y) -++wing-ups-phy-y += xvp.o -++endif -++ -++ifeq ($(CONFIG_WING_UPS_NANO_PHY), y) -++wing-ups-phy-y += nano.o -++endif -++ -++ifeq ($(CONFIG_WING_UPS_MISSILE_PHY), y) -++wing-ups-phy-y += missile.o -++endif -++ -++endif -++ -+diff --git a/drivers/vendor/ups_phy/common.c b/drivers/vendor/ups_phy/common.c -+new file mode 100755 -+index 000000000..c55bc9a6d -+--- /dev/null -++++ b/drivers/vendor/ups_phy/common.c -+@@ -0,0 +1,45 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "[ups-phy-common]" -++#define pr_fmt(fmt) DRVNAME ": " fmt -++ -++#include "phy.h" -++#include "reg.h" -++ -++void combphy_write(void __iomem *reg, u32 addr, u32 value) -++{ -++ u32 val; -++ -++ val = phy_readl(reg); -++ val |= PERI_COMBPHY0_TEST_RST_N; /* Combophy0,1 just l lane */ -++ val &= ~PERI_COMBPHY_TEST_ADDR; -++ val &= ~PERI_COMBPHY_TEST_I; -++ val |= (addr << PERI_COMBPHY_ADDR_OFFSET); -++ val |= (value << PERI_COMBPHY_DATA_OFFSET); -++ phy_writel(val, reg); -++ -++ val = phy_readl(reg); -++ val |= PERI_COMBPHY_TEST_WRITE; -++ phy_writel(val, reg); -++ ups_phy_dbg("ComboPHY write:addr(%#x),value(%#x)\n", addr, value); -++ val = phy_readl(reg); -++ val &= ~PERI_COMBPHY_TEST_WRITE; -++ phy_writel(val, reg); -++} -++ -++void combphy2_write(void __iomem *reg, u32 addr, u32 value) -++{ -++ u32 val; -++ -++ /* Combphy2 is 4 lanes, need configure this */ -++ val = phy_readl(reg); -++ val |= PERI_COMBPHY20_TEST_RST_N; -++ val |= PERI_COMBPHY21_TEST_RST_N; -++ val |= PERI_COMBPHY22_TEST_RST_N; -++ val |= PERI_COMBPHY23_TEST_RST_N; -++ phy_writel(val, reg); -++ -++ combphy_write(reg, addr, value); -++} -+diff --git a/drivers/vendor/ups_phy/missile.c b/drivers/vendor/ups_phy/missile.c -+new file mode 100755 -+index 000000000..4321513c1 -+--- /dev/null -++++ b/drivers/vendor/ups_phy/missile.c -+@@ -0,0 +1,214 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "[usb-missile-phy]" -++#define pr_fmt(fmt) DRVNAME ": " fmt -++ -++#include "phy.h" -++#include "reg.h" -++ -++/* TEST BIT */ -++#define MISSILE_PHY_TEST_REG_8 (0x20) -++#define MISSILE_PHY_CDR_CPF_TRIM_MASK (0xF) -++#define MISSILE_PHY_CDR_CPF_TRIM_VAL (0xF) -++ -++#define MISSILE_PHY_TEST_REG_15 (0x3C) -++#define MISSILE_PHY_TX_PLL_TRIM_USB3_SATA_MASK (0x1F) -++#define MISSILE_PHY_TX_PLL_TRIM_USB3_SATA_VAL (0x3) -++#define MISSILE_PHY_TX_PLL_TRIM_PCIE_MASK (0x1F << 5) -++#define MISSILE_PHY_TX_PLL_TRIM_PCIE_VAL ((0x3 << 5) & MISSILE_PHY_TX_PLL_TRIM_PCIE_MASK) -++ -++#define MISSILE_PHY_TEST_REG_16 (0x40) -++#define MISSILE_PHY_PI_CURRENT_TRIM_MASK (0x3) -++#define MISSILE_PHY_PI_CURRENT_TRIM_VAL (0x2) -++ -++#define MISSILE_PHY_TEST_REG_18 (0x48) -++#define MISSILE_PHY_RX_TERM_USB3_MASK (0xF) -++#define MISSILE_PHY_RX_TERM_USB3_VAL (0xA) -++#define MISSILE_PHY_RX_TERM_MASK (0xF << 4) -++#define MISSILE_PHY_RX_TERM_VAL ((0x7 << 4) & MISSILE_PHY_RX_TERM_MASK) -++ -++#define MISSILE_PHY_TEST_REG_22 (0x58) -++#define MISSILE_PHY_REDUCE_RX_DET_TH_MASK (0x1 << 1) -++#define MISSILE_PHY_REDUCE_RX_DET_TH_VAL (0x1 << 1) -++#define MISSILE_PHY_INTERPOLATOR_JUMP_LATER_MASK (0x1 << 2) -++#define MISSILE_PHY_INTERPOLATOR_JUMP_LATER_VAL (0x1 << 2) -++ -++#define MISSILE_PHY_ANALOG_REG0 (0x80) -++#define MISSILE_PHY_CDR_CTRL_MASK (0x7F << 16) -++#define MISSILE_PHY_CDR_CTRL_VAL ((0x48 << 16) & MISSILE_PHY_CDR_CTRL_MASK) -++ -++/* Performance optimization */ -++#define MISSILE_PHY_ANALOG_REG1 (0x84) -++#define MISSILE_PHY_CSEL_MASK (0x3 << 10) -++#define MISSILE_PHY_CSEL_VAL ((0x1 << 10) & MISSILE_PHY_CSEL_MASK) -++ -++#define MISSILE_PHY_RESEL11_MASK (0x3 << 12) -++#define MISSILE_PHY_RESEL11_VAL ((0x1 << 12) & MISSILE_PHY_RESEL11_MASK) -++ -++#define MISSILE_PHY_RESEL12_MASK (0x3 << 14) -++#define MISSILE_PHY_RESEL12_VAL ((0x0 << 14) & MISSILE_PHY_RESEL12_MASK) -++ -++#define MISSILE_PHY_AUTO_EQ_REG0 (0xB8) -++#define MISSILE_PHY_CFG_AUTO_DESKEW_EN_MASK (0x1 << 20) -++#define MISSILE_PHY_CFG_AUTO_DESKEW_EN_VAL ((0x0 << 20) & MISSILE_PHY_CFG_AUTO_DESKEW_EN_MASK) -++ -++#define MISSILE_PHY_CFG_AUTO_EQ_EN_MASK (0x1 << 21) -++#define MISSILE_PHY_CFG_AUTO_EQ_EN_VAL ((0x0 << 21) & MISSILE_PHY_CFG_AUTO_EQ_EN_MASK) -++ -++#define MISSILE_PHY_AUTO_EQ_REG5 (0xCC) -++#define MISSILE_PHY_CFG_EQ_OW_MASK (0x1F << 0) -++#define MISSILE_PHY_CFG_EQ_OW_VAL ((0xC << 0) & MISSILE_PHY_CFG_EQ_OW_MASK) -++ -++#define MISSILE_PHY_CFG_EQ_OW_EN_MASK (0x1 << 5) -++#define MISSILE_PHY_CFG_EQ_OW_EN_VAL ((0x1 << 5) & MISSILE_PHY_CFG_EQ_OW_EN_MASK) -++ -++#define MISSILE_PHY_CFG_DESKEW_OW_MASK (0x1F << 6) -++#define MISSILE_PHY_CFG_DESKEW_OW_VAL ((0x10 << 6) & MISSILE_PHY_CFG_DESKEW_OW_MASK) -++ -++#define MISSILE_PHY_CFG_DESKEW_OW_EN_MASK (0x1 << 11) -++#define MISSILE_PHY_CFG_DESKEW_OW_EN_VAL ((0x1 << 11) & MISSILE_PHY_CFG_DESKEW_OW_EN_MASK) -++ -++ -++static void missile_phy_eye(const struct ups_phy_priv *priv) -++{ -++ u32 reg; -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_ANALOG_REG1); -++ reg &= ~(MISSILE_PHY_CSEL_MASK); -++ reg |= (MISSILE_PHY_CSEL_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_ANALOG_REG1); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_ANALOG_REG1); -++ reg &= ~(MISSILE_PHY_RESEL11_MASK); -++ reg |= (MISSILE_PHY_RESEL11_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_ANALOG_REG1); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_ANALOG_REG1); -++ reg &= ~(MISSILE_PHY_RESEL12_MASK); -++ reg |= (MISSILE_PHY_RESEL12_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_ANALOG_REG1); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_AUTO_EQ_REG0); -++ reg &= ~(MISSILE_PHY_CFG_AUTO_DESKEW_EN_MASK); -++ reg |= (MISSILE_PHY_CFG_AUTO_DESKEW_EN_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_AUTO_EQ_REG0); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_AUTO_EQ_REG0); -++ reg &= ~(MISSILE_PHY_CFG_AUTO_EQ_EN_MASK); -++ reg |= (MISSILE_PHY_CFG_AUTO_EQ_EN_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_AUTO_EQ_REG0); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ reg &= ~(MISSILE_PHY_CFG_EQ_OW_MASK); -++ reg |= (MISSILE_PHY_CFG_EQ_OW_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ reg &= ~(MISSILE_PHY_CFG_EQ_OW_EN_MASK); -++ reg |= (MISSILE_PHY_CFG_EQ_OW_EN_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ reg &= ~(MISSILE_PHY_CFG_DESKEW_OW_MASK); -++ reg |= (MISSILE_PHY_CFG_DESKEW_OW_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ reg &= ~(MISSILE_PHY_CFG_DESKEW_OW_EN_MASK); -++ reg |= (MISSILE_PHY_CFG_DESKEW_OW_EN_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_AUTO_EQ_REG5); -++ -++ return; -++} -++ -++static int missile_phy_common_init(const struct ups_phy_priv *priv) -++{ -++ u32 reg; -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_TEST_REG_8); -++ reg &= ~(MISSILE_PHY_CDR_CPF_TRIM_MASK); -++ reg |= (MISSILE_PHY_CDR_CPF_TRIM_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_TEST_REG_8); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_TEST_REG_15); -++ reg &= ~(MISSILE_PHY_TX_PLL_TRIM_USB3_SATA_MASK); -++ reg |= (MISSILE_PHY_TX_PLL_TRIM_USB3_SATA_VAL); -++ reg &= ~(MISSILE_PHY_TX_PLL_TRIM_PCIE_MASK); -++ reg |= (MISSILE_PHY_TX_PLL_TRIM_PCIE_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_TEST_REG_15); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_TEST_REG_16); -++ reg &= ~(MISSILE_PHY_PI_CURRENT_TRIM_MASK); -++ reg |= (MISSILE_PHY_PI_CURRENT_TRIM_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_TEST_REG_16); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_TEST_REG_18); -++ reg &= ~(MISSILE_PHY_RX_TERM_USB3_MASK); -++ reg |= (MISSILE_PHY_RX_TERM_USB3_VAL); -++ reg &= ~(MISSILE_PHY_RX_TERM_MASK); -++ reg |= (MISSILE_PHY_RX_TERM_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_TEST_REG_18); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_TEST_REG_22); -++ reg &= ~(MISSILE_PHY_REDUCE_RX_DET_TH_MASK | -++ MISSILE_PHY_INTERPOLATOR_JUMP_LATER_MASK); -++ reg |= (MISSILE_PHY_REDUCE_RX_DET_TH_VAL | -++ MISSILE_PHY_INTERPOLATOR_JUMP_LATER_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_TEST_REG_22); -++ -++ reg = phy_readl(priv->phy_base + MISSILE_PHY_ANALOG_REG0); -++ reg &= ~(MISSILE_PHY_CDR_CTRL_MASK); -++ reg |= (MISSILE_PHY_CDR_CTRL_VAL); -++ phy_writel(reg, priv->phy_base + MISSILE_PHY_ANALOG_REG0); -++ -++ return 0; -++} -++ -++static int missile_phy_power_on(struct phy *phy) -++{ -++ int ret; -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++\n"); -++ -++ ret = clk_prepare(priv->phy_clk); -++ if (ret != 0) { -++ ups_phy_err("missile phy clk prepare failed\n"); -++ return -1; -++ } -++ -++ ret = clk_enable(priv->phy_clk); -++ if (ret != 0) { -++ ups_phy_err("missile phy clk enable failed\n"); -++ return -1; -++ } -++ -++ ret = missile_phy_common_init(priv); -++ if (ret != 0) { -++ ups_phy_err("missile phy common init failed\n"); -++ return -1; -++ } -++ -++ missile_phy_eye(priv); -++ -++ ups_phy_dbg("---\n"); -++ -++ return 0; -++} -++ -++static int missile_phy_power_off(struct phy *phy) -++{ -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ clk_disable_unprepare(priv->phy_clk); -++ -++ return 0; -++} -++ -++struct phy_ops g_missile_phy_common_ops = { -++ .power_on = missile_phy_power_on, -++ .power_off = missile_phy_power_off, -++}; -++ -+diff --git a/drivers/vendor/ups_phy/nano.c b/drivers/vendor/ups_phy/nano.c -+new file mode 100755 -+index 000000000..b63cee40d -+--- /dev/null -++++ b/drivers/vendor/ups_phy/nano.c -+@@ -0,0 +1,379 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "[usb-nano-phy]" -++#define pr_fmt(fmt) DRVNAME ": " fmt -++ -++#include "phy.h" -++#include "reg.h" -++ -++#ifndef CONFIG_ARCH_BSP -++#include -++#endif -++ -++#ifndef WUDANGSTICK_D_MASK -++#define WUDANGSTICK_D_MASK (3272147200ULL) -++#endif -++ -++#ifndef CONFIG_ARCH_BSP -++static bool chip_type_d(void) -++{ -++ return (get_chipid(WUDANGSTICK_D_MASK) == WUDANGSTICK_D_MASK); -++} -++#else -++static inline bool chip_type_d(void) -++{ -++ return true; -++} -++#endif -++ -++static void nano_phy_x1phy_eye(const struct ups_phy_priv *priv, u32 phy_offset) -++{ -++ /* Disable X1 slew assist and SSC offset down 200ppm */ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_SLEW_ASSIST_DIS_AND_SSC_ADDR, -++ X1_SLEW_ASSIST_DIS_AND_SSC_VAL); -++ -++ /* Set X1 TX swing compensation to be level 10 */ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_TX_SWING_COMP_ADDR, X1_TX_SWING_COMP_VAL); -++ -++ /* Set X1 RX CDR direct trim & EQ peaking bit[0] */ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_CDR_DIRECT_TRIM_EQ_PEAKING_ADDR, X1_CDR_DIRECT_TRIM_EQ_PEAKING_VAL); -++ -++ /* Disable X1 all DFE for 8G & 10G */ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_DFE_DIS_8G10G_ADDR, X1_DFE_DIS_8G10G_VAL); -++ -++ /* Set X1 RX EQ swing & EQ peaking bit[1] */ -++ combphy_write(priv->peri_base + phy_offset, -++ EQ_SWING_INC_PEAK_FREQ_ADDR, EQ_SWING_INC_PEAK_FREQ_VAL); -++ -++ /* Set X1 TX PLL charge pump current to be 1.33uA */ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_TXPLL_TRIM_ADDR, X1_TXPLL_TRIM_VAL); -++ -++ /* Set X1 reference PLL to be 100MHz */ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_REF_CLK_100N250_ADDR, X1_REF_CLK_100N250_VAL); -++ -++ /* Set X1 EQ initial value to be 0x2a */ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_EQ_INIT_MANUAL_SET1_ADDR, X1_EQ_INIT_MANUAL_SET1_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_EQ_INIT_PWON_CDR_MANUAL_SET1_ADDR, -++ X1_EQ_INIT_PWON_CDR_MANUAL_SET1_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_EQ_INIT_MANUAL_SET0_ADDR, X1_EQ_INIT_MANUAL_SET0_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy_write(priv->peri_base + phy_offset, -++ X1_EQ_INIT_PWON_CDR_MANUAL_SET0_ADDR, -++ X1_EQ_INIT_PWON_CDR_MANUAL_SET0_VAL); -++} -++ -++static void nano_phy_x4phy_lanec_eye(const struct ups_phy_priv *priv) -++{ -++ u32 reg; -++ -++ reg = phy_readl(priv->peri_base + PERI_COMBOPHY2_CTRL); -++ reg &= COMBOPHY2_2_MODE_MASK; -++ if (reg != COMBOPHY2_2_MODE_USB) { -++ return; -++ } -++ -++ /* Disable X4 slew assist and SSC offset down 200ppm */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_SLEW_ASSIST_DIS_AND_SSC_ADDR, -++ X4_LANEC_SLEW_ASSIST_DIS_AND_SSC_VAL); -++ -++ /* Set X4 TX swing compensation to be level 10 */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_TW_SWING_COMP_ADDR, X4_LANEC_TW_SWING_COMP_VAL); -++ -++ /* Set X4 RX CDR direct trim & EQ peaking bit[0] */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_CDR_DIRECT_TRIM_ADDR, X4_LANEC_CDR_DIRECT_TRIM_VAL); -++ -++ /* Disable X4 all DFE for 8G & 10G */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_DFE_DIS_8G10G_ADDR, X4_LANEC_DFE_DIS_8G10G_VAL); -++ -++ /* Set X4 RX EQ swing & EQ peaking bit[1] */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_EQ_SWING_ADDR, X4_LANEC_EQ_SWING_VAL); -++ -++ /* Set X4 TX PLL charge pump current to be 1.33uA */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_TXPLL_TRIM_ADDR, X4_LANEC_TXPLL_TRIM_VAL); -++ -++ /* Set X4 reference PLL to be 100MHz */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_REF_CLK_100N250_ADDR, X4_LANEC_REF_CLK_100N250_VAL); -++ -++ /* Set X4 EQ initial value to be 0x2a */ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_EQ_INIT_MANUAL_SET1_ADDR, X4_LANEC_EQ_INIT_MANUAL_SET1_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET1_ADDR, -++ X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET1_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_EQ_INIT_MANUAL_SET0_ADDR, X4_LANEC_EQ_INIT_MANUAL_SET0_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy_write(priv->peri_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET0_ADDR, -++ X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET0_VAL); -++} -++ -++static void nano_phy_x4phy_laned_eye(const struct ups_phy_priv *priv) -++{ -++ u32 reg; -++ -++ reg = phy_readl(priv->peri_base + PERI_COMBOPHY2_CTRL); -++ reg &= COMBOPHY2_3_MODE_MASK; -++ if (reg != COMBOPHY2_3_MODE_USB) { -++ return; -++ } -++ -++ /* Disable X4 slew assist and SSC offset down 200ppm */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_SLEW_ASSIST_DIS_AND_SSC_ADDR, -++ X4_LANED_SLEW_ASSIST_DIS_AND_SSC_VAL); -++ -++ /* Set X4 TX swing compensation to be level 10 */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_TW_SWING_COMP_ADDR, X4_LANED_TW_SWING_COMP_VAL); -++ -++ /* Set X4 RX CDR direct trim & EQ peaking bit[0] */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_CDR_DIRECT_TRIM_ADDR, X4_LANED_CDR_DIRECT_TRIM_VAL); -++ -++ /* Disable X4 all DFE for 8G & 10G */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_DFE_DIS_8G10G_ADDR, X4_LANED_DFE_DIS_8G10G_VAL); -++ -++ /* Set X4 RX EQ swing & EQ peaking bit[1] */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_EQ_SWING_ADDR, X4_LANED_EQ_SWING_VAL); -++ -++ /* Set X4 TX PLL charge pump current to be 1.33uA */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_TXPLL_TRIM_ADDR, X4_LANED_TXPLL_TRIM_VAL); -++ -++ /* Set X4 reference PLL to be 100MHz */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_REF_CLK_100N250_ADDR, X4_LANED_REF_CLK_100N250_VAL); -++ -++ /* Set inv_rxcdrclk to invert the polarity of CDR clock at input from -++ * analog to PCS, this is for X4 LaneD only */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_INV_RXCDRCLK_ADDR, X4_LANED_INV_RXCDRCLK_VAL); -++ -++ /* Set X4 EQ initial value to be 0x2a */ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_EQ_INIT_MANUAL_SET1_ADDR, X4_LANED_EQ_INIT_MANUAL_SET1_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET1_ADDR, -++ X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET1_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_EQ_INIT_MANUAL_SET0_ADDR, -++ X4_LANED_EQ_INIT_MANUAL_SET0_VAL); -++ udelay(1); /* delay 1 us */ -++ -++ combphy2_write(priv->phy_base + PERI_COMBOPHY2_CTRL1, -++ X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET0_ADDR, -++ X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET0_VAL); -++} -++ -++static int nano_phy_common_init(const struct ups_phy_priv *priv, -++ u32 reg, u32 u3_disable_bit) -++{ -++ int ret; -++ u32 val; -++ -++ val = phy_readl(priv->peri_base + reg); -++ val &= ~(u3_disable_bit); -++ if (priv->force_5g) -++ val |= PERI_USB3_PORT_FORCE_5G; -++ phy_writel(val, priv->peri_base + reg); -++ -++ ret = clk_prepare_enable(priv->phy_clk); -++ if (ret != 0) { -++ ups_phy_err("clk prepare and enable failed\n"); -++ return -1; -++ } -++ -++ return 0; -++} -++ -++static int nano_phy_combophy0_power_on(struct phy *phy) -++{ -++ int ret; -++ u32 val; -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++\n"); -++ -++ ret = nano_phy_common_init(priv, PERI_USB31_CTRL_CFG0, -++ PERI_USB3_PORT_DISABLE); -++ if (ret < 0) { -++ ups_phy_err("nano combophy0 init failed.\n"); -++ return -1; -++ } -++ -++ val = phy_readl(priv->peri_base + PERI_USB31_CTRL_CFG0); -++ /* both cs and cs ec need close ovrcur */ -++ val &= ~PERI_PORT_OVRCUR_EN; -++ if (!chip_type_d()) { -++ /* because cs chip X1 combphy bug, disable u3 */ -++ val |= PERI_USB3_PORT_DISABLE; -++ } -++ phy_writel(val, priv->peri_base + PERI_USB31_CTRL_CFG0); -++ -++ nano_phy_x1phy_eye(priv, PERI_COMBOPHY0_CTRL1); -++ -++ ups_phy_dbg("---\n"); -++ -++ return 0; -++} -++ -++static int nano_phy_combophy1_power_on(struct phy *phy) -++{ -++ int ret; -++ u32 val; -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++\n"); -++ -++ ret = nano_phy_common_init(priv, PERI_USB31_CTRL_CFG1, -++ PERI_USB3_PORT_DISABLE); -++ if (ret < 0) { -++ ups_phy_err("nano combophy1 init failed.\n"); -++ return -1; -++ } -++ -++ val = phy_readl(priv->peri_base + PERI_USB31_CTRL_CFG1); -++ /* both cs and cs ec need close ovrcur */ -++ val &= ~PERI_PORT_OVRCUR_EN; -++ if (!chip_type_d()) { -++ /* because cs chip X1 combphy bug, disable u3 */ -++ val |= PERI_USB3_PORT_DISABLE; -++ } -++ phy_writel(val, priv->peri_base + PERI_USB31_CTRL_CFG1); -++ -++ nano_phy_x1phy_eye(priv, PERI_COMBOPHY1_CTRL1); -++ -++ ups_phy_dbg("---\n"); -++ -++ return 0; -++} -++ -++static int nano_phy_combophy22_power_on(struct phy *phy) -++{ -++ int ret; -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++\n"); -++ -++ ret = nano_phy_common_init(priv, PERI_USB2_CTRL_CFG1, -++ PERI_USB3_PORT_DISABLE_CSU30); -++ if (ret < 0) { -++ ups_phy_err("nano combophy22 init failed.\n"); -++ return -1; -++ } -++ -++ nano_phy_x4phy_lanec_eye(priv); -++ -++ ups_phy_dbg("---\n"); -++ -++ return 0; -++} -++ -++static int nano_phy_combophy23_power_on(struct phy *phy) -++{ -++ int ret; -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++\n"); -++ -++ ret = nano_phy_common_init(priv, PERI_USB31_CTRL_CFG2, -++ PERI_USB3_PORT_DISABLE); -++ if (ret < 0) { -++ ups_phy_err("nano combophy23 init failed.\n"); -++ return -1; -++ } -++ -++ nano_phy_x4phy_laned_eye(priv); -++ -++ ups_phy_dbg("---\n"); -++ -++ return 0; -++} -++ -++static int nano_phy_power_on(struct phy *phy) -++{ -++ int ret; -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++\n"); -++ -++ ret = clk_prepare_enable(priv->phy_clk); -++ if (ret != 0) { -++ ups_phy_err("nano phy clk prepare and enable failed\n"); -++ return -1; -++ } -++ -++ ups_phy_dbg("---\n"); -++ -++ return 0; -++} -++ -++static int nano_phy_power_off(struct phy *phy) -++{ -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ clk_disable_unprepare(priv->phy_clk); -++ -++ return 0; -++} -++ -++struct phy_ops g_nano_phy_common_ops = { -++ .power_on = nano_phy_power_on, -++ .power_off = nano_phy_power_off, -++}; -++ -++struct phy_ops g_nano_phy_combophy0_ops = { -++ .power_on = nano_phy_combophy0_power_on, -++ .power_off = nano_phy_power_off, -++}; -++ -++struct phy_ops g_nano_phy_combophy1_ops = { -++ .power_on = nano_phy_combophy1_power_on, -++ .power_off = nano_phy_power_off, -++}; -++ -++struct phy_ops g_nano_phy_combophy22_ops = { -++ .power_on = nano_phy_combophy22_power_on, -++ .power_off = nano_phy_power_off, -++}; -++ -++struct phy_ops g_nano_phy_combophy23_ops = { -++ .power_on = nano_phy_combophy23_power_on, -++ .power_off = nano_phy_power_off, -++}; -++ -+diff --git a/drivers/vendor/ups_phy/phy.c b/drivers/vendor/ups_phy/phy.c -+new file mode 100755 -+index 000000000..fdb3163a0 -+--- /dev/null -++++ b/drivers/vendor/ups_phy/phy.c -+@@ -0,0 +1,224 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "ups-phy" -++#define pr_fmt(fmt) DRVNAME ": " fmt -++ -++#include -++#include -++#include -++#include -++#include -++#ifdef CONFIG_PROC_FS -++#include -++#include -++#endif -++#include -++#include -++ -++#include "phy.h" -++ -++static struct phy *ups_phy_xlate(struct device *dev, -++ struct of_phandle_args *args) -++{ -++ struct phy *phy = dev_get_drvdata(dev); -++ -++ if (IS_ERR_OR_NULL(phy)) { -++ ups_phy_err("phy address is error or null\n"); -++ return ERR_PTR(-ENODEV); -++ } -++ -++ return phy; -++} -++ -++static void set_dev_args(struct ups_phy_priv *priv, struct device *dev) -++{ -++ const struct of_device_id *match = NULL; -++ -++ match = of_match_device(dev->driver->of_match_table, dev); -++ if (match != NULL) { -++ priv->phy_ops = (struct phy_ops*)(match->data); -++ } -++} -++ -++static int ups_phy_set_priv(struct platform_device *pdev, -++ struct ups_phy_priv *priv) -++{ -++ int ret; -++ struct device *dev = &pdev->dev; -++ struct device_node *np = dev->of_node; -++ -++ priv->phy_clk = devm_clk_get(dev, "phy-clk"); -++ if (IS_ERR(priv->phy_clk)) { -++ ups_phy_err("get phy_clk failed.\n"); -++ return PTR_ERR(priv->phy_clk); -++ } -++ -++ priv->phy_base = of_iomap(np, PHY_BASE_NODE_IDX); -++ if (IS_ERR_OR_NULL(priv->phy_base)) { -++ ups_phy_err("phy_base ioremap failed.\n"); -++ goto fail; -++ } -++ -++ priv->peri_base = of_iomap(np, PERI_BASE_NODE_IDX); -++ if (IS_ERR_OR_NULL(priv->peri_base)) { -++ ups_phy_err("peri_base ioremap failed.\n"); -++ goto fail; -++ } -++ -++ priv->u2phy_trim_otp = of_iomap(np, TRIM_OTP_NODE_IDX); -++ if (IS_ERR_OR_NULL(priv->u2phy_trim_otp)) -++ ups_phy_dbg("don't get u32phy trim otp.\n"); -++ -++ ret = of_property_read_s32(np, "otp-phy-trim-bitshift", &priv->otp_phy_trim_bitshift); -++ if (ret) { -++ priv->otp_phy_trim_bitshift = 0; -++ } -++ -++ ret = of_property_read_u32_array(np, U2PHY_TRIM_NAME, -++ priv->u2phy_trim, TRIM_NUM_MAX); -++ if (ret != 0) -++ ups_phy_dbg("don't get u2phy trim\n"); -++ -++ priv->force_5g = of_property_read_bool(np, "force-5G"); -++ -++ set_dev_args(priv, dev); -++ -++ return 0; -++ -++fail: -++ devm_clk_put(dev, priv->phy_clk); -++ priv->phy_clk = NULL; -++ -++ if (priv->phy_base != NULL) { -++ iounmap(priv->phy_base); -++ priv->phy_base = NULL; -++ } -++ -++ return -1; -++} -++ -++static int ups_phy_probe(struct platform_device *pdev) -++{ -++ int ret; -++ struct phy *phy; -++ struct phy_provider *phy_provider; -++ struct ups_phy_priv *priv; -++ -++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -++ if (priv == NULL) { -++ ups_phy_err("failed dev_kzalloc\n"); -++ return -ENOMEM; -++ } -++ -++ ret = ups_phy_set_priv(pdev, priv); -++ if (ret != 0) -++ return ret; -++ -++ phy = devm_phy_create(&pdev->dev, NULL, priv->phy_ops); -++ if (IS_ERR(phy)) { -++ ups_phy_err("failed to create PHY, %ld\n", PTR_ERR(phy)); -++ return PTR_ERR(phy); -++ } -++ -++ phy_set_drvdata(phy, priv); -++ dev_set_drvdata(&pdev->dev, phy); -++ -++ phy_provider = devm_of_phy_provider_register(&pdev->dev, ups_phy_xlate); -++ if (IS_ERR(phy_provider)) { -++ ups_phy_err("failed to register phy provider, %ld\n", -++ PTR_ERR(phy_provider)); -++ return PTR_ERR(phy_provider); -++ } -++ -++ return 0; -++} -++ -++static int __exit ups_phy_platform_remove(struct platform_device *pdev) -++{ -++ struct ups_phy_priv *priv = platform_get_drvdata(pdev); -++ -++ if (priv->phy_base != NULL) { -++ iounmap(priv->phy_base); -++ priv->phy_base = NULL; -++ } -++ -++ if (priv->peri_base != NULL) { -++ iounmap(priv->peri_base); -++ priv->peri_base = NULL; -++ } -++ -++ if (priv->u2phy_trim_otp != NULL) { -++ iounmap(priv->u2phy_trim_otp); -++ priv->u2phy_trim_otp = NULL; -++ } -++ -++ return 0; -++} -++ -++static struct of_device_id g_ups_phy_of_match[] = { -++#ifdef CONFIG_WING_UPS_XVP_PHY -++ { -++ .compatible = "usb2phy,xvpphy", -++ .data = &g_xvp_phy_ops -++ }, -++#endif -++#ifdef CONFIG_WING_UPS_NANO_PHY -++ { -++ .compatible = "combophy,common", -++ .data = &g_nano_phy_common_ops -++ }, -++ { -++ .compatible = "combophy,combophy0", -++ .data = &g_nano_phy_combophy0_ops -++ }, -++ { -++ .compatible = "combophy,combophy1", -++ .data = &g_nano_phy_combophy1_ops -++ }, -++ { -++ .compatible = "combophy,combophy2_2", -++ .data = &g_nano_phy_combophy22_ops -++ }, -++ { -++ .compatible = "combophy,combophy2_3", -++ .data = &g_nano_phy_combophy23_ops -++ }, -++#endif -++#ifdef CONFIG_WING_UPS_MISSILE_PHY -++ { -++ .compatible = "combophy,common", -++ .data = &g_missile_phy_common_ops -++ }, -++#endif -++ {}, -++}; -++ -++static struct platform_driver g_ups_phy_driver = { -++ .probe = ups_phy_probe, -++ .remove = __exit_p(ups_phy_platform_remove), -++ .driver = { -++ .name = DRVNAME, -++ .of_match_table = g_ups_phy_of_match, -++ .owner = THIS_MODULE, -++ } -++}; -++ -++static int __init ups_phy_module_init(void) -++{ -++ ups_phy_info("registered new ups phy driver\n"); -++ -++ return platform_driver_register(&g_ups_phy_driver); -++} -++subsys_initcall(ups_phy_module_init); -++ -++static void __exit ups_phy_module_exit(void) -++{ -++ platform_driver_unregister(&g_ups_phy_driver); -++} -++module_exit(ups_phy_module_exit); -++ -++MODULE_AUTHOR("Wing"); -++MODULE_DESCRIPTION("Wing UPS PHY driver"); -++MODULE_LICENSE("GPL v2"); -+diff --git a/drivers/vendor/ups_phy/phy.h b/drivers/vendor/ups_phy/phy.h -+new file mode 100755 -+index 000000000..63281b750 -+--- /dev/null -++++ b/drivers/vendor/ups_phy/phy.h -+@@ -0,0 +1,90 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef UPS_PHY_H -++#define UPS_PHY_H -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++enum { -++ U2PHY_ANA_CFG0 = 0x0, -++ U2PHY_ANA_CFG2 = 0x1, -++ TRIM_NUM_MAX -++}; -++ -++#define PHY_BASE_NODE_IDX 0 -++#define PERI_BASE_NODE_IDX 1 -++#define TRIM_OTP_NODE_IDX 2 -++ -++#define U2PHY_TRIM_NAME "u2phy-trim" -++ -++struct ups_phy_priv { -++ void __iomem *phy_base; -++ void __iomem *peri_base; -++ void __iomem *u2phy_trim_otp; -++ int otp_phy_trim_bitshift; -++ -++ struct clk *phy_clk; -++ struct phy_ops *phy_ops; -++ -++ unsigned int u2phy_trim[TRIM_NUM_MAX]; -++ bool force_5g; -++}; -++ -++#define UPS_PHY_DEBUG 0 -++ -++#define ups_phy_dbg(format, arg...) \ -++ do { \ -++ if (UPS_PHY_DEBUG) \ -++ printk(KERN_INFO "[UPS-PHY][%s]"format, __func__, ##arg); \ -++ } while (0) -++ -++#define ups_phy_info(format, arg...) \ -++ printk(KERN_INFO "[UPS-PHY][%s]"format, __func__, ##arg) -++ -++#define ups_phy_err(format, arg...) \ -++ printk(KERN_ERR "[UPS-PHY][%s]"format, __func__, ##arg) -++ -++#ifdef CONFIG_WING_UPS_XVP_PHY -++extern struct phy_ops g_xvp_phy_ops; -++#endif -++ -++#ifdef CONFIG_WING_UPS_NANO_PHY -++extern struct phy_ops g_nano_phy_common_ops; -++extern struct phy_ops g_nano_phy_combophy0_ops; -++extern struct phy_ops g_nano_phy_combophy1_ops; -++extern struct phy_ops g_nano_phy_combophy22_ops; -++extern struct phy_ops g_nano_phy_combophy23_ops; -++#endif -++ -++#ifdef CONFIG_WING_UPS_MISSILE_PHY -++extern struct phy_ops g_missile_phy_common_ops; -++#endif -++ -++static inline unsigned int phy_readl(const void __iomem *addr) -++{ -++ unsigned int reg = readl(addr); -++ -++ ups_phy_dbg("readl(0x%lx) = %#08X\n", (uintptr_t)addr, reg); -++ return reg; -++} -++ -++static inline void phy_writel(unsigned int v, void __iomem *addr) -++{ -++ writel(v, addr); -++ ups_phy_dbg("writel(0x%lx) = %#08X\n", (uintptr_t)addr, v); -++} -++ -++void combphy_write(void __iomem *reg, u32 addr, u32 value); -++ -++void combphy2_write(void __iomem *reg, u32 addr, u32 value); -++ -++#endif /* UPS_PHY_H */ -+diff --git a/drivers/vendor/ups_phy/reg.h b/drivers/vendor/ups_phy/reg.h -+new file mode 100755 -+index 000000000..0b603370a -+--- /dev/null -++++ b/drivers/vendor/ups_phy/reg.h -+@@ -0,0 +1,138 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef HLUSB_REG_H -++#define HLUSB_REG_H -++ -++#define UDELAY_LEVEL1 (10) -++#define UDELAY_LEVEL2 (20) -++#define UDELAY_LEVEL3 (50) -++#define UDELAY_LEVEL4 (100) -++#define UDELAY_LEVEL5 (1000) -++#define UDELAY_LEVEL6 (3000) -++ -++#define COMBOPHY0_MODE_MASK (0x3<<8) -++#define COMBOPHY0_MODE_USB (0x1<<8) -++#define PERI_COMBOPHY1_CTRL 0x490 -++#define COMBOPHY1_MODE_MASK (0x3<<8) -++#define COMBOPHY1_MODE_USB (0x1<<8) -++#define PERI_COMBOPHY2_CTRL 0x064 -++#define USB_LANE_MODE_MASK (0xf<<28) -++#define USB_LANE_MODE_USB (0x2<<28) -++#define COMBOPHY2_2_MODE_USB (0x1<<20) -++#define COMBOPHY2_2_MODE_MASK (0x3<<20) -++#define COMBOPHY2_3_MODE_USB (0x1<<22) -++#define COMBOPHY2_3_MODE_MASK (0x3<<22) -++ -++#define PERI_COMBOPHY1_CTRL1 0x494 -++#define PERI_COMBOPHY1_TEST_O (0xff << 24) -++#define PERI_COMBOPHY1_TEST_RST (0x01 << 17) -++#define PERI_COMBOPHY1_TEST_WRITE (0x01 << 16) -++#define PERI_COMBOPHY1_TEST_I (0xff << 8) -++#define PERI_COMBOPHY1_TEST_ADD 0xff -++ -++#define PERI_USB2_CTRL_CFG0 0x600 -++#define PERI_USB2_CTRL_CFG1 0x610 -++#define PERI_USB31_CTRL_CFG0 0x620 -++#define PERI_USB31_CTRL_CFG1 0x640 -++#define PERI_USB31_CTRL_CFG2 0x660 -++#define PERI_CTRL_CFG_DEFAULT_VAL 0x020002ff -++#define PERI_PORT_PWR_CTL_EN (0x01<<4) -++#define PERI_PORT_PWREN_POL (0x01<<6) -++#define PERI_PORT_OVRCUR_EN (0x01<<5) -++#define PERI_PORT_OVRCUR_POL (0x01<<7) -++#define PERI_USB3_PORT_DISABLE (0x01<<9) -++#define PERI_USB3_PORT_FORCE_5G (0x01<<10) -++#define PERI_USB3_PORT_DISABLE_CSU30 (0x01<<12) -++ -++/* phy eye related */ -++#define PERI_COMBOPHY0_CTRL1 0x484 -++#define PERI_COMBOPHY1_CTRL1 0x494 -++#define PERI_COMBOPHY2_CTRL1 0x0 -++ -++#define PERI_COMBPHY_TEST_O (0xffU << 24) -++#define PERI_COMBPHY23_TEST_RST_N BIT(20) -++#define PERI_COMBPHY22_TEST_RST_N BIT(19) -++#define PERI_COMBPHY21_TEST_RST_N BIT(18) -++#define PERI_COMBPHY20_TEST_RST_N BIT(17) -++#define PERI_COMBPHY1_TEST_RST_N BIT(17) -++#define PERI_COMBPHY0_TEST_RST_N BIT(17) -++#define PERI_COMBPHY_TEST_WRITE BIT(16) -++#define PERI_COMBPHY_TEST_I (0xffU << 8) -++#define PERI_COMBPHY_TEST_ADDR 0xffU -++#define PERI_COMBPHY_DATA_OFFSET 0x8U -++#define PERI_COMBPHY_ADDR_OFFSET 0x0U -++ -++#define X1_SLEW_ASSIST_DIS_AND_SSC_ADDR 0x04 -++#define X1_SLEW_ASSIST_DIS_AND_SSC_VAL 0x12 -++#define X1_TX_SWING_COMP_ADDR 0x0B -++#define X1_TX_SWING_COMP_VAL 0xA0 -++#define X1_CDR_DIRECT_TRIM_EQ_PEAKING_ADDR 0x10 -++#define X1_CDR_DIRECT_TRIM_EQ_PEAKING_VAL 0x39 -++#define X1_DFE_DIS_8G10G_ADDR 0x1B -++#define X1_DFE_DIS_8G10G_VAL 0x1F -++#define EQ_SWING_INC_PEAK_FREQ_ADDR 0x12 -++#define EQ_SWING_INC_PEAK_FREQ_VAL 0x96 -++#define X1_TXPLL_TRIM_ADDR 0x00 -++#define X1_TXPLL_TRIM_VAL 0x30 -++#define X1_REF_CLK_100N250_ADDR 0x01 -++#define X1_REF_CLK_100N250_VAL 0x40 -++#define X1_EQ_INIT_MANUAL_SET1_ADDR 0x14 -++#define X1_EQ_INIT_MANUAL_SET1_VAL 0x6A -++#define X1_EQ_INIT_PWON_CDR_MANUAL_SET1_ADDR 0x05 -++#define X1_EQ_INIT_PWON_CDR_MANUAL_SET1_VAL 0x10 -++#define X1_EQ_INIT_MANUAL_SET0_ADDR 0x14 -++#define X1_EQ_INIT_MANUAL_SET0_VAL 0x2A -++#define X1_EQ_INIT_PWON_CDR_MANUAL_SET0_ADDR 0x05 -++#define X1_EQ_INIT_PWON_CDR_MANUAL_SET0_VAL 0x00 -++ -++#define X4_LANED_SLEW_ASSIST_DIS_AND_SSC_ADDR 0xC4 -++#define X4_LANED_SLEW_ASSIST_DIS_AND_SSC_VAL 0x12 -++#define X4_LANED_TW_SWING_COMP_ADDR 0xCB -++#define X4_LANED_TW_SWING_COMP_VAL 0xA0 -++#define X4_LANED_CDR_DIRECT_TRIM_ADDR 0xD0 -++#define X4_LANED_CDR_DIRECT_TRIM_VAL 0x39 -++#define X4_LANED_DFE_DIS_8G10G_ADDR 0xDB -++#define X4_LANED_DFE_DIS_8G10G_VAL 0x1F -++#define X4_LANED_EQ_SWING_ADDR 0xD2 -++#define X4_LANED_EQ_SWING_VAL 0x96 -++#define X4_LANED_TXPLL_TRIM_ADDR 0xC0 -++#define X4_LANED_TXPLL_TRIM_VAL 0x00 -++#define X4_LANED_REF_CLK_100N250_ADDR 0xC1 -++#define X4_LANED_REF_CLK_100N250_VAL 0x40 -++#define X4_LANED_INV_RXCDRCLK_ADDR 0xC8 -++#define X4_LANED_INV_RXCDRCLK_VAL 0x08 -++#define X4_LANED_EQ_INIT_MANUAL_SET1_ADDR 0xD4 -++#define X4_LANED_EQ_INIT_MANUAL_SET1_VAL 0x6A -++#define X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET1_ADDR 0xC5 -++#define X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET1_VAL 0x10 -++#define X4_LANED_EQ_INIT_MANUAL_SET0_ADDR 0xD4 -++#define X4_LANED_EQ_INIT_MANUAL_SET0_VAL 0x2A -++#define X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET0_ADDR 0xC5 -++#define X4_LANED_EQ_INIT_PWON_CDR_MANUAL_SET0_VAL 0x00 -++ -++#define X4_LANEC_SLEW_ASSIST_DIS_AND_SSC_ADDR 0x84 -++#define X4_LANEC_SLEW_ASSIST_DIS_AND_SSC_VAL 0x12 -++#define X4_LANEC_TW_SWING_COMP_ADDR 0x8B -++#define X4_LANEC_TW_SWING_COMP_VAL 0xA0 -++#define X4_LANEC_CDR_DIRECT_TRIM_ADDR 0x90 -++#define X4_LANEC_CDR_DIRECT_TRIM_VAL 0x39 -++#define X4_LANEC_DFE_DIS_8G10G_ADDR 0x9B -++#define X4_LANEC_DFE_DIS_8G10G_VAL 0x1F -++#define X4_LANEC_EQ_SWING_ADDR 0x92 -++#define X4_LANEC_EQ_SWING_VAL 0x96 -++#define X4_LANEC_TXPLL_TRIM_ADDR 0x80 -++#define X4_LANEC_TXPLL_TRIM_VAL 0x00 -++#define X4_LANEC_REF_CLK_100N250_ADDR 0x81 -++#define X4_LANEC_REF_CLK_100N250_VAL 0x40 -++#define X4_LANEC_EQ_INIT_MANUAL_SET1_ADDR 0x94 -++#define X4_LANEC_EQ_INIT_MANUAL_SET1_VAL 0x6A -++#define X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET1_ADDR 0x85 -++#define X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET1_VAL 0x10 -++#define X4_LANEC_EQ_INIT_MANUAL_SET0_ADDR 0x94 -++#define X4_LANEC_EQ_INIT_MANUAL_SET0_VAL 0x2A -++#define X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET0_ADDR 0x85 -++#define X4_LANEC_EQ_INIT_PWON_CDR_MANUAL_SET0_VAL 0x00 -++ -++#endif -+diff --git a/drivers/vendor/ups_phy/xvp.c b/drivers/vendor/ups_phy/xvp.c -+new file mode 100755 -+index 000000000..768595c97 -+--- /dev/null -++++ b/drivers/vendor/ups_phy/xvp.c -+@@ -0,0 +1,111 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#define DRVNAME "[ups-xvp-phy]" -++#define pr_fmt(fmt) DRVNAME ": " fmt -++ -++#include "phy.h" -++ -++#define REG_OTPC_REGBASE 0x00b00000 -++#define PHY_PARA_OTP_OFFSET 0x032c -++#define PHY_RT_TRIM_MASK 0x001f -++#define RG_RT_TRIM_MASK 0x1f00 -++#define U2_PHY_TRIM_BIT 0x0008 -++#define TRIM_MAX_VALUE 0x001d -++#define TRIM_MIN_VALUE 0x0009 -++ -++#define U2PHY_ANA_CFG0_OFFSET 0x0000 -++#define U2PHY_ANA_CFG0_VALUE 0x0A33CC2B -++#define U2PHY_ANA_CFG2_OFFSET 0x0008 -++#define U2PHY_ANA_CFG2_VALUE 0x00260F0F -++#define U2PHY_ANA_CFG5_OFFSET 0x0014 -++#define PLL_EN_MASK (0x3U << 0) -++#define PLL_EN_VALUE (0x3U << 0) -++ -++#define TX_DEEMPHASIS_STRENGTH_MASK (0xFU << 8) -++#define MBIAS_MASK (0xFU << 0) -++#define DEEMPHASIS_HALF_BIT_MASK (0xFFU << 20) -++#define DISCONNECT_VREF_MASK (0x7U << 16) -++#define TX_DEEMPHASIS_ENABLE (0x1 << 5) -++ -++static void xvp_phy_config(const struct ups_phy_priv *priv) -++{ -++ u32 reg; -++ u32 usb2_phy_rt_trim; -++ -++ reg = phy_readl(priv->phy_base + U2PHY_ANA_CFG5_OFFSET); -++ reg &= ~(PLL_EN_MASK); -++ reg |= PLL_EN_VALUE; -++ phy_writel(reg, priv->phy_base + U2PHY_ANA_CFG5_OFFSET); -++ -++ /* BE CAREFUL -++ * ANA_CFG2 phy eye diagram config must set before trim config, -++ * because it will write total 32 bits when config ANA_CFG2. -++ * And just set several bits when config trim -++ */ -++ reg = priv->u2phy_trim[U2PHY_ANA_CFG0]; -++ phy_writel(reg, priv->phy_base + U2PHY_ANA_CFG0_OFFSET); -++ -++ reg = priv->u2phy_trim[U2PHY_ANA_CFG2]; -++ phy_writel(reg, priv->phy_base + U2PHY_ANA_CFG2_OFFSET); -++ -++ if (priv->u2phy_trim_otp == NULL) -++ return; -++ -++ /* configure trim from otp */ -++ usb2_phy_rt_trim = phy_readl(priv->u2phy_trim_otp); -++ usb2_phy_rt_trim = (usb2_phy_rt_trim >> priv->otp_phy_trim_bitshift) & PHY_RT_TRIM_MASK; -++ if ((usb2_phy_rt_trim >= TRIM_MIN_VALUE) && -++ (usb2_phy_rt_trim <= TRIM_MAX_VALUE)) { -++ reg = phy_readl(priv->phy_base + U2PHY_ANA_CFG2_OFFSET); -++ reg &= ~(RG_RT_TRIM_MASK); -++ reg |= (usb2_phy_rt_trim << U2_PHY_TRIM_BIT); -++ phy_writel(reg, priv->phy_base + U2PHY_ANA_CFG2_OFFSET); -++ } -++} -++ -++static int xvp_phy_power_on(struct phy *phy) -++{ -++ int ret; -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++"); -++ -++ ret = clk_prepare(priv->phy_clk); -++ if (ret != 0) { -++ ups_phy_err("xvp phy clk prepare failed\n"); -++ return ret; -++ } -++ -++ xvp_phy_config(priv); -++ -++ ret = clk_enable(priv->phy_clk); -++ if (ret != 0) { -++ ups_phy_err("xvp phy clk enable failed\n"); -++ return ret; -++ } -++ -++ ups_phy_dbg("---"); -++ -++ return 0; -++} -++ -++static int xvp_phy_power_off(struct phy *phy) -++{ -++ struct ups_phy_priv *priv = phy_get_drvdata(phy); -++ -++ ups_phy_dbg("+++"); -++ -++ clk_disable_unprepare(priv->phy_clk); -++ -++ ups_phy_dbg("---"); -++ -++ return 0; -++} -++ -++struct phy_ops g_xvp_phy_ops = { -++ .power_on = xvp_phy_power_on, -++ .power_off = xvp_phy_power_off, -++}; -++ -+diff --git a/drivers/vendor/usb/Kconfig b/drivers/vendor/usb/Kconfig -+new file mode 100755 -+index 000000000..a5dfa069f -+--- /dev/null -++++ b/drivers/vendor/usb/Kconfig -+@@ -0,0 +1,6 @@ -++config USB_WING -++ tristate "Wing USB controller" -++ select EXTCON -++ select USB_DWC3_DUAL_ROLE -++ help -++ Say Y or M here if you want support Wing USB controller. -+diff --git a/drivers/vendor/usb/Makefile b/drivers/vendor/usb/Makefile -+new file mode 100755 -+index 000000000..9788498b9 -+--- /dev/null -++++ b/drivers/vendor/usb/Makefile -+@@ -0,0 +1,12 @@ -++include $(src)/version.mak -++ -++KBUILD_CFLAGS += -Werror -++ -++ccflags-y += -I$(srctree)/drivers/usb/dwc3/ -DUSB_KERNEL_VERSION=\"$(USB_KERNEL_VERSION)\" -++ -++ifeq ($(CONFIG_SOCT_DRV_BUILD_KO),y) -++CONFIG_USB_WING = m -++endif -++ -++obj-$(CONFIG_USB_WING) += wing-usb.o -++wing-usb-y := wing_usb.o proc.o -+diff --git a/drivers/vendor/usb/proc.c b/drivers/vendor/usb/proc.c -+new file mode 100755 -+index 000000000..38968b389 -+--- /dev/null -++++ b/drivers/vendor/usb/proc.c -+@@ -0,0 +1,145 @@ -++ /* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include "proc.h" -++ -++#define MODE_BUF_LEN 32 -++ -++static ssize_t wing_usb_mode_write(struct file *file, -++ const char __user *ubuf, size_t count, loff_t *ppos) -++{ -++ struct seq_file *s = file->private_data; -++ struct wing_usb *wusb = s->private; -++ struct wing_usb_event usb_event = {0}; -++ -++ char buf[MODE_BUF_LEN] = {0}; -++ -++ if (ubuf == NULL) -++ return -EFAULT; -++ -++ if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) -++ return -EFAULT; -++ -++ if (strncmp(buf, "device", strlen("device")) == 0) { -++ usb_event.type = SWITCH_TO_DEVICE; -++ } else if (strncmp(buf, "host", strlen("host")) == 0) { -++ usb_event.type = SWITCH_TO_HOST; -++ } else { -++ usb_event.type = NONE_EVENT; -++ wing_usb_err("input event type error\n"); -++ return -EINVAL; -++ } -++ -++ usb_event.ctrl_id = wusb->id; -++ wing_usb_queue_event(&usb_event, wusb); -++ -++ wing_usb_dbg("write %s\n", buf); -++ -++ return count; -++} -++ -++static int wing_usb_mode_show(struct seq_file *s, void *v) -++{ -++ struct wing_usb *wusb = s->private; -++ unsigned long flags; -++ u32 reg; -++ -++ spin_lock_irqsave(&wusb->event_lock, flags); -++ reg = readl(wusb->ctrl_base + DWC3_GCTL); -++ spin_unlock_irqrestore(&wusb->event_lock, flags); -++ switch (DWC3_GCTL_PRTCAP(reg)) { -++ case DWC3_GCTL_PRTCAP_HOST: -++ seq_printf(s, "host\n"); -++ wusb->state = WING_USB_STATE_HOST; -++ break; -++ case DWC3_GCTL_PRTCAP_DEVICE: -++ seq_printf(s, "device\n"); -++ wusb->state = WING_USB_STATE_DEVICE; -++ break; -++ case DWC3_GCTL_PRTCAP_OTG: -++ seq_printf(s, "otg\n"); -++ break; -++ default: -++ seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg)); -++ } -++ -++ return 0; -++} -++ -++static int wing_usb_mode_open(struct inode *inode, struct file *file) -++{ -++ return single_open(file, wing_usb_mode_show, PDE_DATA(inode)); -++} -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++static const struct proc_ops g_wing_usb_proc_mode_ops = { -++ .proc_open = wing_usb_mode_open, -++ .proc_write = wing_usb_mode_write, -++ .proc_read = seq_read, -++ .proc_release = single_release, -++}; -++ -++#else -++static const struct file_operations g_wing_usb_proc_mode_ops = { -++ .open = wing_usb_mode_open, -++ .write = wing_usb_mode_write, -++ .read = seq_read, -++ .release = single_release, -++}; -++ -++#endif -++ -++int wing_usb_create_proc_entry(struct device *dev, struct wing_usb *wusb) -++{ -++ struct proc_dir_entry *proc_entry = NULL; -++ -++ wing_usb_dbg("+\n"); -++ -++ if (wusb == NULL) -++ return -EINVAL; -++ -++ proc_entry = proc_mkdir(dev_name(dev), NULL); -++ if (proc_entry == NULL) { -++ wing_usb_err("failed to create proc file\n"); -++ return -ENOMEM; -++ } -++ -++ wusb->proc_entry = proc_entry; -++ -++ if (proc_create_data("mode", S_IRUGO | S_IWUSR, proc_entry, -++ &g_wing_usb_proc_mode_ops, wusb) == NULL) { -++ wing_usb_err("Failed to create proc file mode \n"); -++ goto remove_entry; -++ } -++ -++ wing_usb_dbg("-\n"); -++ return 0; -++ -++remove_entry: -++ remove_proc_entry(dev_name(dev), NULL); -++ wusb->proc_entry = NULL; -++ -++ return -ENOMEM; -++} -++ -++void wing_usb_remove_proc_entry(struct device *dev, struct wing_usb *wusb) -++{ -++ if (wusb->proc_entry == NULL) -++ return; -++ -++ remove_proc_entry("mode", wusb->proc_entry); -++ remove_proc_entry(dev_name(dev), NULL); -++ -++ wusb->proc_entry = NULL; -++} -++ -+diff --git a/drivers/vendor/usb/proc.h b/drivers/vendor/usb/proc.h -+new file mode 100755 -+index 000000000..1aa745744 -+--- /dev/null -++++ b/drivers/vendor/usb/proc.h -+@@ -0,0 +1,15 @@ -++ /* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _WING_USB_PROC_H_ -++#define _WING_USB_PROC_H_ -++ -++#include -++#include -++#include "wing_usb.h" -++ -++int wing_usb_create_proc_entry(struct device *dev, struct wing_usb *wusb); -++void wing_usb_remove_proc_entry(struct device *dev, struct wing_usb *wusb); -++ -++#endif /* _WING_USB_PROC_H_ */ -+diff --git a/drivers/vendor/usb/version.mak b/drivers/vendor/usb/version.mak -+new file mode 100755 -+index 000000000..758a8ae5f -+--- /dev/null -++++ b/drivers/vendor/usb/version.mak -+@@ -0,0 +1 @@ -++USB_KERNEL_VERSION="USB_KERNEL 1.0.0" -+diff --git a/drivers/vendor/usb/wing_usb.c b/drivers/vendor/usb/wing_usb.c -+new file mode 100755 -+index 000000000..02d066bc2 -+--- /dev/null -++++ b/drivers/vendor/usb/wing_usb.c -+@@ -0,0 +1,1024 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)) -++#include -++#endif -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)) -++#include -++#endif -++#include -++#include -++ -++#include "proc.h" -++#include "wing_usb.h" -++ -++static LIST_HEAD(wing_usb_drd_dev_list); -++ -++static const unsigned int wing_usb_extcon_cable[] = { -++ EXTCON_USB, -++ EXTCON_USB_HOST, -++ EXTCON_NONE -++}; -++ -++static const char *wing_usb_event_type_string( -++ enum wing_usb_event_type event) -++{ -++ static const char * const wing_usb_event_strings[] = { -++ [SWITCH_TO_HOST] = "SWITCH_TO_HOST", -++ [SWITCH_TO_DEVICE] = "SWITCH_TO_DEVICE", -++ [NONE_EVENT] = "NONE_EVENT", -++ }; -++ -++ if (event > NONE_EVENT) -++ return "illegal event"; -++ -++ return wing_usb_event_strings[event]; -++} -++ -++static int __maybe_unused wing_usb_event_enqueue(struct wing_usb *wusb, -++ const struct wing_usb_event *event) -++{ -++ if (event->ctrl_id != wusb->id) { -++ wing_usb_info("event doesn't belong to this controller, event->ctrl_id = %d\n", -++ event->ctrl_id); -++ } -++ -++ if (kfifo_in(&wusb->event_fifo, event, 1) == 0) { -++ wing_usb_err("drop event %s\n", -++ wing_usb_event_type_string(event->type)); -++ return -ENOSPC; -++ } -++ -++ return 0; -++} -++ -++/* -++ * get event frome event_queue -++ * return the numbers of event dequeued, currently it is 1 -++ */ -++static int wing_usb_event_dequeue(struct wing_usb *wusb, -++ struct wing_usb_event *event) -++{ -++ return kfifo_out_spinlocked(&wusb->event_fifo, event, 1, -++ &wusb->event_lock); -++} -++ -++static int wing_usb_remove_child(struct device *dev, void __maybe_unused *data) -++{ -++ int ret; -++ -++ ret = of_platform_device_destroy(dev, NULL); -++ if (ret != 0) { -++ wing_usb_err("device destroy error (ret %d)\n", ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++static struct dwc3 *wing_usb_get_role_sw(const struct wing_usb *wusb) -++{ -++ struct dwc3 *dwc = NULL; -++ struct dwc3 *dwc_role_sw = NULL; -++ -++ if (wusb->dwc3_dev == NULL) { -++ wing_usb_err("no dwc platform device found\n"); -++ return NULL; -++ } -++ -++ dwc = platform_get_drvdata(wusb->dwc3_dev); -++ if (dwc == NULL) { -++ wing_usb_err("no dwc driver data found\n"); -++ return NULL; -++ } -++ -++ if (dwc->role_sw == NULL) { -++ wing_usb_err("no dwc_role_sw device found\n"); -++ return NULL; -++ } -++ -++ dwc_role_sw = (struct dwc3 *)usb_role_switch_get_drvdata(dwc->role_sw); -++ if (dwc_role_sw == NULL) { -++ wing_usb_err("no dwc_role_sw driver data found\n"); -++ return NULL; -++ } -++ -++ return dwc_role_sw; -++} -++#endif -++ -++static int wing_usb_start_device(const struct wing_usb *wusb) -++{ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ struct dwc3 *dwc = NULL; -++#endif -++ int ret = extcon_set_state_sync(wusb->edev, EXTCON_USB, true); -++ if (ret) { -++ wing_usb_err("extcon start peripheral error\n"); -++ return ret; -++ } -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ dwc = wing_usb_get_role_sw(wusb); -++ if (dwc != NULL) { -++ if (dwc->role_sw != NULL) { -++ ret = usb_role_switch_set_role(dwc->role_sw, USB_ROLE_DEVICE); -++ } -++ } -++#endif -++ -++ wing_usb_dbg("wing usb status: OFF -> DEVICE\n"); -++ -++ return ret; -++} -++ -++static int wing_usb_stop_device(const struct wing_usb *wusb) -++{ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ struct dwc3 *dwc = NULL; -++#endif -++ -++ int ret = extcon_set_state_sync(wusb->edev, EXTCON_USB, false); -++ if (ret) { -++ wing_usb_err("extcon stop peripheral error\n"); -++ return ret; -++ } -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ dwc = wing_usb_get_role_sw(wusb); -++ if (dwc != NULL) { -++ if (dwc->role_sw != NULL) { -++ ret = usb_role_switch_set_role(dwc->role_sw, USB_ROLE_NONE); -++ } -++ } -++#endif -++ -++ wing_usb_dbg("wing usb status: DEVICE -> OFF\n"); -++ -++ return ret; -++} -++ -++static int wing_usb_start_host(const struct wing_usb *wusb) -++{ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ struct dwc3 *dwc = NULL; -++#endif -++ int ret = extcon_set_state_sync(wusb->edev, EXTCON_USB_HOST, true); -++ if (ret) { -++ wing_usb_err("extcon start host error\n"); -++ } -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ dwc = wing_usb_get_role_sw(wusb); -++ if (dwc != NULL) { -++ if (dwc->role_sw != NULL) { -++ ret = usb_role_switch_set_role(dwc->role_sw, USB_ROLE_HOST); -++ } -++ } -++#endif -++ -++ wing_usb_dbg("wing usb status: OFF -> HOST\n"); -++ -++ return ret; -++} -++ -++static int wing_usb_stop_host(const struct wing_usb *wusb) -++{ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ struct dwc3 *dwc = NULL; -++#endif -++ int ret = extcon_set_state_sync(wusb->edev, EXTCON_USB_HOST, false); -++ if (ret) { -++ wing_usb_err("extcon stop host error\n"); -++ return ret; -++ } -++ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ dwc = wing_usb_get_role_sw(wusb); -++ if (dwc != NULL) { -++ if (dwc->role_sw != NULL) { -++ ret = usb_role_switch_set_role(dwc->role_sw, USB_ROLE_HOST); -++ } -++ } -++#endif -++ -++ wing_usb_dbg("wing usb status: HOST -> OFF\n"); -++ -++ return ret; -++} -++ -++static int wing_usb_switch_to_host(struct wing_usb *wusb) -++{ -++ int ret; -++ -++ if (wusb == NULL) { -++ return -EINVAL; -++ } -++ -++ if (wusb->state == WING_USB_STATE_HOST) { -++ return 0; -++ } -++ -++ ret = wing_usb_stop_device(wusb); -++ if (ret != 0) { -++ wing_usb_err("stop device failed\n"); -++ return ret; -++ } -++ -++ ret = wing_usb_start_host(wusb); -++ if (ret != 0) { -++ wing_usb_err("start host failed\n"); -++ return ret; -++ } -++ -++ wusb->state = WING_USB_STATE_HOST; -++ -++ return 0; -++} -++ -++static int wing_usb_switch_to_device(struct wing_usb *wusb) -++{ -++ int ret; -++ -++ if (wusb == NULL) { -++ return -EINVAL; -++ } -++ -++ if (wusb->state == WING_USB_STATE_DEVICE) { -++ return 0; -++ } -++ -++ ret = wing_usb_stop_host(wusb); -++ if (ret != 0) { -++ wing_usb_err("stop host failed\n"); -++ return ret; -++ } -++ -++ ret = wing_usb_start_device(wusb); -++ if (ret != 0) { -++ wing_usb_err("start device failed\n"); -++ return ret; -++ } -++ -++ wusb->state = WING_USB_STATE_DEVICE; -++ -++ return 0; -++} -++ -++static void wing_usb_handle_event(struct wing_usb *wusb, -++ enum wing_usb_event_type event_type) -++{ -++ wing_usb_dbg("type: %s\n", wing_usb_event_type_string(event_type)); -++ -++ switch (event_type) { -++ case SWITCH_TO_HOST: -++ wing_usb_switch_to_host(wusb); -++ break; -++ -++ case SWITCH_TO_DEVICE: -++ wing_usb_switch_to_device(wusb); -++ break; -++ -++ default: -++ wing_usb_dbg("illegal event type!\n"); -++ break; -++ } -++} -++ -++static void wing_usb_event_work(struct work_struct *work) -++{ -++ struct wing_usb_event event = {0}; -++ -++ struct wing_usb *wusb = container_of(work, struct wing_usb, event_work); -++ -++ wing_usb_dbg("+\n"); -++ mutex_lock(&wusb->lock); -++ -++ while (wing_usb_event_dequeue(wusb, &event)) { -++ wing_usb_handle_event(wusb, event.type); -++ } -++ -++ mutex_unlock(&wusb->lock); -++ -++ wing_usb_dbg("-\n"); -++} -++ -++/* -++ * return 0 means event was accepted, others means event was rejected. -++ */ -++int wing_usb_queue_event(const struct wing_usb_event *usb_event, -++ struct wing_usb *wusb) -++{ -++#if IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) -++ unsigned long flags; -++ enum wing_usb_event_type event_type; -++ int controller_id; -++ -++ if (usb_event == NULL) -++ return -EINVAL; -++ -++ if (wusb == NULL) -++ return -ENODEV; -++ -++ spin_lock_irqsave(&(wusb->event_lock), flags); -++ -++ event_type = usb_event->type; -++ controller_id = usb_event->ctrl_id; -++ wing_usb_dbg("event: %s, controller id: %d\n", -++ wing_usb_event_type_string(event_type), controller_id); -++ -++ if (wing_usb_event_enqueue(wusb, usb_event)) { -++ wing_usb_err("can't enqueue event:%d\n", event_type); -++ spin_unlock_irqrestore(&(wusb->event_lock), flags); -++ return -EBUSY; -++ } -++ -++ schedule_work(&wusb->event_work); -++ -++ spin_unlock_irqrestore(&(wusb->event_lock), flags); -++ -++ return 0; -++#else -++ return 0; -++#endif -++} -++ -++int wing_usb_otg_event(enum wing_usb_event_type type, int controller_id) -++{ -++ struct wing_usb_event event = {0}; -++ struct wing_usb *wusb = NULL; -++ struct wing_usb *cur_wusb, *next_wusb; -++ -++ event.type = type; -++ event.ctrl_id = controller_id; -++ -++ list_for_each_entry_safe(cur_wusb, next_wusb, -++ &wing_usb_drd_dev_list, list) { -++ wing_usb_info("cur_wusb->id = %d\n", cur_wusb->id); -++ if (cur_wusb->id == controller_id) { -++ wusb = cur_wusb; -++ break; -++ } -++ } -++ -++ if (wusb == NULL) { -++ wing_usb_err("find wing_usb for controler_id = %d failed\n", -++ controller_id); -++ return -1; -++ } -++ -++ return wing_usb_queue_event(&event, wusb); -++} -++EXPORT_SYMBOL(wing_usb_otg_event); -++ -++static int wing_usb_get_resource(struct device *dev, struct wing_usb *wusb) -++{ -++ int ret; -++ -++ wusb->support_drd = of_property_read_bool(dev->of_node, "support-drd"); -++ -++ wusb->is_cur_host = of_property_read_bool(dev->of_node, "host-mode"); -++ -++ wusb->deempth = of_property_read_bool(dev->of_node, "deempth"); -++ -++ /* es chip disable suspend, cs not need, but you can disable it when you want */ -++ wusb->disable_suspend = of_property_read_bool(dev->of_node, "disable-suspend"); -++ -++ /* USB31 need configure this */ -++ wusb->powerdown_scale = of_property_read_bool(dev->of_node, "powerdown-scale"); -++ -++ wusb->is_usb2 = of_property_read_bool(dev->of_node, "is-usb2"); -++ -++ wusb->need_filter_se0_fsls_eop = of_property_read_bool(dev->of_node, "filter-se0-fsls"); -++ -++ wusb->ctrl_base = of_iomap(dev->of_node, 0); -++ if (IS_ERR(wusb->ctrl_base)) { -++ wing_usb_err("alloc ctrl_base failed\n"); -++ return -1; -++ } -++ -++ wusb->usb2_phy = devm_phy_get(dev, "usb2-phy"); -++ if (IS_ERR(wusb->usb2_phy)) { -++ wing_usb_err("get u2phy failed\n"); -++ return -1; -++ } -++ -++ wusb->usb3_phy = devm_phy_get(dev, "usb3-phy"); -++ /* at least one of usb2phy and usb3phy */ -++ if (!wusb->is_usb2 && IS_ERR(wusb->usb3_phy)) { -++ wing_usb_err("get u3phy failed\n"); -++ return -1; -++ } -++ -++ wusb->ctrl_clk = devm_clk_get(dev, "ctrl-clk"); -++ if (IS_ERR(wusb->ctrl_clk)) { -++ wing_usb_err("get ctrl clk failed\n"); -++ return -1; -++ } -++ -++ ret = of_property_read_u32(dev->of_node, "tx-thrcfg", &wusb->tx_thrcfg); -++ if (ret) -++ wusb->tx_thrcfg = 0; -++ -++ ret = of_property_read_u32(dev->of_node, "rx-thrcfg", &wusb->rx_thrcfg); -++ if (ret) -++ wusb->rx_thrcfg = 0; -++ -++ return 0; -++} -++ -++static void wing_usb_set_tx_deemph(const struct wing_usb *wusb) -++{ -++ /* Set X1 Gen2 TX de-emp value for normal use, CP13 & CP14 */ -++ writel(GEN2_TX_DEEMPH_VAL, wusb->ctrl_base + LCSR_TX_DEEMPH_ADDR); -++ writel(LCSR_TX_DEEMPH_CP13_VAL, wusb->ctrl_base + LCSR_TX_DEEMPH_CP13_ADDR); -++ writel(LCSR_TX_DEEMPH_CP14_VAL, wusb->ctrl_base + LCSR_TX_DEEMPH_CP14_ADDR); -++} -++ -++static void wing_usb_disable_suspend(const struct wing_usb *wusb) -++{ -++ u32 reg; -++ -++ reg = readl(wusb->ctrl_base + REG_GUSB3PIPECTL0); -++ reg &= ~(SUSPENDENABLE); -++ writel(reg, wusb->ctrl_base + REG_GUSB3PIPECTL0); -++} -++ -++static void wing_usb_set_powerdown_scale(const struct wing_usb *wusb) -++{ -++ u32 reg; -++ -++ reg = readl(wusb->ctrl_base + GCTL); -++ reg &= ~(PWRDNSCALE_MASK); -++ reg |= PWRDNSCALE_VAL; -++ writel(reg, wusb->ctrl_base + GCTL); -++} -++ -++static void wing_usb_set_mode(const struct wing_usb *wusb) -++{ -++ u32 val; -++ -++ val = readl(wusb->ctrl_base + GCTL); -++ val &= ~(PRTCAPDIR_MASK); -++ if (wusb->is_cur_host) { -++ val |= (PRTCAPDIR_HOST); -++ } else { -++ val |= (PRTCAPDIR_DEVICE); -++ } -++ writel(val, wusb->ctrl_base + GCTL); -++} -++ -++#if IS_ENABLED(CONFIG_PM_SLEEP) -++static void wing_usb_save_mode(struct wing_usb *wusb) -++{ -++ u32 val; -++ -++ val = readl(wusb->ctrl_base + GCTL); -++ val &= PRTCAPDIR_MASK; -++ if (val == PRTCAPDIR_HOST) { -++ wusb->is_cur_host = true; -++ } else { -++ wusb->is_cur_host = false; -++ } -++} -++#endif -++ -++static void config_tx_thrcfg(const struct wing_usb *wusb) -++{ -++ u32 val; -++ -++ if (wusb->tx_thrcfg != 0) { -++ val = readl(wusb->ctrl_base + GTXTHRCFG); -++ val &= ~(USB_TX_PKT_CNT_MASK); -++ val |= (wusb->tx_thrcfg & USB_TX_PKT_CNT_MASK); -++ val &= ~(USB_MAX_TX_BURST_SIZE_MASK); -++ val |= (wusb->tx_thrcfg & USB_MAX_TX_BURST_SIZE_MASK); -++ val |= USB_TX_PKT_CNT_SEL; -++ writel(val, wusb->ctrl_base + GTXTHRCFG); -++ } -++} -++ -++static void config_rx_thrcfg(const struct wing_usb *wusb) -++{ -++ u32 val; -++ -++ if (wusb->rx_thrcfg != 0) { -++ val = readl(wusb->ctrl_base + GRXTHRCFG); -++ val &= ~(USB_RX_PKT_CNT_MASK); -++ val |= (wusb->rx_thrcfg & USB_RX_PKT_CNT_MASK); -++ val &= ~(USB_MAX_RX_BURST_SIZE_MASK); -++ val |= (wusb->rx_thrcfg & USB_MAX_RX_BURST_SIZE_MASK); -++ val |= USB_RX_PKT_CNT_SEL; -++ writel(val, wusb->ctrl_base + GRXTHRCFG); -++ } -++} -++ -++static void wing_usb_usb20_config(const struct wing_usb *wusb) -++{ -++ u32 reg; -++ -++ reg = readl(wusb->ctrl_base + REG_GUSB3PIPECTL0); -++ reg |= PCS_SSP_SOFT_RESET; -++ writel(reg, wusb->ctrl_base + REG_GUSB3PIPECTL0); -++ -++ if (wusb->support_drd) { -++ /* For DRD mode, it is recommanded set SUSPENDUSB20 to 0 */ -++ reg = readl(wusb->ctrl_base + GUSB2PHYCFG0); -++ reg &= ~(SUSPENDUSB20); -++ writel(reg, wusb->ctrl_base + GUSB2PHYCFG0); -++ } -++ -++ reg = readl(wusb->ctrl_base + REG_GUSB3PIPECTL0); -++ reg &= ~(SUSPENDENABLE | PCS_SSP_SOFT_RESET); -++ writel(reg, wusb->ctrl_base + REG_GUSB3PIPECTL0); -++} -++ -++static void wing_usb_filter_se0_fsls_eop_config(const struct wing_usb *wusb) -++{ -++ u32 reg; -++ -++ reg = readl(wusb->ctrl_base + GUCTL1); -++ reg |= FILTER_SE0_FSLS_EOP; -++ writel(reg, wusb->ctrl_base + GUCTL1); -++} -++ -++static void wing_usb_feature_config(struct wing_usb *wusb) -++{ -++ if (wusb->deempth) { -++ wing_usb_set_tx_deemph(wusb); -++ } -++ -++ if (wusb->disable_suspend) { -++ wing_usb_disable_suspend(wusb); -++ } -++ -++ if (wusb->powerdown_scale) { -++ wing_usb_set_powerdown_scale(wusb); -++ } -++ -++ if (wusb->is_usb2) { -++ wing_usb_usb20_config(wusb); -++ } -++ -++ if (wusb->need_filter_se0_fsls_eop) { -++ wing_usb_filter_se0_fsls_eop_config(wusb); -++ } -++ -++ config_tx_thrcfg(wusb); -++ config_rx_thrcfg(wusb); -++ -++ wing_usb_set_mode(wusb); -++} -++ -++static void wing_usb_drd_initialize(struct device *dev, struct wing_usb *wusb) -++{ -++ int ret; -++ -++ ret = of_property_read_s32(dev->of_node, "controller_id", &wusb->id); -++ if (ret) { -++ wing_usb_info("cannot read controller_id: %d\n", ret); -++ wusb->id = -1; -++ } -++ -++ INIT_KFIFO(wusb->event_fifo); -++ spin_lock_init(&wusb->event_lock); -++ INIT_WORK(&wusb->event_work, wing_usb_event_work); -++ mutex_init(&wusb->lock); -++} -++ -++static int wing_usb_drd_init_state(struct device *dev, struct wing_usb *wusb) -++{ -++ struct wing_usb_event usb_event = {0}; -++ const char *buf = NULL; -++ int ret; -++ -++ wing_usb_dbg("+\n"); -++ -++ wusb->state = WING_USB_STATE_UNKNOWN; -++ -++ ret = of_property_read_string(dev->of_node, "init_mode", &buf); -++ if (ret) { -++ wing_usb_info("cannot read init mode: %d, set device mode\n", ret); -++ usb_event.type = SWITCH_TO_DEVICE; -++ } else { -++ wing_usb_dbg("init state: %s\n", buf); -++ -++ if (strncmp(buf, "host", 4) == 0) { /* host len is 4 */ -++ usb_event.type = SWITCH_TO_HOST; -++ } else { -++ usb_event.type = SWITCH_TO_DEVICE; -++ } -++ } -++ -++ ret = wing_usb_queue_event(&usb_event, wusb); -++ if (ret) -++ wing_usb_err("usb_queue_event err: %d\n", ret); -++ -++ wing_usb_dbg("-\n"); -++ -++ return 0; -++} -++ -++static int wing_usb_controller_probe(struct device *dev, struct wing_usb *wusb) -++{ -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)) -++ struct device_node *child_node = NULL; -++ int ret; -++ -++ ret = of_platform_populate(dev->of_node, NULL, NULL, dev); -++ if (ret == 0) { -++ child_node = of_get_next_available_child(dev->of_node, NULL); -++ if (child_node) { -++ wusb->dwc3_dev = of_find_device_by_node(child_node); -++ } -++ } -++ return ret; -++#else -++ return of_platform_populate(dev->of_node, NULL, NULL, dev); -++#endif -++} -++ -++static int wing_usb_pm_runtime_enable(const struct wing_usb *wusb) -++{ -++ struct platform_device *pdev = wusb->pdev; -++ struct device *dev = &pdev->dev; -++ int ret; -++ -++ pm_runtime_set_active(dev); -++ pm_runtime_enable(dev); -++ -++ ret = pm_runtime_get_sync(dev); -++ if (ret < 0) { -++ wing_usb_err("pm_runtime_get_sync failed %d\n", ret); -++ return ret; -++ } -++ -++ pm_runtime_forbid(dev); -++ -++ return ret; -++} -++ -++static int wing_usb_extcon_init(struct device *dev, struct wing_usb *wusb) -++{ -++ int ret; -++ -++ wusb->edev = devm_extcon_dev_allocate(dev, wing_usb_extcon_cable); -++ if (IS_ERR(wusb->edev)) { -++ dev_err(dev, "failed to allocate extcon device\n"); -++ return PTR_ERR(wusb->edev); -++ } -++ -++ ret = devm_extcon_dev_register(dev, wusb->edev); -++ if (ret < 0) { -++ dev_err(dev, "failed to register extcon device\n"); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static int wing_usb_drd_init(struct device *dev, struct wing_usb *wusb) -++{ -++ int ret; -++ -++ ret = wing_usb_extcon_init(dev, wusb); -++ if (ret < 0) { -++ dev_err(dev, "failed to register extcon device\n"); -++ return -1; -++ } -++ -++ ret = wing_usb_create_proc_entry(dev, wusb); -++ if (ret) { -++ dev_err(dev, "create proc entry failed!\n"); -++ goto err_extcon_free; -++ } -++ -++ wing_usb_drd_initialize(dev, wusb); -++ -++ ret = wing_usb_pm_runtime_enable(wusb); -++ if (ret < 0) -++ goto err_remove_attr; -++ -++ ret = wing_usb_controller_probe(dev, wusb); -++ if (ret) { -++ wing_usb_err("register controller failed %d!\n", ret); -++ goto err_pm_put; -++ } -++ -++ ret = wing_usb_drd_init_state(dev, wusb); -++ if (ret) { -++ wing_usb_err("wing_usb_init_state failed!\n"); -++ goto err_remove_child; -++ } -++ -++ list_add_tail(&wusb->list, &wing_usb_drd_dev_list); -++ -++ pm_runtime_allow(dev); -++ wing_usb_dbg("-\n"); -++ -++ return 0; -++ -++err_remove_child: -++ device_for_each_child(dev, NULL, wing_usb_remove_child); -++ -++err_pm_put: -++ pm_runtime_put_sync(dev); -++ pm_runtime_disable(dev); -++ -++err_remove_attr: -++ wing_usb_remove_proc_entry(dev, wusb); -++ -++err_extcon_free: -++ devm_extcon_dev_unregister(dev, wusb->edev); -++ extcon_dev_free(wusb->edev); -++ wusb->edev = NULL; -++ -++ return ret; -++} -++ -++static int wing_usb_host_init(struct device *dev, struct wing_usb *wusb) -++{ -++ int ret; -++ -++ /* enable runtime pm. */ -++ ret = wing_usb_pm_runtime_enable(wusb); -++ if (ret < 0) { -++ wing_usb_err("anble pm runtime failed\n"); -++ return ret; -++ } -++ -++ ret = wing_usb_controller_probe(dev, wusb); -++ if (ret) { -++ wing_usb_err("register controller failed %d!\n", ret); -++ goto err_pm_put; -++ } -++ -++ pm_runtime_allow(dev); -++ -++ return 0; -++ -++err_pm_put: -++ pm_runtime_put_sync(dev); -++ pm_runtime_disable(dev); -++ -++ return ret; -++} -++ -++static int wing_usb_clk_phy_init(const struct wing_usb *wusb) -++{ -++ int ret = 0; -++ -++ ret = clk_prepare(wusb->ctrl_clk); -++ if (ret != 0) { -++ wing_usb_err("ctrl clk prepare failed\n"); -++ return -1; -++ } -++ -++ if (!IS_ERR(wusb->usb2_phy)) { -++ ret = phy_power_on(wusb->usb2_phy); -++ if (ret != 0) { -++ wing_usb_err("usb2 phy init failed\n"); -++ return -1; -++ } -++ } -++ -++ if (!IS_ERR(wusb->usb3_phy)) { -++ ret = phy_power_on(wusb->usb3_phy); -++ if (ret != 0) { -++ wing_usb_err("usb3 phy init failed\n"); -++ return -1; -++ } -++ } -++ -++ ret = clk_enable(wusb->ctrl_clk); -++ if (ret != 0) { -++ wing_usb_err("ctrl clk enable failed\n"); -++ return -1; -++ } -++ -++ return 0; -++} -++ -++static int wing_usb_clk_phy_deinit(const struct wing_usb *wusb) -++{ -++ int ret = 0; -++ -++ clk_disable(wusb->ctrl_clk); -++ -++ if (!IS_ERR(wusb->usb3_phy)) { -++ ret = phy_power_off(wusb->usb3_phy); -++ if (ret != 0) { -++ wing_usb_err("usb3 phy deinit failed\n"); -++ return -1; -++ } -++ } -++ -++ if (!IS_ERR(wusb->usb2_phy)) { -++ ret = phy_power_off(wusb->usb2_phy); -++ if (ret != 0) { -++ wing_usb_err("usb2 phy deinit failed\n"); -++ return -1; -++ } -++ } -++ -++ clk_unprepare(wusb->ctrl_clk); -++ -++ return 0; -++} -++ -++static int wing_usb_probe(struct platform_device *pdev) -++{ -++ int ret; -++ struct wing_usb *wusb = NULL; -++ struct device *dev = &pdev->dev; -++ -++ wing_usb_dbg("+++\n"); -++ -++ BUILD_BUG_ON(sizeof(struct wing_usb_event) != SIZE_WING_USB_EVENT); -++ -++ wusb = devm_kzalloc(dev, sizeof(*wusb), GFP_KERNEL); -++ if (wusb == NULL) { -++ wing_usb_err("alloc wusb failed\n"); -++ return -ENOMEM; -++ } -++ -++ platform_set_drvdata(pdev, wusb); -++ wusb->pdev = pdev; -++ -++ ret = wing_usb_get_resource(dev, wusb); -++ if (ret < 0) { -++ devm_kfree(dev, wusb); -++ wusb = NULL; -++ return -1; -++ } -++ -++ ret = wing_usb_clk_phy_init(wusb); -++ if (ret != 0) { -++ wing_usb_err("init phy failed\n"); -++ goto err_unmap; -++ } -++ -++ wing_usb_feature_config(wusb); -++ -++ if (wusb->support_drd) { -++ ret = wing_usb_drd_init(dev, wusb); -++ } else { -++ ret = wing_usb_host_init(dev, wusb); -++ } -++ -++ if (ret < 0) { -++ wing_usb_err("controller init failed, ret = %d\n", ret); -++ goto err_unmap; -++ } -++ -++ return 0; -++ -++err_unmap: -++ iounmap(wusb->ctrl_base); -++ -++ return ret; -++} -++ -++static int wing_usb_remove(struct platform_device *pdev) -++{ -++ struct wing_usb *wusb = platform_get_drvdata(pdev); -++ struct device *dev = &pdev->dev; -++ -++ wing_usb_dbg("+\n"); -++ if (wusb == NULL) { -++ wing_usb_err("wusb NULL\n"); -++ return -ENODEV; -++ } -++ -++ if (wusb->support_drd) { -++ wing_usb_remove_proc_entry(dev, wusb); -++ -++ devm_extcon_dev_unregister(dev, wusb->edev); -++ extcon_dev_free(wusb->edev); -++ wusb->edev = NULL; -++ -++ cancel_work_sync(&wusb->event_work); -++ } -++ -++ device_for_each_child(dev, NULL, wing_usb_remove_child); -++ -++ pm_runtime_put_sync(dev); -++ pm_runtime_disable(dev); -++ -++ wing_usb_clk_phy_deinit(wusb); -++ -++ iounmap(wusb->ctrl_base); -++ -++ wing_usb_dbg("-\n"); -++ -++ return 0; -++} -++ -++#if IS_ENABLED(CONFIG_PM_SLEEP) -++static int wing_usb_suspend(struct device *dev) -++{ -++ int ret; -++ struct wing_usb *wusb = dev_get_drvdata(dev); -++ -++ if (wusb == NULL) { -++ wing_usb_err("wusb is null\n"); -++ return -1; -++ } -++ -++ wing_usb_save_mode(wusb); -++ -++ ret = wing_usb_clk_phy_deinit(wusb); -++ if (ret != 0) { -++ wing_usb_err("deinit clk and phy failed when suspend\n"); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static int wing_usb_resume(struct device *dev) -++{ -++ int ret; -++ struct wing_usb *wusb = dev_get_drvdata(dev); -++ -++ if (wusb == NULL) { -++ wing_usb_err("wusb is null\n"); -++ return -1; -++ } -++ -++ ret = wing_usb_clk_phy_init(wusb); -++ if (ret != 0) { -++ wing_usb_err("init clk and phy failed when reusme\n"); -++ return ret; -++ } -++ -++ wing_usb_feature_config(wusb); -++ -++ return 0; -++} -++#endif -++ -++const struct dev_pm_ops g_wing_usb_dev_pm_ops = { -++#if IS_ENABLED(CONFIG_PM_SLEEP) -++ SET_SYSTEM_SLEEP_PM_OPS(wing_usb_suspend, wing_usb_resume) -++#endif -++}; -++ -++static const struct of_device_id g_wing_usb_match[] = { -++ { .compatible = "wing-usb,drd" }, -++ { .compatible = "wing-usb,host" }, -++ {}, -++}; -++MODULE_DEVICE_TABLE(of, g_wing_usb_match); -++ -++static struct platform_driver g_wing_usb_driver = { -++ .probe = wing_usb_probe, -++ .remove = wing_usb_remove, -++ .driver = { -++ .name = "wing-usb", -++ .of_match_table = of_match_ptr(g_wing_usb_match), -++ .pm = &g_wing_usb_dev_pm_ops, -++ }, -++}; -++ -++static int __init wing_usb_module_init(void) -++{ -++ int ret; -++ -++ ret = platform_driver_register(&g_wing_usb_driver); -++ if (ret != 0) { -++ wing_usb_err("register wing usb driver failed, ret = %d\n", ret); -++ return ret; -++ } -++ -++ wing_usb_info("register wing usb driver\n"); -++ -++ return ret; -++} -++module_init(wing_usb_module_init); -++ -++static void __exit wing_usb_module_exit(void) -++{ -++ platform_driver_unregister(&g_wing_usb_driver); -++ -++ wing_usb_info("unregister wing usb driver\n"); -++} -++module_exit(wing_usb_module_exit); -++ -++MODULE_DESCRIPTION("Wing USB Controller Driver"); -++MODULE_LICENSE("GPL v2"); -++MODULE_VERSION(USB_KERNEL_VERSION); -+diff --git a/drivers/vendor/usb/wing_usb.h b/drivers/vendor/usb/wing_usb.h -+new file mode 100755 -+index 000000000..d0158073b -+--- /dev/null -++++ b/drivers/vendor/usb/wing_usb.h -+@@ -0,0 +1,145 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _WING_USB_H_ -++#define _WING_USB_H_ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define WING_USB_DEBUG 0 -++ -++#define wing_usb_dbg(format, arg...) \ -++ do { \ -++ if (WING_USB_DEBUG) \ -++ printk(KERN_INFO "[WING-USB][%s]"format, __func__, ##arg); \ -++ } while (0) -++ -++#define wing_usb_info(format, arg...) \ -++ printk(KERN_INFO "[WING-USB][%s]"format, __func__, ##arg) -++ -++#define wing_usb_err(format, arg...) \ -++ printk(KERN_ERR "[WING-USB][%s]"format, __func__, ##arg) -++ -++#define MAX_WING_USB_EVENT_COUNT 16 -++ -++#define LCSR_TX_DEEMPH_ADDR 0xD060 -++#define LCSR_TX_DEEMPH_CP13_ADDR 0xD064 -++#define LCSR_TX_DEEMPH_CP14_ADDR 0xD068 -++#define GEN2_TX_DEEMPH_VAL 0x14FC0 -++#define LCSR_TX_DEEMPH_CP13_VAL 0xFC0 -++#define LCSR_TX_DEEMPH_CP14_VAL 0x4FC5 -++ -++#define REG_GUSB3PIPECTL0 0xc2c0 -++#define SUSPENDENABLE BIT(17) -++#define PCS_SSP_SOFT_RESET BIT(31) -++ -++#define GCTL 0xc110 -++#define PRTCAPDIR_HOST BIT(12) -++#define PRTCAPDIR_DEVICE BIT(13) -++#define PRTCAPDIR_MASK (3U << 12) -++#define PWRDNSCALE_MASK (0x1fffU << 19) -++#define PWRDNSCALE_VAL (0x3fU << 19) -++ -++#define GUCTL1 0xc11c -++#define FILTER_SE0_FSLS_EOP BIT(29) -++ -++#define GTXTHRCFG 0xc108 -++#define USB_TX_PKT_CNT_SEL BIT(29) -++#define USB_TX_PKT_CNT_MASK (0xfU << 24) -++#define USB_TX_PKT_CNT (0x3U << 24) -++#define USB_MAX_TX_BURST_SIZE_MASK (0xffU << 16) -++#define USB_MAX_TX_BURST_SIZE (0x10U << 16) -++ -++#define GRXTHRCFG 0xc10c -++#define USB_RX_PKT_CNT_SEL BIT(29) -++#define USB_RX_PKT_CNT_MASK (0xfU << 24) -++#define USB_RX_PKT_CNT (0x3U << 24) -++#define USB_MAX_RX_BURST_SIZE_MASK (0xffU << 16) -++#define USB_MAX_RX_BURST_SIZE (0x10U << 16) -++ -++#define GUSB2PHYCFG0 0xc200 -++#define ULPI_UTMI_SEL (1U << 4) -++#define SUSPENDUSB20 (1U << 6) -++ -++enum wing_usb_state { -++ WING_USB_STATE_UNKNOWN = 0, -++ WING_USB_STATE_OFF, -++ WING_USB_STATE_HOST, -++ WING_USB_STATE_DEVICE, -++}; -++ -++enum wing_usb_event_type { -++ SWITCH_TO_HOST = 0, -++ SWITCH_TO_DEVICE, -++ NONE_EVENT, -++}; -++ -++#define SIZE_WING_USB_EVENT 32 -++ -++/* size of struct wing_usb_event must be a power of 2 for kfifo */ -++struct wing_usb_event { -++ enum wing_usb_event_type type; -++ int ctrl_id; -++#ifdef CONFIG_64BIT -++ u32 reserved; /* to keep struct size is 32 bytes in 64bit system */ -++#else -++ u32 reserved[3]; /* to keep struct size is 32 bytes in 32bit system */ -++#endif -++ u32 flags; -++ void (*callback)(struct wing_usb_event *event); -++ void *content; -++}; -++ -++struct wing_usb { -++ struct platform_device *pdev; -++ struct extcon_dev *edev; -++ struct platform_device *dwc3_dev; -++ -++ int id; -++ bool support_drd; -++ bool is_cur_host; -++ bool deempth; -++ bool disable_suspend; -++ bool powerdown_scale; -++ bool is_usb2; -++ bool need_filter_se0_fsls_eop; -++ struct list_head list; -++ u32 tx_thrcfg; -++ u32 rx_thrcfg; -++ -++ enum wing_usb_state state; -++ DECLARE_KFIFO(event_fifo, struct wing_usb_event, -++ MAX_WING_USB_EVENT_COUNT); -++ -++ spinlock_t event_lock; -++ struct work_struct event_work; -++ struct phy *usb2_phy; -++ struct phy *usb3_phy; -++ struct clk *ctrl_clk; -++ -++ struct mutex lock; -++ -++ void __iomem *ctrl_base; -++ struct proc_dir_entry *proc_entry; -++}; -++ -++/* -++ * The event will be added to tail of a queue, and processed in a work. -++ * Return 0 means the event added sucessfully, others means event was rejected. -++ */ -++int wing_usb_queue_event(const struct wing_usb_event *usb_event, -++ struct wing_usb *wusb); -++ -++int wing_usb_otg_event(enum wing_usb_event_type type, int controller_id); -++ -++#endif /* _WING_USB_H_ */ -+diff --git a/fs/fat/Kconfig b/fs/fat/Kconfig -+index 66532a71e..bacf46d71 100644 -+--- a/fs/fat/Kconfig -++++ b/fs/fat/Kconfig -+@@ -115,3 +115,15 @@ config FAT_DEFAULT_UTF8 -+ Say Y if you use UTF-8 encoding for file names, N otherwise. -+ -+ See for more information. -++ -++if ARCH_BSP -++ -++config BSP_FAT_OPTIMIZE -++ bool "Enable customized optimization of Fat file system for BSP" -++ depends on VFAT_FS -++ default n -++ help -++ After enabling the optimization option for the FAT file system, -++ the backup function for the FAT table will be skipped in a customized -++ manner, and the update frequency of the FAT table will be reduced. -++endif # ARCH_BSP -+diff --git a/fs/fat/dir.c b/fs/fat/dir.c -+index c4a274285..e6df8a4b0 100644 -+--- a/fs/fat/dir.c -++++ b/fs/fat/dir.c -+@@ -19,6 +19,9 @@ -+ #include -+ #include -+ #include "fat.h" -++#ifdef CONFIG_ARCH_BSP -++#include "linux/securec.h" -++#endif -+ -+ /* -+ * Maximum buffer size of short name. -+@@ -783,6 +786,387 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *file, -+ ret = buf.result; -+ return ret; -+ } -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++/* -++ * 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); -++ -++ ret = memset_s(d_createtime, sizeof(d_createtime), 0, 8); -++ if (ret != EOK) -++ goto fill_failed; -++ 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 (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) -+@@ -790,7 +1174,10 @@ static long fat_dir_ioctl(struct file *filp, unsigned int cmd, -+ struct inode *inode = file_inode(filp); -+ struct __fat_dirent __user *d1 = (struct __fat_dirent __user *)arg; -+ int short_only, both; -+- -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++ 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; -+@@ -1094,11 +1481,15 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, -+ err = -ENOMEM; -+ goto error; -+ } -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ /* Avoid race with userspace read via bdev */ -+ lock_buffer(bhs[n]); -++#endif -+ memset(bhs[n]->b_data, 0, sb->s_blocksize); -+ set_buffer_uptodate(bhs[n]); -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ unlock_buffer(bhs[n]); -++#endif -+ mark_buffer_dirty_inode(bhs[n], dir); -+ -+ n++; -+@@ -1155,8 +1546,10 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts) -+ fat_time_unix2fat(sbi, ts, &time, &date, &time_cs); -+ -+ de = (struct msdos_dir_entry *)bhs[0]->b_data; -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ /* Avoid race with userspace read via bdev */ -+ lock_buffer(bhs[0]); -++#endif -+ /* filling the new directory slots ("." and ".." entries) */ -+ memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME); -+ memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME); -+@@ -1179,7 +1572,9 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts) -+ de[0].size = de[1].size = 0; -+ memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); -+ set_buffer_uptodate(bhs[0]); -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ unlock_buffer(bhs[0]); -++#endif -+ mark_buffer_dirty_inode(bhs[0], dir); -+ -+ err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE); -+@@ -1237,11 +1632,15 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots, -+ -+ /* fill the directory entry */ -+ copy = min(size, sb->s_blocksize); -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ /* Avoid race with userspace read via bdev */ -+ lock_buffer(bhs[n]); -++#endif -+ memcpy(bhs[n]->b_data, slots, copy); -+ set_buffer_uptodate(bhs[n]); -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ unlock_buffer(bhs[n]); -++#endif -+ mark_buffer_dirty_inode(bhs[n], dir); -+ slots += copy; -+ size -= copy; -+diff --git a/fs/fat/fat.h b/fs/fat/fat.h -+index 922a0c6ba..5a312bbba 100644 -+--- a/fs/fat/fat.h -++++ b/fs/fat/fat.h -+@@ -448,6 +448,10 @@ extern int fat_truncate_time(struct inode *inode, struct timespec64 *now, -+ int flags); -+ extern int fat_update_time(struct inode *inode, struct timespec64 *now, -+ int flags); -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++extern void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime, -++ __le16 __time, __le16 __date, u8 time_cs); -++#endif -+ extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); -+ -+ int fat_cache_init(void); -+diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c -+index 353735032..36e41f71a 100644 -+--- a/fs/fat/fatent.c -++++ b/fs/fat/fatent.c -+@@ -380,6 +380,9 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs, -+ int err, n, copy; -+ -+ err = 0; -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++ return 0; -++#endif -+ for (copy = 1; copy < sbi->fats; copy++) { -+ sector_t backup_fat = sbi->fat_length * copy; -+ -+@@ -389,11 +392,15 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs, -+ err = -ENOMEM; -+ goto error; -+ } -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ /* Avoid race with userspace read via bdev */ -+ lock_buffer(c_bh); -++#endif -+ memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize); -+ set_buffer_uptodate(c_bh); -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ unlock_buffer(c_bh); -++#endif -+ mark_buffer_dirty_inode(c_bh, sbi->fat_inode); -+ if (sb->s_flags & SB_SYNCHRONOUS) -+ err = sync_dirty_buffer(c_bh); -+diff --git a/fs/fat/file.c b/fs/fat/file.c -+index f9ee27cf4..cc0a6109f 100644 -+--- a/fs/fat/file.c -++++ b/fs/fat/file.c -+@@ -197,8 +197,17 @@ int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync) -+ -+ return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL); -+ } -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++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, -+@@ -211,6 +220,9 @@ const struct file_operations fat_file_operations = { -+ .splice_read = generic_file_splice_read, -+ .splice_write = iter_file_splice_write, -+ .fallocate = fat_fallocate, -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++ .flush = fat_file_flush, -++#endif -+ }; -+ -+ static int fat_cont_expand(struct inode *inode, loff_t size) -+@@ -461,7 +473,13 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) -+ /* use a default check */ -+ return 0; -+ } -+- -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++void reset_mmu_private(struct inode *inode, loff_t offset) -++{ -++ MSDOS_I(inode)->mmu_private = offset; -++ inode->i_ctime = inode->i_mtime = ((struct timespec64) { get_seconds(), 0 }); -++} -++#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) -+@@ -494,6 +512,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) -+ * hole before it. XXX: this is no longer true with new truncate -+ * sequence. -+ */ -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ if (attr->ia_valid & ATTR_SIZE) { -+ inode_dio_wait(inode); -+ -+@@ -504,7 +523,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) -+ 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) && -+@@ -534,6 +553,9 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) -+ goto out; -+ down_write(&MSDOS_I(inode)->truncate_lock); -+ truncate_setsize(inode, attr->ia_size); -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++ reset_mmu_private(inode, attr->ia_size); -++#endif -+ fat_truncate_blocks(inode, attr->ia_size); -+ up_write(&MSDOS_I(inode)->truncate_lock); -+ } -+diff --git a/fs/fat/inode.c b/fs/fat/inode.c -+index bab9b202b..0d26d9d77 100644 -+--- a/fs/fat/inode.c -++++ b/fs/fat/inode.c -+@@ -628,8 +628,9 @@ static void fat_free_eofblocks(struct inode *inode) -+ round_up(MSDOS_I(inode)->mmu_private, -+ MSDOS_SB(inode->i_sb)->cluster_size)) { -+ int err; -+- -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -+ 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 -+@@ -899,7 +900,70 @@ static int __fat_write_inode(struct inode *inode, int wait) -+ brelse(bh); -+ return err; -+ } -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++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; -++ } -+ -++ raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset]; -++ if (S_ISDIR(inode->i_mode)) { -++ raw_entry->size = 0; -++ } else { -++ if ((raw_entry->start != 0) || (raw_entry->starthi != 0)) { -++ 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; -+@@ -910,8 +974,17 @@ static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) -+ 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 { -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++ if (NULL == wbc) { -++ err = __fat_write_inode(inode, 1); -++ } else { -++ err = __fat_write_inode_(inode, wbc->sync_mode == WB_SYNC_ALL); -++ } -++#else -++ err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); -++#endif -++ } -+ -+ return err; -+ } -+diff --git a/fs/fat/misc.c b/fs/fat/misc.c -+index f1b2a1fc2..cce962962 100644 -+--- a/fs/fat/misc.c -++++ b/fs/fat/misc.c -+@@ -266,6 +266,34 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, -+ *time_cs = (ts->tv_sec & 1) * 100 + ts->tv_nsec / 10000000; -+ } -+ EXPORT_SYMBOL_GPL(fat_time_unix2fat); -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++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); -++ ktime_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) -++ d_createtime[5] += (time_cs / 100); /*second 1s*/ -++} -++EXPORT_SYMBOL_GPL(fat_time_fat2str); -++#endif -+ -+ static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts) -+ { -+diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c -+index f51b23968..b7f9023ae 100644 -+--- a/fs/sysfs/file.c -++++ b/fs/sysfs/file.c -+@@ -252,6 +252,13 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, -+ struct kernfs_node *kn; -+ loff_t size; -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_SYSFS_MINI_OPT -++ struct kobject *obj = parent->priv; -++ if (obj != NULL && obj->sysfs_file_suppress) -++ return 0; -++#endif -++#endif -+ if (!is_bin) { -+ struct kobject *kobj = parent->priv; -+ const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops; -+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h -+index 8716609fb..5150bf0e3 100644 -+--- a/include/asm-generic/vmlinux.lds.h -++++ b/include/asm-generic/vmlinux.lds.h -+@@ -961,6 +961,13 @@ -+ INIT_CALLS_LEVEL(7) \ -+ __initcall_end = .; -+ -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_STARTUP_PARALLEL_OPT)) -++#define ANNOTATED_INITCALLS \ -++ . = ALIGN(32); \ -++ __annotated_initcall_start = .; \ -++ KEEP(*(.annotated_initcall.init)) \ -++ __annotated_initcall_end = .; -++#endif -+ #define CON_INITCALL \ -+ __con_initcall_start = .; \ -+ KEEP(*(.con_initcall.init)) \ -+@@ -1167,14 +1174,26 @@ -+ _einittext = .; \ -+ } -+ -++#if defined(CONFIG_ARCH_BSP) && defined(CONFIG_STARTUP_PARALLEL_OPT) -+ #define INIT_DATA_SECTION(initsetup_align) \ -+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { \ -+ INIT_DATA \ -+ INIT_SETUP(initsetup_align) \ -+ INIT_CALLS \ -++ ANNOTATED_INITCALLS \ -+ CON_INITCALL \ -+ INIT_RAM_FS \ -+ } -++#else -++#define INIT_DATA_SECTION(initsetup_align) \ -++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { \ -++ INIT_DATA \ -++ INIT_SETUP(initsetup_align) \ -++ INIT_CALLS \ -++ CON_INITCALL \ -++ INIT_RAM_FS \ -++ } -++#endif -+ -+ #define BSS_SECTION(sbss_align, bss_align, stop_align) \ -+ . = ALIGN(sbss_align); \ -+diff --git a/include/dt-bindings/clock/basedrv-clock.h b/include/dt-bindings/clock/basedrv-clock.h -+new file mode 100755 -+index 000000000..c9c265717 -+--- /dev/null -++++ b/include/dt-bindings/clock/basedrv-clock.h -+@@ -0,0 +1,17 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __DT_BINDINGS_UPS_CLOCK_H -++#define __DT_BINDINGS_UPS_CLOCK_H -++ -++#define PERI_CRG3664_USB30_CTRL0 0x0000 -++#define PERI_CRG3672_USB30_CTRL1 0x0004 -++#define PERI_CRG3632_USB2_PHY0 0x0008 -++#define PERI_CRG3640_USB2_PHY1 0x000C -++#define PERI_CRG3665_COMBPHY0_CLK 0x0010 -++#define PERI_CRG3673_COMBPHY1_CLK 0x0014 -++ -++#define CLK_MAX 0x0800 -++ -++#endif /* __DT_BINDINGS_UPS_CLOCK_H */ -+diff --git a/include/dt-bindings/clock/hi3516cv610-clock.h b/include/dt-bindings/clock/hi3516cv610-clock.h -+new file mode 100755 -+index 000000000..e0ed754ce -+--- /dev/null -++++ b/include/dt-bindings/clock/hi3516cv610-clock.h -+@@ -0,0 +1,132 @@ -++/* -++ * Copyright (c) 2016-2017 HiSilicon 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 . -++ * -++ */ -++ -++#ifndef __DTS_HI3516CV610_CLOCK_H -++#define __DTS_HI3516CV610_CLOCK_H -++ -++/* clk in HI3516CV610 CRG */ -++#define HI3516CV610_FIXED_2400M 1 -++#define HI3516CV610_FIXED_1200M 2 -++#define HI3516CV610_FIXED_1188M 3 -++#define HI3516CV610_FIXED_896M 4 -++#define HI3516CV610_FIXED_800M 5 -++#define HI3516CV610_FIXED_792M 6 -++#define HI3516CV610_FIXED_786M 7 -++#define HI3516CV610_FIXED_750M 8 -++#define HI3516CV610_FIXED_700M 9 -++#define HI3516CV610_FIXED_672M 10 -++#define HI3516CV610_FIXED_600M 11 -++#define HI3516CV610_FIXED_594M 12 -++#define HI3516CV610_FIXED_560M 13 -++#define HI3516CV610_FIXED_500M 14 -++#define HI3516CV610_FIXED_475M 15 -++#define HI3516CV610_FIXED_396M 16 -++#define HI3516CV610_FIXED_300M 17 -++#define HI3516CV610_FIXED_297M 18 -++#define HI3516CV610_FIXED_257M 19 -++#define HI3516CV610_FIXED_250M 20 -++#define HI3516CV610_FIXED_200M 21 -++#define HI3516CV610_FIXED_198M 22 -++#define HI3516CV610_FIXED_187P_5M 23 -++#define HI3516CV610_FIXED_150M 24 -++#define HI3516CV610_FIXED_148P_5M 25 -++#define HI3516CV610_FIXED_134M 26 -++#define HI3516CV610_FIXED_108M 27 -++#define HI3516CV610_FIXED_100M 28 -++#define HI3516CV610_FIXED_99M 29 -++#define HI3516CV610_FIXED_74P_25M 30 -++#define HI3516CV610_FIXED_72M 31 -++#define HI3516CV610_FIXED_64M 32 -++#define HI3516CV610_FIXED_60M 33 -++#define HI3516CV610_FIXED_54M 34 -++#define HI3516CV610_FIXED_50M 35 -++#define HI3516CV610_FIXED_49P_5M 36 -++#define HI3516CV610_FIXED_37P_125M 37 -++#define HI3516CV610_FIXED_36M 38 -++#define HI3516CV610_FIXED_27M 39 -++#define HI3516CV610_FIXED_25M 40 -++#define HI3516CV610_FIXED_24M 41 -++#define HI3516CV610_FIXED_12M 42 -++#define HI3516CV610_FIXED_12P_288M 43 -++#define HI3516CV610_FIXED_6M 44 -++#define HI3516CV610_FIXED_3M 45 -++#define HI3516CV610_FIXED_1P_6M 46 -++#define HI3516CV610_FIXED_1M 146 -++#define HI3516CV610_FIXED_400K 47 -++#define HI3516CV610_FIXED_100K 48 -++#define HI3516CV610_FIXED_237P_5M 49 -++#define HI3516CV610_FIXED_264M 50 -++ -++/* mux clocks */ -++#define HI3516CV610_FMC_MUX 51 -++#define HI3516CV610_UART0_MUX 52 -++#define HI3516CV610_UART1_MUX 53 -++#define HI3516CV610_UART2_MUX 54 -++#define HI3516CV610_I2C0_MUX 55 -++#define HI3516CV610_I2C1_MUX 56 -++#define HI3516CV610_I2C2_MUX 57 -++#define HI3516CV610_MMC0_MUX 58 -++#define HI3516CV610_MMC1_MUX 59 -++#define HI3516CV610_MMC2_MUX 60 -++#define HI3516CV610_ETH_MUX 61 -++#define HI3516CV610_USB2_MUX 62 -++ -++/* gate clocks */ -++#define HI3516CV610_UART0_CLK 63 -++#define HI3516CV610_UART1_CLK 64 -++#define HI3516CV610_UART2_CLK 65 -++#define HI3516CV610_FMC_CLK 66 -++#define HI3516CV610_ETH0_CLK 67 -++#define HI3516CV610_EDMAC_AXICLK 68 -++#define HI3516CV610_EDMAC_APBCLK 69 -++#define HI3516CV610_SPI0_CLK 70 -++#define HI3516CV610_SPI1_CLK 71 -++#define HI3516CV610_MMC0_CLK 72 -++#define HI3516CV610_MMC1_CLK 73 -++#define HI3516CV610_MMC2_CLK 74 -++#define HI3516CV610_I2C0_CLK 75 -++#define HI3516CV610_I2C1_CLK 76 -++#define HI3516CV610_I2C2_CLK 77 -++#define HI3516CV610_USB2_BUS_CLK 78 -++#define HI3516CV610_USB2_REF_CLK 79 -++#define HI3516CV610_USB2_UTMI_CLK 80 -++#define HI3516CV610_USB2_PHY_APB_CLK 81 -++#define HI3516CV610_USB2_PHY_PLL_CLK 82 -++#define HI3516CV610_USB2_PHY_XO_CLK 83 -++#define HI3516CV610_MMC0_HCLK 84 -++#define HI3516CV610_MMC1_HCLK 85 -++#define HI3516CV610_FEPHY_CLK 86 -++#define HI3516CV610_GPIO0_CLK 87 -++#define HI3516CV610_GPIO1_CLK 88 -++#define HI3516CV610_GPIO2_CLK 89 -++#define HI3516CV610_GPIO3_CLK 90 -++#define HI3516CV610_GPIO4_CLK 91 -++#define HI3516CV610_GPIO5_CLK 92 -++#define HI3516CV610_GPIO6_CLK 93 -++#define HI3516CV610_GPIO7_CLK 94 -++#define HI3516CV610_GPIO8_CLK 95 -++#define HI3516CV610_GPIO9_CLK 96 -++#define HI3516CV610_GPIO10_CLK 97 -++#define HI3516CV610_SYSAXI_CLK 98 -++#define HI3516CV610_SYSAPB_CLK 99 -++#define HI3516CV610_PWM1_CLK 100 -++#define HI3516CV610_PWM1_MUX 101 -++ -++#define HI3516CV610_NR_CLKS 128 -++ -++#endif -+diff --git a/include/dt-bindings/clock/hi3519dv500_clock.h b/include/dt-bindings/clock/hi3519dv500_clock.h -+new file mode 100755 -+index 000000000..2a669f57d -+--- /dev/null -++++ b/include/dt-bindings/clock/hi3519dv500_clock.h -+@@ -0,0 +1,143 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __DTS_HI3519DV500_CLOCK_H -++#define __DTS_HI3519DV500_CLOCK_H -++ -++/* fixed rate */ -++#define HI3519DV500_FIXED_2400M 1 -++#define HI3519DV500_FIXED_1200M 2 -++#define HI3519DV500_FIXED_1188M 3 -++#define HI3519DV500_FIXED_896M 4 -++#define HI3519DV500_FIXED_800M 5 -++#define HI3519DV500_FIXED_792M 6 -++#define HI3519DV500_FIXED_786M 7 -++#define HI3519DV500_FIXED_750M 8 -++#define HI3519DV500_FIXED_700M 9 -++#define HI3519DV500_FIXED_672M 10 -++#define HI3519DV500_FIXED_600M 11 -++#define HI3519DV500_FIXED_594M 12 -++#define HI3519DV500_FIXED_560M 13 -++#define HI3519DV500_FIXED_500M 14 -++#define HI3519DV500_FIXED_475M 15 -++#define HI3519DV500_FIXED_396M 16 -++#define HI3519DV500_FIXED_300M 17 -++#define HI3519DV500_FIXED_297M 18 -++#define HI3519DV500_FIXED_257M 19 -++#define HI3519DV500_FIXED_250M 20 -++#define HI3519DV500_FIXED_200M 21 -++#define HI3519DV500_FIXED_198M 22 -++#define HI3519DV500_FIXED_187P_5M 23 -++#define HI3519DV500_FIXED_150M 24 -++#define HI3519DV500_FIXED_148P_5M 25 -++#define HI3519DV500_FIXED_134M 26 -++#define HI3519DV500_FIXED_108M 27 -++#define HI3519DV500_FIXED_100M 28 -++#define HI3519DV500_FIXED_99M 29 -++#define HI3519DV500_FIXED_74P_25M 30 -++#define HI3519DV500_FIXED_72M 31 -++#define HI3519DV500_FIXED_64M 32 -++#define HI3519DV500_FIXED_60M 33 -++#define HI3519DV500_FIXED_54M 34 -++#define HI3519DV500_FIXED_50M 35 -++#define HI3519DV500_FIXED_49P_5M 36 -++#define HI3519DV500_FIXED_37P_125M 37 -++#define HI3519DV500_FIXED_36M 38 -++#define HI3519DV500_FIXED_27M 39 -++#define HI3519DV500_FIXED_25M 40 -++#define HI3519DV500_FIXED_24M 41 -++#define HI3519DV500_FIXED_12M 42 -++#define HI3519DV500_FIXED_12P_288M 43 -++#define HI3519DV500_FIXED_6M 44 -++#define HI3519DV500_FIXED_3M 45 -++#define HI3519DV500_FIXED_1P_6M 46 -++#define HI3519DV500_FIXED_400K 47 -++#define HI3519DV500_FIXED_100K 48 -++ -++#define HI3519DV500_I2C0_CLK 50 -++#define HI3519DV500_I2C1_CLK 51 -++#define HI3519DV500_I2C2_CLK 52 -++#define HI3519DV500_I2C3_CLK 53 -++#define HI3519DV500_I2C4_CLK 54 -++#define HI3519DV500_I2C5_CLK 55 -++#define HI3519DV500_I2C6_CLK 56 -++#define HI3519DV500_I2C7_CLK 57 -++ -++#define HI3519DV500_SPI0_CLK 62 -++#define HI3519DV500_SPI1_CLK 63 -++#define HI3519DV500_SPI2_CLK 64 -++#define HI3519DV500_SPI3_CLK 65 -++ -++#define HI3519DV500_EDMAC_CLK 69 -++#define HI3519DV500_EDMAC_AXICLK 70 -++ -++/* mux clocks */ -++#define HI3519DV500_I2C0_MUX 72 -++#define HI3519DV500_I2C1_MUX 73 -++#define HI3519DV500_I2C2_MUX 74 -++#define HI3519DV500_I2C3_MUX 75 -++#define HI3519DV500_I2C4_MUX 76 -++#define HI3519DV500_I2C5_MUX 77 -++#define HI3519DV500_I2C6_MUX 78 -++#define HI3519DV500_I2C7_MUX 79 -++ -++#define HI3519DV500_FMC_MUX 80 -++#define HI3519DV500_HPAXI_MUX 81 -++#define HI3519DV500_DDRAXI_MUX 82 -++#define HI3519DV500_MMC0_MUX 83 -++#define HI3519DV500_UART0_MUX 84 -++#define HI3519DV500_UART1_MUX 85 -++#define HI3519DV500_UART2_MUX 86 -++#define HI3519DV500_UART3_MUX 87 -++#define HI3519DV500_UART4_MUX 88 -++#define HI3519DV500_UART5_MUX 89 -++ -++/* gate clocks */ -++#define HI3519DV500_FMC_CLK 90 -++#define HI3519DV500_UART0_CLK 91 -++#define HI3519DV500_UART1_CLK 92 -++#define HI3519DV500_UART2_CLK 93 -++#define HI3519DV500_UART3_CLK 94 -++#define HI3519DV500_UART4_CLK 95 -++#define HI3519DV500_UART5_CLK 96 -++#define HI3519DV500_MMC0_CLK 97 -++#define HI3519DV500_MMC0_HCLK 98 -++#define HI3519DV500_MMC1_CLK 99 -++#define HI3519DV500_MMC1_HCLK 100 -++#define HI3519DV500_MMC2_CLK 101 -++#define HI3519DV500_MMC2_HCLK 102 -++ -++#define HI3519DV500_ETH_CLK 103 -++#define HI3519DV500_ETH_MACIF_CLK 104 -++#define HI3519DV500_ETH1_CLK 105 -++#define HI3519DV500_ETH1_MACIF_CLK 106 -++ -++/* complex */ -++#define HI3519DV500_MAC0_CLK 110 -++#define HI3519DV500_MAC1_CLK 111 -++#define HI3519DV500_SATA_CLK 112 -++#define HI3519DV500_USB_CLK 113 -++#define HI3519DV500_USB1_CLK 114 -++ -++#define HI3519DV500_MMC1_MUX 115 -++#define HI3519DV500_MMC2_MUX 116 -++ -++/* lsadc clocks */ -++#define HI3519DV500_LSADC_CLK 120 -++ -++#define HI3519DV500_PWM0_MUX 121 -++#define HI3519DV500_PWM1_MUX 122 -++#define HI3519DV500_PWM2_MUX 123 -++ -++#define HI3519DV500_PWM0_CLK 124 -++#define HI3519DV500_PWM1_CLK 125 -++#define HI3519DV500_PWM2_CLK 126 -++ -++/* pll clocks */ -++#define HI3519DV500_APLL_CLK 250 -++ -++#define HI3519DV500_CRG_NR_CLKS 256 -++ -++#endif /* __DTS_HI3519DV500_CLOCK_H */ -++ -+diff --git a/include/linux/annotated_initcalls.h b/include/linux/annotated_initcalls.h -+new file mode 100755 -+index 000000000..4ac2580ca -+--- /dev/null -++++ b/include/linux/annotated_initcalls.h -+@@ -0,0 +1,112 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. -++ */ -++#ifndef _LINUX_ANNOTATED_H -++#define _LINUX_ANNOTATED_H -++#include -++typedef int (*threadfn)(void *); -++ -++struct device_driver; -++ -++struct _annotated_initcall { -++ const initcall_t initcall; -++ const unsigned id; /* from driver_ids.h */ -++ const unsigned *dependencies; -++ const struct device_driver *driver; -++}; -++extern const struct _annotated_initcall __annotated_initcall_start[], -++ __annotated_initcall_end[]; -++ -++ -++extern initcall_entry_t __security_initcall_start[], __security_initcall_end[]; -++ -++static int const level3_dep[2] = {0}; -++static int const level4_dep[2] = {LEVEL3_START, 0}; -++static int const level5_dep[2] = {LEVEL4_START, 0}; -++static int const level6_dep[2] = {LEVEL5_START, 0}; -++static int const level7_dep[2] = {LEVEL6_START, 0}; -++ -++#define __define_annotated_initcall_dep_level(fn, _dep_level_, deps) \ -++ static struct _annotated_initcall __annotated_initcall_##fn __used \ -++ __attribute__((__section__(".annotated_initcall.init"))) = \ -++ { .initcall = (fn), .id = fn ## _drv_id, \ -++ .dependencies = level##_dep_level_##_dep}; -++ -++#define __define_annotated_initcall(fn, __id, deps) \ -++ static struct _annotated_initcall __annotated_initcall_##fn __used \ -++ __attribute__((__section__(".annotated_initcall.init"))) = \ -++ { .initcall = (fn), .id = (__id), .dependencies = (deps), \ -++ .driver = NULL } -++ -++#define __define_annotated_initcall_drv(fn, __id, deps, drv) \ -++ static struct _annotated_initcall __annotated_initcall_##fn __used \ -++ __attribute__((__section__(".annotated_initcall.init"))) = \ -++ { .initcall = (fn), .id = (__id), .dependencies = (deps), \ -++ .driver = &(drv) } -++ -++extern bool overflow_enabled; -++ -++void __init load_default_modules(void); -++ -++/* Defined in init/dependencies.c */ -++void __init do_annotated_initcalls(void); -++ -++/* id_dependency will be initialized before id */ -++int __init add_initcall_dependency(unsigned id, unsigned id_dependency); -++ -++extern struct async_domain populate_rootfs_domain; -++ -++/* -++ * Annotated initcalls are accompanied by a struct device_driver. -++ * This makes initcalls identifiable and is used to order initcalls. -++ * -++ * If disabled, nothing is changed and the classic level based -++ * initialization sequence is in use. -++ */ -++#ifdef CONFIG_BSP_FAST_STARTUP -++#define annotated_module_init(fn, id, deps) \ -++ __define_annotated_initcall(fn, id, deps) -++#define annotated_module_init_drv(fn, id, deps, drv) \ -++ __define_annotated_initcall_drv(fn, id, deps, drv) -++#define annotated_initcall(level, fn, id, deps) \ -++ __define_annotated_initcall(fn, id, deps) -++#define annotated_initcall_sync(level, fn, id, deps) \ -++ __define_annotated_initcall(fn, id, deps) -++#define annotated_initcall_drv(level, fn, id, deps, drv) \ -++ __define_annotated_initcall_drv(fn, id, deps, drv) -++#define annotated_initcall_drv_sync(level, fn, id, deps, drv) \ -++ __define_annotated_initcall_drv(fn, id, deps, drv) -++#else -++#define annotated_module_init(fn, id, deps) module_init(fn) -++#define annotated_module_init_drv(fn, id, deps, drv) module_init(fn) -++#define annotated_initcall(level, fn, id, deps) level ## _initcall(fn) -++#define annotated_initcall_sync(level, fn, id, deps) \ -++ level ## _initcall_sync(fn) -++#define annotated_initcall_drv(level, fn, id, deps, drv) \ -++ level ## _initcall(fn) -++#define annotated_initcall_drv_sync(level, fn, id, deps, drv) \ -++ level ## _initcall_sync(fn) -++#endif -++ -++ -++#ifdef CONFIG_BSP_FAST_STARTUP -++#define pure_initcall(fn) __define_initcall(fn, 0) -++#define core_initcall(fn) __define_initcall(fn, 1) -++#define core_initcall_sync(fn) __define_initcall(fn, 1s) -++#define postcore_initcall(fn) __define_initcall(fn, 2) -++#define postcore_initcall_sync(fn) __define_initcall(fn, 2s) -++ -++// start annotated -++#define arch_initcall(fn) __define_annotated_initcall_dep_level(fn, 3, level3_dep) -++#define arch_initcall_sync(fn) __define_annotated_initcall_dep_level(fn, 3, level3_dep) -++#define subsys_initcall(fn) __define_annotated_initcall_dep_level(fn, 4, level4_dep) -++#define subsys_initcall_sync(fn) __define_annotated_initcall_dep_level(fn, 4, level4_dep) -++#define fs_initcall(fn) __define_annotated_initcall_dep_level(fn, 5, level5_dep) -++#define fs_initcall_sync(fn) __define_annotated_initcall_dep_level(fn, 5, level5_dep) -++#define rootfs_initcall(fn) __define_annotated_initcall_dep_level(fn, 5, level5_dep) -++#define device_initcall(fn) __define_annotated_initcall_dep_level(fn, 6, level6_dep) -++#define device_initcall_sync(fn) __define_annotated_initcall_dep_level(fn, 6, level6_dep) -++#define late_initcall(fn) __define_annotated_initcall_dep_level(fn, 7, level7_dep) -++#define late_initcall_sync(fn) __define_annotated_initcall_dep_level(fn, 7, level7_dep) -++#endif -++#endif /* _LINUX_ANNOTATED_H */ -+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -+index 50b4fd0a0..513fc0874 100644 -+--- a/include/linux/blkdev.h -++++ b/include/linux/blkdev.h -+@@ -1401,7 +1401,11 @@ static inline bool bdev_is_partition(struct block_device *bdev) -+ enum blk_default_limits { -+ BLK_MAX_SEGMENTS = 128, -+ BLK_SAFE_MAX_SECTORS = 255, -++#ifndef CONFIG_BSP_MC -+ BLK_DEF_MAX_SECTORS = 2560, -++#else -++ BLK_DEF_MAX_SECTORS = 8192, -++#endif -+ BLK_MAX_SEGMENT_SIZE = 65536, -+ BLK_SEG_BOUNDARY_MASK = 0xFFFFFFFFUL, -+ }; -+diff --git a/include/linux/bsp_cma.h b/include/linux/bsp_cma.h -+new file mode 100755 -+index 000000000..ca0937956 -+--- /dev/null -++++ b/include/linux/bsp_cma.h -+@@ -0,0 +1,41 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#ifndef __BSP_CMA_H__ -++#define __BSP_CMA_H__ -++ -++#ifdef CONFIG_ARCH_BSP -++#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 get_zones_start(void); -++struct cma_zone *get_cma_zone(const char *name); -++struct device *get_cma_device(const char *name); -++int __init declare_heap_memory(void); -++#endif /* CONFIG_CMA */ -++#endif /* CONFIG_ARCH_BSP */ -++ -++#endif -+diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h -+new file mode 100755 -+index 000000000..a63c3f65f -+--- /dev/null -++++ b/include/linux/dma-debug.h -+@@ -0,0 +1,209 @@ -++/* -++ * Copyright (C) 2008 Advanced Micro Devices, Inc. -++ * -++ * Author: Joerg Roedel -++ * -++ * 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, write to the Free Software -++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -++ */ -++ -++#ifndef __DMA_DEBUG_H -++#define __DMA_DEBUG_H -++ -++#ifdef CONFIG_ARCH_BSP -++#include -++ -++struct device; -++struct scatterlist; -++struct bus_type; -++ -++#ifdef CONFIG_DMA_API_DEBUG -++ -++extern void dma_debug_add_bus(struct bus_type *bus); -++ -++extern int dma_debug_resize_entries(u32 num_entries); -++ -++extern void debug_dma_map_page(struct device *dev, struct page *page, -++ size_t offset, size_t size, -++ int direction, dma_addr_t dma_addr, -++ bool map_single); -++ -++extern void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr); -++ -++extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, -++ size_t size, int direction, bool map_single); -++ -++extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, -++ int nents, int mapped_ents, int direction); -++ -++extern void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, -++ int nelems, int dir); -++ -++extern void debug_dma_alloc_coherent(struct device *dev, size_t size, -++ dma_addr_t dma_addr, void *virt); -++ -++extern void debug_dma_free_coherent(struct device *dev, size_t size, -++ void *virt, dma_addr_t addr); -++ -++extern void debug_dma_map_resource(struct device *dev, phys_addr_t addr, -++ size_t size, int direction, -++ dma_addr_t dma_addr); -++ -++extern void debug_dma_unmap_resource(struct device *dev, dma_addr_t dma_addr, -++ size_t size, int direction); -++ -++extern void debug_dma_sync_single_for_cpu(struct device *dev, -++ dma_addr_t dma_handle, size_t size, -++ int direction); -++ -++extern void debug_dma_sync_single_for_device(struct device *dev, -++ dma_addr_t dma_handle, -++ size_t size, int direction); -++ -++extern void debug_dma_sync_single_range_for_cpu(struct device *dev, -++ dma_addr_t dma_handle, -++ unsigned long offset, -++ size_t size, -++ int direction); -++ -++extern void debug_dma_sync_single_range_for_device(struct device *dev, -++ dma_addr_t dma_handle, -++ unsigned long offset, -++ size_t size, int direction); -++ -++extern void debug_dma_sync_sg_for_cpu(struct device *dev, -++ struct scatterlist *sg, -++ int nelems, int direction); -++ -++extern void debug_dma_sync_sg_for_device(struct device *dev, -++ struct scatterlist *sg, -++ int nelems, int direction); -++ -++extern void debug_dma_dump_mappings(struct device *dev); -++ -++extern void debug_dma_assert_idle(struct page *page); -++ -++#else /* CONFIG_DMA_API_DEBUG */ -++ -++static inline void dma_debug_add_bus(struct bus_type *bus) -++{ -++} -++ -++static inline int dma_debug_resize_entries(u32 num_entries) -++{ -++ return 0; -++} -++ -++static inline void debug_dma_map_page(struct device *dev, struct page *page, -++ size_t offset, size_t size, -++ int direction, dma_addr_t dma_addr, -++ bool map_single) -++{ -++} -++ -++static inline void debug_dma_mapping_error(struct device *dev, -++ dma_addr_t dma_addr) -++{ -++} -++ -++static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, -++ size_t size, int direction, -++ bool map_single) -++{ -++} -++ -++static inline void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, -++ int nents, int mapped_ents, int direction) -++{ -++} -++ -++static inline void debug_dma_unmap_sg(struct device *dev, -++ struct scatterlist *sglist, -++ int nelems, int dir) -++{ -++} -++ -++static inline void debug_dma_alloc_coherent(struct device *dev, size_t size, -++ dma_addr_t dma_addr, void *virt) -++{ -++} -++ -++static inline void debug_dma_free_coherent(struct device *dev, size_t size, -++ void *virt, dma_addr_t addr) -++{ -++} -++ -++static inline void debug_dma_map_resource(struct device *dev, phys_addr_t addr, -++ size_t size, int direction, -++ dma_addr_t dma_addr) -++{ -++} -++ -++static inline void debug_dma_unmap_resource(struct device *dev, -++ dma_addr_t dma_addr, size_t size, -++ int direction) -++{ -++} -++ -++static inline void debug_dma_sync_single_for_cpu(struct device *dev, -++ dma_addr_t dma_handle, -++ size_t size, int direction) -++{ -++} -++ -++static inline void debug_dma_sync_single_for_device(struct device *dev, -++ dma_addr_t dma_handle, -++ size_t size, int direction) -++{ -++} -++ -++static inline void debug_dma_sync_single_range_for_cpu(struct device *dev, -++ dma_addr_t dma_handle, -++ unsigned long offset, -++ size_t size, -++ int direction) -++{ -++} -++ -++static inline void debug_dma_sync_single_range_for_device(struct device *dev, -++ dma_addr_t dma_handle, -++ unsigned long offset, -++ size_t size, -++ int direction) -++{ -++} -++ -++static inline void debug_dma_sync_sg_for_cpu(struct device *dev, -++ struct scatterlist *sg, -++ int nelems, int direction) -++{ -++} -++ -++static inline void debug_dma_sync_sg_for_device(struct device *dev, -++ struct scatterlist *sg, -++ int nelems, int direction) -++{ -++} -++ -++static inline void debug_dma_dump_mappings(struct device *dev) -++{ -++} -++ -++static inline void debug_dma_assert_idle(struct page *page) -++{ -++} -++ -++#endif /* CONFIG_DMA_API_DEBUG */ -++#endif /* CONFIG_ARCH_BSP */ -++ -++#endif /* __DMA_DEBUG_H */ -+diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h -+new file mode 100755 -+index 000000000..5463e7812 -+--- /dev/null -++++ b/include/linux/dma_remapping.h -+@@ -0,0 +1,59 @@ -++/* SPDX-License-Identifier: GPL-2.0 */ -++#ifndef _DMA_REMAPPING_H -++#define _DMA_REMAPPING_H -++ -++#ifdef CONFIG_ARCH_BSP -++/* -++ * VT-d hardware uses 4KiB page size regardless of host page size. -++ */ -++#define VTD_PAGE_SHIFT (12) -++#define VTD_PAGE_SIZE (1UL << VTD_PAGE_SHIFT) -++#define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) -++#define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) -++ -++#define VTD_STRIDE_SHIFT (9) -++#define VTD_STRIDE_MASK (((u64)-1) << VTD_STRIDE_SHIFT) -++ -++#define DMA_PTE_READ (1) -++#define DMA_PTE_WRITE (2) -++#define DMA_PTE_LARGE_PAGE (1 << 7) -++#define DMA_PTE_SNP (1 << 11) -++ -++#define CONTEXT_TT_MULTI_LEVEL 0 -++#define CONTEXT_TT_DEV_IOTLB 1 -++#define CONTEXT_TT_PASS_THROUGH 2 -++/* Extended context entry types */ -++#define CONTEXT_TT_PT_PASID 4 -++#define CONTEXT_TT_PT_PASID_DEV_IOTLB 5 -++#define CONTEXT_TT_MASK (7ULL << 2) -++ -++#define CONTEXT_DINVE (1ULL << 8) -++#define CONTEXT_PRS (1ULL << 9) -++#define CONTEXT_PASIDE (1ULL << 11) -++ -++struct intel_iommu; -++struct dmar_domain; -++struct root_entry; -++ -++ -++#ifdef CONFIG_INTEL_IOMMU -++extern int iommu_calculate_agaw(struct intel_iommu *iommu); -++extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu); -++extern int dmar_disabled; -++extern int intel_iommu_enabled; -++extern int intel_iommu_tboot_noforce; -++#else -++static inline int iommu_calculate_agaw(struct intel_iommu *iommu) -++{ -++ return 0; -++} -++static inline int iommu_calculate_max_sagaw(struct intel_iommu *iommu) -++{ -++ return 0; -++} -++#define dmar_disabled (1) -++#define intel_iommu_enabled (0) -++#endif -++#endif /* CONFIG_ARCH_BSP */ -++ -++#endif -+diff --git a/include/linux/driver_ids.h b/include/linux/driver_ids.h -+new file mode 100755 -+index 000000000..f83dae94d -+--- /dev/null -++++ b/include/linux/driver_ids.h -+@@ -0,0 +1,451 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. -++ */ -++#ifndef _LINUX_DRIVER_IDS_H -++#define _LINUX_DRIVER_IDS_H -++ -++initcall_id(cpu_suspend_init) -++initcall_id(asids_init) -++initcall_id(spawn_ksoftirqd) -++initcall_id(migration_init) -++initcall_id(srcu_bootup_announce) -++initcall_id(rcu_spawn_core_kthreads) -++initcall_id(rcu_spawn_gp_kthread) -++initcall_id(check_cpu_stall_init) -++initcall_id(rcu_sysrq_init) -++initcall_id(cpu_stop_init) -++initcall_id(initialize_ptr_random) -++initcall_id(its_pmsi_init) -++initcall_id(its_pci_msi_init) -++initcall_id(dummy_timer_register) -++initcall_id(ipc_ns_init) -++initcall_id(init_mmap_min_addr) -++initcall_id(pci_realloc_setup_params) -++initcall_id(net_ns_init) -++initcall_id(fpsimd_init) -++initcall_id(tagged_addr_init) -++initcall_id(enable_mrs_emulation) -++initcall_id(map_entry_trampoline) -++initcall_id(alloc_frozen_cpus) -++initcall_id(cpu_hotplug_pm_sync_init) -++initcall_id(wq_sysfs_init) -++initcall_id(ksysfs_init) -++initcall_id(pm_init) -++initcall_id(rcu_set_runtime_mode) -++initcall_id(rcu_spawn_tasks_trace_kthread) -++initcall_id(dma_init_reserved_memory) -++initcall_id(init_jiffies_clocksource) -++initcall_id(futex_init) -++initcall_id(cpu_pm_init) -++initcall_id(init_zero_pfn) -++initcall_id(cma_init_reserved_areas) -++initcall_id(fsnotify_init) -++initcall_id(filelock_init) -++initcall_id(init_script_binfmt) -++initcall_id(init_elf_binfmt) -++initcall_id(init_compat_elf_binfmt) -++initcall_id(configfs_init) -++initcall_id(prandom_init_early) -++initcall_id(pinctrl_init) -++initcall_id(gpiolib_dev_init) -++initcall_id(hi3519dv500_crg_init) -++initcall_id(regulator_init) -++initcall_id(soc_bus_register) -++initcall_id(register_cpufreq_notifier) -++initcall_id(cpufreq_core_init) -++initcall_id(cpufreq_gov_performance_init) -++initcall_id(cpufreq_gov_powersave_init) -++initcall_id(cpufreq_gov_userspace_init) -++initcall_id(CPU_FREQ_GOV_ONDEMAND_init) -++initcall_id(CPU_FREQ_GOV_CONSERVATIVE_init) -++initcall_id(cpufreq_dt_platdev_init) -++initcall_id(sock_init) -++initcall_id(net_inuse_init) -++initcall_id(net_defaults_init) -++initcall_id(init_default_flow_dissectors) -++initcall_id(netlink_proto_init) -++initcall_id(genl_init) -++initcall_id(debug_monitors_init) -++initcall_id(irq_sysfs_init) -++initcall_id(dma_atomic_pool_init) -++initcall_id(bdi_class_init) -++initcall_id(mm_sysfs_init) -++initcall_id(init_per_zone_wmark_min) -++initcall_id(kobject_uevent_init) -++initcall_id(gpiolib_sysfs_init) -++initcall_id(pcibus_class_init) -++initcall_id(pci_driver_init) -++initcall_id(amba_init) -++initcall_id(tty_class_init) -++initcall_id(vtconsole_class_init) -++initcall_id(devlink_class_init) -++initcall_id(software_node_init) -++initcall_id(wakeup_sources_debugfs_init) -++initcall_id(wakeup_sources_sysfs_init) -++initcall_id(regmap_initcall) -++initcall_id(syscon_init) -++initcall_id(spi_init) -++initcall_id(i2c_init) -++initcall_id(reserve_memblock_reserved_regions) -++initcall_id(aarch32_alloc_vdso_pages) -++initcall_id(vdso_init) -++initcall_id(asids_update_limit) -++initcall_id(cryptomgr_init) -++initcall_id(dma_channel_table_init) -++initcall_id(dma_bus_init) -++initcall_id(pl011_init) -++initcall_id(of_platform_default_populate_init) -++initcall_id(topology_init) -++initcall_id(uid_cache_init) -++initcall_id(param_sysfs_init) -++initcall_id(user_namespace_sysctl_init) -++initcall_id(iprec_proc_init) -++initcall_id(proc_schedstat_init) -++initcall_id(pm_sysrq_init) -++initcall_id(time_ns_init) -++initcall_id(hung_task_init) -++initcall_id(dev_map_init) -++initcall_id(cpu_map_init) -++initcall_id(netns_bpf_init) -++initcall_id(oom_init) -++initcall_id(default_bdi_init) -++initcall_id(percpu_enable_async) -++initcall_id(kcompactd_init) -++initcall_id(init_user_reserve) -++initcall_id(init_admin_reserve) -++initcall_id(init_reserve_notifier) -++initcall_id(ksm_init) -++initcall_id(io_wq_init) -++initcall_id(crypto_cmac_module_init) -++initcall_id(crypto_null_mod_init) -++initcall_id(sha256_generic_mod_init) -++initcall_id(crypto_ecb_module_init) -++initcall_id(aes_init) -++initcall_id(deflate_mod_init) -++initcall_id(crc32c_mod_init) -++initcall_id(lzo_mod_init) -++initcall_id(lzorle_mod_init) -++initcall_id(zstd_mod_init) -++initcall_id(init_bio) -++initcall_id(blk_settings_init) -++initcall_id(blk_ioc_init) -++initcall_id(blk_mq_init) -++initcall_id(genhd_device_init) -++initcall_id(pci_slot_init) -++initcall_id(fbmem_init) -++initcall_id(misc_init) -++initcall_id(vga_arb_device_init) -++initcall_id(register_cpu_capacity_sysctl) -++initcall_id(dma_buf_init) -++initcall_id(init_scsi) -++initcall_id(pl022_init) -++initcall_id(phy_init) -++initcall_id(usb_common_init) -++initcall_id(usb_init) -++initcall_id(usb_udc_init) -++initcall_id(serio_init) -++initcall_id(gameport_init) -++initcall_id(input_init) -++initcall_id(rtc_init) -++initcall_id(videodev_init) -++initcall_id(init_dvbdev) -++initcall_id(power_supply_class_init) -++initcall_id(mmc_init) -++initcall_id(devfreq_init) -++initcall_id(devfreq_simple_ondemand_init) -++initcall_id(nvmem_init) -++initcall_id(init_soundcore) -++initcall_id(alsa_sound_init) -++initcall_id(proto_init) -++initcall_id(net_dev_init) -++initcall_id(neigh_init) -++initcall_id(fib_notifier_init) -++initcall_id(ethnl_init) -++initcall_id(nexthop_init) -++initcall_id(create_debug_debugfs_entry) -++initcall_id(clocksource_done_booting) -++initcall_id(bpf_init) -++initcall_id(init_pipe_fs) -++initcall_id(inotify_user_setup) -++initcall_id(eventpoll_init) -++initcall_id(anon_inode_init) -++initcall_id(proc_locks_init) -++initcall_id(iomap_init) -++initcall_id(dquot_init) -++initcall_id(proc_cmdline_init) -++initcall_id(proc_consoles_init) -++initcall_id(proc_cpuinfo_init) -++initcall_id(proc_devices_init) -++initcall_id(proc_interrupts_init) -++initcall_id(proc_loadavg_init) -++initcall_id(proc_meminfo_init) -++initcall_id(proc_stat_init) -++initcall_id(proc_uptime_init) -++initcall_id(proc_version_init) -++initcall_id(proc_softirqs_init) -++initcall_id(proc_kmsg_init) -++initcall_id(proc_page_init) -++initcall_id(init_ramfs_fs) -++initcall_id(blk_scsi_ioctl_init) -++initcall_id(chr_dev_init) -++initcall_id(firmware_class_init) -++initcall_id(sysctl_core_init) -++initcall_id(eth_offload_init) -++initcall_id(ipv4_offload_init) -++initcall_id(inet_init) -++initcall_id(af_unix_init) -++initcall_id(ipv6_offload_init) -++initcall_id(init_sunrpc) -++initcall_id(pci_apply_final_quirks) -++initcall_id(default_rootfs) -++initcall_id(register_arm64_panic_block) -++initcall_id(cpuinfo_regs_init) -++initcall_id(proc_execdomains_init) -++initcall_id(register_warn_debugfs) -++initcall_id(cpuhp_sysfs_init) -++initcall_id(ioresources_init) -++initcall_id(init_sched_debug_procfs) -++initcall_id(irq_pm_init_ops) -++initcall_id(timekeeping_init_ops) -++initcall_id(init_clocksource_sysfs) -++initcall_id(init_timer_list_procfs) -++initcall_id(alarmtimer_init) -++initcall_id(init_posix_timers) -++initcall_id(clockevents_init_sysfs) -++initcall_id(sched_clock_syscore_init) -++initcall_id(proc_modules_init) -++initcall_id(kallsyms_init) -++initcall_id(pid_namespaces_init) -++initcall_id(utsname_sysctl_init) -++initcall_id(kswapd_init) -++initcall_id(mm_compute_batch_init) -++initcall_id(slab_proc_init) -++initcall_id(workingset_init) -++initcall_id(proc_vmalloc_init) -++initcall_id(slab_sysfs_init) -++initcall_id(fcntl_init) -++initcall_id(proc_filesystems_init) -++initcall_id(start_dirtytime_writeback) -++initcall_id(blkdev_init) -++initcall_id(dio_init) -++initcall_id(dnotify_init) -++initcall_id(userfaultfd_init) -++initcall_id(aio_setup) -++initcall_id(io_uring_init) -++initcall_id(mbcache_init) -++initcall_id(init_grace) -++initcall_id(init_devpts_fs) -++initcall_id(ext4_init_fs) -++initcall_id(journal_init) -++initcall_id(init_cramfs_fs) -++initcall_id(init_squashfs_fs) -++initcall_id(init_fat_fs) -++initcall_id(init_vfat_fs) -++initcall_id(init_msdos_fs) -++initcall_id(init_iso9660_fs) -++initcall_id(init_nfs_fs) -++initcall_id(init_nfs_v2) -++initcall_id(init_nfs_v3) -++initcall_id(init_nlm) -++initcall_id(init_nls_cp437) -++initcall_id(init_nls_cp936) -++initcall_id(init_nls_ascii) -++initcall_id(init_nls_iso8859_1) -++initcall_id(init_nls_utf8) -++initcall_id(init_jffs2_fs) -++initcall_id(fuse_init) -++initcall_id(init_udf_fs) -++initcall_id(init_xfs_fs) -++initcall_id(ipc_init) -++initcall_id(ipc_sysctl_init) -++initcall_id(crypto_algapi_init) -++initcall_id(proc_genhd_init) -++initcall_id(bsg_init) -++initcall_id(deadline_init) -++initcall_id(kyber_init) -++initcall_id(libcrc32c_mod_init) -++initcall_id(percpu_counter_startup) -++initcall_id(sg_pool_init) -++initcall_id(phy_core_init) -++initcall_id(bsp_usb_phy_driver_init) -++initcall_id(pcs_driver_init) -++initcall_id(bgpio_driver_init) -++initcall_id(pl061_gpio_driver_init) -++initcall_id(pcie_portdrv_init) -++initcall_id(pci_proc_init) -++initcall_id(of_fixed_factor_clk_driver_init) -++initcall_id(of_fixed_clk_driver_init) -++initcall_id(gpio_clk_driver_init) -++initcall_id(n_null_init) -++initcall_id(pty_init) -++initcall_id(sysrq_init) -++initcall_id(topology_sysfs_init) -++initcall_id(cacheinfo_sysfs_init) -++initcall_id(brd_init) -++initcall_id(loop_init) -++initcall_id(bsp_fmc_driver_init) -++initcall_id(init_sd) -++initcall_id(init_mtd) -++initcall_id(cmdline_parser_init) -++initcall_id(ofpart_parser_init) -++initcall_id(init_mtdblock) -++initcall_id(spi_nor_driver_init) -++initcall_id(bsp_spi_nor_driver_init) -++initcall_id(bsp_spi_nand_driver_init) -++initcall_id(spidev_init) -++initcall_id(net_olddevs_init) -++initcall_id(blackhole_netdev_init) -++initcall_id(gemac_mdio_driver_init) -++initcall_id(fixed_mdio_bus_init) -++initcall_id(gmac_init) -++initcall_id(dwc3_driver_init) -++initcall_id(xhci_hcd_init) -++initcall_id(xhci_pci_init) -++initcall_id(xhci_plat_init) -++initcall_id(usb_storage_driver_init) -++initcall_id(gadget_cfs_init) -++initcall_id(acmmod_init) -++initcall_id(userial_init) -++initcall_id(rndismod_init) -++initcall_id(mass_storagemod_init) -++initcall_id(uac1mod_init) -++initcall_id(uvcmod_init) -++initcall_id(serport_init) -++initcall_id(mousedev_init) -++initcall_id(joydev_init) -++initcall_id(evdev_init) -++initcall_id(atkbd_init) -++initcall_id(psmouse_init) -++initcall_id(uinput_misc_init) -++initcall_id(bsp_rtc_driver_init) -++initcall_id(i2c_dev_init) -++initcall_id(bsp_i2c_driver_init) -++initcall_id(uvc_init) -++initcall_id(dt_cpufreq_platdrv_init) -++initcall_id(mmc_pwrseq_simple_driver_init) -++initcall_id(mmc_pwrseq_emmc_driver_init) -++initcall_id(mmc_blk_init) -++initcall_id(sdhci_drv_init) -++initcall_id(sdhci_pltfm_drv_init) -++initcall_id(sdhci_bsp_init) -++initcall_id(smccc_soc_init) -++initcall_id(hid_init) -++initcall_id(hid_generic_init) -++initcall_id(a4_driver_init) -++initcall_id(apple_driver_init) -++initcall_id(belkin_driver_init) -++initcall_id(ch_driver_init) -++initcall_id(ch_driver1_init) -++initcall_id(cp_driver_init) -++initcall_id(ez_driver_init) -++initcall_id(ks_driver_init) -++initcall_id(ms_driver_init) -++initcall_id(mr_driver_init) -++initcall_id(hid1_init) -++initcall_id(alsa_timer_init) -++initcall_id(alsa_pcm_init) -++initcall_id(sock_diag_init) -++initcall_id(gre_offload_init) -++initcall_id(sysctl_ipv4_init) -++initcall_id(inet_diag_init) -++initcall_id(tcp_diag_init) -++initcall_id(cubictcp_register) -++initcall_id(inet6_init) -++initcall_id(packet_init) -++initcall_id(init_oops_id) -++initcall_id(sched_init_debug) -++initcall_id(printk_late_init) -++initcall_id(init_srcu_module_notifier) -++initcall_id(bpf_map_iter_init) -++initcall_id(task_iter_init) -++initcall_id(bpf_prog_iter_init) -++initcall_id(check_early_ioremap_leak) -++initcall_id(ubifs_init) -++initcall_id(blk_timeout_init) -++initcall_id(prandom_init_late) -++initcall_id(pci_resource_alignment_sysfs_init) -++initcall_id(pci_sysfs_init) -++initcall_id(amba_deferred_retry) -++initcall_id(sync_state_resume_initcall) -++initcall_id(deferred_probe_initcall) -++initcall_id(block2mtd_init) -++initcall_id(ubi_init) -++initcall_id(of_fdt_raw_init) -++initcall_id(bpf_sk_storage_map_iter_init) -++initcall_id(tcp_congestion_default) -++initcall_id(init_amu_fie) -++initcall_id(clk_disable_unused) -++initcall_id(regulator_init_complete) -++initcall_id(of_platform_sync_state_init) -++initcall_id(alsa_sound_last_init) -++initcall_id(kernel_panic_sysctls_init) -++initcall_id(kernel_panic_sysfs_init) -++initcall_id(kernel_exit_sysctls_init) -++initcall_id(kernel_exit_sysfs_init) -++initcall_id(populate_rootfs) -++initcall_id(init_romfs_fs) -++initcall_id(mod_init) -++initcall_id(dpages_proc_init) -++initcall_id(usb_roles_init) -++initcall_id(extcon_class_init) -++initcall_id(ups_phy_module_init) -++initcall_id(wing_usb_module_init) -++initcall_id(edmacv310_init) -++initcall_id(sit_init) -++initcall_id(tunnel4_init) -++initcall_id(phy_module_init) -++initcall_id(ot_sysconfig_init) -++initcall_id(osal_module_init) -++initcall_id(mmz_init) -++initcall_id(base_mod_init) -++initcall_id(vb_mod_init) -++initcall_id(vca_mod_init) -++initcall_id(g_ot_sys_driver_init) -++initcall_id(rgn_mod_init) -++initcall_id(vpp_mod_init) -++initcall_id(g_ot_vgs_device_driver_init) -++initcall_id(dis_mod_init) -++initcall_id(g_ot_vi_driver_init) -++initcall_id(isp_mod_init) -++initcall_id(g_ot_vpss_driver_init) -++initcall_id(vo_dev_mod_init) -++initcall_id(g_ot_vo_driver_init) -++initcall_id(chnl_mod_init) -++initcall_id(rc_mod_init) -++initcall_id(venc_mod_init) -++initcall_id(venc_svr_mod_init) -++initcall_id(h264e_mod_init) -++initcall_id(h265e_mod_init) -++initcall_id(jpege_mod_init) -++initcall_id(g_ot_mipi_rx_driver_init) -++initcall_id(i2c_module_init) -++initcall_id(pm_mod_init) -++initcall_id(arm_pmu_hp_init) -++initcall_id(arch_hw_breakpoint_init) -++initcall_id(armv8_pmu_driver_init) -++initcall_id(stack_map_init) -++initcall_id(perf_event_sysfs_init) -++initcall_id(exceptions_init) -++initcall_id(alignment_init) -++initcall_id(gate_vma_init) -++initcall_id(customize_machine) -++initcall_id(init_machine_late) -++initcall_id(proc_cpu_init) -++initcall_id(register_kernel_offset_dumper) -++initcall_id(kcmp_cookies_init) -++initcall_id(spi_mux_driver_init) -++initcall_id(bsp_femac_driver_init) -++initcall_id(ip_auto_config) -++initcall_id(vti_init) -++initcall_id(ipip_init) -++initcall_id(swp_emulation_init) -++initcall_id(user_namespaces_init) -++initcall_id(seccomp_sysctl_init) -++initcall_id(bsp_reboot_driver_init) -++initcall_id(mux_init) -++initcall_id(firmware_memmap_init) -++initcall_id(fw_cfg_sysfs_init) -++initcall_id(bsp_femac_mdio_driver_init) -++initcall_id(g_mipirx_driver_init) -++initcall_id(armv7_pmu_driver_init) -++#endif /* _LINUX_DRIVER_IDS_H */ -+diff --git a/include/linux/drv_def.h b/include/linux/drv_def.h -+new file mode 100755 -+index 000000000..4bf7d42a5 -+--- /dev/null -++++ b/include/linux/drv_def.h -+@@ -0,0 +1,43 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. -++ */ -++#ifndef _LINUX_DRV_DEF_H -++#define _LINUX_DRV_DEF_H -++ -++/* -++ * In fact, the IDs listed here are IDs for initcalls, and not for -++ * drivers. But most of the time, a driver or subsystem has only one -++ * initcall, and talking about IDs for drivers makes more sense than -++ * talking about initcalls, something many people have no clear -++ * understanding about. -++ * -++ * Please use the name of the module as the name for the ID if -++ * something can be build as a module. -++ */ -++ -++ -++/* define the enumeration of all driver */ -++#define initcall_id(_x) _x ## _drv_id, -++ -++enum drv_id { -++ DRVID_UNUSED, -++#include -++ /* To be filled */ -++ DRVID_MAX, -++}; -++ -++#undef initcall_id -++#define initcall_id(_x) _x ## _drv_id -++enum level_start { -++ LEVEL0_START = initcall_id(ipc_ns_init), -++ LEVEL1_START = initcall_id(fpsimd_init), -++ LEVEL2_START = initcall_id(debug_monitors_init), -++ LEVEL3_START = initcall_id(reserve_memblock_reserved_regions), -++ LEVEL4_START = initcall_id(topology_init), -++ LEVEL5_START = initcall_id(create_debug_debugfs_entry), -++ LEVEL6_START = initcall_id(register_arm64_panic_block), -++ LEVEL7_START = initcall_id(init_oops_id), -++ LEVEL8_START = initcall_id(populate_rootfs), -++}; -++ -++#endif /* _LINUX_DRV_DEF_H */ -+diff --git a/include/linux/edmac.h b/include/linux/edmac.h -+new file mode 100755 -+index 000000000..d17454e95 -+--- /dev/null -++++ b/include/linux/edmac.h -+@@ -0,0 +1,71 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef __DMAC_H__ -++#define __DMAC_H__ -++ -++#ifdef CONFIG_ARCH_BSP -++#define DMAC_ERROR_BASE 0x64 -++ -++#define DMAC_CHN_SUCCESS (DMAC_ERROR_BASE + 0x10) -++#define DMAC_CHN_ERROR (DMAC_ERROR_BASE + 0x11) -++#define DMAC_CHN_TIMEOUT (DMAC_ERROR_BASE + 0x12) -++#define DMAC_CHN_ALLOCAT (DMAC_ERROR_BASE + 0x13) -++#define DMAC_CHN_VACANCY (DMAC_ERROR_BASE + 0x14) -++#define DMAC_NOT_FINISHED (DMAC_ERROR_BASE + 0xe) -++ -++#ifdef CONFIG_EDMAC -++extern int dma_driver_init(void); -++extern int dmac_channelclose(unsigned int channel); -++extern int dmac_channelstart(unsigned int u32channel); -++extern int dmac_channel_allocate(void); -++ -++extern int dmac_start_m2p(unsigned int channel, unsigned int pmemaddr, -++ unsigned int uwperipheralid, -++ unsigned int uwnumtransfers, -++ unsigned int next_lli_addr); -++extern int dmac_m2p_transfer(unsigned long long memaddr, unsigned int uwperipheralid, -++ unsigned int length); -++extern int dmac_channel_free(unsigned int channel); -++ -++extern int do_dma_m2p(unsigned long long memaddr, unsigned int peripheral_addr, -++ unsigned int length); -++extern int do_dma_p2m(unsigned long mem_addr, unsigned int peripheral_addr, -++ unsigned int length); -++extern int dmac_wait(int channel); -++ -++extern int dmac_start_m2m(unsigned int channel, unsigned long psource, -++ unsigned long pdest, unsigned int uwnumtransfers); -++extern int dmac_m2m_transfer(unsigned long source, unsigned long dest, -++ unsigned int length); -++extern int dmac_register_isr(unsigned int channel, void *pisr); -++extern int free_dmalli_space(unsigned int *ppheadlli, unsigned int page_num); -++extern int dmac_start_llim2p(unsigned int channel, unsigned int *pfirst_lli, -++ unsigned int uwperipheralid); -++extern int dmac_buildllim2m(const unsigned long *ppheadlli, -++ unsigned long psource, -++ unsigned long pdest, -++ unsigned int totaltransfersize, -++ unsigned int uwnumtransfers); -++ -++extern int dmac_start_llim2m(unsigned int channel, const unsigned long *pfirst_lli); -++ -++extern int allocate_dmalli_space(struct device *dev, unsigned long *ppheadlli, -++ unsigned int page_num); -++#endif /* CONFIG_EDMAC */ -++ -++ -++/* structure for LLI */ -++typedef struct dmac_lli { -++ /* must be 64Byte aligned */ -++ unsigned long next_lli; -++ unsigned int reserved[5]; -++ unsigned int count; -++ unsigned long src_addr; -++ unsigned long dest_addr; -++ unsigned int config; -++ unsigned int pad[51]; -++} dmac_lli; -++#endif /* CONFIG_ARCH_BSP */ -++#endif -+diff --git a/include/linux/i2c.h b/include/linux/i2c.h -+index 58a721c23..656187b77 100644 -+--- a/include/linux/i2c.h -++++ b/include/linux/i2c.h -+@@ -21,6 +21,7 @@ -+ #include /* for swab16 */ -+ #include -+ #include -++#include -+ -+ extern struct bus_type i2c_bus_type; -+ extern struct device_type i2c_adapter_type; -+diff --git a/include/linux/init.h b/include/linux/init.h -+index 7b53cb309..acffbd454 100644 -+--- a/include/linux/init.h -++++ b/include/linux/init.h -+@@ -213,6 +213,7 @@ extern bool initcall_debug; -+ * This only exists for built-in code, not for modules. -+ * Keep main.c:initcall_level_names[] in sync. -+ */ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_STARTUP_PARALLEL_OPT) -+ #define pure_initcall(fn) __define_initcall(fn, 0) -+ -+ #define core_initcall(fn) __define_initcall(fn, 1) -+@@ -230,6 +231,9 @@ extern bool initcall_debug; -+ #define device_initcall_sync(fn) __define_initcall(fn, 6s) -+ #define late_initcall(fn) __define_initcall(fn, 7) -+ #define late_initcall_sync(fn) __define_initcall(fn, 7s) -++#else -++#include -++#endif -+ -+ #define __initcall(fn) device_initcall(fn) -+ -+diff --git a/include/linux/iprec.h b/include/linux/iprec.h -+new file mode 100755 -+index 000000000..745c936f2 -+--- /dev/null -++++ b/include/linux/iprec.h -+@@ -0,0 +1,55 @@ -++#ifndef IPREC_H -++#define IPREC_H -++ -++#ifdef CONFIG_ARCH_BSP -++ -++#include -++ -++#define IPREC "iprec" -++#define IPREC_DUMP "dump" -++#define IPREC_DLAY "delay" -++#define IPREC_LINE "line" -++#define IPREC_LOCK "lock" -++#define IPREC_DEFAULT_DLAY 800 -++#define IPREC_DEFAULT_LINE 2000 -++#define IPREC_STR_LEN 512 -++ -++#define LOG_IPREC_ON 1 -++#define LOG_IPREC_OFF 0 -++ -++#define LOG_IPREC_SWITCH LOG_IPREC_OFF -++ -++char *iprec_tm(void); -++char *iprec_pool(void); -++void iprec_inc(void); -++void iprec_slock(void); -++int iprec_glock(void); -++spinlock_t *iprec_spinlock(void); -++ -++ -++#if (LOG_IPREC_SWITCH == LOG_IPREC_ON) -++ -++#define iprec_fmt(fmt) fmt -++ -++#define iprec(fmt, ...) \ -++ do { \ -++ unsigned long flags; \ -++ spin_lock_irqsave(iprec_spinlock(), flags); \ -++ if (!iprec_glock()) { \ -++ sprintf_s(iprec_pool(), IPREC_STR_LEN, "%s " \ -++ iprec_fmt(fmt), iprec_tm(), ##__VA_ARGS__); \ -++ iprec_inc();} \ -++ spin_unlock_irqrestore(iprec_spinlock(), flags); \ -++ } while (0) -++ -++#else -++ -++#define iprec(fmt, ...) -++ -++#endif // LOG_IPREC_SWITCH -++ -++ -++#endif // CONFIG_ARCH_BSP -++ -++#endif // IPREC_H -++ -+diff --git a/include/linux/kobject.h b/include/linux/kobject.h -+index f3c9ecb71..9daacd937 100644 -+--- a/include/linux/kobject.h -++++ b/include/linux/kobject.h -+@@ -78,10 +78,11 @@ struct kobject { -+ unsigned int state_add_uevent_sent:1; -+ unsigned int state_remove_uevent_sent:1; -+ unsigned int uevent_suppress:1; -+- KABI_RESERVE(1) -+- KABI_RESERVE(2) -+- KABI_RESERVE(3) -+- KABI_RESERVE(4) -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_SYSFS_MINI_OPT -++ unsigned int sysfs_file_suppress:1; -++#endif -++#endif -+ }; -+ -+ extern __printf(2, 3) -+diff --git a/include/linux/mfd/bsp_fmc.h b/include/linux/mfd/bsp_fmc.h -+new file mode 100755 -+index 000000000..63806a76a -+--- /dev/null -++++ b/include/linux/mfd/bsp_fmc.h -+@@ -0,0 +1,493 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. 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) -++ -++#define FMC_MEM_LEN _16M -++#define FMC_MAX_DMA_LEN _8K -++#define MAX_OOB_LEN _512B -++#define MAX_PAGE_SIZE _8K -++#define BUFF_LEN 128 -++ -++/* 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 NFC_CLK_75MHZ 75 -++#define SYS_CTRL_REG_BASE 0x11020000 -++#define SYS_CTRL_STATE_SIZE 0x4 -++#define NFC_1_8_STATA 1 -++#define NFC_3_3_STATA 0 -++#define NFC_STATA_MASK 0x1 -++ -++#if defined(CONFIG_ARCH_HI3519DV500_FAMILY) -++#define SYS_CTRL_STATE_OFF 0x18 -++#define NFC_STATE_BIT_OFF 30 -++#endif -++ -++#if defined(CONFIG_ARCH_HI3516CV610_FAMILY) -++#define SYS_CTRL_STATE_OFF 0xf00 -++#define NFC_STATE_BIT_OFF 0 -++#endif -++ -++#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 & (unsigned int)(_val)) != 0) || \ -++ ((PROTECT_BP2_MASK & (unsigned int)(_val)) != 0) || \ -++ ((PROTECT_BP1_MASK & (unsigned int)(_val)) != 0) || \ -++ ((PROTECT_BP0_MASK & (unsigned int)(_val)) != 0)) -++ -++#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_OP_DMA 0x68 -++#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_BIT_SHIFT_LENTH 32 -++#define FMC_DMA_SADDRH_D0 0x200 -++#define FMC_DMA_SADDRH_SHIFT 0x3LL -++#define FMC_DMA_SADDRH_MASK (FMC_DMA_SADDRH_SHIFT << FMC_DMA_BIT_SHIFT_LENTH) -++ -++#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) != 0) && (timeout != 0)); \ -++ if (timeout <= 0) \ -++ 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) == 0) && (timeout != 0))); \ -++ if (timeout <= 0) \ -++ 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) != 0) && (timeout != 0)); \ -++ if (timeout <= 0) \ -++ pr_info("Error: Wait dma cpu finish timeout!\n"); \ -++ } while (0) -++ -++#define BT_DBG 0 /* Boot init debug print */ -++#define ER_DBG 0 /* Erase debug print */ -++#define WR_DBG 0 /* Write debug print */ -++#define RD_DBG 0 /* Read debug print */ -++#define QE_DBG 0 /* Quad Enable debug print */ -++#define OP_DBG 0 /* OP command debug print */ -++#define DMA_DB 0 /* DMA read or write debug print */ -++#define AC_DBG 0 /* 3-4byte Address Cycle */ -++#define SR_DBG 0 /* Status Register debug print */ -++#define CR_DBG 0 /* Config Register debug print */ -++#define FT_DBG 0 /* Features debug print */ -++#define WE_DBG 0 /* Write Enable debug print */ -++#define BP_DBG 0 /* Block Protection debug print */ -++#define EC_DBG 0 /* enable/disable ecc0 and randomizer */ -++#define PM_DBG 0 /* power management debug */ -++ -++#define fmc_pr(_type, _fmt, arg...) \ -++ do { \ -++ if (_type) \ -++ db_msg(_fmt, ##arg) \ -++ } while (0) -++ -++#define db_msg(_fmt, arg...) \ -++ pr_info("%s(%d): " _fmt, __func__, __LINE__, ##arg); -++ -++#define db_bug(fmt, args...) \ -++ do { \ -++ pr_info("%s(%d): BUG: " fmt, __FILE__, __LINE__, ##args); \ -++ while (1) \ -++ ; \ -++ } while (0) -++ -++enum fmc_iftype { -++ IF_TYPE_STD, -++ IF_TYPE_DUAL, -++ IF_TYPE_DIO, -++ IF_TYPE_QUAD, -++ IF_TYPE_QIO, -++}; -++ -++struct bsp_fmc { -++ void __iomem *regbase; -++ void __iomem *iobase; -++ struct clk *clk; -++ struct mutex lock; -++ void *buffer; -++ dma_addr_t dma_buffer; -++ unsigned int dma_len; -++}; -++ -++struct fmc_cmd_op { -++ unsigned char cs; -++ unsigned char cmd; -++ unsigned char l_cmd; -++ unsigned char addr_h; -++ unsigned int addr_l; -++ unsigned int data_no; -++ unsigned short option; -++ unsigned short op_cfg; -++}; -++ -++extern struct mutex fmc_switch_mutex; -++ -++#endif /* __BSP_FMC_H_ */ -+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -+index fb08b86ac..7e8c67144 100644 -+--- a/include/linux/mmc/host.h -++++ b/include/linux/mmc/host.h -+@@ -173,6 +173,9 @@ struct mmc_host_ops { -+ */ -+ int (*multi_io_quirk)(struct mmc_card *card, -+ unsigned int direction, int blk_size); -++#ifdef CONFIG_ARCH_BSP -++ int (*card_info_save)(struct mmc_host *host); -++#endif -+ }; -+ -+ struct mmc_cqe_ops { -+@@ -426,6 +429,12 @@ struct mmc_host { -+ -+ struct delayed_work detect; -+ int detect_change; /* card detect flag */ -++#ifdef CONFIG_ARCH_BSP -++ u32 card_status; -++#define MMC_CARD_UNINIT 0 -++#define MMC_CARD_INIT 1 -++#define MMC_CARD_INIT_FAIL 2 -++#endif -+ struct mmc_slot slot; -+ -+ const struct mmc_bus_ops *bus_ops; /* current bus driver */ -+diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h -+index 157357ec1..6a8723c69 100644 -+--- a/include/linux/mtd/mtd.h -++++ b/include/linux/mtd/mtd.h -+@@ -18,6 +18,14 @@ -+ -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++#define MTD_ERASE_PENDING 0x01 -++#define MTD_ERASING 0x02 -++#define MTD_ERASE_SUSPEND 0x04 -++#define MTD_ERASE_DONE 0x08 -++#define MTD_ERASE_FAILED 0x10 -++#endif -++ -+ #define MTD_FAIL_ADDR_UNKNOWN -1LL -+ -+ struct mtd_info; -+@@ -28,9 +36,22 @@ struct mtd_info; -+ * or was not specific to any particular block. -+ */ -+ struct erase_info { -++#ifdef CONFIG_ARCH_BSP -++ struct mtd_info *mtd; -++#endif -+ uint64_t addr; -+ uint64_t len; -+ uint64_t fail_addr; -++#ifdef CONFIG_ARCH_BSP -++ u_long time; -++ u_long retries; -++ unsigned dev; -++ unsigned cell; -++ void (*callback) (struct erase_info *self); -++ u_long priv; -++ u_char state; -++ struct erase_info *next; -++#endif -+ }; -+ -+ struct mtd_erase_region_info { -+@@ -314,6 +335,12 @@ struct mtd_info { -+ int (*_point) (struct mtd_info *mtd, loff_t from, size_t len, -+ size_t *retlen, void **virt, resource_size_t *phys); -+ int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len); -++#ifdef CONFIG_ARCH_BSP -++ unsigned long (*_get_unmapped_area) (struct mtd_info *mtd, -++ unsigned long len, -++ unsigned long offset, -++ unsigned long flags); -++#endif -+ int (*_read) (struct mtd_info *mtd, loff_t from, size_t len, -+ size_t *retlen, u_char *buf); -+ int (*_write) (struct mtd_info *mtd, loff_t to, size_t len, -+@@ -361,7 +388,12 @@ struct mtd_info { -+ * action if required to ensure writes go through -+ */ -+ bool oops_panic_write; -+- -++#ifdef CONFIG_ARCH_BSP -++ /* Backing device capabilities for this device -++ * - provides mmap capabilities -++ */ -++ struct backing_dev_info *backing_dev_info; -++#endif -+ struct notifier_block reboot_notifier; /* default mode before reboot */ -+ -+ /* ECC status information */ -+@@ -456,13 +488,19 @@ static inline void mtd_set_of_node(struct mtd_info *mtd, -+ struct device_node *np) -+ { -+ mtd->dev.of_node = np; -++#ifndef CONFIG_ARCH_BSP -+ if (!mtd->name) -+ of_property_read_string(np, "label", &mtd->name); -++#endif -+ } -+ -+ static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd) -+ { -++#ifdef CONFIG_ARCH_BSP -++ return mtd->dev.of_node; -++#else -+ return dev_of_node(&mtd->dev); -++#endif -+ } -+ -+ static inline u32 mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) -+@@ -580,6 +618,7 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd) -+ return do_div(sz, mtd->erasesize); -+ } -+ -++#ifndef CONFIG_ARCH_BSP -+ /** -+ * mtd_align_erase_req - Adjust an erase request to align things on eraseblock -+ * boundaries. -+@@ -607,6 +646,7 @@ static inline void mtd_align_erase_req(struct mtd_info *mtd, -+ if (mod) -+ req->len += mtd->erasesize - mod; -+ } -++#endif -+ -+ static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) -+ { -+@@ -692,6 +732,10 @@ extern void register_mtd_user (struct mtd_notifier *new); -+ extern int unregister_mtd_user (struct mtd_notifier *old); -+ void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); -+ -++#ifdef CONFIG_ARCH_BSP -++void mtd_erase_callback(struct erase_info *instr); -++#endif -++ -+ static inline int mtd_is_bitflip(int err) { -+ return err == -EUCLEAN; -+ } -+diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h -+index 60bac2c0e..291478b19 100644 -+--- a/include/linux/mtd/spi-nor.h -++++ b/include/linux/mtd/spi-nor.h -+@@ -11,6 +11,58 @@ -+ #include -+ #include -+ -++#ifdef CONFIG_ARCH_BSP -++/* -++ * Manufacturer IDs -++ * -++ * The first byte returned from the flash after sending opcode SPINOR_OP_RDID. -++ * 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 -++ -++/* 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_BSP_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_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 LOCK_LEVEL_MAX(bp_num) (((0x01) << bp_num) - 1) -++ -++#endif /* CONFIG_BSP_SPI_BLOCK_PROTECT */ -++#endif /* CONFIG_ARCH_BSP */ -+ /* -+ * Note on opcode nomenclature: some opcodes have a format like -+ * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number -+@@ -98,6 +150,17 @@ -+ -+ /* Used for Spansion flashes only. */ -+ #define SPINOR_OP_BRWR 0x17 /* Bank register write */ -++ -++#ifdef CONFIG_ARCH_BSP -++#define SPINOR_OP_RDSR3 0x15 /* Read Status Register-3 */ -++#define SPINOR_OP_WRSR3 0x11 /* Write Status Register-3 1 byte*/ -++/* Used for GigaDevice flashes only. */ -++#define SPINOR_OP_WRCR 0x31 /* Config register write */ -++/* Software reset code */ -++#define CR_DUMMY_CYCLE (0x03 << 6) /* Macronix dummy cycle bits */ -++#define SR_QUAD_EN_XTX BIT(1) -++#endif -++ -+ #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ -+ -+ /* Used for Micron flashes only. */ -+@@ -166,6 +229,23 @@ -+ (SNOR_PROTO_IS_DTR | \ -+ SNOR_PROTO_STR(_inst_nbits, _addr_nbits, _data_nbits)) -+ -++#ifdef CONFIG_ARCH_BSP -++#define SNOR_OP_READ(_num_mode_clocks, _num_wait_states, _opcode, _proto) \ -++ { \ -++ .num_mode_clocks = _num_mode_clocks, \ -++ .num_wait_states = _num_wait_states, \ -++ .opcode = _opcode, \ -++ .proto = _proto, \ -++ } -++ -++#define SNOR_OP_PROGRAMS(_opcode, _proto) \ -++ { \ -++ .opcode = _opcode, \ -++ .proto = _proto, \ -++ } -++ -++#endif /* CONFIG_ARCH_BSP */ -++ -+ enum spi_nor_protocol { -+ SNOR_PROTO_1_1_1 = SNOR_PROTO_STR(1, 1, 1), -+ SNOR_PROTO_1_1_2 = SNOR_PROTO_STR(1, 1, 2), -+@@ -385,7 +465,15 @@ struct spi_nor { -+ struct spi_mem_dirmap_desc *rdesc; -+ struct spi_mem_dirmap_desc *wdesc; -+ } dirmap; -+- -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_BSP_SPI_BLOCK_PROTECT -++ unsigned int end_addr; -++ unsigned int lock_level_max; -++ unsigned char level; -++#endif -++ struct device_node *flash_node; -++ u32 clkrate; -++#endif -+ void *priv; -+ }; -+ -+@@ -414,6 +502,13 @@ static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) -+ * -+ * Return: 0 for success, others for failure. -+ */ -++#ifdef CONFIG_ARCH_BSP -++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 bsp_spi_nor_resume(struct spi_nor *nor); -++#endif -++#endif /* CONFIG_ARCH_BSP */ -+ int spi_nor_scan(struct spi_nor *nor, const char *name, -+ const struct spi_nor_hwcaps *hwcaps); -+ -+diff --git a/include/linux/of.h b/include/linux/of.h -+index 2362d3b53..7315dbaf0 100644 -+--- a/include/linux/of.h -++++ b/include/linux/of.h -+@@ -150,7 +150,12 @@ extern raw_spinlock_t devtree_lock; -+ #define OF_BAD_ADDR ((u64)-1) -+ -+ #ifdef CONFIG_OF -++ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ void of_core_init(void); -++#else -++static inline void of_core_init(void) { } -++#endif -+ -+ static inline bool is_of_node(const struct fwnode_handle *fwnode) -+ { -+diff --git a/include/linux/pwm.h b/include/linux/pwm.h -+index c0cf66133..3f0d92e44 100644 -+--- a/include/linux/pwm.h -++++ b/include/linux/pwm.h -+@@ -58,6 +58,10 @@ enum { -+ struct pwm_state { -+ u64 period; -+ u64 duty_cycle; -++#ifdef CONFIG_ARCH_BSP -++ u64 duty_cycle1; -++ u64 duty_cycle2; -++#endif /* CONFIG_ARCH_BSP */ -+ enum pwm_polarity polarity; -+ bool enabled; -+ }; -+@@ -261,7 +265,7 @@ struct pwm_ops { -+ int (*capture)(struct pwm_chip *chip, struct pwm_device *pwm, -+ struct pwm_capture *result, unsigned long timeout); -+ int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm, -+- const struct pwm_state *state); -++ struct pwm_state *state); -+ void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm, -+ struct pwm_state *state); -+ struct module *owner; -+diff --git a/include/linux/securec.h b/include/linux/securec.h -+new file mode 100755 -+index 000000000..77af92324 -+--- /dev/null -++++ b/include/linux/securec.h -+@@ -0,0 +1,631 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: The user of this secure c library should include this header file in you source code. -++ * This header file declare all supported API prototype of the library, -++ * such as memcpy_s, strcpy_s, wcscpy_s,strcat_s, strncat_s, sprintf_s, scanf_s, and so on. -++ * Create: 2014-02-25 -++ * Notes: Do not modify this file by yourself. -++ */ -++ -++#ifndef SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27 -++#define SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27 -++ -++#ifdef CONFIG_ARCH_BSP -++#include "securectype.h" -++#ifndef SECUREC_HAVE_STDARG_H -++#define SECUREC_HAVE_STDARG_H 1 -++#endif -++ -++#if SECUREC_HAVE_STDARG_H -++#include -++#endif -++ -++#ifndef SECUREC_HAVE_ERRNO_H -++#define SECUREC_HAVE_ERRNO_H 1 -++#endif -++ -++/* EINVAL ERANGE may defined in errno.h */ -++#if SECUREC_HAVE_ERRNO_H -++#if SECUREC_IN_KERNEL -++#include -++#else -++#include -++#endif -++#endif -++ -++/* Define error code */ -++#if defined(SECUREC_NEED_ERRNO_TYPE) || !defined(__STDC_WANT_LIB_EXT1__) || \ -++ (defined(__STDC_WANT_LIB_EXT1__) && (!__STDC_WANT_LIB_EXT1__)) -++#ifndef SECUREC_DEFINED_ERRNO_TYPE -++#define SECUREC_DEFINED_ERRNO_TYPE -++/* Just check whether macrodefinition exists. */ -++#ifndef errno_t -++typedef int errno_t; -++#endif -++#endif -++#endif -++ -++/* Success */ -++#ifndef EOK -++#define EOK 0 -++#endif -++ -++#ifndef EINVAL -++/* The src buffer is not correct and destination buffer can not be reset */ -++#define EINVAL 22 -++#endif -++ -++#ifndef EINVAL_AND_RESET -++/* Once the error is detected, the dest buffer must be reset! Value is 22 or 128 */ -++#define EINVAL_AND_RESET 150 -++#endif -++ -++#ifndef ERANGE -++/* The destination buffer is not long enough and destination buffer can not be reset */ -++#define ERANGE 34 -++#endif -++ -++#ifndef ERANGE_AND_RESET -++/* Once the error is detected, the dest buffer must be reset! Value is 34 or 128 */ -++#define ERANGE_AND_RESET 162 -++#endif -++ -++#ifndef EOVERLAP_AND_RESET -++/* Once the buffer overlap is detected, the dest buffer must be reset! Value is 54 or 128 */ -++#define EOVERLAP_AND_RESET 182 -++#endif -++ -++/* If you need export the function of this library in Win32 dll, use __declspec(dllexport) */ -++#ifndef SECUREC_API -++#if defined(SECUREC_DLL_EXPORT) -++#define SECUREC_API __declspec(dllexport) -++#elif defined(SECUREC_DLL_IMPORT) -++#define SECUREC_API __declspec(dllimport) -++#else -++/* -++ * Standardized function declaration. If a security function is declared in the your code, -++ * it may cause a compilation alarm,Please delete the security function you declared. -++ * Adding extern under windows will cause the system to have inline functions to expand, -++ * so do not add the extern in default -++ */ -++#if defined(_MSC_VER) -++#define SECUREC_API -++#else -++#define SECUREC_API extern -++#endif -++#endif -++#endif -++ -++#ifdef __cplusplus -++extern "C" { -++#endif -++/* -++ * Description: The GetHwSecureCVersion function get SecureC Version string and version number. -++ * Parameter: verNumber - to store version number (for example value is 0x500 | 0xa) -++ * Return: version string -++ */ -++SECUREC_API const char *GetHwSecureCVersion(unsigned short *verNumber); -++ -++#if SECUREC_ENABLE_MEMSET -++/* -++ * Description: The memset_s function copies the value of c (converted to an unsigned char) into each of -++ * the first count characters of the object pointed to by dest. -++ * Parameter: dest - destination address -++ * Parameter: destMax - The maximum length of destination buffer -++ * Parameter: c - the value to be copied -++ * Parameter: count - copies count bytes of value to dest -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t memset_s(void *dest, size_t destMax, int c, size_t count); -++#endif -++ -++#ifndef SECUREC_ONLY_DECLARE_MEMSET -++#define SECUREC_ONLY_DECLARE_MEMSET 0 -++#endif -++ -++#if !SECUREC_ONLY_DECLARE_MEMSET -++ -++#if SECUREC_ENABLE_MEMMOVE -++/* -++ * Description: The memmove_s function copies n characters from the object pointed to by src -++ * into the object pointed to by dest. -++ * Parameter: dest - destination address -++ * Parameter: destMax - The maximum length of destination buffer -++ * Parameter: src - source address -++ * Parameter: count - copies count bytes from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_MEMCPY -++/* -++ * Description: The memcpy_s function copies n characters from the object pointed to -++ * by src into the object pointed to by dest. -++ * Parameter: dest - destination address -++ * Parameter: destMax - The maximum length of destination buffer -++ * Parameter: src - source address -++ * Parameter: count - copies count bytes from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_STRCPY -++/* -++ * Description: The strcpy_s function copies the string pointed to by strSrc (including -++ * the terminating null character) into the array pointed to by strDest -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) -++ * Parameter: strSrc - source address -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc); -++#endif -++ -++#if SECUREC_ENABLE_STRNCPY -++/* -++ * Description: The strncpy_s function copies not more than n successive characters (not including -++ * the terminating null character) from the array pointed to by strSrc to the array pointed to by strDest. -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) -++ * Parameter: strSrc - source address -++ * Parameter: count - copies count characters from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_STRCAT -++/* -++ * Description: The strcat_s function appends a copy of the string pointed to by strSrc (including -++ * the terminating null character) to the end of the string pointed to by strDest. -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character) -++ * Parameter: strSrc - source address -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc); -++#endif -++ -++#if SECUREC_ENABLE_STRNCAT -++/* -++ * Description: The strncat_s function appends not more than n successive characters (not including -++ * the terminating null character) -++ * from the array pointed to by strSrc to the end of the string pointed to by strDest. -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) -++ * Parameter: strSrc - source address -++ * Parameter: count - copies count characters from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_VSPRINTF -++/* -++ * Description: The vsprintf_s function is equivalent to the vsprintf function except for the parameter destMax -++ * and the explicit runtime-constraints violation -++ * Parameter: strDest - produce output according to a format,write to the character string strDest. -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character) -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of characters printed(not including the terminating null byte '\0'), -++ * If an error occurred Return: -1. -++ */ -++SECUREC_API int vsprintf_s(char *strDest, size_t destMax, const char *format, -++ va_list argList) SECUREC_ATTRIBUTE(3, 0); -++#endif -++ -++#if SECUREC_ENABLE_SPRINTF -++/* -++ * Description: The sprintf_s function is equivalent to the sprintf function except for the parameter destMax -++ * and the explicit runtime-constraints violation -++ * Parameter: strDest - produce output according to a format ,write to the character string strDest. -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') -++ * Parameter: format - format string -++ * Return: the number of characters printed(not including the terminating null byte '\0'), -++ * If an error occurred Return: -1. -++*/ -++SECUREC_API int sprintf_s(char *strDest, size_t destMax, const char *format, ...) SECUREC_ATTRIBUTE(3, 4); -++#endif -++ -++#if SECUREC_ENABLE_VSNPRINTF -++/* -++ * Description: The vsnprintf_s function is equivalent to the vsnprintf function except for -++ * the parameter destMax/count and the explicit runtime-constraints violation -++ * Parameter: strDest - produce output according to a format ,write to the character string strDest. -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') -++ * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0') -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of characters printed(not including the terminating null byte '\0'), -++ * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs. -++ */ -++SECUREC_API int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, -++ va_list argList) SECUREC_ATTRIBUTE(4, 0); -++#endif -++ -++#if SECUREC_ENABLE_SNPRINTF -++/* -++ * Description: The snprintf_s function is equivalent to the snprintf function except for -++ * the parameter destMax/count and the explicit runtime-constraints violation -++ * Parameter: strDest - produce output according to a format ,write to the character string strDest. -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') -++ * Parameter: count - do not write more than count bytes to strDest(not including the terminating null byte '\0') -++ * Parameter: format - format string -++ * Return: the number of characters printed(not including the terminating null byte '\0'), -++ * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs. -++ */ -++SECUREC_API int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, -++ ...) SECUREC_ATTRIBUTE(4, 5); -++#endif -++ -++#if SECUREC_SNPRINTF_TRUNCATED -++/* -++ * Description: The vsnprintf_truncated_s function is equivalent to the vsnprintf_s function except -++ * no count parameter and return value -++ * Parameter: strDest - produce output according to a format ,write to the character string strDest -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of characters printed(not including the terminating null byte '\0'), -++ * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs -++*/ -++SECUREC_API int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, -++ va_list argList) SECUREC_ATTRIBUTE(3, 0); -++ -++/* -++ * Description: The snprintf_truncated_s function is equivalent to the snprintf_s function except -++ * no count parameter and return value -++ * Parameter: strDest - produce output according to a format,write to the character string strDest. -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\0') -++ * Parameter: format - format string -++ * Return: the number of characters printed(not including the terminating null byte '\0'), -++ * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs. -++ */ -++SECUREC_API int snprintf_truncated_s(char *strDest, size_t destMax, -++ const char *format, ...) SECUREC_ATTRIBUTE(3, 4); -++#endif -++ -++#if SECUREC_ENABLE_SCANF -++/* -++ * Description: The scanf_s function is equivalent to fscanf_s with the argument stdin -++ * interposed before the arguments to scanf_s -++ * Parameter: format - format string -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int scanf_s(const char *format, ...); -++#endif -++ -++#if SECUREC_ENABLE_VSCANF -++/* -++ * Description: The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int vscanf_s(const char *format, va_list argList); -++#endif -++ -++#if SECUREC_ENABLE_SSCANF -++/* -++ * Description: The sscanf_s function is equivalent to fscanf_s, except that input is obtained from a -++ * string (specified by the argument buffer) rather than from a stream -++ * Parameter: buffer - read character from buffer -++ * Parameter: format - format string -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int sscanf_s(const char *buffer, const char *format, ...); -++#endif -++ -++#if SECUREC_ENABLE_VSSCANF -++/* -++ * Description: The vsscanf_s function is equivalent to sscanf_s, with the variable argument list -++ * replaced by argList -++ * Parameter: buffer - read character from buffer -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int vsscanf_s(const char *buffer, const char *format, va_list argList); -++#endif -++ -++#if SECUREC_ENABLE_FSCANF -++/* -++ * Description: The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers -++ * apply to a pair of arguments (unless assignment suppression is indicated by a *) -++ * Parameter: stream - stdio file stream -++ * Parameter: format - format string -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int fscanf_s(FILE *stream, const char *format, ...); -++#endif -++ -++#if SECUREC_ENABLE_VFSCANF -++/* -++ * Description: The vfscanf_s function is equivalent to fscanf_s, with the variable argument list -++ * replaced by argList -++ * Parameter: stream - stdio file stream -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int vfscanf_s(FILE *stream, const char *format, va_list argList); -++#endif -++ -++#if SECUREC_ENABLE_STRTOK -++/* -++ * Description: The strtok_s function parses a string into a sequence of strToken, -++ * replace all characters in strToken string that match to strDelimit set with 0. -++ * On the first call to strtok_s the string to be parsed should be specified in strToken. -++ * In each subsequent call that should parse the same string, strToken should be NULL -++ * Parameter: strToken - the string to be delimited -++ * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string -++ * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function -++ * Return: On the first call returns the address of the first non \0 character, otherwise NULL is returned. -++ * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call, -++ * return NULL if the *context string length is equal 0, otherwise return *context. -++ */ -++SECUREC_API char *strtok_s(char *strToken, const char *strDelimit, char **context); -++#endif -++ -++#if SECUREC_ENABLE_GETS && !SECUREC_IN_KERNEL -++/* -++ * Description: The gets_s function reads at most one less than the number of characters specified -++ * by destMax from the stream pointed to by stdin, into the array pointed to by buffer -++ * Parameter: buffer - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null character) -++ * Return: buffer if there was no runtime-constraint violation,If an error occurred Return: NULL. -++ */ -++SECUREC_API char *gets_s(char *buffer, size_t destMax); -++#endif -++ -++#if SECUREC_ENABLE_WCHAR_FUNC -++#if SECUREC_ENABLE_MEMCPY -++/* -++ * Description: The wmemcpy_s function copies n successive wide characters from the object pointed to -++ * by src into the object pointed to by dest. -++ * Parameter: dest - destination address -++ * Parameter: destMax - The maximum length of destination buffer -++ * Parameter: src - source address -++ * Parameter: count - copies count wide characters from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_MEMMOVE -++/* -++ * Description: The wmemmove_s function copies n successive wide characters from the object -++ * pointed to by src into the object pointed to by dest. -++ * Parameter: dest - destination address -++ * Parameter: destMax - The maximum length of destination buffer -++ * Parameter: src - source address -++ * Parameter: count - copies count wide characters from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_STRCPY -++/* -++ * Description: The wcscpy_s function copies the wide string pointed to by strSrc(including the terminating -++ * null wide character) into the array pointed to by strDest -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer -++ * Parameter: strSrc - source address -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc); -++#endif -++ -++#if SECUREC_ENABLE_STRNCPY -++/* -++ * Description: The wcsncpy_s function copies not more than n successive wide characters (not including the -++ * terminating null wide character) from the array pointed to by strSrc to the array pointed to by strDest -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) -++ * Parameter: strSrc - source address -++ * Parameter: count - copies count wide characters from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_STRCAT -++/* -++ * Description: The wcscat_s function appends a copy of the wide string pointed to by strSrc (including the -++ * terminating null wide character) to the end of the wide string pointed to by strDest -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) -++ * Parameter: strSrc - source address -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc); -++#endif -++ -++#if SECUREC_ENABLE_STRNCAT -++/* -++ * Description: The wcsncat_s function appends not more than n successive wide characters (not including the -++ * terminating null wide character) from the array pointed to by strSrc to the end of the wide string pointed to -++ * by strDest. -++ * Parameter: strDest - destination address -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character) -++ * Parameter: strSrc - source address -++ * Parameter: count - copies count wide characters from the src -++ * Return: EOK if there was no runtime-constraint violation -++ */ -++SECUREC_API errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count); -++#endif -++ -++#if SECUREC_ENABLE_STRTOK -++/* -++ * Description: The wcstok_s function is the wide-character equivalent of the strtok_s function -++ * Parameter: strToken - the string to be delimited -++ * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string -++ * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function -++ * Return: a pointer to the first character of a token, or a null pointer if there is no token -++ * or there is a runtime-constraint violation. -++ */ -++SECUREC_API wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context); -++#endif -++ -++#if SECUREC_ENABLE_VSPRINTF -++/* -++ * Description: The vswprintf_s function is the wide-character equivalent of the vsprintf_s function -++ * Parameter: strDest - produce output according to a format,write to the character string strDest -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null) -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of characters printed(not including the terminating null wide character), -++ * If an error occurred Return: -1. -++ */ -++SECUREC_API int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, va_list argList); -++#endif -++ -++#if SECUREC_ENABLE_SPRINTF -++/* -++ * Description: The swprintf_s function is the wide-character equivalent of the sprintf_s function -++ * Parameter: strDest - produce output according to a format,write to the character string strDest -++ * Parameter: destMax - The maximum length of destination buffer(including the terminating null) -++ * Parameter: format - format string -++ * Return: the number of characters printed(not including the terminating null wide character), -++ * If an error occurred Return: -1. -++ */ -++SECUREC_API int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...); -++#endif -++ -++#if SECUREC_ENABLE_FSCANF -++/* -++ * Description: The fwscanf_s function is the wide-character equivalent of the fscanf_s function -++ * Parameter: stream - stdio file stream -++ * Parameter: format - format string -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int fwscanf_s(FILE *stream, const wchar_t *format, ...); -++#endif -++ -++#if SECUREC_ENABLE_VFSCANF -++/* -++ * Description: The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function -++ * Parameter: stream - stdio file stream -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList); -++#endif -++ -++#if SECUREC_ENABLE_SCANF -++/* -++ * Description: The wscanf_s function is the wide-character equivalent of the scanf_s function -++ * Parameter: format - format string -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int wscanf_s(const wchar_t *format, ...); -++#endif -++ -++#if SECUREC_ENABLE_VSCANF -++/* -++ * Description: The vwscanf_s function is the wide-character equivalent of the vscanf_s function -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int vwscanf_s(const wchar_t *format, va_list argList); -++#endif -++ -++#if SECUREC_ENABLE_SSCANF -++/* -++ * Description: The swscanf_s function is the wide-character equivalent of the sscanf_s function -++ * Parameter: buffer - read character from buffer -++ * Parameter: format - format string -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...); -++#endif -++ -++#if SECUREC_ENABLE_VSSCANF -++/* -++ * Description: The vswscanf_s function is the wide-character equivalent of the vsscanf_s function -++ * Parameter: buffer - read character from buffer -++ * Parameter: format - format string -++ * Parameter: argList - instead of a variable number of arguments -++ * Return: the number of input items assigned, If an error occurred Return: -1. -++ */ -++SECUREC_API int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList); -++#endif -++#endif /* SECUREC_ENABLE_WCHAR_FUNC */ -++#endif -++ -++/* Those functions are used by macro,must declare hare, also for without function declaration warning */ -++extern errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count); -++extern errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc); -++ -++#if SECUREC_WITH_PERFORMANCE_ADDONS -++/* Those functions are used by macro */ -++extern errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count); -++extern errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count); -++extern errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count); -++extern errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count); -++ -++/* The strcpy_sp is a macro, not a function in performance optimization mode. */ -++#define strcpy_sp(dest, destMax, src) ((__builtin_constant_p((destMax)) && \ -++ __builtin_constant_p((src))) ? \ -++ SECUREC_STRCPY_SM((dest), (destMax), (src)) : \ -++ strcpy_s((dest), (destMax), (src))) -++ -++/* The strncpy_sp is a macro, not a function in performance optimization mode. */ -++#define strncpy_sp(dest, destMax, src, count) ((__builtin_constant_p((count)) && \ -++ __builtin_constant_p((destMax)) && \ -++ __builtin_constant_p((src))) ? \ -++ SECUREC_STRNCPY_SM((dest), (destMax), (src), (count)) : \ -++ strncpy_s((dest), (destMax), (src), (count))) -++ -++/* The strcat_sp is a macro, not a function in performance optimization mode. */ -++#define strcat_sp(dest, destMax, src) ((__builtin_constant_p((destMax)) && \ -++ __builtin_constant_p((src))) ? \ -++ SECUREC_STRCAT_SM((dest), (destMax), (src)) : \ -++ strcat_s((dest), (destMax), (src))) -++ -++/* The strncat_sp is a macro, not a function in performance optimization mode. */ -++#define strncat_sp(dest, destMax, src, count) ((__builtin_constant_p((count)) && \ -++ __builtin_constant_p((destMax)) && \ -++ __builtin_constant_p((src))) ? \ -++ SECUREC_STRNCAT_SM((dest), (destMax), (src), (count)) : \ -++ strncat_s((dest), (destMax), (src), (count))) -++ -++/* The memcpy_sp is a macro, not a function in performance optimization mode. */ -++#define memcpy_sp(dest, destMax, src, count) (__builtin_constant_p((count)) ? \ -++ (SECUREC_MEMCPY_SM((dest), (destMax), (src), (count))) : \ -++ (__builtin_constant_p((destMax)) ? \ -++ (((size_t)(destMax) > 0 && \ -++ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \ -++ memcpy_sOptTc((dest), (destMax), (src), (count)) : ERANGE) : \ -++ memcpy_sOptAsm((dest), (destMax), (src), (count)))) -++ -++/* The memset_sp is a macro, not a function in performance optimization mode. */ -++#define memset_sp(dest, destMax, c, count) (__builtin_constant_p((count)) ? \ -++ (SECUREC_MEMSET_SM((dest), (destMax), (c), (count))) : \ -++ (__builtin_constant_p((destMax)) ? \ -++ (((((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \ -++ memset_sOptTc((dest), (destMax), (c), (count)) : ERANGE) : \ -++ memset_sOptAsm((dest), (destMax), (c), (count)))) -++ -++#endif -++ -++#ifdef __cplusplus -++} -++#endif -++#endif /* CONFIG_ARCH_BSP */ -++#endif -++ -+diff --git a/include/linux/securectype.h b/include/linux/securectype.h -+new file mode 100755 -+index 000000000..0dcac363a -+--- /dev/null -++++ b/include/linux/securectype.h -+@@ -0,0 +1,587 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: Define internal used macro and data type. The marco of SECUREC_ON_64BITS -++ * will be determined in this header file, which is a switch for part -++ * of code. Some macro are used to suppress warning by MS compiler. -++ * Create: 2014-02-25 -++ * Notes: User can change the value of SECUREC_STRING_MAX_LEN and SECUREC_MEM_MAX_LEN -++ * macro to meet their special need, but The maximum value should not exceed 2G. -++ */ -++/* -++ * [Standardize-exceptions]: Performance-sensitive -++ * [reason]: Strict parameter verification has been done before use -++ */ -++ -++#ifndef SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7 -++#define SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7 -++ -++#ifdef CONFIG_ARCH_BSP -++#ifndef SECUREC_USING_STD_SECURE_LIB -++#if defined(_MSC_VER) && _MSC_VER >= 1400 -++#if defined(__STDC_WANT_SECURE_LIB__) && (!__STDC_WANT_SECURE_LIB__) -++/* Security functions have been provided since vs2005, default use of system library functions */ -++#define SECUREC_USING_STD_SECURE_LIB 0 -++#else -++#define SECUREC_USING_STD_SECURE_LIB 1 -++#endif -++#else -++#define SECUREC_USING_STD_SECURE_LIB 0 -++#endif -++#endif -++ -++/* Compatibility with older Secure C versions, shielding VC symbol redefinition warning */ -++#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!SECUREC_USING_STD_SECURE_LIB) -++#ifndef SECUREC_DISABLE_CRT_FUNC -++#define SECUREC_DISABLE_CRT_FUNC 1 -++#endif -++#ifndef SECUREC_DISABLE_CRT_IMP -++#define SECUREC_DISABLE_CRT_IMP 1 -++#endif -++#else /* MSC VER */ -++#ifndef SECUREC_DISABLE_CRT_FUNC -++#define SECUREC_DISABLE_CRT_FUNC 0 -++#endif -++#ifndef SECUREC_DISABLE_CRT_IMP -++#define SECUREC_DISABLE_CRT_IMP 0 -++#endif -++#endif -++ -++#if SECUREC_DISABLE_CRT_FUNC -++#ifdef __STDC_WANT_SECURE_LIB__ -++#undef __STDC_WANT_SECURE_LIB__ -++#endif -++#define __STDC_WANT_SECURE_LIB__ 0 -++#endif -++ -++#if SECUREC_DISABLE_CRT_IMP -++#ifdef _CRTIMP_ALTERNATIVE -++#undef _CRTIMP_ALTERNATIVE -++#endif -++#define _CRTIMP_ALTERNATIVE /* Comment Microsoft *_s function */ -++#endif -++ -++/* Compile in kernel under macro control */ -++#ifndef SECUREC_IN_KERNEL -++#ifdef __KERNEL__ -++#define SECUREC_IN_KERNEL 1 -++#else -++#define SECUREC_IN_KERNEL 0 -++#endif -++#endif -++ -++/* make kernel symbols of functions available to loadable modules */ -++#ifndef SECUREC_EXPORT_KERNEL_SYMBOL -++#if SECUREC_IN_KERNEL -++#define SECUREC_EXPORT_KERNEL_SYMBOL 1 -++#else -++#define SECUREC_EXPORT_KERNEL_SYMBOL 0 -++#endif -++#endif -++ -++#if SECUREC_IN_KERNEL -++#ifndef SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_SCANF_FILE 0 -++#endif -++#ifndef SECUREC_ENABLE_WCHAR_FUNC -++#define SECUREC_ENABLE_WCHAR_FUNC 0 -++#endif -++#else /* SECUREC_IN_KERNEL */ -++#ifndef SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_SCANF_FILE 1 -++#endif -++#ifndef SECUREC_ENABLE_WCHAR_FUNC -++#define SECUREC_ENABLE_WCHAR_FUNC 1 -++#endif -++#endif -++ -++/* Default secure function declaration, default declarations for non-standard functions */ -++#ifndef SECUREC_SNPRINTF_TRUNCATED -++#define SECUREC_SNPRINTF_TRUNCATED 1 -++#endif -++ -++#if SECUREC_USING_STD_SECURE_LIB -++#if defined(_MSC_VER) && _MSC_VER >= 1400 -++/* Declare secure functions that are not available in the VS compiler */ -++#ifndef SECUREC_ENABLE_MEMSET -++#define SECUREC_ENABLE_MEMSET 1 -++#endif -++/* VS 2005 have vsnprintf_s function */ -++#ifndef SECUREC_ENABLE_VSNPRINTF -++#define SECUREC_ENABLE_VSNPRINTF 0 -++#endif -++#ifndef SECUREC_ENABLE_SNPRINTF -++/* VS 2005 have vsnprintf_s function Adapt the snprintf_s of the security function */ -++#define snprintf_s _snprintf_s -++#define SECUREC_ENABLE_SNPRINTF 0 -++#endif -++/* Before VS 2010 do not have v functions */ -++#if _MSC_VER <= 1600 || defined(SECUREC_FOR_V_SCANFS) -++#ifndef SECUREC_ENABLE_VFSCANF -++#define SECUREC_ENABLE_VFSCANF 1 -++#endif -++#ifndef SECUREC_ENABLE_VSCANF -++#define SECUREC_ENABLE_VSCANF 1 -++#endif -++#ifndef SECUREC_ENABLE_VSSCANF -++#define SECUREC_ENABLE_VSSCANF 1 -++#endif -++#endif -++ -++#else /* MSC VER */ -++#ifndef SECUREC_ENABLE_MEMSET -++#define SECUREC_ENABLE_MEMSET 0 -++#endif -++#ifndef SECUREC_ENABLE_SNPRINTF -++#define SECUREC_ENABLE_SNPRINTF 0 -++#endif -++#ifndef SECUREC_ENABLE_VSNPRINTF -++#define SECUREC_ENABLE_VSNPRINTF 0 -++#endif -++#endif -++ -++#ifndef SECUREC_ENABLE_MEMMOVE -++#define SECUREC_ENABLE_MEMMOVE 0 -++#endif -++#ifndef SECUREC_ENABLE_MEMCPY -++#define SECUREC_ENABLE_MEMCPY 0 -++#endif -++#ifndef SECUREC_ENABLE_STRCPY -++#define SECUREC_ENABLE_STRCPY 0 -++#endif -++#ifndef SECUREC_ENABLE_STRNCPY -++#define SECUREC_ENABLE_STRNCPY 0 -++#endif -++#ifndef SECUREC_ENABLE_STRCAT -++#define SECUREC_ENABLE_STRCAT 0 -++#endif -++#ifndef SECUREC_ENABLE_STRNCAT -++#define SECUREC_ENABLE_STRNCAT 0 -++#endif -++#ifndef SECUREC_ENABLE_SPRINTF -++#define SECUREC_ENABLE_SPRINTF 0 -++#endif -++#ifndef SECUREC_ENABLE_VSPRINTF -++#define SECUREC_ENABLE_VSPRINTF 0 -++#endif -++#ifndef SECUREC_ENABLE_SSCANF -++#define SECUREC_ENABLE_SSCANF 0 -++#endif -++#ifndef SECUREC_ENABLE_VSSCANF -++#define SECUREC_ENABLE_VSSCANF 0 -++#endif -++#ifndef SECUREC_ENABLE_SCANF -++#define SECUREC_ENABLE_SCANF 0 -++#endif -++#ifndef SECUREC_ENABLE_VSCANF -++#define SECUREC_ENABLE_VSCANF 0 -++#endif -++ -++#ifndef SECUREC_ENABLE_FSCANF -++#define SECUREC_ENABLE_FSCANF 0 -++#endif -++#ifndef SECUREC_ENABLE_VFSCANF -++#define SECUREC_ENABLE_VFSCANF 0 -++#endif -++#ifndef SECUREC_ENABLE_STRTOK -++#define SECUREC_ENABLE_STRTOK 0 -++#endif -++#ifndef SECUREC_ENABLE_GETS -++#define SECUREC_ENABLE_GETS 0 -++#endif -++ -++#else /* SECUREC USE STD SECURE LIB */ -++ -++#ifndef SECUREC_ENABLE_MEMSET -++#define SECUREC_ENABLE_MEMSET 1 -++#endif -++#ifndef SECUREC_ENABLE_MEMMOVE -++#define SECUREC_ENABLE_MEMMOVE 1 -++#endif -++#ifndef SECUREC_ENABLE_MEMCPY -++#define SECUREC_ENABLE_MEMCPY 1 -++#endif -++#ifndef SECUREC_ENABLE_STRCPY -++#define SECUREC_ENABLE_STRCPY 1 -++#endif -++#ifndef SECUREC_ENABLE_STRNCPY -++#define SECUREC_ENABLE_STRNCPY 1 -++#endif -++#ifndef SECUREC_ENABLE_STRCAT -++#define SECUREC_ENABLE_STRCAT 1 -++#endif -++#ifndef SECUREC_ENABLE_STRNCAT -++#define SECUREC_ENABLE_STRNCAT 1 -++#endif -++#ifndef SECUREC_ENABLE_SPRINTF -++#define SECUREC_ENABLE_SPRINTF 1 -++#endif -++#ifndef SECUREC_ENABLE_VSPRINTF -++#define SECUREC_ENABLE_VSPRINTF 1 -++#endif -++#ifndef SECUREC_ENABLE_SNPRINTF -++#define SECUREC_ENABLE_SNPRINTF 1 -++#endif -++#ifndef SECUREC_ENABLE_VSNPRINTF -++#define SECUREC_ENABLE_VSNPRINTF 1 -++#endif -++#ifndef SECUREC_ENABLE_SSCANF -++#define SECUREC_ENABLE_SSCANF 1 -++#endif -++#ifndef SECUREC_ENABLE_VSSCANF -++#define SECUREC_ENABLE_VSSCANF 1 -++#endif -++#ifndef SECUREC_ENABLE_SCANF -++#if SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_SCANF 1 -++#else -++#define SECUREC_ENABLE_SCANF 0 -++#endif -++#endif -++#ifndef SECUREC_ENABLE_VSCANF -++#if SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_VSCANF 1 -++#else -++#define SECUREC_ENABLE_VSCANF 0 -++#endif -++#endif -++ -++#ifndef SECUREC_ENABLE_FSCANF -++#if SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_FSCANF 1 -++#else -++#define SECUREC_ENABLE_FSCANF 0 -++#endif -++#endif -++#ifndef SECUREC_ENABLE_VFSCANF -++#if SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_VFSCANF 1 -++#else -++#define SECUREC_ENABLE_VFSCANF 0 -++#endif -++#endif -++ -++#ifndef SECUREC_ENABLE_STRTOK -++#define SECUREC_ENABLE_STRTOK 1 -++#endif -++#ifndef SECUREC_ENABLE_GETS -++#define SECUREC_ENABLE_GETS 1 -++#endif -++#endif /* SECUREC_USE_STD_SECURE_LIB */ -++ -++#if !SECUREC_ENABLE_SCANF_FILE -++#if SECUREC_ENABLE_FSCANF -++#undef SECUREC_ENABLE_FSCANF -++#define SECUREC_ENABLE_FSCANF 0 -++#endif -++#if SECUREC_ENABLE_VFSCANF -++#undef SECUREC_ENABLE_VFSCANF -++#define SECUREC_ENABLE_VFSCANF 0 -++#endif -++#if SECUREC_ENABLE_SCANF -++#undef SECUREC_ENABLE_SCANF -++#define SECUREC_ENABLE_SCANF 0 -++#endif -++#if SECUREC_ENABLE_FSCANF -++#undef SECUREC_ENABLE_FSCANF -++#define SECUREC_ENABLE_FSCANF 0 -++#endif -++ -++#endif -++ -++#if SECUREC_IN_KERNEL -++#include -++#include -++#else -++#ifndef SECUREC_HAVE_STDIO_H -++#define SECUREC_HAVE_STDIO_H 1 -++#endif -++#ifndef SECUREC_HAVE_STRING_H -++#define SECUREC_HAVE_STRING_H 1 -++#endif -++#ifndef SECUREC_HAVE_STDLIB_H -++#define SECUREC_HAVE_STDLIB_H 1 -++#endif -++#if SECUREC_HAVE_STDIO_H -++#include -++#endif -++#if SECUREC_HAVE_STRING_H -++#include -++#endif -++#if SECUREC_HAVE_STDLIB_H -++#include -++#endif -++#endif -++ -++/* -++ * If you need high performance, enable the SECUREC_WITH_PERFORMANCE_ADDONS macro, default is enable. -++ * The macro is automatically closed on the windows platform and linux kernel -++ */ -++#ifndef SECUREC_WITH_PERFORMANCE_ADDONS -++#if SECUREC_IN_KERNEL -++#define SECUREC_WITH_PERFORMANCE_ADDONS 0 -++#else -++#define SECUREC_WITH_PERFORMANCE_ADDONS 1 -++#endif -++#endif -++ -++/* If enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible to Windows. */ -++#if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && !defined(SECUREC_COMPATIBLE_LINUX_FORMAT) -++#ifndef SECUREC_COMPATIBLE_WIN_FORMAT -++#define SECUREC_COMPATIBLE_WIN_FORMAT -++#endif -++#endif -++ -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++/* On windows platform, can't use optimized function for there is no __builtin_constant_p like function */ -++/* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */ -++#ifdef SECUREC_WITH_PERFORMANCE_ADDONS -++#undef SECUREC_WITH_PERFORMANCE_ADDONS -++#define SECUREC_WITH_PERFORMANCE_ADDONS 0 -++#endif -++#endif -++ -++#if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || defined(_VXWORKS_PLATFORM_) || \ -++ defined(SECUREC_VXWORKS_VERSION_5_4) -++#ifndef SECUREC_VXWORKS_PLATFORM -++#define SECUREC_VXWORKS_PLATFORM -++#endif -++#endif -++ -++/* If enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be compatible to Linux. */ -++#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) && !defined(SECUREC_VXWORKS_PLATFORM) -++#ifndef SECUREC_COMPATIBLE_LINUX_FORMAT -++#define SECUREC_COMPATIBLE_LINUX_FORMAT -++#endif -++#endif -++ -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++#ifndef SECUREC_HAVE_STDDEF_H -++#define SECUREC_HAVE_STDDEF_H 1 -++#endif -++/* Some system may no stddef.h */ -++#if SECUREC_HAVE_STDDEF_H -++#if !SECUREC_IN_KERNEL -++#include -++#endif -++#endif -++#endif -++ -++/* -++ * Add the -DSECUREC_SUPPORT_FORMAT_WARNING=1 compiler option to supoort -Wformat=2. -++ * Default does not check the format is that the same data type in the actual code. -++ * In the product is different in the original data type definition of VxWorks and Linux. -++ */ -++#ifndef SECUREC_SUPPORT_FORMAT_WARNING -++#define SECUREC_SUPPORT_FORMAT_WARNING 0 -++#endif -++ -++#if SECUREC_SUPPORT_FORMAT_WARNING -++#define SECUREC_ATTRIBUTE(x, y) __attribute__((format(printf, (x), (y)))) -++#else -++#define SECUREC_ATTRIBUTE(x, y) -++#endif -++ -++/* -++ * Add the -DSECUREC_SUPPORT_BUILTIN_EXPECT=0 compiler option, if compiler can not support __builtin_expect. -++ */ -++#ifndef SECUREC_SUPPORT_BUILTIN_EXPECT -++#define SECUREC_SUPPORT_BUILTIN_EXPECT 1 -++#endif -++ -++#if SECUREC_SUPPORT_BUILTIN_EXPECT && defined(__GNUC__) && ((__GNUC__ > 3) || \ -++ (defined(__GNUC_MINOR__) && (__GNUC__ == 3 && __GNUC_MINOR__ > 3))) -++/* -++ * This is a built-in function that can be used without a declaration, if warning for declaration not found occurred, -++ * you can add -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to compiler options -++ */ -++#ifdef SECUREC_NEED_BUILTIN_EXPECT_DECLARE -++long __builtin_expect(long exp, long c); -++#endif -++ -++#define SECUREC_LIKELY(x) __builtin_expect(!!(x), 1) -++#define SECUREC_UNLIKELY(x) __builtin_expect(!!(x), 0) -++#else -++#define SECUREC_LIKELY(x) (x) -++#define SECUREC_UNLIKELY(x) (x) -++#endif -++ -++/* Define the max length of the string */ -++#ifndef SECUREC_STRING_MAX_LEN -++#define SECUREC_STRING_MAX_LEN 0x7fffffffUL -++#endif -++#define SECUREC_WCHAR_STRING_MAX_LEN (SECUREC_STRING_MAX_LEN / sizeof(wchar_t)) -++ -++/* Add SECUREC_MEM_MAX_LEN for memcpy and memmove */ -++#ifndef SECUREC_MEM_MAX_LEN -++#define SECUREC_MEM_MAX_LEN 0x7fffffffUL -++#endif -++#define SECUREC_WCHAR_MEM_MAX_LEN (SECUREC_MEM_MAX_LEN / sizeof(wchar_t)) -++ -++#if SECUREC_STRING_MAX_LEN > 0x7fffffffUL -++#error "max string is 2G" -++#endif -++ -++#if (defined(__GNUC__) && defined(__SIZEOF_POINTER__)) -++#if (__SIZEOF_POINTER__ != 4) && (__SIZEOF_POINTER__ != 8) -++#error "unsupported system" -++#endif -++#endif -++ -++#if defined(_WIN64) || defined(WIN64) || defined(__LP64__) || defined(_LP64) -++#define SECUREC_ON_64BITS -++#endif -++ -++#if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__) && defined(__SIZEOF_POINTER__)) -++#if __SIZEOF_POINTER__ == 8 -++#define SECUREC_ON_64BITS -++#endif -++#endif -++ -++#if defined(__SVR4) || defined(__svr4__) -++#define SECUREC_ON_SOLARIS -++#endif -++ -++#if (defined(__hpux) || defined(_AIX) || defined(SECUREC_ON_SOLARIS)) -++#define SECUREC_ON_UNIX -++#endif -++ -++/* -++ * Codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknown system on default, -++ * and strtold. -++ * The function strtold is referenced first at ISO9899:1999(C99), and some old compilers can -++ * not support these functions. Here provides a macro to open these functions: -++ * SECUREC_SUPPORT_STRTOLD -- If defined, strtold will be used -++ */ -++#ifndef SECUREC_SUPPORT_STRTOLD -++#define SECUREC_SUPPORT_STRTOLD 0 -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) -++#if defined(__USE_ISOC99) || \ -++ (defined(_AIX) && defined(_ISOC99_SOURCE)) || \ -++ (defined(__hpux) && defined(__ia64)) || \ -++ (defined(SECUREC_ON_SOLARIS) && (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \ -++ defined(_STDC_C99) || defined(__EXTENSIONS__)) -++#undef SECUREC_SUPPORT_STRTOLD -++#define SECUREC_SUPPORT_STRTOLD 1 -++#endif -++#endif -++#if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_))) -++#undef SECUREC_SUPPORT_STRTOLD -++#define SECUREC_SUPPORT_STRTOLD 0 -++#endif -++#endif -++ -++#if SECUREC_WITH_PERFORMANCE_ADDONS -++ -++#ifndef SECUREC_TWO_MIN -++#define SECUREC_TWO_MIN(a, b) ((a) < (b) ? (a) : (b)) -++#endif -++ -++/* For strncpy_s performance optimization */ -++#define SECUREC_STRNCPY_SM(dest, destMax, src, count) \ -++ (((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ -++ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ -++ (SECUREC_TWO_MIN((size_t)(count), strlen(src)) + 1) <= (size_t)(destMax)) ? \ -++ (((size_t)(count) < strlen(src)) ? (memcpy((dest), (src), (count)), *((char *)(dest) + (count)) = '\0', EOK) : \ -++ (memcpy((dest), (src), strlen(src) + 1), EOK)) : (strncpy_error((dest), (destMax), (src), (count)))) -++ -++#define SECUREC_STRCPY_SM(dest, destMax, src) \ -++ (((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ -++ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ -++ (strlen(src) + 1) <= (size_t)(destMax)) ? (memcpy((dest), (src), strlen(src) + 1), EOK) : \ -++ (strcpy_error((dest), (destMax), (src)))) -++ -++/* For strcat_s performance optimization */ -++#if defined(__GNUC__) -++#define SECUREC_STRCAT_SM(dest, destMax, src) ({ \ -++ int catRet_ = EOK; \ -++ if ((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ -++ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ -++ char *catTmpDst_ = (char *)(dest); \ -++ size_t catRestSize_ = (destMax); \ -++ while (catRestSize_ > 0 && *catTmpDst_ != '\0') { \ -++ ++catTmpDst_; \ -++ --catRestSize_; \ -++ } \ -++ if (catRestSize_ == 0) { \ -++ catRet_ = EINVAL; \ -++ } else if ((strlen(src) + 1) <= catRestSize_) { \ -++ memcpy(catTmpDst_, (src), strlen(src) + 1); \ -++ catRet_ = EOK; \ -++ } else { \ -++ catRet_ = ERANGE; \ -++ } \ -++ if (catRet_ != EOK) { \ -++ catRet_ = strcat_s((dest), (destMax), (src)); \ -++ } \ -++ } else { \ -++ catRet_ = strcat_s((dest), (destMax), (src)); \ -++ } \ -++ catRet_; \ -++}) -++#else -++#define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s((dest), (destMax), (src)) -++#endif -++ -++/* For strncat_s performance optimization */ -++#if defined(__GNUC__) -++#define SECUREC_STRNCAT_SM(dest, destMax, src, count) ({ \ -++ int ncatRet_ = EOK; \ -++ if ((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \ -++ (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \ -++ (((unsigned long long)(count) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \ -++ char *ncatTmpDest_ = (char *)(dest); \ -++ size_t ncatRestSize_ = (size_t)(destMax); \ -++ while (ncatRestSize_ > 0 && *ncatTmpDest_ != '\0') { \ -++ ++ncatTmpDest_; \ -++ --ncatRestSize_; \ -++ } \ -++ if (ncatRestSize_ == 0) { \ -++ ncatRet_ = EINVAL; \ -++ } else if ((SECUREC_TWO_MIN((count), strlen(src)) + 1) <= ncatRestSize_) { \ -++ if ((size_t)(count) < strlen(src)) { \ -++ memcpy(ncatTmpDest_, (src), (count)); \ -++ *(ncatTmpDest_ + (count)) = '\0'; \ -++ } else { \ -++ memcpy(ncatTmpDest_, (src), strlen(src) + 1); \ -++ } \ -++ } else { \ -++ ncatRet_ = ERANGE; \ -++ } \ -++ if (ncatRet_ != EOK) { \ -++ ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \ -++ } \ -++ } else { \ -++ ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \ -++ } \ -++ ncatRet_; \ -++}) -++#else -++#define SECUREC_STRNCAT_SM(dest, destMax, src, count) strncat_s((dest), (destMax), (src), (count)) -++#endif -++ -++/* This macro do not check buffer overlap by default */ -++#define SECUREC_MEMCPY_SM(dest, destMax, src, count) \ -++ (!(((size_t)(destMax) == 0) || \ -++ (((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ -++ ((size_t)(count) > (size_t)(destMax)) || ((void *)(dest)) == NULL || ((const void *)(src) == NULL)) ? \ -++ (memcpy((dest), (src), (count)), EOK) : \ -++ (memcpy_s((dest), (destMax), (src), (count)))) -++ -++#define SECUREC_MEMSET_SM(dest, destMax, c, count) \ -++ (!((((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \ -++ ((void *)(dest) == NULL) || ((size_t)(count) > (size_t)(destMax))) ? \ -++ (memset((dest), (c), (count)), EOK) : \ -++ (memset_s((dest), (destMax), (c), (count)))) -++ -++#endif -++#endif /* CONFIG_ARCH_BSP */ -++#endif -++ -+diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h -+index 18a9949bb..12cae68e2 100644 -+--- a/include/linux/tee_drv.h -++++ b/include/linux/tee_drv.h -+@@ -186,6 +186,22 @@ void tee_device_unregister(struct tee_device *teedev); -+ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method, -+ const u8 connection_data[TEE_IOCTL_UUID_LEN]); -+ -++#ifdef CONFIG_ARCH_BSP -++/** -++ * regist_smmz_parameter_conversion_hook() -++ * @hook: Hook to be registered -++ * -++ * If the hook is registered multiple times, the previous hook will -++ * be overwritten by the later hook. -++ * -++ * If a module has a hook registered, the module cannot be removed. -++ * -++ */ -++void regist_smmz_parameter_conversion_hook(phys_addr_t (*hook)(int, pid_t)); -++ -++void unregist_smmz_parameter_conversion_hook(void); -++#endif -++ -+ /** -+ * struct tee_shm - shared memory object -+ * @ctx: context using the object -+diff --git a/include/linux/vendor/sva_ext.h b/include/linux/vendor/sva_ext.h -+new file mode 100755 -+index 000000000..f037f99c3 -+--- /dev/null -++++ b/include/linux/vendor/sva_ext.h -+@@ -0,0 +1,82 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _SVA_EXTEND_H -++#define _SVA_EXTEND_H -++ -++#ifdef CONFIG_VENDOR_NPU -++ -++extern void iommu_sva_flush_iotlb_single(struct mm_struct *mm); -++ -++extern const char *iommu_sva_get_smmu_device_name(struct mm_struct *mm); -++ -++extern int arm_smmu_device_post_probe(const char *device_name); -++ -++extern int arm_smmu_device_resume(const char *device_name); -++ -++extern int arm_smmu_device_suspend(const char *device_name); -++ -++extern int arm_smmu_device_reset_ex(const char *device_name); -++ -++extern const char *arm_smmu_get_device_name(struct iommu_domain *domain); -++ -++extern int svm_flush_cache(struct mm_struct *mm, unsigned long addr, size_t size); -++ -++extern void svm_smmu_clk_live_enter(void); -++extern void svm_smmu_clk_live_exit(void); -++ -++#else -++static inline void iommu_sva_flush_iotlb_single(struct mm_struct *mm) -++{ -++ return; -++} -++ -++static inline const char *iommu_sva_get_smmu_device_name(struct mm_struct *mm) -++{ -++ return NULL; -++} -++ -++static inline int arm_smmu_device_post_probe(const char *device_name) -++{ -++ return -1; -++} -++ -++static inline int arm_smmu_device_resume(const char *device_name) -++{ -++ return -1; -++} -++ -++static inline int arm_smmu_device_suspend(const char *device_name) -++{ -++ return -1; -++} -++ -++static inline int arm_smmu_device_reset_ex(const char *device_name) -++{ -++ return -1; -++} -++ -++static const char *arm_smmu_get_device_name(struct iommu_domain *domain) -++{ -++ return NULL; -++} -++ -++static inline int svm_flush_cache(struct mm_struct *mm, unsigned long addr, size_t size) -++{ -++ return -1; -++} -++ -++static inline void svm_smmu_clk_live_enter(void) -++{ -++ return; -++} -++ -++static inline void svm_smmu_clk_live_exit(void) -++{ -++ return; -++} -++ -++#endif -++ -++#endif /* _SVA_EXTEND_H */ -+diff --git a/include/linux/vendor/vendor_i2c.h b/include/linux/vendor/vendor_i2c.h -+new file mode 100755 -+index 000000000..e3094662a -+--- /dev/null -++++ b/include/linux/vendor/vendor_i2c.h -+@@ -0,0 +1,27 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++#ifndef __VENDOR_LINUX_I2C_H -++#define __VENDOR_LINUX_I2C_H -++ -++struct i2c_msg; -++struct i2c_adapter; -++struct i2c_client; -++ -++#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 */ -++ -++extern int bsp_i2c_master_send(const struct i2c_client *client, const char *buf, -++ __u16 count); -++ -++extern int bsp_i2c_master_send_mul_reg(const struct i2c_client *client, const char *buf, -++ __u16 count, unsigned int reg_data_width); -++ -++extern int bsp_i2c_master_recv(const struct i2c_client *client, const char *buf, -++ int count); -++ -++extern int bsp_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, -++ int num); -++ -++#endif /* __VENDOR_LINUX_I2C_H */ -+diff --git a/include/uapi/linux/i2c-dev.h b/include/uapi/linux/i2c-dev.h -+index 85f8047af..0e88211f8 100644 -+--- a/include/uapi/linux/i2c-dev.h -++++ b/include/uapi/linux/i2c-dev.h -+@@ -52,7 +52,6 @@ -+ #define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */ -+ #define I2C_SMBUS 0x0720 /* SMBus transfer */ -+ -+- -+ /* This is the structure as used in the I2C_SMBUS ioctl call */ -+ struct i2c_smbus_ioctl_data { -+ __u8 read_write; -+diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h -+index f71a1751c..8f329bcff 100644 -+--- a/include/uapi/linux/i2c.h -++++ b/include/uapi/linux/i2c.h -+@@ -22,7 +22,7 @@ -+ MA 02110-1301 USA. */ -+ /* ------------------------------------------------------------------------- */ -+ -+-/* With some changes from Kyösti Mälkki and -++/* With some changes from Kyosti Malkki and -+ Frodo Looijaard */ -+ -+ #ifndef _UAPI_LINUX_I2C_H -+diff --git a/include/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h -+index a5773899f..c3fa48f92 100644 -+--- a/include/uapi/linux/msdos_fs.h -++++ b/include/uapi/linux/msdos_fs.h -+@@ -93,7 +93,23 @@ struct __fat_dirent { -+ unsigned short d_reclen; -+ char d_name[256]; /* We must not include limits.h! */ -+ }; -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++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 -+ */ -+@@ -104,7 +120,9 @@ struct __fat_dirent { -+ #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) -+- -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_BSP_FAT_OPTIMIZE)) -++#define VFAT_IOCTL_READDIR_ALL _IOR('r', 0x14, struct fat_direntall_buf) -++#endif -+ struct fat_boot_sector { -+ __u8 ignored[3]; /* Boot strap short or near jump */ -+ __u8 system_id[8]; /* Name - can be used to special case -+diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h -+index 652f169a0..8880b7c9f 100644 -+--- a/include/uapi/linux/usb/g_uvc.h -++++ b/include/uapi/linux/usb/g_uvc.h -+@@ -34,6 +34,24 @@ struct uvc_event { -+ }; -+ }; -+ -++#ifdef CONFIG_ARCH_BSP -++#if IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) -++/*-------------------------------------------------------------------------*/ -++struct uvc_pack { -++ uint64_t buf_vir_addr; -++ uint32_t buf_size; -++ uint64_t pack_vir_addr; -++ uint32_t pack_len; -++ void *private_data; -++ -++ void (*callback_func)(void *); -++ bool is_frame_end; -++}; -++ -++extern int uvc_recv_pack(struct uvc_pack *pack); -++#endif /* IS_ENABLED(CONFIG_MPP_TO_GADGET_UVC) */ -++#endif // CONFIG_ARCH_BSP -++/*-------------------------------------------------------------------------*/ -+ #define UVCIOC_SEND_RESPONSE _IOW('U', 1, struct uvc_request_data) -+ -+ #endif /* __LINUX_USB_G_UVC_H */ -+diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h -+index c58854fb7..f1c413f7e 100644 -+--- a/include/uapi/linux/usb/video.h -++++ b/include/uapi/linux/usb/video.h -+@@ -372,6 +372,9 @@ struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) { \ -+ __u8 iExtension; \ -+ } __attribute__ ((packed)) -+ -++#ifdef CONFIG_ARCH_BSP -++DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(1,2); -++#endif -+ /* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */ -+ struct uvc_control_endpoint_descriptor { -+ __u8 bLength; -+@@ -597,5 +600,64 @@ struct UVC_FRAME_MJPEG(n) { \ -+ __le32 dwFrameInterval[n]; \ -+ } __attribute__ ((packed)) -+ -++#ifdef CONFIG_ARCH_BSP -++/* 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; -++ __le16 wWidth; -++ __le16 wHeight; -++ __le32 dwMinBitRate; -++ __le32 dwMaxBitRate; -++ __le32 dwDefaultFrameInterval; -++ __u8 bFrameIntervalType; -++ __le32 dwBytesPerLine; -++ __le32 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; \ -++ __le16 wWidth; \ -++ __le16 wHeight; \ -++ __le32 dwMinBitRate; \ -++ __le32 dwMaxBitRate; \ -++ __le32 dwDefaultFrameInterval; \ -++ __u8 bFrameIntervalType; \ -++ __le32 dwBytesPerLine; \ -++ __le32 dwFrameInterval[n]; \ -++} __attribute__ ((packed)) -++#endif // CONFIG_ARCH_BSP -+ #endif /* __LINUX_USB_VIDEO_H */ -+ -+diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h -+index 55b8c4b82..ec0b39d1d 100644 -+--- a/include/uapi/linux/videodev2.h -++++ b/include/uapi/linux/videodev2.h -+@@ -705,6 +705,9 @@ struct v4l2_pix_format { -+ #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */ -+ #define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */ -+ #define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */ -++#ifdef CONFIG_ARCH_BSP -++#define V4L2_PIX_FMT_H265 v4l2_fourcc('H', '2', '6', '5') /* H.265 aka HEVC */ -++#endif -+ -+ /* Vendor-specific formats */ -+ #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ -+diff --git a/init/Kconfig.faststartup b/init/Kconfig.faststartup -+new file mode 100755 -+index 000000000..6a2e8baf6 -+--- /dev/null -++++ b/init/Kconfig.faststartup -+@@ -0,0 +1,69 @@ -++config BSP_FAST_STARTUP -++ bool "for fast startup usage" -++ select MINI_OPT -++ depends on ARCH_BSP -++ -++if BSP_FAST_STARTUP -++config STARTUP_PARALLEL_CREATION_NODE_OPT -++ bool "parallize node creation" -++config STARTUP_PARALLEL_OPT -++ bool "parallize init module" -++ if STARTUP_PARALLEL_OPT -++ config DEPENDENCIES -++ bool "Use dependency based initialization sequence (DO NOT USE)" -++ select ANNOTATED_INITCALLS -++ depends on STARTUP_PARALLEL_OPT -++ help -++ This will likely crash your kernel at startup. You have been warned. -++ That means you should make sure you have a working backup kernel -++ you can boot from in case the kernel with this feature turned on -++ crashes. -++ In order to benefit from this feature, statically linked drivers -++ have to provide dependencies. -++ config DEPENDENCIES_PARALLEL -++ bool "Call annotated initcalls in parallel" -++ depends on DEPENDENCIES -++ help -++ Calculates which (annotated) initcalls can be called in parallel -++ and calls them using multiple threads. -++ config DEPENDENCIES_THREADS -++ int "Number of threads to use for parallel initialization" -++ depends on DEPENDENCIES_PARALLEL -++ default 0 -++ help -++ 0 means the number of threads used for parallel initialization -++ of drivers equals the number of online CPUs. -++ 1 means the threaded initialization is disabled. -++ endif -++endif -++ -++config MINI_OPT -++ bool "for miniaturization optimize usage" -++ -++if MINI_OPT -++config SYSFS_MINI_OPT -++ bool "sysfs file creation optimization" -++ default y -++ help -++ Optimize sysfs file node creation, only disabling those unnecessary -++ for function or debugging features. -++config KUEVENT_MINI_OPT -++ bool "kuevent diabled before finshing boot" -++ default y -++ help -++ Optimize uevent notification, only keep those required by the scenario, -++ such as the SD card, USB block subsystem device insertion and removal.. -++config BOOTSTAGE_PRINTK_MINI_OPT -++ bool "diable log to mem" -++ default y -++ help -++ Generally, printk can be configured based on the priority to disable serial port output. -++ However, it still prints to the memory, which still consumes memory and performance. -++ Therefore, performance and memory can be optimized by completely disabling printing. -++config SYSFS_SLAB_MINI_OPT -++ bool "sysfs slab debug disable control" -++ default y -++ help -++ The sysfs saves the slab allocation information to facilitate debugging. -++ In the optimized fastboot version, the function can be disabled and enabled as required. -++endif -+diff --git a/init/Kconfig.timestamp b/init/Kconfig.timestamp -+new file mode 100755 -+index 000000000..905e63957 -+--- /dev/null -++++ b/init/Kconfig.timestamp -+@@ -0,0 +1,7 @@ -++ -++config CMD_TIMESTAMP -++ bool "Show timing information that stamped during booting stage in the start_kernel" -++ depends on BSP_FAST_STARTUP -++ default n -++ help -++ The timestamp is always recorded internally, you can use 'dmesg | grep timestamp' command to check the details. -+diff --git a/init/Makefile b/init/Makefile -+index 6bc37f64b..de88af977 100644 -+--- a/init/Makefile -++++ b/init/Makefile -+@@ -19,6 +19,12 @@ mounts-y := do_mounts.o -+ mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o -+ mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o -+ -++ifdef CONFIG_ARCH_BSP -++ifdef CONFIG_STARTUP_PARALLEL_OPT -++obj-$(CONFIG_BSP_FAST_STARTUP) += dependencies.o -++endif -++endif -++ -+ # dependencies on generated files need to be listed explicitly -+ $(obj)/version.o: include/generated/compile.h -+ -+@@ -35,3 +41,5 @@ include/generated/compile.h: FORCE -+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ -+ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" \ -+ "$(CONFIG_PREEMPT_RT)" $(CONFIG_CC_VERSION_TEXT) "$(LD)" -++ -++obj-$(CONFIG_ARCH_BSP) += vendor/ -+diff --git a/init/dependencies.c b/init/dependencies.c -+new file mode 100755 -+index 000000000..3bb3bec4b -+--- /dev/null -++++ b/init/dependencies.c -+@@ -0,0 +1,452 @@ -++/* -++ * Copyright (c) CompanyNameMagicTag 2023-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#define MAX_VERTICES DRVID_MAX /* maximum number of vertices */ -++#define MAX_EDGES (MAX_VERTICES * 5) /* maximum number of edges (dependencies) */ -++struct edgenode { -++ unsigned y; /* initcall ID */ -++#ifdef CONFIG_DEPENDENCIES_PARALLEL -++ unsigned x; -++#endif -++ struct edgenode *next; /* next edge in list */ -++}; -++ -++/* Vertex numbers correspond to initcall IDs. */ -++static struct edgenode edge_slots[MAX_EDGES] __initdata; /* avoid kmalloc */ -++static struct edgenode *edges[MAX_VERTICES] __initdata; /* adjacency info */ -++static unsigned nedges __initdata; /* number of edges */ -++static unsigned nvertices __initdata; /* number of vertices */ -++static bool processed[MAX_VERTICES] __initdata; -++static bool include_node[MAX_VERTICES] __initdata; -++static bool discovered[MAX_VERTICES] __initdata; -++ -++static unsigned order[MAX_VERTICES] __initdata; -++static unsigned norder __initdata; -++static const struct _annotated_initcall -++ *annotated_initcall_by_drvid[MAX_VERTICES] __initdata; -++#ifdef CONFIG_LOAD_VI_ONLY -++#if defined (CONFIG_MPPQUICKKO_LOAD_FROM_XXX_SUPPORT_PM) -++#define WHITELIST_COUNT (15) -++#else -++#define WHITELIST_COUNT (15) -++#endif -++#else // CONFIG_LOAD_VI_ONLY -++#ifdef CONFIG_MPPQUICKKO_LOAD_FROM_XXX_SUPPORT_VO -++#if defined (CONFIG_MPPQUICKKO_LOAD_FROM_XXX_SUPPORT_PM) -++#define WHITELIST_COUNT (26) -++#else -++#define WHITELIST_COUNT (25) -++#endif -++#else // CONFIG_MPPQUICKKO_LOAD_FROM_XXX_SUPPORT_VO -++#if defined (CONFIG_MPPQUICKKO_LOAD_FROM_XXX_SUPPORT_PM) -++#define WHITELIST_COUNT (23) -++#else -++#define WHITELIST_COUNT (22) -++#endif -++#endif -++static const struct _annotated_initcall -++ *annotated_initcall_mppko_whitelist_by_drvid[WHITELIST_COUNT] __initdata; -++static const unsigned annotated_initcall_mppko_whitelist_drvid[WHITELIST_COUNT] = { -++ initcall_id(ot_sysconfig_init), -++ initcall_id(osal_module_init), -++ initcall_id(mmz_init), -++ initcall_id(base_mod_init), -++ initcall_id(vb_mod_init), -++ initcall_id(vca_mod_init), -++ initcall_id(g_ot_sys_driver_init), -++ initcall_id(rgn_mod_init), -++ initcall_id(vpp_mod_init), -++ initcall_id(g_ot_vgs_device_driver_init), -++ initcall_id(g_ot_vi_driver_init), -++ initcall_id(isp_mod_init), -++ initcall_id(g_ot_vpss_driver_init), -++ initcall_id(chnl_mod_init), -++ initcall_id(rc_mod_init), -++ initcall_id(venc_mod_init), -++ initcall_id(h264e_mod_init), -++ initcall_id(h265e_mod_init), -++ initcall_id(jpege_mod_init), -++ initcall_id(g_mipirx_driver_init), -++ initcall_id(i2c_module_init), -++}; -++#endif -++ -++int __init add_initcall_dependency(unsigned id, unsigned id_dependency) -++{ -++ struct edgenode *p; -++ -++ if (!id || !id_dependency) -++ return 0; /* ignore root */ -++ if (unlikely(nedges >= MAX_EDGES)) { -++ pr_err("init: maximum number of edges (%u) reached!\n", -++ MAX_EDGES); -++ return -EINVAL; -++ } -++ if (unlikely(id == id_dependency)) -++ return 0; -++ if (!include_node[id] || !include_node[id_dependency]) -++ return 0; /* ignore edges for initcalls not included */ -++ p = &edge_slots[nedges++]; -++ p->y = id_dependency; -++#ifdef CONFIG_DEPENDENCIES_PARALLEL -++ p->x = id; -++#endif -++ /* insert at head of list */ -++ p->next = edges[id]; -++ edges[id] = p; -++ -++ return 0; -++} -++ -++static int __init depth_first_search(unsigned v) -++{ -++ struct edgenode *p; -++ unsigned y; /* successor vertex */ -++ -++ discovered[v] = 1; -++ p = edges[v]; -++ while (p) { -++ y = p->y; -++ if (unlikely(discovered[y] && !processed[y])) { -++ pr_err("init: cycle found %u <-> %u!\n", v, y); -++ return -EINVAL; -++ } -++ if (!discovered[y] && depth_first_search(y)) -++ return -EINVAL; -++ p = p->next; -++ } -++ order[norder++] = v; -++ processed[v] = 1; -++ return 0; -++} -++ -++static int __init topological_sort(void) -++{ -++ unsigned i; -++ -++ for (i = 1; i <= nvertices; ++i) -++ if (!discovered[i] && include_node[i]) -++ if (depth_first_search(i)) -++ return -EINVAL; -++ return 0; -++} -++ -++#ifdef CONFIG_DEPENDENCIES_PARALLEL -++/* -++ * The algorithm I've used below to calculate the max. distance for -++ * nodes to the root node likely isn't the fasted. But based on the -++ * already done implementation of the topological sort, this is an -++ * easy way to achieve this. Instead of first doing an topological -++ * sort and then using the stuff below to calculate the distances, -++ * using an algorithm which does spit out distances directly would -++ * be likely faster (also we are talking here about a few ms). -++ * If you want to spend the time, you could have a look e.g. at the -++ * topic 'layered graph drawing'. -++ */ -++/* max. distance from a node to root */ -++static unsigned distance[MAX_VERTICES] __initdata; -++static struct { -++ unsigned start; -++ unsigned length; -++} tgroup[20] __initdata; -++static unsigned count_groups __initdata; -++static __initdata DECLARE_COMPLETION(initcall_thread_done); -++static atomic_t shared_counter __initdata; -++static atomic_t count_initcall_threads __initdata; -++static atomic_t ostart __initdata; -++static atomic_t ocount __initdata; -++static atomic_t current_group __initdata; -++static unsigned num_threads __initdata; -++static __initdata DECLARE_WAIT_QUEUE_HEAD(group_waitqueue); -++ -++static void __init calc_max_distance(uint32_t v) -++{ -++ unsigned i; -++ unsigned max_dist = 0; -++ pr_debug("edges num is %u +++++++++++++++++++++\n", nedges); -++ for (i = 0; i < nedges; ++i) -++ if (edge_slots[i].x == v) -++ max_dist = max(max_dist, distance[edge_slots[i].y] + 1); -++ distance[v] = max_dist; -++} -++ -++static void __init calc_distances(void) -++{ -++ unsigned i; -++ -++ for (i = 0; i < norder; ++i) -++ calc_max_distance(order[i]); -++} -++ -++static int __init compare_by_distance(const void *lhs, const void *rhs) -++{ -++ if (distance[*(unsigned *)lhs] < distance[*(unsigned *)rhs]) -++ return -1; -++ if (distance[*(unsigned *)lhs] > distance[*(unsigned *)rhs]) -++ return 1; -++ if (*(unsigned *)lhs < *(unsigned *)rhs) -++ return -1; -++ if (*(unsigned *)lhs > *(unsigned *)rhs) -++ return 1; -++ return 0; -++} -++ -++static void __init build_order_by_distance(void) -++{ -++ calc_distances(); -++ sort(order, norder, sizeof(unsigned), &compare_by_distance, NULL); -++} -++ -++static void __init build_tgroups(void) -++{ -++ unsigned i; -++ unsigned dist = 0; -++ -++ for (i = 0; i < norder; ++i) { -++ if (distance[order[i]] != dist) { -++ dist = distance[order[i]]; -++ count_groups++; -++ tgroup[count_groups].start = i; -++ } -++ tgroup[count_groups].length++; -++ } -++ count_groups++; -++#ifdef DEBUG -++ for (i = 0; i < count_groups; ++i) -++ pr_info("init: group %u length %u (start %u)\n", i, -++ tgroup[i].length, tgroup[i].start); -++#endif -++} -++ -++static void __init init_drivers_non_threaded_for_mppko_whitelist(void) -++{ -++ unsigned i; -++ const struct _annotated_initcall *ac; -++ -++ for (i = 0; i < WHITELIST_COUNT; i++) { -++ ac = annotated_initcall_mppko_whitelist_by_drvid[i]; -++ if (ac != NULL) { -++ pr_debug("do_initcall_media: %ps\n", *ac->initcall); -++ do_one_initcall(*ac->initcall); -++ } -++ } -++} -++ -++static int __init initcall_thread(void *thread_nr) -++{ -++ int i; -++ unsigned group; -++ int start, count; -++ const struct _annotated_initcall *ac; -++ DEFINE_WAIT(wait); -++ while ((group = atomic_read(¤t_group)) < count_groups) { -++ start = atomic_read(&ostart); -++ count = atomic_read(&ocount); -++ while ((i = atomic_dec_return(&shared_counter)) >= 0) { -++ ac = annotated_initcall_by_drvid[order[start + count - -++ 1 - i]]; -++ pr_err("do_initcall: %ps\n", *ac->initcall); -++ do_one_initcall(*ac->initcall); -++ } -++ prepare_to_wait(&group_waitqueue, &wait, TASK_UNINTERRUPTIBLE); -++ if (!atomic_dec_and_test(&count_initcall_threads)) { -++ /* -++ * The current group was processed, sleep until the -++ * last thread finished work on this group, changes -++ * the group and wakes up all threads. -++ */ -++ schedule(); -++ finish_wait(&group_waitqueue, &wait); -++ continue; -++ } -++ atomic_inc(¤t_group); -++ atomic_set(&count_initcall_threads, num_threads); -++ if (++group >= count_groups) { -++ /* -++ * All groups processed and all threads finished. -++ * Prepare to process unordered annotated -++ * initcalls and wake up other threads to call -++ * them too. -++ */ -++ atomic_set( -++ &shared_counter, -++ __annotated_initcall_end - -++ __annotated_initcall_start); // here changed by yu -++ wake_up_all(&group_waitqueue); -++ finish_wait(&group_waitqueue, &wait); -++ break; -++ } -++ /* -++ * Finalize the switch to the next group and wake up other -++ * threads to process the new group too. -++ */ -++ atomic_set(&ostart, tgroup[group].start); -++ atomic_set(&ocount, tgroup[group].length); -++ atomic_set(&shared_counter, tgroup[group].length); -++ wake_up_all(&group_waitqueue); -++ finish_wait(&group_waitqueue, &wait); -++ } -++ if (atomic_dec_and_test(&count_initcall_threads)) -++ complete(&initcall_thread_done); -++ do_exit(0); -++ return 0; -++} -++#endif /* CONFIG_DEPENDENCIES_PARALLEL */ -++ -++static void __init init_drivers_non_threaded(void) -++{ -++ unsigned i; -++ const struct _annotated_initcall *ac; -++ -++ for (i = 0; i < norder; ++i) { -++ ac = annotated_initcall_by_drvid[order[i]]; -++ do_one_initcall(*ac->initcall); -++ } -++} -++ -++static int __init add_dependencies(void) -++{ -++ int rc; -++ const struct _annotated_initcall *ac; -++ const unsigned *dep; -++ unsigned i; -++ pr_debug("add_dependencies++++++++++\n"); -++ -++ ac = __annotated_initcall_start; -++ for (; ac < __annotated_initcall_end; ++ac) { -++ dep = ac->dependencies; -++ pr_debug( -++ "for cnt ac : %p dep = %p ---------\n", -++ ac, dep); -++ if (dep) -++ for (i = 0; dep[i]; ++i) { -++ pr_debug("ac->id = %d dependency = %d", ac->id, -++ dep[i]); -++ rc = add_initcall_dependency(ac->id, dep[i]); -++ if (unlikely(rc)) -++ return rc; -++ } -++ } -++ return 0; -++} -++ -++ -++static bool __init find_mppko_whitelist(unsigned int id, int* index) -++{ -++ int i; -++ for (i = 0; i < WHITELIST_COUNT; i++) { -++ if (id == annotated_initcall_mppko_whitelist_drvid[i]) { -++ *index = i; -++ return true; -++ } -++ } -++ return false; -++} -++ -++static void __init build_inventory(void) -++{ -++ const struct _annotated_initcall *ac; -++ int index = 0; -++ -++ ac = __annotated_initcall_start; -++ for (; ac < __annotated_initcall_end; ++ac) { -++ if (find_mppko_whitelist(ac->id, &index)) { -++ pr_info("find the mppko ac id=%d in whitelist, index=%d\n", ac->id, index); -++ annotated_initcall_mppko_whitelist_by_drvid[index] = ac; -++ continue; -++ } -++ include_node[ac->id] = true; -++ annotated_initcall_by_drvid[ac->id] = ac; -++ nvertices = max(nvertices, ac->id); -++ } -++} -++ -++static int __init build_order(void) -++{ -++ int rc = 0; -++ -++ build_inventory(); -++ add_dependencies(); -++ if (topological_sort()) { -++ return -EINVAL; /* cycle found */ -++ } -++ pr_debug( -++ "init: vertices: %u edges %u count %u ++++++++++++++++++++++++++++++++++\n", -++ nvertices, nedges, norder); -++#ifdef CONFIG_DEPENDENCIES_PARALLEL -++ build_order_by_distance(); -++ build_tgroups(); -++#endif -++ return rc; -++} -++ -++void __init do_annotated_initcalls(void) -++{ -++ unsigned i; -++ -++ printk("config_dependencies is y\n"); -++ i = __annotated_initcall_end - __annotated_initcall_start; -++ pr_debug( -++ "i = %u, __annotated_initcall_end = %px, __annotated_initcall_start = %px\n", -++ i, __annotated_initcall_end, __annotated_initcall_start); -++ pr_debug("__con_initcall_end = %px ,__con_initcall_start = %px\n", -++ __con_initcall_end, __con_initcall_start); -++ if (!i) -++ return; -++ -++ if (build_order()) { -++ /* -++ * Building order failed (likely because of a dependency -++ * circle). Try to boot anyway by calling all annotated -++ * initcalls unordered. -++ */ -++ const struct _annotated_initcall *ac; -++ -++ ac = __annotated_initcall_start; -++ for (; ac < __annotated_initcall_end; ++ac) -++ do_one_initcall(*ac->initcall); -++ return; -++ } -++ -++#ifndef CONFIG_DEPENDENCIES_PARALLEL -++ init_drivers_non_threaded(); -++#else -++ if (CONFIG_DEPENDENCIES_THREADS == 0) -++ num_threads = num_online_cpus(); -++ else -++ num_threads = CONFIG_DEPENDENCIES_THREADS; -++ if (num_threads < 2) { -++ init_drivers_non_threaded(); -++ return; -++ } -++ pr_info("threadsnum = %u -----------------------------------\n", -++ num_threads); -++ pr_info("init: using %u threads to call annotated initcalls\n", -++ num_threads); -++ atomic_set(&count_initcall_threads, num_threads); -++ atomic_set(&ostart, tgroup[0].start); -++ atomic_set(&ocount, tgroup[0].length); -++ atomic_set(&shared_counter, tgroup[0].length); -++ atomic_set(¤t_group, 0); -++ -++ for (i = 0; i < num_threads; ++i) { -++ struct task_struct *p; -++ p = kthread_create_on_cpu(initcall_thread, (void *)(unsigned long)i, i, "initcalls"); -++ if (!IS_ERR(p)) -++ wake_up_process(p); -++ } -++ -++ wait_for_completion(&initcall_thread_done); -++ init_drivers_non_threaded_for_mppko_whitelist(); -++ pr_debug("init: all threads done\n"); -++#endif -++} -+diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c -+index ac021ae6e..6b24aaedf 100644 -+--- a/init/do_mounts_rd.c -++++ b/init/do_mounts_rd.c -+@@ -198,7 +198,9 @@ int __init rd_load_image(char *from) -+ out_file = filp_open("/dev/ram", O_RDWR, 0); -+ if (IS_ERR(out_file)) -+ goto out; -+- -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY)) -++ goto successful_load; -++#endif -+ in_file = filp_open(from, O_RDONLY, 0); -+ if (IS_ERR(in_file)) -+ goto noclose_input; -+@@ -267,11 +269,15 @@ int __init rd_load_image(char *from) -+ successful_load: -+ res = 1; -+ done: -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY)) -+ fput(in_file); -++#endif -+ noclose_input: -+ fput(out_file); -+ out: -++#if !((defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY)) -+ kfree(buf); -++#endif -+ init_unlink("/dev/ram"); -+ return res; -+ } -+diff --git a/init/initramfs.c b/init/initramfs.c -+index de10d99ae..7fbcfd808 100644 -+--- a/init/initramfs.c -++++ b/init/initramfs.c -+@@ -758,6 +758,12 @@ static inline bool kexec_free_initrd(void) -+ #ifdef CONFIG_BLK_DEV_RAM -+ static void __init populate_initrd_image(char *err) -+ { -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY)) -++ unpack_to_rootfs(__initramfs_start, __initramfs_size); -++ devtmpfs_mount(); -++ printk(KERN_INFO "rootfs image is not initramfs (%s); using ramdisk zero copy patch,\ -++ no need to write the initrd into /initrd.image\n", err); -++#else -+ ssize_t written; -+ struct file *file; -+ loff_t pos = 0; -+@@ -776,6 +782,7 @@ static void __init populate_initrd_image(char *err) -+ pr_err("/initrd.image: incomplete write (%zd != %ld)\n", -+ written, initrd_end - initrd_start); -+ fput(file); -++#endif -+ } -+ #endif /* CONFIG_BLK_DEV_RAM */ -+ -+@@ -798,6 +805,9 @@ static int __init populate_rootfs(void) -+ if (err) { -+ #ifdef CONFIG_BLK_DEV_RAM -+ populate_initrd_image(err); -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_RAMDISK_ZERO_COPY)) -++ return 0; -++#endif -+ #else -+ printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err); -+ #endif -+diff --git a/init/main.c b/init/main.c -+index f06fbe79a..543f6d4c3 100644 -+--- a/init/main.c -++++ b/init/main.c -+@@ -110,6 +110,8 @@ -+ -+ #include -+ -++#include "vendor/faststartup.h" -++ -+ static int kernel_init(void *); -+ -+ extern void init_IRQ(void); -+@@ -990,6 +992,9 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) -+ */ -+ random_init(command_line); -+ boot_init_stack_canary(); -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_CMD_TIMESTAMP)) -++ boot_timestamp_print(); -++#endif -+ -+ perf_event_init(); -+ profile_init(); -+@@ -1320,6 +1325,9 @@ static void __init do_initcalls(void) -+ } -+ -+ kfree(command_line); -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_STARTUP_PARALLEL_OPT)) -++ do_annotated_initcalls(); -++#endif -+ } -+ -+ /* -+@@ -1353,7 +1361,7 @@ static int run_init_process(const char *init_filename) -+ const char *const *p; -+ -+ argv_init[0] = init_filename; -+- pr_info("Run %s as init process\n", init_filename); -++ printk_deferred("Run %s as init process\n", init_filename); -+ pr_debug(" with arguments:\n"); -+ for (p = argv_init; *p; p++) -+ pr_debug(" %s\n", *p); -+@@ -1412,6 +1420,10 @@ static void mark_readonly(void) -+ * flushed so that we don't hit false positives looking for -+ * insecure pages which are W+X. -+ */ -++ -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_TIMER_TRIGGER_RCU)) -++ do_fast_rcu(); -++#endif -+ rcu_barrier(); -+ mark_rodata_ro(); -+ rodata_test(); -+diff --git a/init/vendor/Makefile b/init/vendor/Makefile -+new file mode 100755 -+index 000000000..cd3287929 -+--- /dev/null -++++ b/init/vendor/Makefile -+@@ -0,0 +1 @@ -++obj-$(CONFIG_BSP_FAST_STARTUP) += faststartup.o -+diff --git a/init/vendor/faststartup.c b/init/vendor/faststartup.c -+new file mode 100755 -+index 000000000..8f31335ab -+--- /dev/null -++++ b/init/vendor/faststartup.c -+@@ -0,0 +1,117 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include -++#include -++ -++#include -++ -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_CMD_TIMESTAMP)) -++#define TIMESTAMP_MAGIC_VALUE 0x55aa55aa -++#define TIMESTAMP_MAGIC_OFFSET 0 -++#define TIMESTAMP_COUNT_OFFSET 4 -++#define TIMESTAMP_ITEM_OFFSET 8 -++#define TIMESTAMP_NAME_LEN 64 -++#define TIMESTAMP_COUNT_MAX 100 -++typedef struct { -++ char name[TIMESTAMP_NAME_LEN]; -++ unsigned int line; -++ unsigned int stamp; -++} timestamp_item; -++ -++static phys_addr_t timestamp_record_start; -++static unsigned long timestamp_record_size; -++static int __init early_timestamp(char *p) -++{ -++ phys_addr_t start; -++ unsigned long size; -++ char *endp; -++ -++ start = memparse(p, &endp); -++ if (*endp == ',') { -++ size = memparse(endp + 1, NULL); -++ -++ timestamp_record_start = start; -++ timestamp_record_size = size; -++ } -++ return 0; -++} -++early_param("timestamp", early_timestamp); -++ -++void boot_timestamp_print(void) -++{ -++ void __iomem *base; -++ unsigned int i; -++ unsigned int value; -++ unsigned int count; -++ timestamp_item *item; -++ -++#ifdef CONFIG_PHYS_ADDR_T_64BIT -++ printk(KERN_INFO "timestamp_record_start:0x%llx timestamp_record_size:0x%lx\n", -++ timestamp_record_start, timestamp_record_size); -++#else -++ printk(KERN_INFO "timestamp_record_start:0x%x timestamp_record_size:0x%lx\n", -++ timestamp_record_start, timestamp_record_size); -++ -++#endif -++ if (timestamp_record_start == 0 || timestamp_record_size == 0) { -++ printk(KERN_INFO "boot args not pass timestamp params to kernel, please check the bootargs"); -++ return; -++ } -++ -++ base = ioremap(timestamp_record_start, timestamp_record_size); -++ value = *((volatile unsigned int *)(base + TIMESTAMP_MAGIC_OFFSET)); -++ if (value != TIMESTAMP_MAGIC_VALUE) { -++ iounmap(base); -++ printk(KERN_INFO "error: timestamp area maybe overlay:0x%x\n", value); -++ return; -++ } -++ count = *((volatile unsigned int *)(base + TIMESTAMP_COUNT_OFFSET)); -++ item = (timestamp_item *)(base + TIMESTAMP_ITEM_OFFSET); -++ printk(KERN_INFO "count:%d\n", count); -++ for (i = 0; i < count && count < TIMESTAMP_COUNT_MAX; i++) { -++ printk_deferred(" -%d- boot timestamp %s @ %u\n", i, item[i].name, item[i].stamp); -++ } -++ iounmap(base); -++} -++#endif -++ -++#if ((defined CONFIG_ARCH_BSP) && (defined CONFIG_VENDOR_TIMER_TRIGGER_RCU)) -++/* fast rcu */ -++static int rcu_wake_thread_func(void *fn) -++{ -++ int i; -++ int rs_times = 20; -++ int wait_usecs = 1000; -++ -++ for (i = 0; i < rs_times; i++) { -++ raise_softirq(RCU_SOFTIRQ); -++ usleep_range(wait_usecs, wait_usecs); -++ } -++ -++ return 0; -++} -++ -++void do_fast_rcu(void) -++{ -++ unsigned i; -++ int cpu_nums = num_online_cpus(); -++ -++ for (i = 0; i < cpu_nums; ++i) { -++ struct task_struct *task = kthread_create_on_cpu(rcu_wake_thread_func, NULL, i, "fast_rcu_thread"); -++ if (IS_ERR_OR_NULL(task)) { -++ pr_err("Create fast_rcu_thread thread failed\n"); -++ continue; -++ } else { -++ wake_up_process(task); -++ } -++ } -++} -++#endif -++ -+diff --git a/init/vendor/faststartup.h b/init/vendor/faststartup.h -+new file mode 100755 -+index 000000000..cda60c0d6 -+--- /dev/null -++++ b/init/vendor/faststartup.h -+@@ -0,0 +1,11 @@ -++/* -++ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2023. All rights reserved. -++ */ -++ -++#ifndef _VENDOR_LINUX_INIT_H -++#define _VENDOR_LINUX_INIT_H -++ -++void do_fast_rcu(void); -++void boot_timestamp_print(void); -++ -++#endif /* _VENDOR_LINUX_INIT_H */ -+diff --git a/kernel/Kconfig.freezer b/kernel/Kconfig.freezer -+index 68646feef..5de04fc2d 100644 -+--- a/kernel/Kconfig.freezer -++++ b/kernel/Kconfig.freezer -+@@ -1,3 +1,11 @@ -+ # SPDX-License-Identifier: GPL-2.0-only -+ config FREEZER -+ def_bool PM_SLEEP || CGROUP_FREEZER -++ -++if ARCH_BSP -++config ENABLE_IPREC_DEBUG -++ bool "Enable iprec debug" -++ default y -++ help -++ This is used for iprec debug printing. -++endif -+diff --git a/kernel/Makefile b/kernel/Makefile -+index 74be2e38d..96d12af05 100644 -+--- a/kernel/Makefile -++++ b/kernel/Makefile -+@@ -12,6 +12,8 @@ obj-y = fork.o exec_domain.o panic.o \ -+ notifier.o ksysfs.o cred.o reboot.o \ -+ async.o range.o smpboot.o ucount.o regset.o -+ -++obj-$(CONFIG_ENABLE_IPREC_DEBUG) += iprec.o -++ -+ obj-$(CONFIG_USERMODE_DRIVER) += usermode_driver.o -+ obj-$(CONFIG_MODULES) += kmod.o -+ obj-$(CONFIG_MULTIUSER) += groups.o -+diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c -+index 16b95ff12..0b8a3a92c 100644 -+--- a/kernel/dma/contiguous.c -++++ b/kernel/dma/contiguous.c -+@@ -164,6 +164,11 @@ void __init dma_pernuma_cma_reserve(void) -+ * has been activated and all other subsystems have already allocated/reserved -+ * memory. -+ */ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_64BIT -++extern __init int declare_heap_memory(void); -++#endif -++#endif -+ void __init dma_contiguous_reserve(phys_addr_t limit) -+ { -+ phys_addr_t selected_size = 0; -+@@ -173,6 +178,11 @@ void __init dma_contiguous_reserve(phys_addr_t limit) -+ -+ pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit); -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_64BIT -++ declare_heap_memory(); -++#endif -++#endif -+ if (size_cmdline != -1) { -+ selected_size = size_cmdline; -+ selected_base = base_cmdline; -+@@ -262,6 +272,9 @@ struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, -+ -+ return cma_alloc(dev_get_cma_area(dev), count, align, no_warn); -+ } -++#ifdef CONFIG_ARCH_BSP -++EXPORT_SYMBOL(dma_alloc_from_contiguous); -++#endif -+ -+ /** -+ * dma_release_from_contiguous() - release allocated pages -+@@ -278,6 +291,9 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, -+ { -+ return cma_release(dev_get_cma_area(dev), pages, count); -+ } -++#ifdef CONFIG_ARCH_BSP -++EXPORT_SYMBOL(dma_release_from_contiguous); -++#endif -+ -+ static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp) -+ { -+diff --git a/kernel/iprec.c b/kernel/iprec.c -+new file mode 100755 -+index 000000000..e0ac06d4f -+--- /dev/null -++++ b/kernel/iprec.c -+@@ -0,0 +1,417 @@ -++/* -++ * iprec.c: Record any ip io transfer process to -++ * system memory. Reduce printk log latency -++ * or ftrace complexity. -++ * -++ * -++ */ -++#include -++#include -++#include -++#include -++#include -++ -++#include -++ -++ -++#define SEC_FOUR_DIGIT 10000 -++#define USEC_TO_MSEC 1000 -++#define TIME_STAMP_LEN 16 -++ -++static struct proc_dir_entry *iprec_proc; -++static int iprec_init = 0; -++static int iprec_proc_cnt = 0; -++static char tim[TIME_STAMP_LEN] = {0}; -++extern void iprec_inc(void); -++ -++static char **rec_pool = NULL; -++static int rec_lines = IPREC_DEFAULT_LINE; -++static int rec_delay = IPREC_DEFAULT_DLAY; -++static int rem_delay = -1; -++static int rec_lock = 0; -++static int rec_line = 0; -++static int rec_ovwr = 0; -++ -++ -++static spinlock_t rec_spinlock; -++ -++spinlock_t *iprec_spinlock(void) -++{ -++ return &rec_spinlock; -++} -++EXPORT_SYMBOL_GPL(iprec_spinlock); -++ -++void iprec_slock(void) -++{ -++ iprec("_SLOCK_"); -++ if (rec_delay == 0) -++ rec_lock = 1; -++ else -++ rem_delay = rec_delay; -++} -++EXPORT_SYMBOL_GPL(iprec_slock); -++ -++int iprec_glock(void) -++{ -++ return rec_lock; -++} -++EXPORT_SYMBOL_GPL(iprec_glock); -++ -++char *iprec_pool(void) -++{ -++ return (rec_pool[rec_line % rec_lines]); -++} -++EXPORT_SYMBOL_GPL(iprec_pool); -++ -++char *iprec_tm(void) -++{ -++ int ret; -++ struct timespec64 tv; -++ u64 s, ms, us, tmp; -++ -++ ktime_get_boottime_ts64(&tv); -++ -++ tmp = tv.tv_sec; -++ s = do_div(tmp, SEC_FOUR_DIGIT); -++ -++ tmp = tv.tv_nsec; -++ do_div(tmp, USEC_TO_MSEC * USEC_TO_MSEC); -++ ms = tmp; -++ -++ tmp = tv.tv_nsec; -++ us = do_div(tmp, (USEC_TO_MSEC * USEC_TO_MSEC)); -++ do_div(us, USEC_TO_MSEC); -++ -++ ret = sprintf_s(tim, TIME_STAMP_LEN, "[%04lld.%03lld%03lld]", s, ms, us); -++ -++ if (ret < 0) { -++ pr_err("[%s line:%d] sprintf_s failed\n", __func__, __LINE__); -++ } -++ -++ return tim; -++} -++EXPORT_SYMBOL_GPL(iprec_tm); -++ -++void iprec_inc(void) -++{ -++ rec_line++; -++ rec_line %= rec_lines; -++ if (rec_line == 0) -++ rec_ovwr++; -++ -++ if (rec_delay) { -++ // check if lock is actived! -++ if (rem_delay > 0) { -++ rem_delay--; -++ } else if (rem_delay == 0) { /* set lock */ -++ rec_lock = 1; -++ rem_delay = -1; // lock is unactived! -++ } -++ } -++} -++EXPORT_SYMBOL_GPL(iprec_inc); -++ -++static void iprec_show(struct seq_file *s) -++{ -++ int i; -++ rec_lock = 1; -++ -++ seq_printf(s, "|__ ov: %d __|__ delay: %d __|\n\n", rec_ovwr, rec_delay); -++ -++ if (rec_ovwr == 0) { -++ for (i = 0; i < rec_line; i++) { -++ seq_printf(s, " %04d %s\n", (i + 1), rec_pool[i]); -++ } -++ } else { -++ for (i = rec_line; i < rec_lines; i++) { -++ seq_printf(s, " %04d %s\n", (i - rec_line + 1), rec_pool[i]); -++ } -++ -++ for (i = 0; i < rec_line; i++) { -++ seq_printf(s, " %04d %s\n", (i + rec_lines - rec_line + 1), -++ rec_pool[i]); -++ } -++ } -++ -++ seq_printf(s, "\n|__ ov: %d __|__ delay: %d __|\n", rec_ovwr, rec_delay); -++} -++ -++static void iprec_pool_free(char **pool) -++{ -++ int i; -++ -++ if (!pool) -++ return; -++ -++ for (i = 0; i < rec_lines; i++) { -++ if (pool[i]) -++ kfree(pool[i]); -++ } -++ kfree(pool); -++} -++ -++static char **iprec_pool_alloc(int lines) -++{ -++ int i; -++ char *mem = NULL; -++ char **pool = NULL; -++ -++ if (lines <= 0) -++ return NULL; -++ -++ pool = kmalloc(lines * sizeof(char *), GFP_KERNEL); -++ if (pool == NULL) { -++ pr_err("%s: no enough mem iprec %d\n", __func__, lines); -++ return NULL; -++ } -++ -++ for (i = 0; i < lines; i++) { -++ mem = kmalloc(IPREC_STR_LEN, GFP_KERNEL); -++ if (mem == NULL) -++ goto free_pool; -++ mem[0] = 0; -++ pool[i] = mem; -++ } -++ -++ return pool; -++ -++free_pool: -++ iprec_pool_free(pool); -++ -++ return NULL; -++} -++ -++static int iprec_dump_seq_show(struct seq_file *s, void *v) -++{ -++ iprec_show(s); -++ return 0; -++} -++ -++static int iprec_proc_dump_open(struct inode *inode, struct file *file) -++{ -++ return single_open(file, iprec_dump_seq_show, PDE_DATA(inode)); -++} -++ -++static const struct proc_ops iprec_dump_ops = { -++ .proc_open = iprec_proc_dump_open, -++ .proc_read = seq_read, -++ .proc_release = single_release, -++}; -++ -++static int iprec_line_seq_show(struct seq_file *s, void *v) -++{ -++ seq_printf(s, "%d (N x %dB)\n", rec_lines, IPREC_STR_LEN); -++ return 0; -++} -++ -++static int iprec_proc_line_open(struct inode *inode, struct file *file) -++{ -++ return single_open(file, iprec_line_seq_show, PDE_DATA(inode)); -++} -++ -++static ssize_t iprec_proc_line_write(struct file *file, -++ const char __user *buffer, size_t count, loff_t *pos) -++{ -++ int err; -++ unsigned long flags; -++ unsigned int val = 0; -++ char **pool = NULL; -++ -++ err = kstrtouint_from_user(buffer, count, 0, &val); -++ if (err) -++ return err; -++ -++ spin_lock_irqsave(iprec_spinlock(), flags); -++ -++ pool = iprec_pool_alloc(val); -++ if (pool) { -++ iprec_pool_free(rec_pool); -++ rec_pool = pool; -++ rec_lines = val; -++ rec_line = 0; // reset -++ } -++ spin_unlock_irqrestore(iprec_spinlock(), flags); -++ return count; -++} -++ -++static const struct proc_ops iprec_line_ops = { -++ .proc_open = iprec_proc_line_open, -++ .proc_read = seq_read, -++ .proc_write = iprec_proc_line_write, -++ .proc_release = single_release, -++}; -++ -++static int iprec_lock_seq_show(struct seq_file *s, void *v) -++{ -++ seq_printf(s, "%d\n", rec_lock); -++ return 0; -++} -++ -++static int iprec_proc_lock_open(struct inode *inode, struct file *file) -++{ -++ return single_open(file, iprec_lock_seq_show, PDE_DATA(inode)); -++} -++ -++static ssize_t iprec_proc_lock_write(struct file *file, -++ const char __user *buffer, size_t count, loff_t *pos) -++{ -++ int err; -++ unsigned int val = 0; -++ -++ err = kstrtouint_from_user(buffer, count, 0, &val); -++ if (err) -++ return err; -++ -++ if (val) { -++ iprec_slock(); -++ } else { -++ rec_lock = 0; -++ rem_delay = -1; -++ } -++ -++ return count; -++} -++ -++static const struct proc_ops iprec_lock_ops = { -++ .proc_open = iprec_proc_lock_open, -++ .proc_read = seq_read, -++ .proc_write = iprec_proc_lock_write, -++ .proc_release = single_release, -++}; -++ -++static int iprec_delay_seq_show(struct seq_file *s, void *v) -++{ -++ seq_printf(s, "%d\n", rec_delay); -++ return 0; -++} -++ -++static int iprec_proc_delay_open(struct inode *inode, struct file *file) -++{ -++ return single_open(file, iprec_delay_seq_show, PDE_DATA(inode)); -++} -++ -++static ssize_t iprec_proc_delay_write(struct file *file, -++ const char __user *buffer, size_t count, loff_t *pos) -++{ -++ int err; -++ unsigned int val = 0; -++ -++ err = kstrtouint_from_user(buffer, count, 0, &val); -++ if (err) -++ return err; -++ if (val) -++ rec_delay = (val < rec_lines) ? val : (rec_lines - 1); -++ -++ return count; -++} -++ -++static const struct proc_ops iprec_delay_ops = { -++ .proc_open = iprec_proc_delay_open, -++ .proc_read = seq_read, -++ .proc_write = iprec_proc_delay_write, -++ .proc_release = single_release, -++}; -++ -++static int iprec_lines__setup(char *line) -++{ -++ return kstrtouint(line, 10, &rec_lines); /* 10 decimal */ -++} -++__setup("iprec.line=", iprec_lines__setup); -++ -++static struct proc_dir_entry *iprec_create_proc_node(const char *name, -++ struct proc_dir_entry *proc_entry, const struct proc_ops *fileops -++ /* const struct file_operations *fileops */) -++{ -++ struct proc_dir_entry *ret = NULL; -++ ret = proc_create_data(name, 0, proc_entry, fileops, NULL); -++ if (ret == NULL) -++ pr_err("[iprec] failed to create proc file %s\n", name); -++ -++ return ret; -++} -++ -++static int __init iprec_proc_init(void) -++{ -++ char **pool = NULL; -++ struct proc_dir_entry *proc_entry = NULL; -++ -++ if (iprec_init == 0) { -++ proc_entry = proc_mkdir(IPREC, NULL); -++ if (proc_entry == NULL) { -++ pr_err("%s: failed to create proc file %s\n", __func__, IPREC); -++ return -ENOMEM; -++ } -++ iprec_proc = proc_entry; -++ -++ if (iprec_create_proc_node(IPREC_DUMP, iprec_proc, &iprec_dump_ops) == -++ NULL) { -++ pr_err("%s: failed to create proc file %s\n", __func__, IPREC_DUMP); -++ goto remove_entry; -++ } -++ -++ if (iprec_create_proc_node(IPREC_LINE, iprec_proc, &iprec_line_ops) == -++ NULL) { -++ pr_err("%s: failed to create proc file %s\n", __func__, IPREC_LINE); -++ goto remove_dump; -++ } -++ -++ if (iprec_create_proc_node(IPREC_LOCK, iprec_proc, &iprec_lock_ops) == -++ NULL) { -++ pr_err("%s: failed to create proc file %s\n", __func__, IPREC_LOCK); -++ goto remove_line; -++ } -++ -++ if (iprec_create_proc_node(IPREC_DLAY, iprec_proc, &iprec_delay_ops) == -++ NULL) { -++ pr_err("%s: failed to create proc file %s\n", __func__, IPREC_DLAY); -++ goto remove_lock; -++ } -++ -++ pool = iprec_pool_alloc(rec_lines); -++ if (pool == NULL) -++ goto remove_delay; -++ rec_pool = pool; -++ spin_lock_init(&rec_spinlock); -++ iprec_init = 1; -++ } -++ iprec_proc_cnt++; -++ return 0; -++ -++remove_delay: -++ remove_proc_entry(IPREC_DLAY, iprec_proc); -++remove_lock: -++ remove_proc_entry(IPREC_LOCK, iprec_proc); -++remove_line: -++ remove_proc_entry(IPREC_LINE, iprec_proc); -++remove_dump: -++ remove_proc_entry(IPREC_DUMP, iprec_proc); -++remove_entry: -++ remove_proc_entry(IPREC, NULL); -++ return -1; -++} -++ -++static void __exit iprec_proc_shutdown(void) -++{ -++ if (iprec_init) { -++ if (iprec_proc_cnt == 0) { -++ remove_proc_entry(IPREC_DUMP, iprec_proc); -++ remove_proc_entry(IPREC_DLAY, iprec_proc); -++ remove_proc_entry(IPREC_LINE, iprec_proc); -++ remove_proc_entry(IPREC_LOCK, iprec_proc); -++ remove_proc_entry(IPREC, NULL); -++ if (rec_pool) { -++ iprec_pool_free(rec_pool); -++ rec_pool = NULL; -++ } -++ iprec_proc = NULL; -++ iprec_init = 0; -++ } -++ iprec_proc_cnt--; -++ } -++ -++ return; -++} -++subsys_initcall(iprec_proc_init); -++module_exit(iprec_proc_shutdown); -++ -++MODULE_LICENSE("GPL"); -+diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c -+index 6c009a033..4d8214509 100644 -+--- a/kernel/irq/irqdesc.c -++++ b/kernel/irq/irqdesc.c -+@@ -137,6 +137,11 @@ static DECLARE_BITMAP(allocated_irqs, IRQ_BITMAP_BITS); -+ -+ static void irq_kobj_release(struct kobject *kobj); -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_SYSFS_MINI_OPT -++#undef CONFIG_SYSFS -++#endif -++#endif -+ #ifdef CONFIG_SYSFS -+ static struct kobject *irq_kobj_base; -+ -+diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c -+index e20c19e3b..44c392c24 100644 -+--- a/kernel/ksysfs.c -++++ b/kernel/ksysfs.c -+@@ -194,6 +194,7 @@ extern const void __start_notes __weak; -+ extern const void __stop_notes __weak; -+ #define notes_size (&__stop_notes - &__start_notes) -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ static ssize_t notes_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *bin_attr, -+ char *buf, loff_t off, size_t count) -+@@ -209,6 +210,7 @@ static struct bin_attribute notes_attr __ro_after_init = { -+ }, -+ .read = ¬es_read, -+ }; -++#endif -+ -+ struct kobject *kernel_kobj; -+ EXPORT_SYMBOL_GPL(kernel_kobj); -+@@ -254,17 +256,21 @@ static int __init ksysfs_init(void) -+ if (error) -+ goto kset_exit; -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ if (notes_size > 0) { -+ notes_attr.size = notes_size; -+ error = sysfs_create_bin_file(kernel_kobj, ¬es_attr); -+ if (error) -+ goto group_exit; -+ } -++#endif -+ -+ return 0; -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ group_exit: -+ sysfs_remove_group(kernel_kobj, &kernel_attr_group); -++#endif -+ kset_exit: -+ kobject_put(kernel_kobj); -+ exit: -+diff --git a/kernel/module.c b/kernel/module.c -+index e978debc9..a74eafbe6 100644 -+--- a/kernel/module.c -++++ b/kernel/module.c -+@@ -1448,6 +1448,9 @@ static int verify_namespace_is_imported(const struct load_info *info, -+ -+ static bool inherit_taint(struct module *mod, struct module *owner) -+ { -++#ifdef CONFIG_ARCH_BSP -++ return true; /* do not inherit taint */ -++#endif -+ if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints)) -+ return true; -+ -+diff --git a/kernel/params.c b/kernel/params.c -+index 164d79330..a33638730 100644 -+--- a/kernel/params.c -++++ b/kernel/params.c -+@@ -775,6 +775,7 @@ static struct module_kobject * __init locate_module_kobject(const char *name) -+ return mk; -+ } -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ static void __init kernel_add_sysfs_param(const char *name, -+ const struct kernel_param *kparam, -+ unsigned int name_skip) -+@@ -794,10 +795,13 @@ static void __init kernel_add_sysfs_param(const char *name, -+ err = add_sysfs_param(mk, kparam, kparam->name + name_skip); -+ BUG_ON(err); -+ err = sysfs_create_group(&mk->kobj, &mk->mp->grp); -++ mk->kobj.uevent_suppress = 1; -+ BUG_ON(err); -+ kobject_uevent(&mk->kobj, KOBJ_ADD); -+ kobject_put(&mk->kobj); -+ } -++#endif -++ -+ -+ /* -+ * param_sysfs_builtin - add sysfs parameters for built-in modules -+@@ -809,6 +813,7 @@ static void __init kernel_add_sysfs_param(const char *name, -+ * extract the "module" name for all built-in kernel_param-eters, -+ * and for all who have the same, call kernel_add_sysfs_param. -+ */ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_MINI_OPT) -+ static void __init param_sysfs_builtin(void) -+ { -+ const struct kernel_param *kp; -+@@ -833,6 +838,9 @@ static void __init param_sysfs_builtin(void) -+ kernel_add_sysfs_param(modname, kp, name_len); -+ } -+ } -++#else -++static void __init param_sysfs_builtin(void) {} -++#endif -+ -+ ssize_t __modver_version_show(struct module_attribute *mattr, -+ struct module_kobject *mk, char *buf) -+diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -+index ffd7f90b8..96014ff0d 100644 -+--- a/kernel/printk/printk.c -++++ b/kernel/printk/printk.c -+@@ -2062,6 +2062,13 @@ asmlinkage int vprintk_emit(int facility, int level, -+ bool in_sched = false; -+ unsigned long flags; -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_BOOTSTAGE_PRINTK_MINI_OPT -++ if (likely((level >= LOGLEVEL_DEFAULT) && -++ (system_state < SYSTEM_RUNNING))) -++ return 0; -++#endif -++#endif -+ /* Suppress unimportant messages after panic happens */ -+ if (unlikely(suppress_printk)) -+ return 0; -+diff --git a/kernel/sched/core.c b/kernel/sched/core.c -+index fa71c7c51..39c474dbe 100644 -+--- a/kernel/sched/core.c -++++ b/kernel/sched/core.c -+@@ -8052,7 +8052,7 @@ int sched_cpu_activate(unsigned int cpu) -+ static_branch_inc_cpuslocked(&sched_smt_present); -+ #endif -+ set_cpu_active(cpu, true); -+- tg_update_affinity_domains(cpu, 1); -++ // tg_update_affinity_domains(cpu, 1); -+ -+ if (sched_smp_initialized) { -+ sched_domains_numa_masks_set(cpu); -+@@ -8115,7 +8115,7 @@ int sched_cpu_deactivate(unsigned int cpu) -+ return ret; -+ } -+ sched_domains_numa_masks_clear(cpu); -+- tg_update_affinity_domains(cpu, 0); -++ //tg_update_affinity_domains(cpu, 0); -+ return 0; -+ } -+ -+@@ -8187,7 +8187,7 @@ void __init sched_init_smp(void) -+ sched_smp_initialized = true; -+ -+ sched_grid_zone_init(); -+- init_auto_affinity(&root_task_group); -++ //init_auto_affinity(&root_task_group); -+ } -+ -+ static int __init migration_init(void) -+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug -+index d7ba1cde5..03c1ff296 100644 -+--- a/lib/Kconfig.debug -++++ b/lib/Kconfig.debug -+@@ -18,6 +18,11 @@ config PRINTK_TIME -+ The behavior is also controlled by the kernel command line -+ parameter printk.time=1. See Documentation/admin-guide/kernel-parameters.rst -+ -++#ifdef CONFIG_ARCH_BSP -++source "init/Kconfig.timestamp" -++source "init/Kconfig.faststartup" -++#endif -++ -+ config PRINTK_CALLER -+ bool "Show caller information on printks" -+ depends on PRINTK -+diff --git a/lib/kobject.c b/lib/kobject.c -+index 73047e847..9e92d44f9 100644 -+--- a/lib/kobject.c -++++ b/lib/kobject.c -+@@ -227,6 +227,14 @@ static void kobject_init_internal(struct kobject *kobj) -+ kobj->state_add_uevent_sent = 0; -+ kobj->state_remove_uevent_sent = 0; -+ kobj->state_initialized = 1; -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_KUEVENT_MINI_OPT -++ kobj->uevent_suppress = 1; -++#endif -++#ifdef CONFIG_SYSFS_MINI_OPT -++ kobj->sysfs_file_suppress = 0; -++#endif -++#endif -+ } -+ -+ -+diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c -+index c87d5b6a8..6c2c756a4 100644 -+--- a/lib/kobject_uevent.c -++++ b/lib/kobject_uevent.c -+@@ -492,6 +492,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, -+ kset = top_kobj->kset; -+ uevent_ops = kset->uevent_ops; -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_KUEVENT_MINI_OPT) -+ /* skip the event, if uevent_suppress is set*/ -+ if (kobj->uevent_suppress) { -+ pr_debug("kobject: '%s' (%p): %s: uevent_suppress " -+@@ -499,6 +500,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, -+ kobject_name(kobj), kobj, __func__); -+ return 0; -+ } -++#endif -+ /* skip the event, if the filter returns zero. */ -+ if (uevent_ops && uevent_ops->filter) -+ if (!uevent_ops->filter(kset, kobj)) { -+@@ -520,6 +522,17 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, -+ return 0; -+ } -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_KUEVENT_MINI_OPT -++ /* skip the event except for block subsystem, if uevent_suppress is set */ -++ if (kobj->uevent_suppress && subsystem != NULL && !strstr(subsystem, "block")) { -++ pr_debug("kobject: '%s' (%p): %s: uevent_suppress " -++ "caused the event to drop!\n", -++ kobject_name(kobj), kobj, __func__); -++ return 0; -++ } -++#endif -++#endif -+ /* environment buffer */ -+ env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); -+ if (!env) -+diff --git a/lib/securec/LICENSE b/lib/securec/LICENSE -+new file mode 100755 -+index 000000000..42f2a8367 -+--- /dev/null -++++ b/lib/securec/LICENSE -+@@ -0,0 +1,124 @@ -++木兰宽松许可证, 第2版 -++ -++2020年1月 http://license.coscl.org.cn/MulanPSL2 -++ -++您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: -++ -++0. 定义 -++ -++“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 -++ -++“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 -++ -++“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 -++ -++“法人实体” 是指提交贡献的机构及其“关联实体”。 -++ -++“关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 -++ -++1. 授予版权许可 -++ -++每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 -++ -++2. 授予专利许可 -++ -++每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 -++ -++3. 无商标许可 -++ -++“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 -++ -++4. 分发限制 -++ -++您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 -++ -++5. 免责声明与责任限制 -++ -++“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 -++ -++6. 语言 -++ -++“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 -++ -++条款结束 -++ -++如何将木兰宽松许可证,第2版,应用到您的软件 -++ -++如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: -++ -++1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; -++ -++2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; -++ -++3, 请将如下声明文本放入每个源文件的头部注释中。 -++ -++Copyright (c) [Year] [name of copyright holder] -++[Software Name] is licensed under Mulan PSL v2. -++You can use this software according to the terms and conditions of the Mulan PSL v2. -++You may obtain a copy of Mulan PSL v2 at: -++ http://license.coscl.org.cn/MulanPSL2 -++THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++See the Mulan PSL v2 for more details. -++Mulan Permissive Software License,Version 2 -++Mulan Permissive Software License,Version 2 (Mulan PSL v2) -++ -++January 2020 http://license.coscl.org.cn/MulanPSL2 -++ -++Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: -++ -++0. Definition -++ -++Software means the program and related documents which are licensed under this License and comprise all Contribution(s). -++ -++Contribution means the copyrightable work licensed by a particular Contributor under this License. -++ -++Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. -++ -++Legal Entity means the entity making a Contribution and all its Affiliates. -++ -++Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, 'control' means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. -++ -++1. Grant of Copyright License -++ -++Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. -++ -++2. Grant of Patent License -++ -++Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. -++ -++3. No Trademark License -++ -++No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4. -++ -++4. Distribution Restriction -++ -++You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. -++ -++5. Disclaimer of Warranty and Limitation of Liability -++ -++THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT'S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -++ -++6. Language -++ -++THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. -++ -++END OF THE TERMS AND CONDITIONS -++ -++How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software -++ -++To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: -++ -++Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; -++Create a file named "LICENSE" which contains the whole context of this License in the first directory of your software package; -++Attach the statement to the appropriate annotated syntax at the beginning of each source file. -++Copyright (c) [Year] [name of copyright holder] -++[Software Name] is licensed under Mulan PSL v2. -++You can use this software according to the terms and conditions of the Mulan PSL v2. -++You may obtain a copy of Mulan PSL v2 at: -++ http://license.coscl.org.cn/MulanPSL2 -++THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++See the Mulan PSL v2 for more details. -+\ No newline at end of file -+diff --git a/lib/securec/Makefile b/lib/securec/Makefile -+new file mode 100755 -+index 000000000..acdcee4f8 -+--- /dev/null -++++ b/lib/securec/Makefile -+@@ -0,0 +1,3 @@ -++ifdef CONFIG_ARCH_BSP -++obj-y += src/ -++endif -+diff --git a/lib/securec/README.en.md b/lib/securec/README.en.md -+new file mode 100755 -+index 000000000..60c477fe8 -+--- /dev/null -++++ b/lib/securec/README.en.md -+@@ -0,0 +1,59 @@ -++# libboundscheck -++ -++#### Description -++ -++- following the standard of C11 Annex K (bound-checking interfaces), functions of the common memory/string operation classes, such as memcpy_s, strcpy_s, are selected and implemented. -++ -++- other standard functions in C11 Annex K will be analyzed in the future and implemented in this organization if necessary. -++ -++- handles the release, update, and maintenance of bounds_checking_function. -++ -++#### Function List -++ -++- memcpy_s -++- wmemcpy_s -++- memmove_s -++- wmemmove_s -++- memset_s -++- strcpy_s -++- wcscpy_s -++- strncpy_s -++- wcsncpy_s -++- strcat_s -++- wcscat_s -++- strncat_s -++- wcsncat_s -++- strtok_s -++- wcstok_s -++- sprintf_s -++- swprintf_s -++- vsprintf_s -++- vswprintf_s -++- snprintf_s -++- vsnprintf_s -++- scanf_s -++- wscanf_s -++- vscanf_s -++- vwscanf_s -++- fscanf_s -++- fwscanf_s -++- vfscanf_s -++- vfwscanf_s -++- sscanf_s -++- swscanf_s -++- vsscanf_s -++- vswscanf_s -++- gets_s -++ -++ -++#### Build -++ -++``` -++CC=gcc make -++``` -++The generated Dynamic library libboundscheck.so is stored in the newly created directory lib. -++ -++#### How to use -++1. Copy the libboundscheck.so to the library file directory, for example: "/usr/local/lib/". -++ -++2. To use the libboundscheck, add the “-lboundscheck” parameters to the compiler, for example: “gcc -g -o test test.c -lboundscheck”. -+\ No newline at end of file -+diff --git a/lib/securec/README.md b/lib/securec/README.md -+new file mode 100755 -+index 000000000..c16cbb176 -+--- /dev/null -++++ b/lib/securec/README.md -+@@ -0,0 +1,56 @@ -++# libboundscheck -++ -++#### 介绍 -++- 遵循C11 Annex K (Bounds-checking interfaces)的标准,选取并实现了常见的内存/字符串操作类的函数,如memcpy_s、strcpy_s等函数。 -++- 未来将分析C11 Annex K中的其他标准函数,如果有必要,将在该组织中实现。 -++- 处理边界检查函数的版本发布、更新以及维护。 -++ -++#### 函数清单 -++ -++- memcpy_s -++- wmemcpy_s -++- memmove_s -++- wmemmove_s -++- memset_s -++- strcpy_s -++- wcscpy_s -++- strncpy_s -++- wcsncpy_s -++- strcat_s -++- wcscat_s -++- strncat_s -++- wcsncat_s -++- strtok_s -++- wcstok_s -++- sprintf_s -++- swprintf_s -++- vsprintf_s -++- vswprintf_s -++- snprintf_s -++- vsnprintf_s -++- scanf_s -++- wscanf_s -++- vscanf_s -++- vwscanf_s -++- fscanf_s -++- fwscanf_s -++- vfscanf_s -++- vfwscanf_s -++- sscanf_s -++- swscanf_s -++- vsscanf_s -++- vswscanf_s -++- gets_s -++ -++#### 构建方法 -++ -++运行命令 -++``` -++make CC=gcc -++``` -++生成的动态库libboundscheck.so存放在新创建的lib目录下。 -++ -++#### 使用方法 -++1. 将构建生成的动态库libboundscheck.so放到库文件目录下,例如:"/usr/local/lib/"。 -++ -++2. 为使用libboundscheck,编译程序时需增加编译参数"-lboundscheck",例如:"gcc -g -o test test.c -lboundscheck"。 -+\ No newline at end of file -+diff --git a/lib/securec/src/Makefile b/lib/securec/src/Makefile -+new file mode 100755 -+index 000000000..42554f880 -+--- /dev/null -++++ b/lib/securec/src/Makefile -+@@ -0,0 +1,17 @@ -++obj-y += securecutil.o -++obj-y += strncpy_s.o -++obj-y += vsprintf_s.o -++obj-y += snprintf_s.o -++obj-y += memcpy_s.o -++obj-y += memmove_s.o -++obj-y += strcat_s.o -++obj-y += secureprintoutput_a.o -++obj-y += memset_s.o -++obj-y += strtok_s.o -++obj-y += sprintf_s.o -++obj-y += strncat_s.o -++obj-y += strcpy_s.o -++obj-y += vsnprintf_s.o -++obj-y += secureinput_a.o -++obj-y += vsscanf_s.o -++obj-y += sscanf_s.o -+diff --git a/lib/securec/src/input.inl b/lib/securec/src/input.inl -+new file mode 100755 -+index 000000000..5880d45df -+--- /dev/null -++++ b/lib/securec/src/input.inl -+@@ -0,0 +1,2229 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: Used by secureinput_a.c and secureinput_w.c to include. -++ * This file provides a template function for ANSI and UNICODE compiling by -++ * different type definition. The functions of SecInputS or -++ * SecInputSW provides internal implementation for scanf family API, such as sscanf_s, fscanf_s. -++ * Create: 2014-02-25 -++ * Notes: The formatted input processing results of integers on different platforms are different. -++ */ -++/* -++ * [Standardize-exceptions] Use unsafe function: Performance-sensitive -++ * [reason] Always used in the performance critical path, -++ * and sufficient input validation is performed before calling -++ */ -++#ifndef INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 -++#define INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 -++ -++#if SECUREC_IN_KERNEL -++#if !defined(SECUREC_CTYPE_MACRO_ADAPT) -++#include -++#endif -++#else -++#if !defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT) -++//#include -++#ifdef SECUREC_FOR_WCHAR -++//#include /* For iswspace */ -++#endif -++#endif -++#endif -++ -++#ifndef EOF -++#define EOF (-1) -++#endif -++ -++#define SECUREC_NUM_WIDTH_SHORT 0 -++#define SECUREC_NUM_WIDTH_INT 1 -++#define SECUREC_NUM_WIDTH_LONG 2 -++#define SECUREC_NUM_WIDTH_LONG_LONG 3 /* Also long double */ -++ -++#define SECUREC_BUFFERED_BLOK_SIZE 1024U -++ -++#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(va_copy) && !defined(__va_copy) -++/* The name is the same as system macro. */ -++#define __va_copy(dest, src) do { \ -++ size_t destSize_ = (size_t)sizeof(dest); \ -++ size_t srcSize_ = (size_t)sizeof(src); \ -++ if (destSize_ != srcSize_) { \ -++ SECUREC_MEMCPY_WARP_OPT((dest), (src), sizeof(va_list)); \ -++ } else { \ -++ SECUREC_MEMCPY_WARP_OPT(&(dest), &(src), sizeof(va_list)); \ -++ } \ -++} SECUREC_WHILE_ZERO -++#endif -++ -++#define SECUREC_MULTI_BYTE_MAX_LEN 6 -++ -++/* Compatibility macro name cannot be modifie */ -++#ifndef UNALIGNED -++#if !(defined(_M_IA64)) && !(defined(_M_AMD64)) -++#define UNALIGNED -++#else -++#define UNALIGNED __unaligned -++#endif -++#endif -++ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++/* Max 64bit value is 0xffffffffffffffff */ -++#define SECUREC_MAX_64BITS_VALUE 18446744073709551615ULL -++#define SECUREC_MAX_64BITS_VALUE_DIV_TEN 1844674407370955161ULL -++#define SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT 18446744073709551610ULL -++#define SECUREC_MIN_64BITS_NEG_VALUE 9223372036854775808ULL -++#define SECUREC_MAX_64BITS_POS_VALUE 9223372036854775807ULL -++#define SECUREC_MIN_32BITS_NEG_VALUE 2147483648UL -++#define SECUREC_MAX_32BITS_POS_VALUE 2147483647UL -++#define SECUREC_MAX_32BITS_VALUE 4294967295UL -++#define SECUREC_MAX_32BITS_VALUE_INC 4294967296UL -++#define SECUREC_MAX_32BITS_VALUE_DIV_TEN 429496729UL -++#define SECUREC_LONG_BIT_NUM ((unsigned int)(sizeof(long) << 3U)) -++/* Use ULL to clean up cl6x compilation alerts */ -++#define SECUREC_MAX_LONG_POS_VALUE ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)) - 1) -++#define SECUREC_MIN_LONG_NEG_VALUE ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1))) -++ -++/* Covert to long long to clean up cl6x compilation alerts */ -++#define SECUREC_LONG_HEX_BEYOND_MAX(number) (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 4U)) > 0) -++#define SECUREC_LONG_OCTAL_BEYOND_MAX(number) (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 3U)) > 0) -++ -++#define SECUREC_QWORD_HEX_BEYOND_MAX(number) (((number) >> (64U - 4U)) > 0) -++#define SECUREC_QWORD_OCTAL_BEYOND_MAX(number) (((number) >> (64U - 3U)) > 0) -++ -++#define SECUREC_LP64_BIT_WIDTH 64 -++#define SECUREC_LP32_BIT_WIDTH 32 -++ -++#define SECUREC_CONVERT_IS_SIGNED(conv) ((conv) == 'd' || (conv) == 'i') -++#endif -++ -++#define SECUREC_BRACE '{' /* [ to { */ -++#define SECUREC_FILED_WIDTH_ENOUGH(spec) ((spec)->widthSet == 0 || (spec)->width > 0) -++#define SECUREC_FILED_WIDTH_DEC(spec) do { \ -++ if ((spec)->widthSet != 0) { \ -++ --(spec)->width; \ -++ } \ -++} SECUREC_WHILE_ZERO -++ -++#ifdef SECUREC_FOR_WCHAR -++/* Bits for all wchar, size is 65536/8, only supports wide characters with a maximum length of two bytes */ -++#define SECUREC_BRACKET_TABLE_SIZE 8192 -++#define SECUREC_EOF WEOF -++#define SECUREC_MB_LEN 16 /* Max. # bytes in multibyte char ,see MB_LEN_MAX */ -++#else -++/* Bits for all char, size is 256/8 */ -++#define SECUREC_BRACKET_TABLE_SIZE 32 -++#define SECUREC_EOF EOF -++#endif -++ -++#if SECUREC_HAVE_WCHART -++#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || \ -++ ((spec).isWCharOrLong <= 0 && (spec).arrayWidth > SECUREC_STRING_MAX_LEN) || \ -++ ((spec).isWCharOrLong > 0 && (spec).arrayWidth > SECUREC_WCHAR_STRING_MAX_LEN)) -++#else -++#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || (spec).arrayWidth > SECUREC_STRING_MAX_LEN) -++#endif -++ -++#ifdef SECUREC_ON_64BITS -++/* Use 0xffffffffUL mask to pass integer as array length */ -++#define SECUREC_GET_ARRAYWIDTH(argList) (((size_t)va_arg((argList), size_t)) & 0xffffffffUL) -++#else /* !SECUREC_ON_64BITS */ -++#define SECUREC_GET_ARRAYWIDTH(argList) ((size_t)va_arg((argList), size_t)) -++#endif -++ -++typedef struct { -++#ifdef SECUREC_FOR_WCHAR -++ unsigned char *table; /* Default NULL */ -++#else -++ unsigned char table[SECUREC_BRACKET_TABLE_SIZE]; /* Array length is large enough in application scenarios */ -++#endif -++ unsigned char mask; /* Default 0 */ -++} SecBracketTable; -++ -++#ifdef SECUREC_FOR_WCHAR -++#define SECUREC_INIT_BRACKET_TABLE { NULL, 0 } -++#else -++#define SECUREC_INIT_BRACKET_TABLE { {0}, 0 } -++#endif -++ -++#if SECUREC_ENABLE_SCANF_FLOAT -++typedef struct { -++ size_t floatStrTotalLen; /* Initialization must be length of buffer in charater */ -++ size_t floatStrUsedLen; /* Store float string len */ -++ SecChar *floatStr; /* Initialization must point to buffer */ -++ SecChar *allocatedFloatStr; /* Initialization must be NULL to store alloced point */ -++ SecChar buffer[SECUREC_FLOAT_BUFSIZE + 1]; -++} SecFloatSpec; -++#endif -++ -++#define SECUREC_NUMBER_STATE_DEFAULT 0U -++#define SECUREC_NUMBER_STATE_STARTED 1U -++ -++typedef struct { -++ SecInt ch; /* Char read from input */ -++ int charCount; /* Number of characters processed */ -++ void *argPtr; /* Variable parameter pointer, point to the end of the string */ -++ size_t arrayWidth; /* Length of pointer Variable parameter, in charaters */ -++ SecUnsignedInt64 number64; /* Store input number64 value */ -++ unsigned long number; /* Store input number32 value */ -++ int numberWidth; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */ -++ int numberArgType; /* 1 for 64-bit integer, 0 otherwise. use it as decode function index */ -++ unsigned int negative; /* 0 is positive */ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ unsigned int beyondMax; /* Non-zero means beyond */ -++#endif -++ unsigned int numberState; /* Identifies whether to start processing numbers, 1 is can input number */ -++ int width; /* Width number in format */ -++ int widthSet; /* 0 is not set width in format */ -++ int convChr; /* Lowercase format conversion characters */ -++ int oriConvChr; /* Store original format conversion, convChr may change when parsing integers */ -++ signed char isWCharOrLong; /* -1/0 not wchar or long, 1 for wchar or long */ -++ unsigned char suppress; /* 0 is not have %* in format */ -++} SecScanSpec; -++ -++#ifdef SECUREC_FOR_WCHAR -++#define SECUREC_GETC fgetwc -++#define SECUREC_UN_GETC ungetwc -++/* Only supports wide characters with a maximum length of two bytes in format string */ -++#define SECUREC_BRACKET_CHAR_MASK 0xffffU -++#else -++#define SECUREC_GETC fgetc -++#define SECUREC_UN_GETC ungetc -++#define SECUREC_BRACKET_CHAR_MASK 0xffU -++#endif -++ -++#define SECUREC_CHAR_SIZE ((unsigned int)(sizeof(SecChar))) -++/* To avoid 648, mask high bit: 0x00ffffff 0x0000ffff or 0x00000000 */ -++#define SECUREC_CHAR_MASK_HIGH (((((((((unsigned int)(-1) >> SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \ -++ SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \ -++ SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \ -++ SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) -++ -++/* For char is 0xff, wcahr_t is 0xffff or 0xffffffff. */ -++#define SECUREC_CHAR_MASK (~((((((((((unsigned int)(-1) & SECUREC_CHAR_MASK_HIGH) << \ -++ SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \ -++ SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \ -++ SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \ -++ SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE)) -++ -++/* According wchar_t has multiple bytes, so use sizeof */ -++#define SECUREC_GET_CHAR(stream, outCh) do { \ -++ if ((stream)->count >= sizeof(SecChar)) { \ -++ *(outCh) = (SecInt)(SECUREC_CHAR_MASK & \ -++ (unsigned int)(int)(*((const SecChar *)(const void *)(stream)->cur))); \ -++ (stream)->cur += sizeof(SecChar); \ -++ (stream)->count -= sizeof(SecChar); \ -++ } else { \ -++ *(outCh) = SECUREC_EOF; \ -++ } \ -++} SECUREC_WHILE_ZERO -++ -++#define SECUREC_UN_GET_CHAR(stream) do { \ -++ if ((stream)->cur > (stream)->base) { \ -++ (stream)->cur -= sizeof(SecChar); \ -++ (stream)->count += sizeof(SecChar); \ -++ } \ -++} SECUREC_WHILE_ZERO -++ -++/* Convert wchar_t to int and then to unsigned int to keep data clearing warning */ -++#define SECUREC_TO_LOWERCASE(chr) ((int)((unsigned int)(int)(chr) | (unsigned int)('a' - 'A'))) -++ -++/* Record a flag for each bit */ -++#define SECUREC_BRACKET_INDEX(x) ((unsigned int)(x) >> 3U) -++#define SECUREC_BRACKET_VALUE(x) ((unsigned char)(1U << ((unsigned int)(x) & 7U))) -++#if SECUREC_IN_KERNEL -++#define SECUREC_CONVERT_IS_UNSIGNED(conv) ((conv) == 'x' || (conv) == 'o' || (conv) == 'u') -++#endif -++ -++/* -++ * Set char in %[xxx] into table, only supports wide characters with a maximum length of two bytes -++ */ -++SECUREC_INLINE void SecBracketSetBit(unsigned char *table, SecUnsignedChar ch) -++{ -++ unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); -++ unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); -++ /* Do not use |= optimize this code, it will cause compiling warning */ -++ table[tableIndex] = (unsigned char)(table[tableIndex] | tableValue); -++} -++ -++SECUREC_INLINE void SecBracketSetBitRange(unsigned char *table, SecUnsignedChar startCh, SecUnsignedChar endCh) -++{ -++ SecUnsignedChar expCh; -++ /* %[a-z] %[a-a] Format %[a-\xff] end is 0xFF, condition (expCh <= endChar) cause dead loop */ -++ for (expCh = startCh; expCh < endCh; ++expCh) { -++ SecBracketSetBit(table, expCh); -++ } -++ SecBracketSetBit(table, endCh); -++} -++/* -++ * Determine whether the expression can be satisfied -++ */ -++SECUREC_INLINE int SecCanInputForBracket(int convChr, SecInt ch, const SecBracketTable *bracketTable) -++{ -++ unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); -++ unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK)); -++#ifdef SECUREC_FOR_WCHAR -++ if (((unsigned int)(int)ch & (~(SECUREC_BRACKET_CHAR_MASK))) != 0) { -++ /* The value of the wide character exceeds the size of two bytes */ -++ return 0; -++ } -++ return (int)(convChr == SECUREC_BRACE && -++ (((unsigned int)bracketTable->table[tableIndex] ^ (unsigned int)bracketTable->mask) & tableValue) != 0); -++#else -++ return (int)(convChr == SECUREC_BRACE && -++ (((unsigned int)bracketTable->table[tableIndex] ^ (unsigned int)bracketTable->mask) & tableValue) != 0); -++#endif -++} -++ -++/* -++ * String input ends when blank character is encountered -++ */ -++SECUREC_INLINE int SecCanInputString(int convChr, SecInt ch) -++{ -++ return (int)(convChr == 's' && -++ (!(ch >= SECUREC_CHAR('\t') && ch <= SECUREC_CHAR('\r')) && ch != SECUREC_CHAR(' '))); -++} -++ -++/* -++ * Can input a character when format is %c -++ */ -++SECUREC_INLINE int SecCanInputCharacter(int convChr) -++{ -++ return (int)(convChr == 'c'); -++} -++ -++/* -++ * Determine if it is a 64-bit pointer function -++ * Return 0 is not ,1 is 64bit pointer -++ */ -++SECUREC_INLINE int SecNumberArgType(size_t sizeOfVoidStar) -++{ -++ /* Point size is 4 or 8 , Under the 64 bit system, the value not 0 */ -++ /* To clear e778 */ -++ if ((sizeOfVoidStar & sizeof(SecInt64)) != 0) { -++ return 1; -++ } -++ return 0; -++} -++SECUREC_INLINE int SecIsDigit(SecInt ch); -++SECUREC_INLINE int SecIsXdigit(SecInt ch); -++SECUREC_INLINE int SecIsSpace(SecInt ch); -++SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter); -++SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter); -++SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter); -++ -++#if SECUREC_ENABLE_SCANF_FLOAT -++ -++/* -++ * Convert a floating point string to a floating point number -++ */ -++SECUREC_INLINE int SecAssignNarrowFloat(const char *floatStr, const SecScanSpec *spec) -++{ -++ char *endPtr = NULL; -++ double d; -++#if SECUREC_SUPPORT_STRTOLD -++ if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG_LONG) { -++ long double d2 = strtold(floatStr, &endPtr); -++ if (endPtr == floatStr) { -++ return -1; -++ } -++ *(long double UNALIGNED *)(spec->argPtr) = d2; -++ return 0; -++ } -++#endif -++ d = strtod(floatStr, &endPtr); -++ /* cannot detect if endPtr points to the end of floatStr,because strtod handles only two characters for 1.E */ -++ if (endPtr == floatStr) { -++ return -1; -++ } -++ if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) { -++ *(double UNALIGNED *)(spec->argPtr) = (double)d; -++ } else { -++ *(float UNALIGNED *)(spec->argPtr) = (float)d; -++ } -++ return 0; -++} -++ -++#ifdef SECUREC_FOR_WCHAR -++/* -++ * Convert a floating point wchar string to a floating point number -++ * Success ret 0 -++ */ -++SECUREC_INLINE int SecAssignWideFloat(const SecFloatSpec *floatSpec, const SecScanSpec *spec) -++{ -++ int retVal; -++ /* Convert float string */ -++ size_t mbsLen; -++ size_t tempFloatStrLen = (size_t)(floatSpec->floatStrUsedLen + 1) * sizeof(wchar_t); -++ char *tempFloatStr = (char *)SECUREC_MALLOC(tempFloatStrLen); -++ if (tempFloatStr == NULL) { -++ return -1; -++ } -++ tempFloatStr[0] = '\0'; -++ SECUREC_MASK_MSVC_CRT_WARNING -++ mbsLen = wcstombs(tempFloatStr, floatSpec->floatStr, tempFloatStrLen - 1); -++ SECUREC_END_MASK_MSVC_CRT_WARNING -++ /* This condition must satisfy mbsLen is not -1 */ -++ if (mbsLen >= tempFloatStrLen) { -++ SECUREC_FREE(tempFloatStr); -++ return -1; -++ } -++ tempFloatStr[mbsLen] = '\0'; -++ retVal = SecAssignNarrowFloat(tempFloatStr, spec); -++ SECUREC_FREE(tempFloatStr); -++ return retVal; -++} -++#endif -++ -++SECUREC_INLINE int SecAssignFloat(const SecFloatSpec *floatSpec, const SecScanSpec *spec) -++{ -++#ifdef SECUREC_FOR_WCHAR -++ return SecAssignWideFloat(floatSpec, spec); -++#else -++ return SecAssignNarrowFloat(floatSpec->floatStr, spec); -++#endif -++} -++ -++/* -++ * Init SecFloatSpec before parse format -++ */ -++SECUREC_INLINE void SecInitFloatSpec(SecFloatSpec *floatSpec) -++{ -++ floatSpec->floatStr = floatSpec->buffer; -++ floatSpec->allocatedFloatStr = NULL; -++ floatSpec->floatStrTotalLen = sizeof(floatSpec->buffer) / sizeof(floatSpec->buffer[0]); -++ floatSpec->floatStrUsedLen = 0; -++} -++ -++SECUREC_INLINE void SecFreeFloatSpec(SecFloatSpec *floatSpec, int *doneCount) -++{ -++ /* 2014.3.6 add, clear the stack data */ -++ if (memset_s(floatSpec->buffer, sizeof(floatSpec->buffer), 0, sizeof(floatSpec->buffer)) != EOK) { -++ *doneCount = 0; /* This code just to meet the coding requirements */ -++ } -++ /* The pFloatStr can be alloced in SecExtendFloatLen function, clear and free it */ -++ if (floatSpec->allocatedFloatStr != NULL) { -++ size_t bufferSize = floatSpec->floatStrTotalLen * sizeof(SecChar); -++ if (memset_s(floatSpec->allocatedFloatStr, bufferSize, 0, bufferSize) != EOK) { -++ *doneCount = 0; /* This code just to meet the coding requirements */ -++ } -++ SECUREC_FREE(floatSpec->allocatedFloatStr); -++ floatSpec->allocatedFloatStr = NULL; -++ floatSpec->floatStr = NULL; -++ } -++} -++ -++/* -++ * Splice floating point string -++ * Return 0 OK -++ */ -++SECUREC_INLINE int SecExtendFloatLen(SecFloatSpec *floatSpec) -++{ -++ if (floatSpec->floatStrUsedLen >= floatSpec->floatStrTotalLen) { -++ /* Buffer size is len x sizeof(SecChar) */ -++ size_t oriSize = floatSpec->floatStrTotalLen * sizeof(SecChar); -++ /* Add one character to clear tool warning */ -++ size_t nextSize = (oriSize * 2) + sizeof(SecChar); /* Multiply 2 to extend buffer size */ -++ -++ /* Prevents integer overflow, the maximum length of SECUREC_MAX_WIDTH_LEN is enough */ -++ if (nextSize <= (size_t)SECUREC_MAX_WIDTH_LEN) { -++ void *nextBuffer = (void *)SECUREC_MALLOC(nextSize); -++ if (nextBuffer == NULL) { -++ return -1; -++ } -++ if (memcpy_s(nextBuffer, nextSize, floatSpec->floatStr, oriSize) != EOK) { -++ SECUREC_FREE(nextBuffer); /* This is a dead code, just to meet the coding requirements */ -++ return -1; -++ } -++ /* Clear old buffer memory */ -++ if (memset_s(floatSpec->floatStr, oriSize, 0, oriSize) != EOK) { -++ SECUREC_FREE(nextBuffer); /* This is a dead code, just to meet the coding requirements */ -++ return -1; -++ } -++ /* Free old allocated buffer */ -++ if (floatSpec->allocatedFloatStr != NULL) { -++ SECUREC_FREE(floatSpec->allocatedFloatStr); -++ } -++ floatSpec->allocatedFloatStr = (SecChar *)(nextBuffer); /* Use to clear free on stack warning */ -++ floatSpec->floatStr = (SecChar *)(nextBuffer); -++ floatSpec->floatStrTotalLen = nextSize / sizeof(SecChar); /* Get buffer total len in character */ -++ return 0; -++ } -++ return -1; /* Next size is beyond max */ -++ } -++ return 0; -++} -++ -++/* Do not use localeconv()->decimal_pointif onlay support '.' */ -++SECUREC_INLINE int SecIsFloatDecimal(SecChar ch) -++{ -++ return (int)(ch == SECUREC_CHAR('.')); -++} -++ -++SECUREC_INLINE int SecInputFloatSign(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) -++{ -++ if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ return 0; -++ } -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) { -++ SECUREC_FILED_WIDTH_DEC(spec); /* Make sure the count after un get char is correct */ -++ if (spec->ch == SECUREC_CHAR('-')) { -++ floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('-'); -++ ++floatSpec->floatStrUsedLen; -++ if (SecExtendFloatLen(floatSpec) != 0) { -++ return -1; -++ } -++ } -++ } else { -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ } -++ return 0; -++} -++ -++SECUREC_INLINE int SecInputFloatDigit(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) -++{ -++ /* Now get integral part */ -++ while (SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ if (SecIsDigit(spec->ch) == 0) { -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ return 0; -++ } -++ SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ -++ spec->numberState = SECUREC_NUMBER_STATE_STARTED; -++ floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch; -++ ++floatSpec->floatStrUsedLen; -++ if (SecExtendFloatLen(floatSpec) != 0) { -++ return -1; -++ } -++ } -++ return 0; -++} -++ -++/* -++* Scan value of exponent. -++* Return 0 OK -++*/ -++SECUREC_INLINE int SecInputFloatE(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) -++{ -++ if (SecInputFloatSign(stream, spec, floatSpec) == -1) { -++ return -1; -++ } -++ if (SecInputFloatDigit(stream, spec, floatSpec) != 0) { -++ return -1; -++ } -++ return 0; -++} -++ -++SECUREC_INLINE int SecInputFloatFractional(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) -++{ -++ if (SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ if (SecIsFloatDecimal((SecChar)spec->ch) == 0) { -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ return 0; -++ } -++ SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ -++ /* Now check for decimal */ -++ floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch; -++ ++floatSpec->floatStrUsedLen; -++ if (SecExtendFloatLen(floatSpec) != 0) { -++ return -1; -++ } -++ if (SecInputFloatDigit(stream, spec, floatSpec) != 0) { -++ return -1; -++ } -++ } -++ return 0; -++} -++ -++SECUREC_INLINE int SecInputFloatExponent(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) -++{ -++ /* Now get exponent part */ -++ if (spec->numberState == SECUREC_NUMBER_STATE_STARTED && SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ if (spec->ch != SECUREC_CHAR('e') && spec->ch != SECUREC_CHAR('E')) { -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ return 0; -++ } -++ SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ -++ floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('e'); -++ ++floatSpec->floatStrUsedLen; -++ if (SecExtendFloatLen(floatSpec) != 0) { -++ return -1; -++ } -++ if (SecInputFloatE(stream, spec, floatSpec) != 0) { -++ return -1; -++ } -++ } -++ return 0; -++} -++ -++/* -++* Scan %f. -++* Return 0 OK -++*/ -++SECUREC_INLINE int SecInputFloat(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec) -++{ -++ floatSpec->floatStrUsedLen = 0; -++ -++ /* The following code sequence is strict */ -++ if (SecInputFloatSign(stream, spec, floatSpec) != 0) { -++ return -1; -++ } -++ if (SecInputFloatDigit(stream, spec, floatSpec) != 0) { -++ return -1; -++ } -++ if (SecInputFloatFractional(stream, spec, floatSpec) != 0) { -++ return -1; -++ } -++ if (SecInputFloatExponent(stream, spec, floatSpec) != 0) { -++ return -1; -++ } -++ -++ /* Make sure have a string terminator, buffer is large enough */ -++ floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('\0'); -++ if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) { -++ return 0; -++ } -++ return -1; -++} -++#endif -++ -++#if (!defined(SECUREC_FOR_WCHAR) && SECUREC_HAVE_WCHART && SECUREC_HAVE_MBTOWC) || \ -++ (!defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)) -++/* only multi-bytes string need isleadbyte() function */ -++SECUREC_INLINE int SecIsLeadByte(SecInt ch) -++{ -++ unsigned int c = (unsigned int)ch; -++#if !(defined(_MSC_VER) || defined(_INC_WCTYPE)) -++ return (int)(c & 0x80U); /* Use bitwise operation to check if the most significant bit is 1 */ -++#else -++ return (int)isleadbyte((int)(c & 0xffU)); /* Use bitwise operations to limit character values to valid ranges */ -++#endif -++} -++#endif -++ -++/* -++ * Parsing whether it is a wide character -++ */ -++SECUREC_INLINE void SecUpdateWcharFlagByType(SecUnsignedChar ch, SecScanSpec *spec) -++{ -++ if (spec->isWCharOrLong != 0) { -++ /* Wide character identifiers have been explicitly set by l or h flag */ -++ return; -++ } -++ -++ /* Set default flag */ -++#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ spec->isWCharOrLong = 1; /* On windows wide char version %c %s %[ is wide char */ -++#else -++ spec->isWCharOrLong = -1; /* On linux all version %c %s %[ is multi char */ -++#endif -++ -++ if (ch == SECUREC_CHAR('C') || ch == SECUREC_CHAR('S')) { -++#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ spec->isWCharOrLong = -1; /* On windows wide char version %C %S is multi char */ -++#else -++ spec->isWCharOrLong = 1; /* On linux all version %C %S is wide char */ -++#endif -++ } -++ -++ return; -++} -++/* -++ * Decode %l %ll -++ */ -++SECUREC_INLINE void SecDecodeScanQualifierL(const SecUnsignedChar **format, SecScanSpec *spec) -++{ -++ const SecUnsignedChar *fmt = *format; -++ if (*(fmt + 1) == SECUREC_CHAR('l')) { -++ spec->numberArgType = 1; -++ spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; -++ ++fmt; -++ } else { -++ spec->numberWidth = SECUREC_NUM_WIDTH_LONG; -++#if defined(SECUREC_ON_64BITS) && !(defined(SECUREC_COMPATIBLE_WIN_FORMAT)) -++ /* On window 64 system sizeof long is 32bit */ -++ spec->numberArgType = 1; -++#endif -++ spec->isWCharOrLong = 1; -++ } -++ *format = fmt; -++} -++ -++/* -++ * Decode %I %I43 %I64 %Id %Ii %Io ... -++ * Set finishFlag to 1 finish Flag -++ */ -++SECUREC_INLINE void SecDecodeScanQualifierI(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag) -++{ -++ const SecUnsignedChar *fmt = *format; -++ if ((*(fmt + 1) == SECUREC_CHAR('6')) && -++ (*(fmt + 2) == SECUREC_CHAR('4'))) { /* Offset 2 for I64 */ -++ spec->numberArgType = 1; -++ *format = *format + 2; /* Add 2 to skip I64 point to '4' next loop will inc */ -++ } else if ((*(fmt + 1) == SECUREC_CHAR('3')) && -++ (*(fmt + 2) == SECUREC_CHAR('2'))) { /* Offset 2 for I32 */ -++ *format = *format + 2; /* Add 2 to skip I32 point to '2' next loop will inc */ -++ } else if ((*(fmt + 1) == SECUREC_CHAR('d')) || -++ (*(fmt + 1) == SECUREC_CHAR('i')) || -++ (*(fmt + 1) == SECUREC_CHAR('o')) || -++ (*(fmt + 1) == SECUREC_CHAR('x')) || -++ (*(fmt + 1) == SECUREC_CHAR('X'))) { -++ spec->numberArgType = SecNumberArgType(sizeof(void *)); -++ } else { -++ /* For %I */ -++ spec->numberArgType = SecNumberArgType(sizeof(void *)); -++ *finishFlag = 1; -++ } -++} -++ -++SECUREC_INLINE int SecDecodeScanWidth(const SecUnsignedChar **format, SecScanSpec *spec) -++{ -++ const SecUnsignedChar *fmt = *format; -++ while (SecIsDigit((SecInt)(int)(*fmt)) != 0) { -++ spec->widthSet = 1; -++ if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(spec->width)) { -++ return -1; -++ } -++ spec->width = (int)SECUREC_MUL_TEN((unsigned int)spec->width) + (unsigned char)(*fmt - SECUREC_CHAR('0')); -++ ++fmt; -++ } -++ *format = fmt; -++ return 0; -++} -++ -++/* -++ * Init default flags for each format. do not init ch this variable is context-dependent -++ */ -++SECUREC_INLINE void SecSetDefaultScanSpec(SecScanSpec *spec) -++{ -++ /* The ch and charCount member variables cannot be initialized here */ -++ spec->argPtr = NULL; -++ spec->arrayWidth = 0; -++ spec->number64 = 0; -++ spec->number = 0; -++ spec->numberWidth = SECUREC_NUM_WIDTH_INT; /* 0 = SHORT, 1 = int, > 1 long or L_DOUBLE */ -++ spec->numberArgType = 0; /* 1 for 64-bit integer, 0 otherwise */ -++ spec->width = 0; -++ spec->widthSet = 0; -++ spec->convChr = 0; -++ spec->oriConvChr = 0; -++ spec->isWCharOrLong = 0; -++ spec->suppress = 0; -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ spec->beyondMax = 0; -++#endif -++ spec->negative = 0; -++ spec->numberState = SECUREC_NUMBER_STATE_DEFAULT; -++} -++ -++/* -++ * Decode qualifier %I %L %h ... -++ * Set finishFlag to 1 finish Flag -++ */ -++SECUREC_INLINE void SecDecodeScanQualifier(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag) -++{ -++ switch (**format) { -++ case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('N'): -++ break; -++ case SECUREC_CHAR('h'): -++ --spec->numberWidth; /* The h for SHORT , hh for CHAR */ -++ spec->isWCharOrLong = -1; -++ break; -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++ case SECUREC_CHAR('j'): -++ spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; /* For intmax_t or uintmax_t */ -++ spec->numberArgType = 1; -++ break; -++ case SECUREC_CHAR('t'): /* fall-through */ /* FALLTHRU */ -++#endif -++#if SECUREC_IN_KERNEL -++ case SECUREC_CHAR('Z'): /* fall-through */ /* FALLTHRU */ -++#endif -++ case SECUREC_CHAR('z'): -++#ifdef SECUREC_ON_64BITS -++ spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; -++ spec->numberArgType = 1; -++#else -++ spec->numberWidth = SECUREC_NUM_WIDTH_LONG; -++#endif -++ break; -++ case SECUREC_CHAR('L'): /* For long double */ /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('q'): -++ spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG; -++ spec->numberArgType = 1; -++ break; -++ case SECUREC_CHAR('l'): -++ SecDecodeScanQualifierL(format, spec); -++ break; -++ case SECUREC_CHAR('w'): -++ spec->isWCharOrLong = 1; -++ break; -++ case SECUREC_CHAR('*'): -++ spec->suppress = 1; -++ break; -++ case SECUREC_CHAR('I'): -++ SecDecodeScanQualifierI(format, spec, finishFlag); -++ break; -++ default: -++ *finishFlag = 1; -++ break; -++ } -++} -++/* -++ * Decode width and qualifier in format -++ */ -++SECUREC_INLINE int SecDecodeScanFlag(const SecUnsignedChar **format, SecScanSpec *spec) -++{ -++ const SecUnsignedChar *fmt = *format; -++ int finishFlag = 0; -++ -++ do { -++ ++fmt; /* First skip % , next seek fmt */ -++ /* May %*6d , so put it inside the loop */ -++ if (SecDecodeScanWidth(&fmt, spec) != 0) { -++ return -1; -++ } -++ SecDecodeScanQualifier(&fmt, spec, &finishFlag); -++ } while (finishFlag == 0); -++ *format = fmt; -++ return 0; -++} -++ -++/* -++ * Judging whether a zeroing buffer is needed according to different formats -++ */ -++SECUREC_INLINE int SecDecodeClearFormat(const SecUnsignedChar *format, int *convChr) -++{ -++ const SecUnsignedChar *fmt = format; -++ /* To lowercase */ -++ int ch = SECUREC_TO_LOWERCASE(*fmt); -++ if (!(ch == 'c' || ch == 's' || ch == SECUREC_BRACE)) { -++ return -1; /* First argument is not a string type */ -++ } -++ if (ch == SECUREC_BRACE) { -++#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT)) -++ if (*fmt == SECUREC_CHAR('{')) { -++ return -1; -++ } -++#endif -++ ++fmt; -++ if (*fmt == SECUREC_CHAR('^')) { -++ ++fmt; -++ } -++ if (*fmt == SECUREC_CHAR(']')) { -++ ++fmt; -++ } -++ while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR(']')) { -++ ++fmt; -++ } -++ if (*fmt == SECUREC_CHAR('\0')) { -++ return -1; /* Trunc'd format string */ -++ } -++ } -++ *convChr = ch; -++ return 0; -++} -++ -++/* -++ * Add L'\0' for wchar string , add '\0' for char string -++ */ -++SECUREC_INLINE void SecAddEndingZero(void *ptr, const SecScanSpec *spec) -++{ -++ if (spec->suppress == 0) { -++ *(char *)ptr = '\0'; -++#if SECUREC_HAVE_WCHART -++ if (spec->isWCharOrLong > 0) { -++ *(wchar_t UNALIGNED *)ptr = L'\0'; -++ } -++#endif -++ } -++} -++ -++SECUREC_INLINE void SecDecodeClearArg(SecScanSpec *spec, va_list argList) -++{ -++ va_list argListSave; /* Backup for argList value, this variable don't need initialized */ -++ (void)SECUREC_MEMSET_FUNC_OPT(&argListSave, 0, sizeof(va_list)); /* To clear e530 argListSave not initialized */ -++#if defined(va_copy) -++ va_copy(argListSave, argList); -++#elif defined(__va_copy) /* For vxworks */ -++ __va_copy(argListSave, argList); -++#else -++ argListSave = argList; -++#endif -++ spec->argPtr = (void *)va_arg(argListSave, void *); -++ /* Get the next argument, size of the array in characters */ -++ /* Use 0xffffffffUL mask to Support pass integer as array length */ -++ spec->arrayWidth = ((size_t)(va_arg(argListSave, size_t))) & 0xffffffffUL; -++ va_end(argListSave); -++ /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ (void)argListSave; -++} -++ -++#ifdef SECUREC_FOR_WCHAR -++/* -++ * Clean up the first %s %c buffer to zero for wchar version -++ */ -++void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList) -++#else -++/* -++ * Clean up the first %s %c buffer to zero for char version -++ */ -++void SecClearDestBuf(const char *buffer, const char *format, va_list argList) -++#endif -++{ -++ SecScanSpec spec; -++ int convChr = 0; -++ const SecUnsignedChar *fmt = (const SecUnsignedChar *)format; -++ -++ /* Find first % */ -++ while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR('%')) { -++ ++fmt; -++ } -++ if (*fmt == SECUREC_CHAR('\0')) { -++ return; -++ } -++ -++ SecSetDefaultScanSpec(&spec); -++ if (SecDecodeScanFlag(&fmt, &spec) != 0) { -++ return; -++ } -++ -++ /* Update wchar flag for %S %C */ -++ SecUpdateWcharFlagByType(*fmt, &spec); -++ if (spec.suppress != 0) { -++ return; -++ } -++ -++ if (SecDecodeClearFormat(fmt, &convChr) != 0) { -++ return; -++ } -++ -++ if (*buffer != SECUREC_CHAR('\0') && convChr != 's') { -++ /* -++ * When buffer not empty just clear %s. -++ * Example call sscanf by argment of (" \n", "%s", s, sizeof(s)) -++ */ -++ return; -++ } -++ -++ SecDecodeClearArg(&spec, argList); -++ /* There is no need to judge the upper limit */ -++ if (spec.arrayWidth == 0 || spec.argPtr == NULL) { -++ return; -++ } -++ /* Clear one char */ -++ SecAddEndingZero(spec.argPtr, &spec); -++ return; -++} -++ -++/* -++ * Assign number to output buffer -++ */ -++SECUREC_INLINE void SecAssignNumber(const SecScanSpec *spec) -++{ -++ void *argPtr = spec->argPtr; -++ if (spec->numberArgType != 0) { -++#if defined(SECUREC_VXWORKS_PLATFORM) -++#if defined(SECUREC_VXWORKS_PLATFORM_COMP) -++ *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64); -++#else -++ /* Take number64 as unsigned number unsigned to int clear Compile warning */ -++ *(SecInt64 UNALIGNED *)argPtr = *(SecUnsignedInt64 *)(&(spec->number64)); -++#endif -++#else -++ /* Take number64 as unsigned number */ -++ *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64); -++#endif -++ return; -++ } -++ if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) { -++ /* Take number as unsigned number */ -++ *(long UNALIGNED *)argPtr = (long)(spec->number); -++ } else if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) { -++ *(int UNALIGNED *)argPtr = (int)(spec->number); -++ } else if (spec->numberWidth == SECUREC_NUM_WIDTH_SHORT) { -++ /* Take number as unsigned number */ -++ *(short UNALIGNED *)argPtr = (short)(spec->number); -++ } else { /* < 0 for hh format modifier */ -++ /* Take number as unsigned number */ -++ *(char UNALIGNED *)argPtr = (char)(spec->number); -++ } -++} -++ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++/* -++ * Judge the long bit width -++ */ -++SECUREC_INLINE int SecIsLongBitEqual(int bitNum) -++{ -++ return (int)((unsigned int)bitNum == SECUREC_LONG_BIT_NUM); -++} -++#endif -++ -++/* -++ * Convert hexadecimal characters to decimal value -++ */ -++SECUREC_INLINE int SecHexValueOfChar(SecInt ch) -++{ -++ /* Use isdigt Causing tool false alarms */ -++ return (int)((ch >= '0' && ch <= '9') ? ((unsigned char)ch - '0') : -++ ((((unsigned char)ch | (unsigned char)('a' - 'A')) - ('a')) + 10)); /* Adding 10 is to hex value */ -++} -++ -++/* -++ * Parse decimal character to integer for 32bit . -++ */ -++static void SecDecodeNumberDecimal(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ unsigned long decimalEdge = SECUREC_MAX_32BITS_VALUE_DIV_TEN; -++#ifdef SECUREC_ON_64BITS -++ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { -++ decimalEdge = (unsigned long)SECUREC_MAX_64BITS_VALUE_DIV_TEN; -++ } -++#endif -++ if (spec->number > decimalEdge) { -++ spec->beyondMax = 1; -++ } -++#endif -++ spec->number = SECUREC_MUL_TEN(spec->number); -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (spec->number == SECUREC_MUL_TEN(decimalEdge)) { -++ /* This code is specially converted to unsigned long type for compatibility */ -++ SecUnsignedInt64 number64As = (unsigned long)SECUREC_MAX_64BITS_VALUE - spec->number; -++ if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')) { -++ spec->beyondMax = 1; -++ } -++ } -++#endif -++ spec->number += ((unsigned long)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')); -++} -++ -++/* -++ * Parse Hex character to integer for 32bit . -++ */ -++static void SecDecodeNumberHex(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (SECUREC_LONG_HEX_BEYOND_MAX(spec->number)) { -++ spec->beyondMax = 1; -++ } -++#endif -++ spec->number = SECUREC_MUL_SIXTEEN(spec->number); -++ spec->number += (unsigned long)(unsigned int)SecHexValueOfChar(spec->ch); -++} -++ -++/* -++ * Parse Octal character to integer for 32bit . -++ */ -++static void SecDecodeNumberOctal(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (SECUREC_LONG_OCTAL_BEYOND_MAX(spec->number)) { -++ spec->beyondMax = 1; -++ } -++#endif -++ spec->number = SECUREC_MUL_EIGHT(spec->number); -++ spec->number += ((unsigned long)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')); -++} -++ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++/* Compatible with integer negative values other than int */ -++SECUREC_INLINE void SecFinishNumberNegativeOther(SecScanSpec *spec) -++{ -++ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { -++ if (spec->number > SECUREC_MIN_LONG_NEG_VALUE) { -++ spec->number = SECUREC_MIN_LONG_NEG_VALUE; -++ } else { -++ spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ -++ } -++ if (spec->beyondMax != 0) { -++ if (spec->numberWidth < SECUREC_NUM_WIDTH_INT) { -++ spec->number = 0; -++ } -++ if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG) { -++ spec->number = SECUREC_MIN_LONG_NEG_VALUE; -++ } -++ } -++ } else { /* For o, u, x, X, p */ -++ spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ -++ if (spec->beyondMax != 0) { -++ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; -++ } -++ } -++} -++/* Compatible processing of integer negative numbers */ -++SECUREC_INLINE void SecFinishNumberNegativeInt(SecScanSpec *spec) -++{ -++ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { -++#ifdef SECUREC_ON_64BITS -++ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { -++ if ((spec->number > SECUREC_MIN_64BITS_NEG_VALUE)) { -++ spec->number = 0; -++ } else { -++ spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ -++ } -++ } -++#else -++ if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { -++ if ((spec->number > SECUREC_MIN_32BITS_NEG_VALUE)) { -++ spec->number = SECUREC_MIN_32BITS_NEG_VALUE; -++ } else { -++ spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ -++ } -++ } -++#endif -++ if (spec->beyondMax != 0) { -++#ifdef SECUREC_ON_64BITS -++ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { -++ spec->number = 0; -++ } -++#else -++ if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { -++ spec->number = SECUREC_MIN_32BITS_NEG_VALUE; -++ } -++#endif -++ } -++ } else { /* For o, u, x, X ,p */ -++#ifdef SECUREC_ON_64BITS -++ if (spec->number > SECUREC_MAX_32BITS_VALUE_INC) { -++ spec->number = SECUREC_MAX_32BITS_VALUE; -++ } else { -++ spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ -++ } -++#else -++ spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */ -++#endif -++ if (spec->beyondMax != 0) { -++ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; -++ } -++ } -++} -++ -++/* Compatible with integer positive values other than int */ -++SECUREC_INLINE void SecFinishNumberPositiveOther(SecScanSpec *spec) -++{ -++ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { -++ if (spec->number > SECUREC_MAX_LONG_POS_VALUE) { -++ spec->number = SECUREC_MAX_LONG_POS_VALUE; -++ } -++ if ((spec->beyondMax != 0 && spec->numberWidth < SECUREC_NUM_WIDTH_INT)) { -++ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; -++ } -++ if (spec->beyondMax != 0 && spec->numberWidth == SECUREC_NUM_WIDTH_LONG) { -++ spec->number = SECUREC_MAX_LONG_POS_VALUE; -++ } -++ } else { -++ if (spec->beyondMax != 0) { -++ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; -++ } -++ } -++} -++ -++/* Compatible processing of integer positive numbers */ -++SECUREC_INLINE void SecFinishNumberPositiveInt(SecScanSpec *spec) -++{ -++ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { -++#ifdef SECUREC_ON_64BITS -++ if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { -++ if (spec->number > SECUREC_MAX_64BITS_POS_VALUE) { -++ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; -++ } -++ } -++ if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) { -++ spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE; -++ } -++#else -++ if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { -++ if (spec->number > SECUREC_MAX_32BITS_POS_VALUE) { -++ spec->number = SECUREC_MAX_32BITS_POS_VALUE; -++ } -++ } -++ if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) { -++ spec->number = SECUREC_MAX_32BITS_POS_VALUE; -++ } -++#endif -++ } else { /* For o,u,x,X,p */ -++ if (spec->beyondMax != 0) { -++ spec->number = SECUREC_MAX_32BITS_VALUE; -++ } -++ } -++} -++ -++#endif -++ -++/* -++ * Parse decimal character to integer for 64bit . -++ */ -++static void SecDecodeNumber64Decimal(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (spec->number64 > SECUREC_MAX_64BITS_VALUE_DIV_TEN) { -++ spec->beyondMax = 1; -++ } -++#endif -++ spec->number64 = SECUREC_MUL_TEN(spec->number64); -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (spec->number64 == SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT) { -++ SecUnsignedInt64 number64As = (SecUnsignedInt64)SECUREC_MAX_64BITS_VALUE - spec->number64; -++ if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')) { -++ spec->beyondMax = 1; -++ } -++ } -++#endif -++ spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')); -++} -++ -++/* -++ * Parse Hex character to integer for 64bit . -++ */ -++static void SecDecodeNumber64Hex(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (SECUREC_QWORD_HEX_BEYOND_MAX(spec->number64)) { -++ spec->beyondMax = 1; -++ } -++#endif -++ spec->number64 = SECUREC_MUL_SIXTEEN(spec->number64); -++ spec->number64 += (SecUnsignedInt64)(unsigned int)SecHexValueOfChar(spec->ch); -++} -++ -++/* -++ * Parse Octal character to integer for 64bit . -++ */ -++static void SecDecodeNumber64Octal(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (SECUREC_QWORD_OCTAL_BEYOND_MAX(spec->number64)) { -++ spec->beyondMax = 1; -++ } -++#endif -++ spec->number64 = SECUREC_MUL_EIGHT(spec->number64); -++ spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')); -++} -++ -++#define SECUREC_DECODE_NUMBER_FUNC_NUM 2 -++ -++/* -++ * Parse 64-bit integer formatted input, return 0 when ch is a number. -++ */ -++SECUREC_INLINE int SecDecodeNumber(SecScanSpec *spec) -++{ -++ /* Function name cannot add address symbol, causing 546 alarm */ -++ static void (* const secDecodeNumberHex[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { -++ SecDecodeNumberHex, SecDecodeNumber64Hex -++ }; -++ static void (* const secDecodeNumberOctal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { -++ SecDecodeNumberOctal, SecDecodeNumber64Octal -++ }; -++ static void (* const secDecodeNumberDecimal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { -++ SecDecodeNumberDecimal, SecDecodeNumber64Decimal -++ }; -++ if (spec->convChr == 'x' || spec->convChr == 'p') { -++ if (SecIsXdigit(spec->ch) != 0) { -++ (*secDecodeNumberHex[spec->numberArgType])(spec); -++ } else { -++ return -1; -++ } -++ return 0; -++ } -++ if (SecIsDigit(spec->ch) == 0) { -++ return -1; -++ } -++ if (spec->convChr == 'o') { -++ if (spec->ch < SECUREC_CHAR('8')) { /* Octal maximum limit '8' */ -++ (*secDecodeNumberOctal[spec->numberArgType])(spec); -++ } else { -++ return -1; -++ } -++ } else { /* The convChr is 'd' */ -++ (*secDecodeNumberDecimal[spec->numberArgType])(spec); -++ } -++ return 0; -++} -++ -++/* -++ * Complete the final 32-bit integer formatted input -++ */ -++static void SecFinishNumber(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (spec->negative != 0) { -++ if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) { -++ SecFinishNumberNegativeInt(spec); -++ } else { -++ SecFinishNumberNegativeOther(spec); -++ } -++ } else { -++ if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) { -++ SecFinishNumberPositiveInt(spec); -++ } else { -++ SecFinishNumberPositiveOther(spec); -++ } -++ } -++#else -++ if (spec->negative != 0) { -++#if defined(__hpux) -++ if (spec->oriConvChr != 'p') { -++ spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ -++ } -++#else -++ spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */ -++#endif -++ } -++#endif -++ return; -++} -++ -++/* -++ * Complete the final 64-bit integer formatted input -++ */ -++static void SecFinishNumber64(SecScanSpec *spec) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX))) -++ if (spec->negative != 0) { -++ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { -++ if (spec->number64 > SECUREC_MIN_64BITS_NEG_VALUE) { -++ spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE; -++ } else { -++ spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ -++ } -++ if (spec->beyondMax != 0) { -++ spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE; -++ } -++ } else { /* For o, u, x, X, p */ -++ spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ -++ if (spec->beyondMax != 0) { -++ spec->number64 = SECUREC_MAX_64BITS_VALUE; -++ } -++ } -++ } else { -++ if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) { -++ if (spec->number64 > SECUREC_MAX_64BITS_POS_VALUE) { -++ spec->number64 = SECUREC_MAX_64BITS_POS_VALUE; -++ } -++ if (spec->beyondMax != 0) { -++ spec->number64 = SECUREC_MAX_64BITS_POS_VALUE; -++ } -++ } else { -++ if (spec->beyondMax != 0) { -++ spec->number64 = SECUREC_MAX_64BITS_VALUE; -++ } -++ } -++ } -++#else -++ if (spec->negative != 0) { -++#if defined(__hpux) -++ if (spec->oriConvChr != 'p') { -++ spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ -++ } -++#else -++ spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */ -++#endif -++ } -++#endif -++ return; -++} -++ -++#if SECUREC_ENABLE_SCANF_FILE -++ -++/* -++ * Adjust the pointer position of the file stream -++ */ -++SECUREC_INLINE void SecSeekStream(SecFileStream *stream) -++{ -++ if (stream->count == 0) { -++ if (feof(stream->pf) != 0) { -++ /* File pointer at the end of file, don't need to seek back */ -++ stream->base[0] = '\0'; -++ return; -++ } -++ } -++ /* Seek to original position, for file read, but nothing to input */ -++ if (fseek(stream->pf, stream->oriFilePos, SEEK_SET) != 0) { -++ /* Seek failed, ignore it */ -++ stream->oriFilePos = 0; -++ return; -++ } -++ -++ if (stream->fileRealRead > 0) { /* Do not seek without input data */ -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ size_t residue = stream->fileRealRead % SECUREC_BUFFERED_BLOK_SIZE; -++ size_t loops; -++ for (loops = 0; loops < (stream->fileRealRead / SECUREC_BUFFERED_BLOK_SIZE); ++loops) { -++ if (fread(stream->base, (size_t)SECUREC_BUFFERED_BLOK_SIZE, (size_t)1, stream->pf) != (size_t)1) { -++ break; -++ } -++ } -++ if (residue != 0) { -++ long curFilePos; -++ if (fread(stream->base, residue, (size_t)1, stream->pf) != (size_t)1) { -++ return; -++ } -++ curFilePos = ftell(stream->pf); -++ if (curFilePos < stream->oriFilePos || -++ (size_t)(unsigned long)(curFilePos - stream->oriFilePos) < stream->fileRealRead) { -++ /* Try to remedy the problem */ -++ long adjustNum = (long)(stream->fileRealRead - (size_t)(unsigned long)(curFilePos - stream->oriFilePos)); -++ (void)fseek(stream->pf, adjustNum, SEEK_CUR); -++ } -++ } -++#else -++ /* Seek from oriFilePos. Regardless of the integer sign problem, call scanf will not read very large data */ -++ if (fseek(stream->pf, (long)stream->fileRealRead, SEEK_CUR) != 0) { -++ /* Seek failed, ignore it */ -++ stream->oriFilePos = 0; -++ return; -++ } -++#endif -++ } -++ return; -++} -++ -++/* -++ * Adjust the pointer position of the file stream and free memory -++ */ -++SECUREC_INLINE void SecAdjustStream(SecFileStream *stream) -++{ -++ if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0 && stream->base != NULL) { -++ SecSeekStream(stream); -++ SECUREC_FREE(stream->base); -++ stream->base = NULL; -++ } -++ return; -++} -++#endif -++ -++SECUREC_INLINE void SecSkipSpaceFormat(const SecUnsignedChar **format) -++{ -++ const SecUnsignedChar *fmt = *format; -++ while (SecIsSpace((SecInt)(int)(*fmt)) != 0) { -++ ++fmt; -++ } -++ *format = fmt; -++} -++ -++#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION) -++/* -++ * Handling multi-character characters -++ */ -++SECUREC_INLINE int SecDecodeLeadByte(SecScanSpec *spec, const SecUnsignedChar **format, SecFileStream *stream) -++{ -++#if SECUREC_HAVE_MBTOWC -++ const SecUnsignedChar *fmt = *format; -++ int ch1 = (int)spec->ch; -++ int ch2 = SecGetChar(stream, &(spec->charCount)); -++ spec->ch = (SecInt)ch2; -++ if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch2) { -++ /* in console mode, ungetc twice may cause problem */ -++ SecUnGetChar(ch2, stream, &(spec->charCount)); -++ SecUnGetChar(ch1, stream, &(spec->charCount)); -++ return -1; -++ } -++ ++fmt; -++ if ((unsigned int)MB_CUR_MAX >= SECUREC_UTF8_BOM_HEADER_SIZE && -++ (((unsigned char)ch1 & SECUREC_UTF8_LEAD_1ST) == SECUREC_UTF8_LEAD_1ST) && -++ (((unsigned char)ch2 & SECUREC_UTF8_LEAD_2ND) == SECUREC_UTF8_LEAD_2ND)) { -++ /* This char is very likely to be a UTF-8 char */ -++ wchar_t tempWChar; -++ char temp[SECUREC_MULTI_BYTE_MAX_LEN]; -++ int ch3 = (int)SecGetChar(stream, &(spec->charCount)); -++ spec->ch = (SecInt)ch3; -++ if (*fmt == SECUREC_CHAR('\0') || (int)(*fmt) != ch3) { -++ SecUnGetChar(ch3, stream, &(spec->charCount)); -++ return -1; -++ } -++ temp[0] = (char)ch1; -++ temp[1] = (char)ch2; /* 1 index of second character */ -++ temp[2] = (char)ch3; /* 2 index of third character */ -++ temp[3] = '\0'; /* 3 of string terminator position */ -++ if (mbtowc(&tempWChar, temp, sizeof(temp)) > 0) { -++ /* Succeed */ -++ ++fmt; -++ --spec->charCount; -++ } else { -++ SecUnGetChar(ch3, stream, &(spec->charCount)); -++ } -++ } -++ --spec->charCount; /* Only count as one character read */ -++ *format = fmt; -++ return 0; -++#else -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ (void)format; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ return -1; -++#endif -++} -++ -++SECUREC_INLINE int SecFilterWcharInFormat(SecScanSpec *spec, const SecUnsignedChar **format, SecFileStream *stream) -++{ -++ if (SecIsLeadByte(spec->ch) != 0) { -++ if (SecDecodeLeadByte(spec, format, stream) != 0) { -++ return -1; -++ } -++ } -++ return 0; -++} -++#endif -++ -++/* -++ * Resolving sequence of characters from %[ format, format wile point to ']' -++ */ -++SECUREC_INLINE int SecSetupBracketTable(const SecUnsignedChar **format, SecBracketTable *bracketTable) -++{ -++ const SecUnsignedChar *fmt = *format; -++ SecUnsignedChar prevChar = 0; -++#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT)) -++ if (*fmt == SECUREC_CHAR('{')) { -++ return -1; -++ } -++#endif -++ /* For building "table" data */ -++ ++fmt; /* Skip [ */ -++ bracketTable->mask = 0; /* Set all bits to 0 */ -++ if (*fmt == SECUREC_CHAR('^')) { -++ ++fmt; -++ bracketTable->mask = (unsigned char)0xffU; /* Use 0xffU to set all bits to 1 */ -++ } -++ if (*fmt == SECUREC_CHAR(']')) { -++ prevChar = SECUREC_CHAR(']'); -++ ++fmt; -++ SecBracketSetBit(bracketTable->table, SECUREC_CHAR(']')); -++ } -++ while (*fmt != SECUREC_CHAR('\0') && *fmt != SECUREC_CHAR(']')) { -++ SecUnsignedChar expCh = *fmt; -++ ++fmt; -++ if (expCh != SECUREC_CHAR('-') || prevChar == 0 || *fmt == SECUREC_CHAR(']')) { -++ /* Normal character */ -++ prevChar = expCh; -++ SecBracketSetBit(bracketTable->table, expCh); -++ } else { -++ /* For %[a-z] */ -++ expCh = *fmt; /* Get end of range */ -++ ++fmt; -++ if (prevChar <= expCh) { /* %[a-z] %[a-a] */ -++ SecBracketSetBitRange(bracketTable->table, prevChar, expCh); -++ } else { -++ /* For %[z-a] */ -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ /* Swap start and end characters */ -++ SecBracketSetBitRange(bracketTable->table, expCh, prevChar); -++#else -++ SecBracketSetBit(bracketTable->table, SECUREC_CHAR('-')); -++ SecBracketSetBit(bracketTable->table, expCh); -++#endif -++ } -++ prevChar = 0; -++ } -++ } -++ *format = fmt; -++ return 0; -++} -++ -++#ifdef SECUREC_FOR_WCHAR -++SECUREC_INLINE int SecInputForWchar(SecScanSpec *spec) -++{ -++ void *endPtr = spec->argPtr; -++ if (spec->isWCharOrLong > 0) { -++ *(wchar_t UNALIGNED *)endPtr = (wchar_t)spec->ch; -++ endPtr = (wchar_t *)endPtr + 1; -++ --spec->arrayWidth; -++ } else { -++#if SECUREC_HAVE_WCTOMB -++ int temp; -++ char tmpBuf[SECUREC_MB_LEN + 1]; -++ SECUREC_MASK_MSVC_CRT_WARNING temp = wctomb(tmpBuf, (wchar_t)spec->ch); -++ SECUREC_END_MASK_MSVC_CRT_WARNING -++ if (temp <= 0 || (size_t)(unsigned int)temp > sizeof(tmpBuf)) { -++ /* If wctomb error, then ignore character */ -++ return 0; -++ } -++ if (((size_t)(unsigned int)temp) > spec->arrayWidth) { -++ return -1; -++ } -++ if (memcpy_s(endPtr, spec->arrayWidth, tmpBuf, (size_t)(unsigned int)temp) != EOK) { -++ return -1; -++ } -++ endPtr = (char *)endPtr + temp; -++ spec->arrayWidth -= (size_t)(unsigned int)temp; -++#else -++ return -1; -++#endif -++ } -++ spec->argPtr = endPtr; -++ return 0; -++} -++#endif -++ -++#ifndef SECUREC_FOR_WCHAR -++#if SECUREC_HAVE_WCHART -++SECUREC_INLINE wchar_t SecConvertInputCharToWchar(SecScanSpec *spec, SecFileStream *stream) -++{ -++ wchar_t tempWChar = L'?'; /* Set default char is ? */ -++#if SECUREC_HAVE_MBTOWC -++ char temp[SECUREC_MULTI_BYTE_MAX_LEN + 1]; -++ temp[0] = (char)spec->ch; -++ temp[1] = '\0'; -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ if (SecIsLeadByte(spec->ch) != 0) { -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ temp[1] = (char)spec->ch; -++ temp[2] = '\0'; /* 2 of string terminator position */ -++ } -++ if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) { -++ /* No string termination error for tool */ -++ tempWChar = L'?'; -++ } -++#else -++ if (SecIsLeadByte(spec->ch) != 0) { -++ int convRes = 0; -++ int di = 1; -++ /* On Linux like system, the string is encoded in UTF-8 */ -++ while (convRes <= 0 && di < (int)MB_CUR_MAX && di < SECUREC_MULTI_BYTE_MAX_LEN) { -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ temp[di] = (char)spec->ch; -++ ++di; -++ temp[di] = '\0'; -++ convRes = mbtowc(&tempWChar, temp, sizeof(temp)); -++ } -++ if (convRes <= 0) { -++ tempWChar = L'?'; -++ } -++ } else { -++ if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) { -++ tempWChar = L'?'; -++ } -++ } -++#endif -++#else -++ (void)spec; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++#endif /* SECUREC_HAVE_MBTOWC */ -++ -++ return tempWChar; -++} -++#endif /* SECUREC_HAVE_WCHART */ -++ -++SECUREC_INLINE int SecInputForChar(SecScanSpec *spec, SecFileStream *stream) -++{ -++ void *endPtr = spec->argPtr; -++ if (spec->isWCharOrLong > 0) { -++#if SECUREC_HAVE_WCHART -++ *(wchar_t UNALIGNED *)endPtr = SecConvertInputCharToWchar(spec, stream); -++ endPtr = (wchar_t *)endPtr + 1; -++ --spec->arrayWidth; -++#else -++ (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ return -1; -++#endif -++ } else { -++ *(char *)endPtr = (char)spec->ch; -++ endPtr = (char *)endPtr + 1; -++ --spec->arrayWidth; -++ } -++ spec->argPtr = endPtr; -++ return 0; -++} -++#endif -++ -++/* -++ * Scan digital part of %d %i %o %u %x %p. -++ * Return 0 OK -++ */ -++SECUREC_INLINE int SecInputNumberDigital(SecFileStream *stream, SecScanSpec *spec) -++{ -++ static void (* const secFinishNumber[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = { -++ SecFinishNumber, SecFinishNumber64 -++ }; -++ while (SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ /* Decode ch to number */ -++ if (SecDecodeNumber(spec) != 0) { -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ break; -++ } -++ SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */ -++ spec->numberState = SECUREC_NUMBER_STATE_STARTED; -++ } -++ /* Handling integer negative numbers and beyond max */ -++ (*secFinishNumber[spec->numberArgType])(spec); -++ if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) { -++ return 0; -++ } -++ return -1; -++} -++ -++/* -++ * Scan %d %i %o %u %x %p. -++ * Return 0 OK -++ */ -++SECUREC_INLINE int SecInputNumber(SecFileStream *stream, SecScanSpec *spec) -++{ -++ /* Character already read */ -++ if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) { -++ if (spec->ch == SECUREC_CHAR('-')) { -++ spec->negative = 1; -++#if SECUREC_IN_KERNEL -++ /* In kernel Refuse to enter negative number */ -++ if (SECUREC_CONVERT_IS_UNSIGNED(spec->oriConvChr)) { -++ return -1; -++ } -++#endif -++ } -++ SECUREC_FILED_WIDTH_DEC(spec); /* Do not need to check width here, must be greater than 0 */ -++ spec->ch = SecGetChar(stream, &(spec->charCount)); /* Eat + or - */ -++ spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next character, used for the '0' judgments */ -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); /* Not sure if it was actually read, so push back */ -++ } -++ -++ if (spec->oriConvChr == 'i') { -++ spec->convChr = 'd'; /* The i could be d, o, or x, use d as default */ -++ } -++ -++ if (spec->ch == SECUREC_CHAR('0') && (spec->oriConvChr == 'x' || spec->oriConvChr == 'i') && -++ SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ /* Input string begin with 0, may be 0x123 0X123 0123 0x 01 0yy 09 0 0ab 00 */ -++ SECUREC_FILED_WIDTH_DEC(spec); -++ spec->ch = SecGetChar(stream, &(spec->charCount)); /* ch is '0' */ -++ -++ /* Read only '0' due to width limitation */ -++ if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ /* The number or number64 in spec has been set 0 */ -++ return 0; -++ } -++ -++ spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next char to check x or X, do not dec width */ -++ if ((SecChar)spec->ch == SECUREC_CHAR('x') || (SecChar)spec->ch == SECUREC_CHAR('X')) { -++ spec->convChr = 'x'; -++ SECUREC_FILED_WIDTH_DEC(spec); /* Make incorrect width for x or X */ -++ } else { -++ if (spec->oriConvChr == 'i') { -++ spec->convChr = 'o'; -++ } -++ /* For "0y" "08" "01" "0a" ... ,push the 'y' '8' '1' 'a' back */ -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ /* Since 0 has been read, it indicates that a valid character has been read */ -++ spec->numberState = SECUREC_NUMBER_STATE_STARTED; -++ } -++ } -++ return SecInputNumberDigital(stream, spec); -++} -++ -++/* -++ * Scan %c %s %[ -++ * Return 0 OK -++ */ -++SECUREC_INLINE int SecInputString(SecFileStream *stream, SecScanSpec *spec, -++ const SecBracketTable *bracketTable, int *doneCount) -++{ -++ void *startPtr = spec->argPtr; -++ int suppressed = 0; -++ int errNoMem = 0; -++ -++ while (SECUREC_FILED_WIDTH_ENOUGH(spec)) { -++ SECUREC_FILED_WIDTH_DEC(spec); -++ spec->ch = SecGetChar(stream, &(spec->charCount)); -++ /* -++ * The char condition or string condition and bracket condition. -++ * Only supports wide characters with a maximum length of two bytes -++ */ -++ if (spec->ch != SECUREC_EOF && (SecCanInputCharacter(spec->convChr) != 0 || -++ SecCanInputString(spec->convChr, spec->ch) != 0 || -++ SecCanInputForBracket(spec->convChr, spec->ch, bracketTable) != 0)) { -++ if (spec->suppress != 0) { -++ /* Used to identify processed data for %*, use argPtr to identify will cause 613, so use suppressed */ -++ suppressed = 1; -++ continue; -++ } -++ /* Now suppress is not set */ -++ if (spec->arrayWidth == 0) { -++ errNoMem = 1; /* We have exhausted the user's buffer */ -++ break; -++ } -++#ifdef SECUREC_FOR_WCHAR -++ errNoMem = SecInputForWchar(spec); -++#else -++ errNoMem = SecInputForChar(spec, stream); -++#endif -++ if (errNoMem != 0) { -++ break; -++ } -++ } else { -++ SecUnGetChar(spec->ch, stream, &(spec->charCount)); -++ break; -++ } -++ } -++ -++ if (errNoMem != 0) { -++ /* In case of error, blank out the input buffer */ -++ SecAddEndingZero(startPtr, spec); -++ return -1; -++ } -++ if ((spec->suppress != 0 && suppressed == 0) || -++ (spec->suppress == 0 && startPtr == spec->argPtr)) { -++ /* No input was scanned */ -++ return -1; -++ } -++ if (spec->convChr != 'c') { -++ /* Add null-terminate for strings */ -++ SecAddEndingZero(spec->argPtr, spec); -++ } -++ if (spec->suppress == 0) { -++ *doneCount = *doneCount + 1; -++ } -++ return 0; -++} -++ -++#ifdef SECUREC_FOR_WCHAR -++/* -++ * Alloce buffer for wchar version of %[. -++ * Return 0 OK -++ */ -++SECUREC_INLINE int SecAllocBracketTable(SecBracketTable *bracketTable) -++{ -++ if (bracketTable->table == NULL) { -++ /* Table should be freed after use */ -++ bracketTable->table = (unsigned char *)SECUREC_MALLOC(SECUREC_BRACKET_TABLE_SIZE); -++ if (bracketTable->table == NULL) { -++ return -1; -++ } -++ } -++ return 0; -++} -++ -++/* -++ * Free buffer for wchar version of %[ -++ */ -++SECUREC_INLINE void SecFreeBracketTable(SecBracketTable *bracketTable) -++{ -++ if (bracketTable->table != NULL) { -++ SECUREC_FREE(bracketTable->table); -++ bracketTable->table = NULL; -++ } -++} -++#endif -++ -++#ifdef SECUREC_FOR_WCHAR -++/* -++ * Formatting input core functions for wchar version.Called by a function such as vswscanf_s -++ */ -++int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList) -++#else -++/* -++ * Formatting input core functions for char version.Called by a function such as vsscanf_s -++ */ -++int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList) -++#endif -++{ -++ const SecUnsignedChar *format = (const SecUnsignedChar *)cFormat; -++ SecBracketTable bracketTable = SECUREC_INIT_BRACKET_TABLE; -++ SecScanSpec spec; -++ int doneCount = 0; -++ int formatError = 0; -++ int paraIsNull = 0; -++ int match = 0; /* When % is found , inc this value */ -++ int errRet = 0; -++#if SECUREC_ENABLE_SCANF_FLOAT -++ SecFloatSpec floatSpec; -++ SecInitFloatSpec(&floatSpec); -++#endif -++ spec.ch = 0; /* Need to initialize to 0 */ -++ spec.charCount = 0; /* Need to initialize to 0 */ -++ -++ /* Format must not NULL, use err < 1 to claer 845 */ -++ while (errRet < 1 && *format != SECUREC_CHAR('\0')) { -++ /* Skip space in format and space in input */ -++ if (SecIsSpace((SecInt)(int)(*format)) != 0) { -++ /* Read first no space char */ -++ spec.ch = SecSkipSpaceChar(stream, &(spec.charCount)); -++ /* Read the EOF cannot be returned directly here, because the case of " %n" needs to be handled */ -++ /* Put fist no space char backup. put EOF back is also OK, and to modify the character count */ -++ SecUnGetChar(spec.ch, stream, &(spec.charCount)); -++ SecSkipSpaceFormat(&format); -++ continue; -++ } -++ -++ if (*format != SECUREC_CHAR('%')) { -++ spec.ch = SecGetChar(stream, &(spec.charCount)); -++ if ((int)(*format) != (int)(spec.ch)) { -++ SecUnGetChar(spec.ch, stream, &(spec.charCount)); -++ break; -++ } -++ ++format; -++#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION) -++ if (SecFilterWcharInFormat(&spec, &format, stream) != 0) { -++ break; -++ } -++#endif -++ continue; -++ } -++ -++ /* Now *format is % */ -++ /* Set default value for each % */ -++ SecSetDefaultScanSpec(&spec); -++ if (SecDecodeScanFlag(&format, &spec) != 0) { -++ formatError = 1; -++ ++errRet; -++ continue; -++ } -++ if (!SECUREC_FILED_WIDTH_ENOUGH(&spec)) { -++ /* 0 width in format */ -++ ++errRet; -++ continue; -++ } -++ -++ /* Update wchar flag for %S %C */ -++ SecUpdateWcharFlagByType(*format, &spec); -++ -++ spec.convChr = SECUREC_TO_LOWERCASE(*format); -++ spec.oriConvChr = spec.convChr; /* convChr may be modified to handle integer logic */ -++ if (spec.convChr != 'n') { -++ if (spec.convChr != 'c' && spec.convChr != SECUREC_BRACE) { -++ spec.ch = SecSkipSpaceChar(stream, &(spec.charCount)); -++ } else { -++ spec.ch = SecGetChar(stream, &(spec.charCount)); -++ } -++ if (spec.ch == SECUREC_EOF) { -++ ++errRet; -++ continue; -++ } -++ } -++ -++ /* Now no 0 width in format and get one char from input */ -++ switch (spec.oriConvChr) { -++ case 'c': /* Also 'C' */ -++ if (spec.widthSet == 0) { -++ spec.widthSet = 1; -++ spec.width = 1; -++ } -++ /* fall-through */ /* FALLTHRU */ -++ case 's': /* Also 'S': */ -++ /* fall-through */ /* FALLTHRU */ -++ case SECUREC_BRACE: -++ /* Unset last char to stream */ -++ SecUnGetChar(spec.ch, stream, &(spec.charCount)); -++ /* Check dest buffer and size */ -++ if (spec.suppress == 0) { -++ spec.argPtr = (void *)va_arg(argList, void *); -++ if (spec.argPtr == NULL) { -++ paraIsNull = 1; -++ ++errRet; -++ continue; -++ } -++ /* Get the next argument, size of the array in characters */ -++ spec.arrayWidth = SECUREC_GET_ARRAYWIDTH(argList); -++ if (SECUREC_ARRAY_WIDTH_IS_WRONG(spec)) { -++ /* Do not clear buffer just go error */ -++ ++errRet; -++ continue; -++ } -++ /* One element is needed for '\0' for %s and %[ */ -++ if (spec.convChr != 'c') { -++ --spec.arrayWidth; -++ } -++ } else { -++ /* Set argPtr to NULL is necessary, in supress mode we don't use argPtr to store data */ -++ spec.argPtr = NULL; -++ } -++ -++ if (spec.convChr == SECUREC_BRACE) { -++ /* Malloc when first %[ is meet for wchar version */ -++#ifdef SECUREC_FOR_WCHAR -++ if (SecAllocBracketTable(&bracketTable) != 0) { -++ ++errRet; -++ continue; -++ } -++#endif -++ (void)SECUREC_MEMSET_FUNC_OPT(bracketTable.table, 0, (size_t)SECUREC_BRACKET_TABLE_SIZE); -++ if (SecSetupBracketTable(&format, &bracketTable) != 0) { -++ ++errRet; -++ continue; -++ } -++ -++ if (*format == SECUREC_CHAR('\0')) { -++ /* Default add string terminator */ -++ SecAddEndingZero(spec.argPtr, &spec); -++ ++errRet; -++ /* Truncated format */ -++ continue; -++ } -++ } -++ -++ /* Set completed. Now read string or character */ -++ if (SecInputString(stream, &spec, &bracketTable, &doneCount) != 0) { -++ ++errRet; -++ continue; -++ } -++ break; -++ case 'p': -++ /* Make %hp same as %p */ -++ spec.numberWidth = SECUREC_NUM_WIDTH_INT; -++#ifdef SECUREC_ON_64BITS -++ spec.numberArgType = 1; -++#endif -++ /* fall-through */ /* FALLTHRU */ -++ case 'o': /* fall-through */ /* FALLTHRU */ -++ case 'u': /* fall-through */ /* FALLTHRU */ -++ case 'd': /* fall-through */ /* FALLTHRU */ -++ case 'i': /* fall-through */ /* FALLTHRU */ -++ case 'x': -++ /* Unset last char to stream */ -++ SecUnGetChar(spec.ch, stream, &(spec.charCount)); -++ if (SecInputNumber(stream, &spec) != 0) { -++ ++errRet; -++ continue; -++ } -++ if (spec.suppress == 0) { -++ spec.argPtr = (void *)va_arg(argList, void *); -++ if (spec.argPtr == NULL) { -++ paraIsNull = 1; -++ ++errRet; -++ continue; -++ } -++ SecAssignNumber(&spec); -++ ++doneCount; -++ } -++ break; -++ case 'n': /* Char count */ -++ if (spec.suppress == 0) { -++ spec.argPtr = (void *)va_arg(argList, void *); -++ if (spec.argPtr == NULL) { -++ paraIsNull = 1; -++ ++errRet; -++ continue; -++ } -++ spec.number = (unsigned long)(unsigned int)(spec.charCount); -++ spec.numberArgType = 0; -++ SecAssignNumber(&spec); -++ } -++ break; -++ case 'e': /* fall-through */ /* FALLTHRU */ -++ case 'f': /* fall-through */ /* FALLTHRU */ -++ case 'g': /* Scan a float */ -++ /* Unset last char to stream */ -++ SecUnGetChar(spec.ch, stream, &(spec.charCount)); -++#if SECUREC_ENABLE_SCANF_FLOAT -++ if (SecInputFloat(stream, &spec, &floatSpec) != 0) { -++ ++errRet; -++ continue; -++ } -++ if (spec.suppress == 0) { -++ spec.argPtr = (void *)va_arg(argList, void *); -++ if (spec.argPtr == NULL) { -++ ++errRet; -++ paraIsNull = 1; -++ continue; -++ } -++ if (SecAssignFloat(&floatSpec, &spec) != 0) { -++ ++errRet; -++ continue; -++ } -++ ++doneCount; -++ } -++ break; -++#else /* SECUREC_ENABLE_SCANF_FLOAT */ -++ ++errRet; -++ continue; -++#endif -++ default: -++ if ((int)(*format) != (int)spec.ch) { -++ SecUnGetChar(spec.ch, stream, &(spec.charCount)); -++ formatError = 1; -++ ++errRet; -++ continue; -++ } else { -++ --match; /* Compensate for the self-increment of the following code */ -++ } -++ break; -++ } -++ ++match; -++ ++format; -++ } -++ -++#ifdef SECUREC_FOR_WCHAR -++ SecFreeBracketTable(&bracketTable); -++#endif -++ -++#if SECUREC_ENABLE_SCANF_FLOAT -++ SecFreeFloatSpec(&floatSpec, &doneCount); -++#endif -++ -++#if SECUREC_ENABLE_SCANF_FILE -++ SecAdjustStream(stream); -++#endif -++ -++ if (spec.ch == SECUREC_EOF) { -++ return ((doneCount != 0 || match != 0) ? doneCount : SECUREC_SCANF_EINVAL); -++ } -++ if (formatError != 0 || paraIsNull != 0) { -++ /* Invalid Input Format or parameter, but not meet EOF */ -++ return SECUREC_SCANF_ERROR_PARA; -++ } -++ return doneCount; -++} -++ -++#if SECUREC_ENABLE_SCANF_FILE -++/* -++ * Get char from stream use std function -++ */ -++SECUREC_INLINE SecInt SecGetCharFromStream(const SecFileStream *stream) -++{ -++ SecInt ch; -++ ch = SECUREC_GETC(stream->pf); -++ return ch; -++} -++ -++/* -++ * Try to read the BOM header, when meet a BOM head, discard it, then data is Aligned to base -++ */ -++SECUREC_INLINE void SecReadAndSkipBomHeader(SecFileStream *stream) -++{ -++ /* Use size_t type conversion to clean e747 */ -++ stream->count = fread(stream->base, (size_t)1, (size_t)SECUREC_BOM_HEADER_SIZE, stream->pf); -++ if (stream->count > SECUREC_BOM_HEADER_SIZE) { -++ stream->count = 0; -++ } -++ if (SECUREC_BEGIN_WITH_BOM(stream->base, stream->count)) { -++ /* It's BOM header, discard it */ -++ stream->count = 0; -++ } -++} -++ -++/* -++ * Get char from file stream or buffer -++ */ -++SECUREC_INLINE SecInt SecGetCharFromFile(SecFileStream *stream) -++{ -++ SecInt ch; -++ if (stream->count < sizeof(SecChar)) { -++ /* Load file to buffer */ -++ size_t len; -++ if (stream->base != NULL) { -++ /* Put the last unread data in the buffer head */ -++ for (len = 0; len < stream->count; ++len) { -++ stream->base[len] = stream->cur[len]; -++ } -++ } else { -++ stream->oriFilePos = ftell(stream->pf); /* Save original file read position */ -++ if (stream->oriFilePos == -1) { -++ /* It may be a pipe stream */ -++ stream->flag = SECUREC_PIPE_STREAM_FLAG; -++ return SecGetCharFromStream(stream); -++ } -++ /* Reserve the length of BOM head */ -++ stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE + -++ SECUREC_BOM_HEADER_SIZE + sizeof(SecChar)); /* To store '\0' and aligned to wide char */ -++ if (stream->base == NULL) { -++ return SECUREC_EOF; -++ } -++ /* First read file */ -++ if (stream->oriFilePos == 0) { -++ /* Make sure the data is aligned to base */ -++ SecReadAndSkipBomHeader(stream); -++ } -++ } -++ -++ /* Skip existing data and read data */ -++ len = fread(stream->base + stream->count, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE, stream->pf); -++ if (len > SECUREC_BUFFERED_BLOK_SIZE) { /* It won't happen, */ -++ len = 0; -++ } -++ stream->count += len; -++ stream->cur = stream->base; -++ stream->flag |= SECUREC_LOAD_FILE_TO_MEM_FLAG; -++ stream->base[stream->count] = '\0'; /* For tool Warning string null */ -++ } -++ -++ SECUREC_GET_CHAR(stream, &ch); -++ if (ch != SECUREC_EOF) { -++ stream->fileRealRead += sizeof(SecChar); -++ } -++ return ch; -++} -++#endif -++ -++/* -++ * Get char for wchar version -++ */ -++SECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter) -++{ -++ *counter = *counter + 1; /* Always plus 1 */ -++ /* The main scenario is scanf str */ -++ if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) { -++ SecInt ch; -++ SECUREC_GET_CHAR(stream, &ch); -++ return ch; -++ } -++#if SECUREC_ENABLE_SCANF_FILE -++ if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0) { -++ return SecGetCharFromFile(stream); -++ } -++ if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) { -++ return SecGetCharFromStream(stream); -++ } -++#endif -++ return SECUREC_EOF; -++} -++ -++/* -++ * Unget Public realizatio char for wchar and char version -++ */ -++SECUREC_INLINE void SecUnGetCharImpl(SecInt ch, SecFileStream *stream) -++{ -++ if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) { -++ SECUREC_UN_GET_CHAR(stream); -++ return; -++ } -++#if SECUREC_ENABLE_SCANF_FILE -++ if ((stream->flag & SECUREC_LOAD_FILE_TO_MEM_FLAG) != 0) { -++ SECUREC_UN_GET_CHAR(stream); -++ if (stream->fileRealRead > 0) { -++ stream->fileRealRead -= sizeof(SecChar); -++ } -++ return; -++ } -++ if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) { -++ (void)SECUREC_UN_GETC(ch, stream->pf); -++ return; -++ } -++#else -++ (void)ch; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++#endif -++} -++ -++/* -++ * Unget char for char version -++ */ -++SECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter) -++{ -++ *counter = *counter - 1; /* Always mius 1 */ -++ if (ch != SECUREC_EOF) { -++ SecUnGetCharImpl(ch, stream); -++ } -++} -++ -++/* -++ * Skip space char by isspace -++ */ -++SECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter) -++{ -++ SecInt ch; -++ do { -++ ch = SecGetChar(stream, counter); -++ if (ch == SECUREC_EOF) { -++ break; -++ } -++ } while (SecIsSpace(ch) != 0); -++ return ch; -++} -++#endif /* INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 */ -++ -+diff --git a/lib/securec/src/memcpy_s.c b/lib/securec/src/memcpy_s.c -+new file mode 100755 -+index 000000000..a7fd48748 -+--- /dev/null -++++ b/lib/securec/src/memcpy_s.c -+@@ -0,0 +1,555 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: memcpy_s function -++ * Create: 2014-02-25 -++ */ -++/* -++ * [Standardize-exceptions] Use unsafe function: Portability -++ * [reason] Use unsafe function to implement security function to maintain platform compatibility. -++ * And sufficient input validation is performed before calling -++ */ -++ -++#include "securecutil.h" -++ -++#if SECUREC_WITH_PERFORMANCE_ADDONS -++#ifndef SECUREC_MEMCOPY_THRESHOLD_SIZE -++#define SECUREC_MEMCOPY_THRESHOLD_SIZE 64UL -++#endif -++ -++#define SECUREC_SMALL_MEM_COPY(dest, src, count) do { \ -++ if (SECUREC_ADDR_ALIGNED_8(dest) && SECUREC_ADDR_ALIGNED_8(src)) { \ -++ /* Use struct assignment */ \ -++ switch (count) { \ -++ case 1: \ -++ *(unsigned char *)(dest) = *(const unsigned char *)(src); \ -++ break; \ -++ case 2: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 2); \ -++ break; \ -++ case 3: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 3); \ -++ break; \ -++ case 4: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 4); \ -++ break; \ -++ case 5: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 5); \ -++ break; \ -++ case 6: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 6); \ -++ break; \ -++ case 7: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 7); \ -++ break; \ -++ case 8: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 8); \ -++ break; \ -++ case 9: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 9); \ -++ break; \ -++ case 10: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 10); \ -++ break; \ -++ case 11: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 11); \ -++ break; \ -++ case 12: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 12); \ -++ break; \ -++ case 13: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 13); \ -++ break; \ -++ case 14: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 14); \ -++ break; \ -++ case 15: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 15); \ -++ break; \ -++ case 16: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 16); \ -++ break; \ -++ case 17: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 17); \ -++ break; \ -++ case 18: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 18); \ -++ break; \ -++ case 19: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 19); \ -++ break; \ -++ case 20: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 20); \ -++ break; \ -++ case 21: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 21); \ -++ break; \ -++ case 22: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 22); \ -++ break; \ -++ case 23: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 23); \ -++ break; \ -++ case 24: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 24); \ -++ break; \ -++ case 25: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 25); \ -++ break; \ -++ case 26: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 26); \ -++ break; \ -++ case 27: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 27); \ -++ break; \ -++ case 28: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 28); \ -++ break; \ -++ case 29: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 29); \ -++ break; \ -++ case 30: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 30); \ -++ break; \ -++ case 31: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 31); \ -++ break; \ -++ case 32: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 32); \ -++ break; \ -++ case 33: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 33); \ -++ break; \ -++ case 34: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 34); \ -++ break; \ -++ case 35: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 35); \ -++ break; \ -++ case 36: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 36); \ -++ break; \ -++ case 37: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 37); \ -++ break; \ -++ case 38: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 38); \ -++ break; \ -++ case 39: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 39); \ -++ break; \ -++ case 40: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 40); \ -++ break; \ -++ case 41: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 41); \ -++ break; \ -++ case 42: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 42); \ -++ break; \ -++ case 43: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 43); \ -++ break; \ -++ case 44: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 44); \ -++ break; \ -++ case 45: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 45); \ -++ break; \ -++ case 46: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 46); \ -++ break; \ -++ case 47: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 47); \ -++ break; \ -++ case 48: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 48); \ -++ break; \ -++ case 49: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 49); \ -++ break; \ -++ case 50: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 50); \ -++ break; \ -++ case 51: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 51); \ -++ break; \ -++ case 52: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 52); \ -++ break; \ -++ case 53: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 53); \ -++ break; \ -++ case 54: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 54); \ -++ break; \ -++ case 55: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 55); \ -++ break; \ -++ case 56: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 56); \ -++ break; \ -++ case 57: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 57); \ -++ break; \ -++ case 58: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 58); \ -++ break; \ -++ case 59: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 59); \ -++ break; \ -++ case 60: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 60); \ -++ break; \ -++ case 61: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 61); \ -++ break; \ -++ case 62: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 62); \ -++ break; \ -++ case 63: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 63); \ -++ break; \ -++ case 64: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 64); \ -++ break; \ -++ default: \ -++ /* Do nothing */ \ -++ break; \ -++ } /* END switch */ \ -++ } else { \ -++ unsigned char *tmpDest_ = (unsigned char *)(dest); \ -++ const unsigned char *tmpSrc_ = (const unsigned char *)(src); \ -++ switch (count) { \ -++ case 64: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 63: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 62: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 61: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 60: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 59: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 58: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 57: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 56: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 55: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 54: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 53: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 52: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 51: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 50: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 49: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 48: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 47: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 46: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 45: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 44: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 43: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 42: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 41: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 40: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 39: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 38: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 37: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 36: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 35: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 34: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 33: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 32: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 31: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 30: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 29: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 28: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 27: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 26: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 25: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 24: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 23: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 22: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 21: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 20: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 19: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 18: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 17: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 16: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 15: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 14: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 13: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 12: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 11: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 10: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 9: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 8: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 7: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 6: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 5: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 4: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 3: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 2: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 1: \ -++ *(tmpDest_++) = *(tmpSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ default: \ -++ /* Do nothing */ \ -++ break; \ -++ } \ -++ } \ -++} SECUREC_WHILE_ZERO -++ -++/* -++ * Performance optimization -++ */ -++#define SECUREC_MEMCPY_OPT(dest, src, count) do { \ -++ if ((count) > SECUREC_MEMCOPY_THRESHOLD_SIZE) { \ -++ SECUREC_MEMCPY_WARP_OPT((dest), (src), (count)); \ -++ } else { \ -++ SECUREC_SMALL_MEM_COPY((dest), (src), (count)); \ -++ } \ -++} SECUREC_WHILE_ZERO -++#endif -++ -++/* -++ * Handling errors -++ */ -++SECUREC_INLINE errno_t SecMemcpyError(void *dest, size_t destMax, const void *src, size_t count) -++{ -++ if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { -++ SECUREC_ERROR_INVALID_RANGE("memcpy_s"); -++ return ERANGE; -++ } -++ if (dest == NULL || src == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("memcpy_s"); -++ if (dest != NULL) { -++ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax); -++ return EINVAL_AND_RESET; -++ } -++ return EINVAL; -++ } -++ if (count > destMax) { -++ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax); -++ SECUREC_ERROR_INVALID_RANGE("memcpy_s"); -++ return ERANGE_AND_RESET; -++ } -++ if (SECUREC_MEMORY_IS_OVERLAP(dest, src, count)) { -++ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax); -++ SECUREC_ERROR_BUFFER_OVERLAP("memcpy_s"); -++ return EOVERLAP_AND_RESET; -++ } -++ /* Count is 0 or dest equal src also ret EOK */ -++ return EOK; -++} -++ -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ /* -++ * The fread API in windows will call memcpy_s and pass 0xffffffff to destMax. -++ * To avoid the failure of fread, we don't check desMax limit. -++ */ -++#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \ -++ (dest) != NULL && (src) != NULL && \ -++ (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) -++#else -++#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \ -++ (dest) != NULL && (src) != NULL && (destMax) <= SECUREC_MEM_MAX_LEN && \ -++ (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) -++#endif -++ -++/* -++ * -++ * The memcpy_s function copies n characters from the object pointed to by src into the object pointed to by dest -++ * -++ * -++ * dest Destination buffer. -++ * destMax Size of the destination buffer. -++ * src Buffer to copy from. -++ * count Number of characters to copy -++ * -++ * -++ * dest buffer is updated. -++ * -++ * -++ * EOK Success -++ * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN -++ * EINVAL_AND_RESET dest != NULL and src is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN -++ * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0 -++ * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN -++ * and dest != NULL and src != NULL -++ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and -++ * count <= destMax destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL -++ * and src != NULL and dest != src -++ * -++ * if an error occurred, dest will be filled with 0. -++ * If the source and destination overlap, the behavior of memcpy_s is undefined. -++ * Use memmove_s to handle overlapping regions. -++ */ -++errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count) -++{ -++ if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) { -++ SECUREC_MEMCPY_WARP_OPT(dest, src, count); -++ return EOK; -++ } -++ /* Meet some runtime violation, return error code */ -++ return SecMemcpyError(dest, destMax, src, count); -++} -++ -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(memcpy_s); -++#endif -++ -++#if SECUREC_WITH_PERFORMANCE_ADDONS -++/* -++ * Performance optimization -++ */ -++errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count) -++{ -++ if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) { -++ SECUREC_MEMCPY_OPT(dest, src, count); -++ return EOK; -++ } -++ /* Meet some runtime violation, return error code */ -++ return SecMemcpyError(dest, destMax, src, count); -++} -++ -++/* Trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" */ -++errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count) -++{ -++ if (SECUREC_LIKELY(count <= destMax && dest != NULL && src != NULL && \ -++ count > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) { -++ SECUREC_MEMCPY_OPT(dest, src, count); -++ return EOK; -++ } -++ /* Meet some runtime violation, return error code */ -++ return SecMemcpyError(dest, destMax, src, count); -++} -++#endif -++ -+diff --git a/lib/securec/src/memmove_s.c b/lib/securec/src/memmove_s.c -+new file mode 100755 -+index 000000000..f231f05da -+--- /dev/null -++++ b/lib/securec/src/memmove_s.c -+@@ -0,0 +1,123 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: memmove_s function -++ * Create: 2014-02-25 -++ */ -++/* -++ * [Standardize-exceptions] Use unsafe function: Portability -++ * [reason] Use unsafe function to implement security function to maintain platform compatibility. -++ * And sufficient input validation is performed before calling -++ */ -++ -++#include "securecutil.h" -++ -++#ifdef SECUREC_NOT_CALL_LIBC_CORE_API -++/* -++ * Implementing memory data movement -++ */ -++SECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count) -++{ -++ unsigned char *pDest = (unsigned char *)dst; -++ const unsigned char *pSrc = (const unsigned char *)src; -++ size_t maxCount = count; -++ -++ if (dst <= src || pDest >= (pSrc + maxCount)) { -++ /* -++ * Non-Overlapping Buffers -++ * Copy from lower addresses to higher addresses -++ */ -++ while (maxCount > 0) { -++ --maxCount; -++ *pDest = *pSrc; -++ ++pDest; -++ ++pSrc; -++ } -++ } else { -++ /* -++ * Overlapping Buffers -++ * Copy from higher addresses to lower addresses -++ */ -++ pDest = pDest + maxCount - 1; -++ pSrc = pSrc + maxCount - 1; -++ while (maxCount > 0) { -++ --maxCount; -++ *pDest = *pSrc; -++ --pDest; -++ --pSrc; -++ } -++ } -++} -++#endif -++ -++/* -++ * -++ * The memmove_s function copies count bytes of characters from src to dest. -++ * This function can be assigned correctly when memory overlaps. -++ * -++ * dest Destination object. -++ * destMax Size of the destination buffer. -++ * src Source object. -++ * count Number of characters to copy. -++ * -++ * -++ * dest buffer is updated. -++ * -++ * -++ * EOK Success -++ * EINVAL dest is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN -++ * EINVAL_AND_RESET dest != NULL and src is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN -++ * ERANGE destMax > SECUREC_MEM_MAX_LEN or destMax is 0 -++ * ERANGE_AND_RESET count > destMax and dest != NULL and src != NULL and destMax != 0 -++ * and destMax <= SECUREC_MEM_MAX_LEN -++ * -++ * If an error occurred, dest will be filled with 0 when dest and destMax valid. -++ * If some regions of the source area and the destination overlap, memmove_s -++ * ensures that the original source bytes in the overlapping region are copied -++ * before being overwritten. -++ */ -++errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count) -++{ -++ if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { -++ SECUREC_ERROR_INVALID_RANGE("memmove_s"); -++ return ERANGE; -++ } -++ if (dest == NULL || src == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("memmove_s"); -++ if (dest != NULL) { -++ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax); -++ return EINVAL_AND_RESET; -++ } -++ return EINVAL; -++ } -++ if (count > destMax) { -++ (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax); -++ SECUREC_ERROR_INVALID_RANGE("memmove_s"); -++ return ERANGE_AND_RESET; -++ } -++ if (dest == src) { -++ return EOK; -++ } -++ -++ if (count > 0) { -++#ifdef SECUREC_NOT_CALL_LIBC_CORE_API -++ SecUtilMemmove(dest, src, count); -++#else -++ /* Use underlying memmove for performance consideration */ -++ (void)memmove(dest, src, count); -++#endif -++ } -++ return EOK; -++} -++ -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(memmove_s); -++#endif -++ -+diff --git a/lib/securec/src/memset_s.c b/lib/securec/src/memset_s.c -+new file mode 100755 -+index 000000000..d9a657fd3 -+--- /dev/null -++++ b/lib/securec/src/memset_s.c -+@@ -0,0 +1,510 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: memset_s function -++ * Create: 2014-02-25 -++ */ -++/* -++ * [Standardize-exceptions] Use unsafe function: Portability -++ * [reason] Use unsafe function to implement security function to maintain platform compatibility. -++ * And sufficient input validation is performed before calling -++ */ -++ -++#include "securecutil.h" -++ -++#define SECUREC_MEMSET_PARAM_OK(dest, destMax, count) (SECUREC_LIKELY((destMax) <= SECUREC_MEM_MAX_LEN && \ -++ (dest) != NULL && (count) <= (destMax))) -++ -++#if SECUREC_WITH_PERFORMANCE_ADDONS -++ -++/* Use union to clear strict-aliasing warning */ -++typedef union { -++ SecStrBuf32 buf32; -++ SecStrBuf31 buf31; -++ SecStrBuf30 buf30; -++ SecStrBuf29 buf29; -++ SecStrBuf28 buf28; -++ SecStrBuf27 buf27; -++ SecStrBuf26 buf26; -++ SecStrBuf25 buf25; -++ SecStrBuf24 buf24; -++ SecStrBuf23 buf23; -++ SecStrBuf22 buf22; -++ SecStrBuf21 buf21; -++ SecStrBuf20 buf20; -++ SecStrBuf19 buf19; -++ SecStrBuf18 buf18; -++ SecStrBuf17 buf17; -++ SecStrBuf16 buf16; -++ SecStrBuf15 buf15; -++ SecStrBuf14 buf14; -++ SecStrBuf13 buf13; -++ SecStrBuf12 buf12; -++ SecStrBuf11 buf11; -++ SecStrBuf10 buf10; -++ SecStrBuf9 buf9; -++ SecStrBuf8 buf8; -++ SecStrBuf7 buf7; -++ SecStrBuf6 buf6; -++ SecStrBuf5 buf5; -++ SecStrBuf4 buf4; -++ SecStrBuf3 buf3; -++ SecStrBuf2 buf2; -++} SecStrBuf32Union; -++/* C standard initializes the first member of the consortium. */ -++static const SecStrBuf32 g_allZero = {{ -++ 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, -++ 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, -++ 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, -++ 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U -++}}; -++static const SecStrBuf32 g_allFF = {{ -++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF -++}}; -++ -++/* Clear conversion warning strict aliasing" */ -++SECUREC_INLINE const SecStrBuf32Union *SecStrictAliasingCast(const SecStrBuf32 *buf) -++{ -++ return (const SecStrBuf32Union *)buf; -++} -++ -++#ifndef SECUREC_MEMSET_THRESHOLD_SIZE -++#define SECUREC_MEMSET_THRESHOLD_SIZE 32UL -++#endif -++ -++#define SECUREC_UNALIGNED_SET(dest, c, count) do { \ -++ unsigned char *pDest_ = (unsigned char *)(dest); \ -++ switch (count) { \ -++ case 32: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 31: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 30: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 29: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 28: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 27: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 26: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 25: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 24: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 23: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 22: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 21: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 20: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 19: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 18: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 17: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 16: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 15: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 14: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 13: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 12: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 11: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 10: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 9: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 8: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 7: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 6: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 5: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 4: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 3: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 2: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 1: \ -++ *(pDest_++) = (unsigned char)(c); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ default: \ -++ /* Do nothing */ \ -++ break; \ -++ } \ -++} SECUREC_WHILE_ZERO -++ -++#define SECUREC_SET_VALUE_BY_STRUCT(dest, dataName, n) do { \ -++ *(SecStrBuf##n *)(dest) = *(const SecStrBuf##n *)(&((SecStrictAliasingCast(&(dataName)))->buf##n)); \ -++} SECUREC_WHILE_ZERO -++ -++#define SECUREC_ALIGNED_SET_OPT_ZERO_FF(dest, c, count) do { \ -++ switch (c) { \ -++ case 0: \ -++ switch (count) { \ -++ case 1: \ -++ *(unsigned char *)(dest) = (unsigned char)0; \ -++ break; \ -++ case 2: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 2); \ -++ break; \ -++ case 3: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 3); \ -++ break; \ -++ case 4: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 4); \ -++ break; \ -++ case 5: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 5); \ -++ break; \ -++ case 6: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 6); \ -++ break; \ -++ case 7: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 7); \ -++ break; \ -++ case 8: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 8); \ -++ break; \ -++ case 9: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 9); \ -++ break; \ -++ case 10: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 10); \ -++ break; \ -++ case 11: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 11); \ -++ break; \ -++ case 12: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 12); \ -++ break; \ -++ case 13: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 13); \ -++ break; \ -++ case 14: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 14); \ -++ break; \ -++ case 15: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 15); \ -++ break; \ -++ case 16: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 16); \ -++ break; \ -++ case 17: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 17); \ -++ break; \ -++ case 18: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 18); \ -++ break; \ -++ case 19: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 19); \ -++ break; \ -++ case 20: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 20); \ -++ break; \ -++ case 21: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 21); \ -++ break; \ -++ case 22: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 22); \ -++ break; \ -++ case 23: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 23); \ -++ break; \ -++ case 24: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 24); \ -++ break; \ -++ case 25: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 25); \ -++ break; \ -++ case 26: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 26); \ -++ break; \ -++ case 27: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 27); \ -++ break; \ -++ case 28: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 28); \ -++ break; \ -++ case 29: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 29); \ -++ break; \ -++ case 30: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 30); \ -++ break; \ -++ case 31: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 31); \ -++ break; \ -++ case 32: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 32); \ -++ break; \ -++ default: \ -++ /* Do nothing */ \ -++ break; \ -++ } \ -++ break; \ -++ case 0xFF: \ -++ switch (count) { \ -++ case 1: \ -++ *(unsigned char *)(dest) = (unsigned char)0xffU; \ -++ break; \ -++ case 2: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 2); \ -++ break; \ -++ case 3: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 3); \ -++ break; \ -++ case 4: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 4); \ -++ break; \ -++ case 5: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 5); \ -++ break; \ -++ case 6: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 6); \ -++ break; \ -++ case 7: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 7); \ -++ break; \ -++ case 8: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 8); \ -++ break; \ -++ case 9: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 9); \ -++ break; \ -++ case 10: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 10); \ -++ break; \ -++ case 11: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 11); \ -++ break; \ -++ case 12: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 12); \ -++ break; \ -++ case 13: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 13); \ -++ break; \ -++ case 14: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 14); \ -++ break; \ -++ case 15: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 15); \ -++ break; \ -++ case 16: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 16); \ -++ break; \ -++ case 17: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 17); \ -++ break; \ -++ case 18: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 18); \ -++ break; \ -++ case 19: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 19); \ -++ break; \ -++ case 20: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 20); \ -++ break; \ -++ case 21: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 21); \ -++ break; \ -++ case 22: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 22); \ -++ break; \ -++ case 23: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 23); \ -++ break; \ -++ case 24: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 24); \ -++ break; \ -++ case 25: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 25); \ -++ break; \ -++ case 26: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 26); \ -++ break; \ -++ case 27: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 27); \ -++ break; \ -++ case 28: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 28); \ -++ break; \ -++ case 29: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 29); \ -++ break; \ -++ case 30: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 30); \ -++ break; \ -++ case 31: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 31); \ -++ break; \ -++ case 32: \ -++ SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 32); \ -++ break; \ -++ default: \ -++ /* Do nothing */ \ -++ break; \ -++ } \ -++ break; \ -++ default: \ -++ SECUREC_UNALIGNED_SET((dest), (c), (count)); \ -++ break; \ -++ } /* END switch */ \ -++} SECUREC_WHILE_ZERO -++ -++#define SECUREC_SMALL_MEM_SET(dest, c, count) do { \ -++ if (SECUREC_ADDR_ALIGNED_8((dest))) { \ -++ SECUREC_ALIGNED_SET_OPT_ZERO_FF((dest), (c), (count)); \ -++ } else { \ -++ SECUREC_UNALIGNED_SET((dest), (c), (count)); \ -++ } \ -++} SECUREC_WHILE_ZERO -++ -++/* -++ * Performance optimization -++ */ -++#define SECUREC_MEMSET_OPT(dest, c, count) do { \ -++ if ((count) > SECUREC_MEMSET_THRESHOLD_SIZE) { \ -++ SECUREC_MEMSET_PREVENT_DSE((dest), (c), (count)); \ -++ } else { \ -++ SECUREC_SMALL_MEM_SET((dest), (c), (count)); \ -++ } \ -++} SECUREC_WHILE_ZERO -++#endif -++ -++/* -++ * Handling errors -++ */ -++SECUREC_INLINE errno_t SecMemsetError(void *dest, size_t destMax, int c) -++{ -++ /* Check destMax is 0 compatible with _sp macro */ -++ if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) { -++ SECUREC_ERROR_INVALID_RANGE("memset_s"); -++ return ERANGE; -++ } -++ if (dest == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("memset_s"); -++ return EINVAL; -++ } -++ SECUREC_MEMSET_PREVENT_DSE(dest, c, destMax); /* Set entire buffer to value c */ -++ SECUREC_ERROR_INVALID_RANGE("memset_s"); -++ return ERANGE_AND_RESET; -++} -++ -++/* -++ * -++ * The memset_s function copies the value of c (converted to an unsigned char) -++ * into each of the first count characters of the object pointed to by dest. -++ * -++ * -++ * dest Pointer to destination. -++ * destMax The size of the buffer. -++ * c Character to set. -++ * count Number of characters. -++ * -++ * -++ * dest buffer is updated. -++ * -++ * -++ * EOK Success -++ * EINVAL dest == NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN -++ * ERANGE destMax > SECUREC_MEM_MAX_LEN or (destMax is 0 and count > destMax) -++ * ERANGE_AND_RESET count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL -++ * -++ * if return ERANGE_AND_RESET then fill dest to c ,fill length is destMax -++ */ -++errno_t memset_s(void *dest, size_t destMax, int c, size_t count) -++{ -++ if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) { -++ SECUREC_MEMSET_PREVENT_DSE(dest, c, count); -++ return EOK; -++ } -++ /* Meet some runtime violation, return error code */ -++ return SecMemsetError(dest, destMax, c); -++} -++ -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(memset_s); -++#endif -++ -++#if SECUREC_WITH_PERFORMANCE_ADDONS -++/* -++ * Performance optimization -++ */ -++errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count) -++{ -++ if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) { -++ SECUREC_MEMSET_OPT(dest, c, count); -++ return EOK; -++ } -++ /* Meet some runtime violation, return error code */ -++ return SecMemsetError(dest, destMax, c); -++} -++ -++/* -++ * Performance optimization, trim judgement on "destMax <= SECUREC_MEM_MAX_LEN" -++ */ -++errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count) -++{ -++ if (SECUREC_LIKELY(count <= destMax && dest != NULL)) { -++ SECUREC_MEMSET_OPT(dest, c, count); -++ return EOK; -++ } -++ /* Meet some runtime violation, return error code */ -++ return SecMemsetError(dest, destMax, c); -++} -++#endif -++ -+diff --git a/lib/securec/src/output.inl b/lib/securec/src/output.inl -+new file mode 100755 -+index 000000000..9392efaaf -+--- /dev/null -++++ b/lib/securec/src/output.inl -+@@ -0,0 +1,1720 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: Used by secureprintoutput_a.c and secureprintoutput_w.c to include. -++ * This file provides a template function for ANSI and UNICODE compiling -++ * by different type definition. The functions of SecOutputS or -++ * SecOutputSW provides internal implementation for printf family API, such as sprintf, swprintf_s. -++ * Create: 2014-02-25 -++ * Notes: see www.cplusplus.com/reference/cstdio/printf/ -++ */ -++/* -++ * [Standardize-exceptions] Use unsafe function: Portability -++ * [reason] Use unsafe function to implement security function to maintain platform compatibility. -++ * And sufficient input validation is performed before calling -++ */ -++#ifndef OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 -++#define OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 -++ -++#ifndef SECUREC_ENABLE_SPRINTF_LONG_DOUBLE -++/* Some compilers do not support long double */ -++#define SECUREC_ENABLE_SPRINTF_LONG_DOUBLE 1 -++#endif -++ -++#define SECUREC_NULL_STRING_SIZE 8 -++#define SECUREC_STATE_TABLE_SIZE 337 -++ -++#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS) -++#define SECUREC_DIV_QUOTIENT_OCTAL(val64) ((val64) >> 3ULL) -++#define SECUREC_DIV_RESIDUE_OCTAL(val64) ((val64) & 7ULL) -++ -++#define SECUREC_DIV_QUOTIENT_HEX(val64) ((val64) >> 4ULL) -++#define SECUREC_DIV_RESIDUE_HEX(val64) ((val64) & 0xfULL) -++#endif -++ -++#define SECUREC_RADIX_OCTAL 8U -++#define SECUREC_RADIX_DECIMAL 10U -++#define SECUREC_RADIX_HEX 16U -++#define SECUREC_PREFIX_LEN 2 -++/* Size include '+' and '\0' */ -++#define SECUREC_FLOAT_BUF_EXT 2 -++ -++/* Sign extend or Zero-extend */ -++#define SECUREC_GET_LONG_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ -++ (SecInt64)(long)va_arg(argList, long) : \ -++ (SecInt64)(unsigned long)va_arg(argList, long)) -++ -++/* Sign extend or Zero-extend */ -++#define SECUREC_GET_CHAR_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ -++ SecUpdateNegativeChar(&(attr), ((char)va_arg(argList, int))) : \ -++ (SecInt64)(unsigned char)va_arg(argList, int)) -++ -++/* Sign extend or Zero-extend */ -++#define SECUREC_GET_SHORT_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ -++ (SecInt64)(short)va_arg(argList, int) : \ -++ (SecInt64)(unsigned short)va_arg(argList, int)) -++ -++/* Sign extend or Zero-extend */ -++#define SECUREC_GET_INT_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ -++ (SecInt64)(int)va_arg(argList, int) : \ -++ (SecInt64)(unsigned int)va_arg(argList, int)) -++ -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++/* Sign extend or Zero-extend. No suitable macros were found to handle the branch */ -++#define SECUREC_GET_SIZE_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \ -++ ((SecIsSameSize(sizeof(size_t), sizeof(long)) != 0) ? (SecInt64)(long)va_arg(argList, long) : \ -++ ((SecIsSameSize(sizeof(size_t), sizeof(long long)) != 0) ? (SecInt64)(long long)va_arg(argList, long long) : \ -++ (SecInt64)(int)va_arg(argList, int))) : \ -++ (SecInt64)(size_t)va_arg(argList, size_t)) -++#endif -++ -++/* Format output buffer pointer and available size */ -++typedef struct { -++ int count; -++ SecChar *cur; -++} SecPrintfStream; -++ -++typedef union { -++ /* Integer formatting refers to the end of the buffer, plus 1 to prevent tool alarms */ -++ char str[SECUREC_BUFFER_SIZE + 1]; -++#if SECUREC_HAVE_WCHART -++ wchar_t wStr[SECUREC_WCHAR_BUFFER_SIZE]; /* Just for %lc */ -++#endif -++} SecBuffer; -++ -++typedef union { -++ char *str; /* Not a null terminated string */ -++#if SECUREC_HAVE_WCHART -++ wchar_t *wStr; -++#endif -++} SecFormatBuf; -++ -++typedef struct { -++ const char *digits; /* Point to the hexadecimal subset */ -++ SecFormatBuf text; /* Point to formatted string */ -++ int textLen; /* Length of the text */ -++ int textIsWide; /* Flag for text is wide chars ; 0 is not wide char */ -++ unsigned int radix; /* Use for output number , default set to 10 */ -++ unsigned int flags; -++ int fldWidth; -++ int precision; -++ int dynWidth; /* %* 1 width from variable parameter ;0 not */ -++ int dynPrecision; /* %.* 1 precision from variable parameter ;0 not */ -++ int padding; /* Padding len */ -++ int prefixLen; /* Length of prefix, 0 or 1 or 2 */ -++ SecChar prefix[SECUREC_PREFIX_LEN]; /* Prefix is 0 or 0x */ -++ SecBuffer buffer; -++} SecFormatAttr; -++ -++#if SECUREC_ENABLE_SPRINTF_FLOAT -++#ifdef SECUREC_STACK_SIZE_LESS_THAN_1K -++#define SECUREC_FMT_STR_LEN 8 -++#else -++#define SECUREC_FMT_STR_LEN 16 -++#endif -++typedef struct { -++ char buffer[SECUREC_FMT_STR_LEN]; -++ char *fmtStr; /* Initialization must point to buffer */ -++ char *allocatedFmtStr; /* Initialization must be NULL to store allocated point */ -++ char *floatBuffer; /* Use heap memory if the SecFormatAttr.buffer is not enough */ -++ int bufferSize; /* The size of floatBuffer */ -++} SecFloatAdapt; -++#endif -++ -++/* Use 20 to Align the data */ -++#define SECUREC_DIGITS_BUF_SIZE 20 -++/* The serial number of 'x' or 'X' is 16 */ -++#define SECUREC_NUMBER_OF_X 16 -++/* Some systems can not use pointers to point to string literals, but can use string arrays. */ -++/* For example, when handling code under uboot, there is a problem with the pointer */ -++static const char g_itoaUpperDigits[SECUREC_DIGITS_BUF_SIZE] = "0123456789ABCDEFX"; -++static const char g_itoaLowerDigits[SECUREC_DIGITS_BUF_SIZE] = "0123456789abcdefx"; -++ -++#if SECUREC_ENABLE_SPRINTF_FLOAT -++/* Call system sprintf to format float value */ -++SECUREC_INLINE int SecFormatFloat(char *strDest, const char *format, ...) -++{ -++ int ret; /* If initialization causes e838 */ -++ va_list argList; -++ -++ va_start(argList, format); -++ SECUREC_MASK_VSPRINTF_WARNING -++ ret = vsprintf(strDest, format, argList); -++ SECUREC_END_MASK_VSPRINTF_WARNING -++ va_end(argList); -++ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ -++ return ret; -++} -++ -++#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && SECUREC_ENABLE_SPRINTF_LONG_DOUBLE -++/* Out put long double value to dest */ -++SECUREC_INLINE void SecFormatLongDouble(SecFormatAttr *attr, const SecFloatAdapt *floatAdapt, long double ldValue) -++{ -++ int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ? (-attr->fldWidth) : attr->fldWidth); -++ if (attr->dynWidth != 0 && attr->dynPrecision != 0) { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, attr->precision, ldValue); -++ } else if (attr->dynWidth != 0) { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, ldValue); -++ } else if (attr->dynPrecision != 0) { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, attr->precision, ldValue); -++ } else { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, ldValue); -++ } -++ if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) { -++ attr->textLen = 0; -++ } -++} -++#endif -++ -++/* Out put double value to dest */ -++SECUREC_INLINE void SecFormatDouble(SecFormatAttr *attr, const SecFloatAdapt *floatAdapt, double dValue) -++{ -++ int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ? (-attr->fldWidth) : attr->fldWidth); -++ if (attr->dynWidth != 0 && attr->dynPrecision != 0) { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, attr->precision, dValue); -++ } else if (attr->dynWidth != 0) { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, dValue); -++ } else if (attr->dynPrecision != 0) { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, attr->precision, dValue); -++ } else { -++ attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, dValue); -++ } -++ if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) { -++ attr->textLen = 0; -++ } -++} -++#endif -++ -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++/* To clear e506 warning */ -++SECUREC_INLINE int SecIsSameSize(size_t sizeA, size_t sizeB) -++{ -++ return (int)(sizeA == sizeB); -++} -++#endif -++ -++#ifndef SECUREC_ON_64BITS -++/* -++ * Compiler Optimized Division 8. -++ * The text.str point to buffer end, must be Large enough -++ */ -++SECUREC_INLINE void SecNumber32ToOctalString(SecUnsignedInt32 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt32 val32 = number; -++ do { -++ --attr->text.str; -++ /* Just use lowerDigits for 0 - 9 */ -++ *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_OCTAL]; -++ val32 /= SECUREC_RADIX_OCTAL; -++ } while (val32 != 0); -++} -++ -++#ifdef _AIX -++/* -++ * Compiler Optimized Division 10. -++ * The text.str point to buffer end, must be Large enough -++ */ -++SECUREC_INLINE void SecNumber32ToDecString(SecUnsignedInt32 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt32 val32 = number; -++ do { -++ --attr->text.str; -++ /* Just use lowerDigits for 0 - 9 */ -++ *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL]; -++ val32 /= SECUREC_RADIX_DECIMAL; -++ } while (val32 != 0); -++} -++#endif -++/* -++ * Compiler Optimized Division 16. -++ * The text.str point to buffer end, must be Large enough -++ */ -++SECUREC_INLINE void SecNumber32ToHexString(SecUnsignedInt32 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt32 val32 = number; -++ do { -++ --attr->text.str; -++ *(attr->text.str) = attr->digits[val32 % SECUREC_RADIX_HEX]; -++ val32 /= SECUREC_RADIX_HEX; -++ } while (val32 != 0); -++} -++ -++#ifndef _AIX -++/* Use fast div 10 */ -++SECUREC_INLINE void SecNumber32ToDecStringFast(SecUnsignedInt32 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt32 val32 = number; -++ do { -++ SecUnsignedInt32 quotient; -++ SecUnsignedInt32 remain; -++ --attr->text.str; -++ *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL]; -++ quotient = (val32 >> 1U) + (val32 >> 2U); /* Fast div magic 2 */ -++ quotient = quotient + (quotient >> 4U); /* Fast div magic 4 */ -++ quotient = quotient + (quotient >> 8U); /* Fast div magic 8 */ -++ quotient = quotient + (quotient >> 16U); /* Fast div magic 16 */ -++ quotient = quotient >> 3U; /* Fast div magic 3 */ -++ remain = val32 - SECUREC_MUL_TEN(quotient); -++ val32 = (remain > 9U) ? (quotient + 1U) : quotient; /* Fast div magic 9 */ -++ } while (val32 != 0); -++} -++#endif -++ -++SECUREC_INLINE void SecNumber32ToString(SecUnsignedInt32 number, SecFormatAttr *attr) -++{ -++ switch (attr->radix) { -++ case SECUREC_RADIX_HEX: -++ SecNumber32ToHexString(number, attr); -++ break; -++ case SECUREC_RADIX_OCTAL: -++ SecNumber32ToOctalString(number, attr); -++ break; -++ case SECUREC_RADIX_DECIMAL: -++#ifdef _AIX -++ /* The compiler will optimize div 10 */ -++ SecNumber32ToDecString(number, attr); -++#else -++ SecNumber32ToDecStringFast(number, attr); -++#endif -++ break; -++ default: -++ /* Do nothing */ -++ break; -++ } -++} -++#endif -++ -++#if defined(SECUREC_USE_SPECIAL_DIV64) || (defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)) -++/* -++ * This function just to clear warning, on sume vxworks compiler shift 32 bit make warnings -++ */ -++SECUREC_INLINE SecUnsignedInt64 SecU64Shr32(SecUnsignedInt64 number) -++{ -++ return (((number) >> 16U) >> 16U); /* Two shifts of 16 bits to realize shifts of 32 bits */ -++} -++/* -++ * Fast divide by 10 algorithm. -++ * Calculation divisor multiply 0xcccccccccccccccdULL, resultHi64 >> 3 as quotient -++ */ -++SECUREC_INLINE void SecU64Div10(SecUnsignedInt64 divisor, SecUnsignedInt64 *quotient, SecUnsignedInt32 *residue) -++{ -++ SecUnsignedInt64 mask = 0xffffffffULL; /* Use 0xffffffffULL as 32 bit mask */ -++ SecUnsignedInt64 magicHi = 0xccccccccULL; /* Fast divide 10 magic numbers high 32bit 0xccccccccULL */ -++ SecUnsignedInt64 magicLow = 0xcccccccdULL; /* Fast divide 10 magic numbers low 32bit 0xcccccccdULL */ -++ SecUnsignedInt64 divisorHi = (SecUnsignedInt64)(SecU64Shr32(divisor)); /* High 32 bit use */ -++ SecUnsignedInt64 divisorLow = (SecUnsignedInt64)(divisor & mask); /* Low 32 bit mask */ -++ SecUnsignedInt64 factorHi = divisorHi * magicHi; -++ SecUnsignedInt64 factorLow1 = divisorHi * magicLow; -++ SecUnsignedInt64 factorLow2 = divisorLow * magicHi; -++ SecUnsignedInt64 factorLow3 = divisorLow * magicLow; -++ SecUnsignedInt64 carry = (factorLow1 & mask) + (factorLow2 & mask) + SecU64Shr32(factorLow3); -++ SecUnsignedInt64 resultHi64 = factorHi + SecU64Shr32(factorLow1) + SecU64Shr32(factorLow2) + SecU64Shr32(carry); -++ -++ *quotient = resultHi64 >> 3U; /* Fast divide 10 magic numbers 3 */ -++ *residue = (SecUnsignedInt32)(divisor - ((*quotient) * 10)); /* Quotient mul 10 */ -++ return; -++} -++#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS) -++/* -++ * Divide function for VXWORKS -++ */ -++SECUREC_INLINE int SecU64Div32(SecUnsignedInt64 divisor, SecUnsignedInt32 radix, -++ SecUnsignedInt64 *quotient, SecUnsignedInt32 *residue) -++{ -++ switch (radix) { -++ case SECUREC_RADIX_DECIMAL: -++ SecU64Div10(divisor, quotient, residue); -++ break; -++ case SECUREC_RADIX_HEX: -++ *quotient = SECUREC_DIV_QUOTIENT_HEX(divisor); -++ *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_HEX(divisor); -++ break; -++ case SECUREC_RADIX_OCTAL: -++ *quotient = SECUREC_DIV_QUOTIENT_OCTAL(divisor); -++ *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_OCTAL(divisor); -++ break; -++ default: -++ return -1; /* This does not happen in the current file */ -++ } -++ return 0; -++} -++SECUREC_INLINE void SecNumber64ToStringSpecial(SecUnsignedInt64 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt64 val64 = number; -++ do { -++ SecUnsignedInt32 digit = 0; /* Ascii value of digit */ -++ SecUnsignedInt64 quotient = 0; -++ if (SecU64Div32(val64, (SecUnsignedInt32)attr->radix, "ient, &digit) != 0) { -++ /* Just break, when enter this function, no error is returned */ -++ break; -++ } -++ --attr->text.str; -++ *(attr->text.str) = attr->digits[digit]; -++ val64 = quotient; -++ } while (val64 != 0); -++} -++#endif -++#endif -++ -++#if defined(SECUREC_ON_64BITS) || !defined(SECUREC_VXWORKS_VERSION_5_4) -++#if defined(SECUREC_USE_SPECIAL_DIV64) -++/* The compiler does not provide 64 bit division problems */ -++SECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt64 val64 = number; -++ do { -++ SecUnsignedInt64 quotient = 0; -++ SecUnsignedInt32 digit = 0; -++ SecU64Div10(val64, "ient, &digit); -++ --attr->text.str; -++ /* Just use lowerDigits for 0 - 9 */ -++ *(attr->text.str) = g_itoaLowerDigits[digit]; -++ val64 = quotient; -++ } while (val64 != 0); -++} -++#else -++/* -++ * Compiler Optimized Division 10. -++ * The text.str point to buffer end, must be Large enough -++ */ -++SECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt64 val64 = number; -++ do { -++ --attr->text.str; -++ /* Just use lowerDigits for 0 - 9 */ -++ *(attr->text.str) = g_itoaLowerDigits[val64 % SECUREC_RADIX_DECIMAL]; -++ val64 /= SECUREC_RADIX_DECIMAL; -++ } while (val64 != 0); -++} -++#endif -++ -++/* -++ * Compiler Optimized Division 8. -++ * The text.str point to buffer end, must be Large enough -++ */ -++SECUREC_INLINE void SecNumber64ToOctalString(SecUnsignedInt64 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt64 val64 = number; -++ do { -++ --attr->text.str; -++ /* Just use lowerDigits for 0 - 9 */ -++ *(attr->text.str) = g_itoaLowerDigits[val64 % SECUREC_RADIX_OCTAL]; -++ val64 /= SECUREC_RADIX_OCTAL; -++ } while (val64 != 0); -++} -++/* -++ * Compiler Optimized Division 16. -++ * The text.str point to buffer end, must be Large enough -++ */ -++SECUREC_INLINE void SecNumber64ToHexString(SecUnsignedInt64 number, SecFormatAttr *attr) -++{ -++ SecUnsignedInt64 val64 = number; -++ do { -++ --attr->text.str; -++ *(attr->text.str) = attr->digits[val64 % SECUREC_RADIX_HEX]; -++ val64 /= SECUREC_RADIX_HEX; -++ } while (val64 != 0); -++} -++ -++SECUREC_INLINE void SecNumber64ToString(SecUnsignedInt64 number, SecFormatAttr *attr) -++{ -++ switch (attr->radix) { -++ /* The compiler will optimize div 10 */ -++ case SECUREC_RADIX_DECIMAL: -++ SecNumber64ToDecString(number, attr); -++ break; -++ case SECUREC_RADIX_OCTAL: -++ SecNumber64ToOctalString(number, attr); -++ break; -++ case SECUREC_RADIX_HEX: -++ SecNumber64ToHexString(number, attr); -++ break; -++ default: -++ /* Do nothing */ -++ break; -++ } -++} -++#endif -++ -++/* -++ * Converting integers to string -++ */ -++SECUREC_INLINE void SecNumberToString(SecUnsignedInt64 number, SecFormatAttr *attr) -++{ -++#ifdef SECUREC_ON_64BITS -++ SecNumber64ToString(number, attr); -++#else /* For 32 bits system */ -++ if (number <= 0xffffffffUL) { /* Use 0xffffffffUL to check if the value is in the 32-bit range */ -++ /* In most case, the value to be converted is small value */ -++ SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number; -++ SecNumber32ToString(n32Tmp, attr); -++ } else { -++ /* The value to be converted is greater than 4G */ -++#if defined(SECUREC_VXWORKS_VERSION_5_4) -++ SecNumber64ToStringSpecial(number, attr); -++#else -++ SecNumber64ToString(number, attr); -++#endif -++ } -++#endif -++} -++ -++SECUREC_INLINE int SecIsNumberNeedTo32Bit(const SecFormatAttr *attr) -++{ -++ return (int)(((attr->flags & SECUREC_FLAG_I64) == 0) && -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++ ((attr->flags & SECUREC_FLAG_INTMAX) == 0) && -++#endif -++#ifdef SECUREC_ON_64BITS -++ ((attr->flags & SECUREC_FLAG_PTRDIFF) == 0) && -++ ((attr->flags & SECUREC_FLAG_SIZE) == 0) && -++#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) /* on window 64 system sizeof long is 32bit */ -++ ((attr->flags & SECUREC_FLAG_LONG) == 0) && -++#endif -++#endif -++ ((attr->flags & SECUREC_FLAG_LONGLONG) == 0)); -++} -++ -++SECUREC_INLINE void SecNumberToBuffer(SecFormatAttr *attr, SecInt64 num64) -++{ -++ SecUnsignedInt64 number; -++ /* Check for negative; copy into number */ -++ if ((attr->flags & SECUREC_FLAG_SIGNED) != 0 && num64 < 0) { -++ number = (SecUnsignedInt64)(0 - (SecUnsignedInt64)num64); /* Wrap with unsigned int64 numbers */ -++ attr->flags |= SECUREC_FLAG_NEGATIVE; -++ } else { -++ number = (SecUnsignedInt64)num64; -++ } -++ if (SecIsNumberNeedTo32Bit(attr) != 0) { -++ number = (number & (SecUnsignedInt64)0xffffffffUL); /* Use 0xffffffff as 32 bit mask */ -++ } -++ -++ /* The text.str must be point to buffer.str, this pointer is used outside the function */ -++ attr->text.str = &attr->buffer.str[SECUREC_BUFFER_SIZE]; -++ -++ if (number == 0) { -++ /* Turn off hex prefix default, and textLen is zero */ -++ attr->prefixLen = 0; -++ attr->textLen = 0; -++ return; -++ } -++ -++ /* Convert integer to string. It must be invoked when number > 0, otherwise the following logic is incorrect */ -++ SecNumberToString(number, attr); -++ /* Compute length of number, text.str must be in buffer.str */ -++ attr->textLen = (int)(size_t)((char *)&attr->buffer.str[SECUREC_BUFFER_SIZE] - attr->text.str); -++} -++ -++/* -++ * Write one character to dest buffer -++ */ -++SECUREC_INLINE void SecWriteChar(SecPrintfStream *stream, SecChar ch, int *charsOut) -++{ -++ /* Count must be reduced first, In order to identify insufficient length */ -++ --stream->count; -++ if (stream->count >= 0) { -++ *(stream->cur) = ch; -++ ++stream->cur; -++ *charsOut = *charsOut + 1; -++ return; -++ } -++ /* No enough length */ -++ *charsOut = -1; -++} -++ -++/* -++* Write multiple identical characters. -++*/ -++SECUREC_INLINE void SecWriteMultiChar(SecPrintfStream *stream, SecChar ch, int num, int *charsOut) -++{ -++ int count; -++ for (count = num; count > 0; --count) { -++ --stream->count; /* count may be negative,indicating insufficient space */ -++ if (stream->count < 0) { -++ *charsOut = -1; -++ return; -++ } -++ *(stream->cur) = ch; -++ ++stream->cur; -++ } -++ *charsOut = *charsOut + num; -++} -++ -++/* -++* Write string function, where this function is called, make sure that len is greater than 0 -++*/ -++SECUREC_INLINE void SecWriteString(SecPrintfStream *stream, const SecChar *str, int len, int *charsOut) -++{ -++ const SecChar *tmp = str; -++ int count; -++ for (count = len; count > 0; --count) { -++ --stream->count; /* count may be negative,indicating insufficient space */ -++ if (stream->count < 0) { -++ *charsOut = -1; -++ return; -++ } -++ *(stream->cur) = *tmp; -++ ++stream->cur; -++ ++tmp; -++ } -++ *charsOut = *charsOut + len; -++} -++ -++/* Use loop copy char or wchar_t string */ -++SECUREC_INLINE void SecWriteStringByLoop(SecPrintfStream *stream, const SecChar *str, int len) -++{ -++ int i; -++ const SecChar *tmp = str; -++ for (i = 0; i < len; ++i) { -++ *stream->cur = *tmp; -++ ++stream->cur; -++ ++tmp; -++ } -++ stream->count -= len; -++} -++ -++SECUREC_INLINE void SecWriteStringOpt(SecPrintfStream *stream, const SecChar *str, int len) -++{ -++ if (len < 12) { /* Performance optimization for mobile number length 12 */ -++ SecWriteStringByLoop(stream, str, len); -++ } else { -++ size_t count = (size_t)(unsigned int)len * sizeof(SecChar); -++ SECUREC_MEMCPY_WARP_OPT(stream->cur, str, count); -++ stream->cur += len; -++ stream->count -= len; -++ } -++} -++ -++/* -++ * Return if buffer length is enough -++ * The count variable can be reduced to 0, and the external function complements the \0 terminator. -++ */ -++SECUREC_INLINE int SecIsStreamBufEnough(const SecPrintfStream *stream, int needLen) -++{ -++ return (int)(stream->count >= needLen); -++} -++ -++/* Write text string */ -++SECUREC_INLINE void SecWriteTextOpt(SecPrintfStream *stream, const SecChar *str, int len, int *charsOut) -++{ -++ if (SecIsStreamBufEnough(stream, len) != 0) { -++ SecWriteStringOpt(stream, str, len); -++ *charsOut += len; -++ } else { -++ SecWriteString(stream, str, len, charsOut); -++ } -++} -++ -++/* Write left padding */ -++SECUREC_INLINE void SecWriteLeftPadding(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++ if ((attr->flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) == 0 && attr->padding > 0) { -++ /* Pad on left with blanks */ -++ SecWriteMultiChar(stream, SECUREC_CHAR(' '), attr->padding, charsOut); -++ } -++} -++ -++/* Write prefix */ -++SECUREC_INLINE void SecWritePrefix(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++ if (attr->prefixLen > 0) { -++ SecWriteString(stream, attr->prefix, attr->prefixLen, charsOut); -++ } -++} -++ -++/* Write leading zeros */ -++SECUREC_INLINE void SecWriteLeadingZero(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++ if ((attr->flags & SECUREC_FLAG_LEADZERO) != 0 && (attr->flags & SECUREC_FLAG_LEFT) == 0 && -++ attr->padding > 0) { -++ SecWriteMultiChar(stream, SECUREC_CHAR('0'), attr->padding, charsOut); -++ } -++} -++ -++/* Write right padding */ -++SECUREC_INLINE void SecWriteRightPadding(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++ if (*charsOut >= 0 && (attr->flags & SECUREC_FLAG_LEFT) != 0 && attr->padding > 0) { -++ /* Pad on right with blanks */ -++ SecWriteMultiChar(stream, SECUREC_CHAR(' '), attr->padding, charsOut); -++ } -++} -++ -++#ifdef SECUREC_FOR_WCHAR -++#define SECUREC_TEXT_CHAR_PTR(text) ((text).wStr) -++#define SECUREC_NEED_CONVERT_TEXT(attr) ((attr)->textIsWide == 0) -++#if SECUREC_HAVE_MBTOWC -++#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) SecWriteTextAfterMbtowc((stream), (attr), (charsOut)) -++#else -++#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) (*(charsOut) = -1) -++#endif -++#else -++#define SECUREC_TEXT_CHAR_PTR(text) ((text).str) -++#define SECUREC_NEED_CONVERT_TEXT(attr) ((attr)->textIsWide != 0) -++#if SECUREC_HAVE_WCTOMB -++#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) SecWriteTextAfterWctomb((stream), (attr), (charsOut)) -++#else -++#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) (*(charsOut) = -1) -++#endif -++#endif -++ -++#ifdef SECUREC_FOR_WCHAR -++#if SECUREC_HAVE_MBTOWC -++SECUREC_INLINE void SecWriteTextAfterMbtowc(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++ const char *p = attr->text.str; -++ int count = attr->textLen; -++ while (count > 0) { -++ wchar_t wChar = L'\0'; -++ int retVal = mbtowc(&wChar, p, (size_t)MB_CUR_MAX); -++ if (retVal <= 0) { -++ *charsOut = -1; -++ break; -++ } -++ SecWriteChar(stream, wChar, charsOut); -++ if (*charsOut == -1) { -++ break; -++ } -++ p += retVal; -++ count -= retVal; -++ } -++} -++#endif -++#else /* Not SECUREC_FOR_WCHAR */ -++#if SECUREC_HAVE_WCTOMB -++SECUREC_INLINE void SecWriteTextAfterWctomb(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++ const wchar_t *p = attr->text.wStr; -++ int count = attr->textLen; -++ while (count > 0) { -++ char tmpBuf[SECUREC_MB_LEN + 1]; -++ SECUREC_MASK_MSVC_CRT_WARNING -++ int retVal = wctomb(tmpBuf, *p); -++ SECUREC_END_MASK_MSVC_CRT_WARNING -++ if (retVal <= 0) { -++ *charsOut = -1; -++ break; -++ } -++ SecWriteString(stream, tmpBuf, retVal, charsOut); -++ if (*charsOut == -1) { -++ break; -++ } -++ --count; -++ ++p; -++ } -++} -++#endif -++#endif -++ -++#if SECUREC_ENABLE_SPRINTF_FLOAT -++/* -++ * Write text of float -++ * Using independent functions to optimize the expansion of inline functions by the compiler -++ */ -++SECUREC_INLINE void SecWriteFloatText(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++#ifdef SECUREC_FOR_WCHAR -++#if SECUREC_HAVE_MBTOWC -++ SecWriteTextAfterMbtowc(stream, attr, charsOut); -++#else -++ *charsOut = -1; -++ (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ (void)attr; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++#endif -++#else /* Not SECUREC_FOR_WCHAR */ -++ SecWriteString(stream, attr->text.str, attr->textLen, charsOut); -++#endif -++} -++#endif -++ -++/* Write text of integer or string ... */ -++SECUREC_INLINE void SecWriteText(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut) -++{ -++ if (SECUREC_NEED_CONVERT_TEXT(attr)) { -++ SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut); -++ } else { -++ SecWriteTextOpt(stream, SECUREC_TEXT_CHAR_PTR(attr->text), attr->textLen, charsOut); -++ } -++} -++ -++#define SECUREC_FMT_STATE_OFFSET 256 -++ -++SECUREC_INLINE SecFmtState SecDecodeState(SecChar ch, SecFmtState lastState) -++{ -++ static const unsigned char stateTable[SECUREC_STATE_TABLE_SIZE] = { -++ /* -++ * Type -++ * 0: nospecial meaning; -++ * 1: '%' -++ * 2: '.' -++ * 3: '*' -++ * 4: '0' -++ * 5: '1' ... '9' -++ * 6: ' ', '+', '-', '#' -++ * 7: 'h', 'l', 'L', 'w' , 'N', 'z', 'q', 't', 'j' -++ * 8: 'd', 'o', 'u', 'i', 'x', 'X', 'e', 'f', 'g', 'E', 'F', 'G', 's', 'c', '[', 'p' -++ */ -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00, -++ 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, -++ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00, 0x00, 0x08, -++ 0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, -++ /* Fill zero for normal char 128 byte for 0x80 - 0xff */ -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ /* -++ * State -++ * 0: normal -++ * 1: percent -++ * 2: flag -++ * 3: width -++ * 4: dot -++ * 5: precis -++ * 6: size -++ * 7: type -++ * 8: invalid -++ */ -++ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, -++ 0x01, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x08, 0x05, -++ 0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, -++ 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, -++ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, -++ 0x00 -++ }; -++ -++#ifdef SECUREC_FOR_WCHAR -++ /* Convert to unsigned char to clear gcc 4.3.4 warning */ -++ unsigned char fmtType = (unsigned char)((((unsigned int)(int)(ch)) <= (unsigned int)(int)(L'~')) ? \ -++ (stateTable[(unsigned char)(ch)]) : 0); -++ return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID + 1) + -++ (unsigned char)(lastState) + SECUREC_FMT_STATE_OFFSET]); -++#else -++ unsigned char fmtType = stateTable[(unsigned char)(ch)]; -++ return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID + 1) + -++ (unsigned char)(lastState) + SECUREC_FMT_STATE_OFFSET]); -++#endif -++} -++ -++SECUREC_INLINE void SecDecodeFlags(SecChar ch, SecFormatAttr *attr) -++{ -++ switch (ch) { -++ case SECUREC_CHAR(' '): -++ attr->flags |= SECUREC_FLAG_SIGN_SPACE; -++ break; -++ case SECUREC_CHAR('+'): -++ attr->flags |= SECUREC_FLAG_SIGN; -++ break; -++ case SECUREC_CHAR('-'): -++ attr->flags |= SECUREC_FLAG_LEFT; -++ break; -++ case SECUREC_CHAR('0'): -++ attr->flags |= SECUREC_FLAG_LEADZERO; /* Add zero th the front */ -++ break; -++ case SECUREC_CHAR('#'): -++ attr->flags |= SECUREC_FLAG_ALTERNATE; /* Output %x with 0x */ -++ break; -++ default: -++ /* Do nothing */ -++ break; -++ } -++ return; -++} -++ -++/* -++ * Decoded size identifier in format string to Reduce the number of lines of function code -++ */ -++SECUREC_INLINE int SecDecodeSizeI(SecFormatAttr *attr, const SecChar **format) -++{ -++#ifdef SECUREC_ON_64BITS -++ attr->flags |= SECUREC_FLAG_I64; /* %I to INT64 */ -++#endif -++ if ((**format == SECUREC_CHAR('6')) && (*((*format) + 1) == SECUREC_CHAR('4'))) { -++ (*format) += 2; /* Add 2 to skip I64 */ -++ attr->flags |= SECUREC_FLAG_I64; /* %I64 to INT64 */ -++ } else if ((**format == SECUREC_CHAR('3')) && (*((*format) + 1) == SECUREC_CHAR('2'))) { -++ (*format) += 2; /* Add 2 to skip I32 */ -++ attr->flags &= ~SECUREC_FLAG_I64; /* %I64 to INT32 */ -++ } else if ((**format == SECUREC_CHAR('d')) || (**format == SECUREC_CHAR('i')) || -++ (**format == SECUREC_CHAR('o')) || (**format == SECUREC_CHAR('u')) || -++ (**format == SECUREC_CHAR('x')) || (**format == SECUREC_CHAR('X'))) { -++ /* Do nothing */ -++ } else { -++ /* Compatibility code for "%I" just print I */ -++ return -1; -++ } -++ return 0; -++} -++ -++/* -++ * Decoded size identifier in format string, and skip format to next charater -++ */ -++SECUREC_INLINE int SecDecodeSize(SecChar ch, SecFormatAttr *attr, const SecChar **format) -++{ -++ switch (ch) { -++ case SECUREC_CHAR('l'): -++ if (**format == SECUREC_CHAR('l')) { -++ *format = *format + 1; -++ attr->flags |= SECUREC_FLAG_LONGLONG; /* For long long */ -++ } else { -++ attr->flags |= SECUREC_FLAG_LONG; /* For long int or wchar_t */ -++ } -++ break; -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++ case SECUREC_CHAR('z'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('Z'): -++ attr->flags |= SECUREC_FLAG_SIZE; -++ break; -++ case SECUREC_CHAR('j'): -++ attr->flags |= SECUREC_FLAG_INTMAX; -++ break; -++#endif -++ case SECUREC_CHAR('t'): -++ attr->flags |= SECUREC_FLAG_PTRDIFF; -++ break; -++ case SECUREC_CHAR('q'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('L'): -++ attr->flags |= (SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE); -++ break; -++ case SECUREC_CHAR('I'): -++ if (SecDecodeSizeI(attr, format) != 0) { -++ /* Compatibility code for "%I" just print I */ -++ return -1; -++ } -++ break; -++ case SECUREC_CHAR('h'): -++ if (**format == SECUREC_CHAR('h')) { -++ *format = *format + 1; -++ attr->flags |= SECUREC_FLAG_CHAR; /* For char */ -++ } else { -++ attr->flags |= SECUREC_FLAG_SHORT; /* For short int */ -++ } -++ break; -++ case SECUREC_CHAR('w'): -++ attr->flags |= SECUREC_FLAG_WIDECHAR; /* For wide char */ -++ break; -++ default: -++ /* Do nothing */ -++ break; -++ } -++ return 0; -++} -++ -++/* -++ * Decoded char type identifier -++ */ -++SECUREC_INLINE void SecDecodeTypeC(SecFormatAttr *attr, unsigned int c) -++{ -++ attr->textLen = 1; /* Only 1 wide character */ -++ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && !(defined(SECUREC_ON_SOLARIS)) -++ attr->flags &= ~SECUREC_FLAG_LEADZERO; -++#endif -++ -++#ifdef SECUREC_FOR_WCHAR -++ if ((attr->flags & SECUREC_FLAG_SHORT) != 0) { -++ /* Get multibyte character from argument */ -++ attr->buffer.str[0] = (char)c; -++ attr->text.str = attr->buffer.str; -++ attr->textIsWide = 0; -++ } else { -++ attr->buffer.wStr[0] = (wchar_t)c; -++ attr->text.wStr = attr->buffer.wStr; -++ attr->textIsWide = 1; -++ } -++#else /* Not SECUREC_FOR_WCHAR */ -++ if ((attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) != 0) { -++#if SECUREC_HAVE_WCHART -++ attr->buffer.wStr[0] = (wchar_t)c; -++ attr->text.wStr = attr->buffer.wStr; -++ attr->textIsWide = 1; -++#else -++ attr->textLen = 0; /* Ignore unsupported characters */ -++ attr->fldWidth = 0; /* No paddings */ -++#endif -++ } else { -++ /* Get multibyte character from argument */ -++ attr->buffer.str[0] = (char)c; -++ attr->text.str = attr->buffer.str; -++ attr->textIsWide = 0; -++ } -++#endif -++} -++ -++#ifdef SECUREC_FOR_WCHAR -++#define SECUREC_IS_NARROW_STRING(attr) (((attr)->flags & SECUREC_FLAG_SHORT) != 0) -++#else -++#define SECUREC_IS_NARROW_STRING(attr) (((attr)->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) == 0) -++#endif -++ -++SECUREC_INLINE void SecDecodeTypeSchar(SecFormatAttr *attr) -++{ -++ size_t textLen; -++ if (attr->text.str == NULL) { -++ /* -++ * Literal string to print null ptr, define it as array rather than const text area -++ * To avoid gcc warning with pointing const text with variable -++ */ -++ static char strNullString[SECUREC_NULL_STRING_SIZE] = "(null)"; -++ attr->text.str = strNullString; -++ } -++ if (attr->precision == -1) { -++ /* Precision NOT assigned */ -++ /* The strlen performance is high when the string length is greater than 32 */ -++ textLen = strlen(attr->text.str); -++ if (textLen > SECUREC_STRING_MAX_LEN) { -++ textLen = 0; -++ } -++ } else { -++ /* Precision assigned */ -++ SECUREC_CALC_STR_LEN(attr->text.str, (size_t)(unsigned int)attr->precision, &textLen); -++ } -++ attr->textLen = (int)textLen; -++} -++ -++SECUREC_INLINE void SecDecodeTypeSwchar(SecFormatAttr *attr) -++{ -++#if SECUREC_HAVE_WCHART -++ size_t textLen; -++ attr->textIsWide = 1; -++ if (attr->text.wStr == NULL) { -++ /* -++ * Literal string to print null ptr, define it as array rather than const text area -++ * To avoid gcc warning with pointing const text with variable -++ */ -++ static wchar_t wStrNullString[SECUREC_NULL_STRING_SIZE] = { L'(', L'n', L'u', L'l', L'l', L')', L'\0', L'\0' }; -++ attr->text.wStr = wStrNullString; -++ } -++ /* The textLen in wchar_t,when precision is -1, it is unlimited */ -++ SECUREC_CALC_WSTR_LEN(attr->text.wStr, (size_t)(unsigned int)attr->precision, &textLen); -++ if (textLen > SECUREC_WCHAR_STRING_MAX_LEN) { -++ textLen = 0; -++ } -++ attr->textLen = (int)textLen; -++#else -++ attr->textLen = 0; -++#endif -++} -++ -++/* -++ * Decoded string identifier -++ */ -++SECUREC_INLINE void SecDecodeTypeS(SecFormatAttr *attr, char *argPtr) -++{ -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) -++#if (!defined(SECUREC_ON_UNIX)) -++ attr->flags &= ~SECUREC_FLAG_LEADZERO; -++#endif -++#if (defined(SECUREC_FOR_WCHAR)) -++ if ((attr->flags & SECUREC_FLAG_LONG) == 0) { -++ attr->flags |= SECUREC_FLAG_SHORT; -++ } -++#endif -++#endif -++ attr->text.str = argPtr; -++ if (SECUREC_IS_NARROW_STRING(attr)) { -++ /* The textLen now contains length in multibyte chars */ -++ SecDecodeTypeSchar(attr); -++ } else { -++ /* The textLen now contains length in wide chars */ -++ SecDecodeTypeSwchar(attr); -++ } -++} -++ -++/* -++ * Check precision in format -++ */ -++SECUREC_INLINE int SecDecodePrecision(SecChar ch, SecFormatAttr *attr) -++{ -++ if (attr->dynPrecision == 0) { -++ /* Add digit to current precision */ -++ if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->precision)) { -++ return -1; -++ } -++ attr->precision = (int)SECUREC_MUL_TEN((unsigned int)attr->precision) + -++ (unsigned char)(ch - SECUREC_CHAR('0')); -++ } else { -++ if (attr->precision < 0) { -++ attr->precision = -1; -++ } -++ if (attr->precision > SECUREC_MAX_WIDTH_LEN) { -++ return -1; -++ } -++ } -++ return 0; -++} -++ -++/* -++ * Check width in format -++ */ -++SECUREC_INLINE int SecDecodeWidth(SecChar ch, SecFormatAttr *attr, SecFmtState lastState) -++{ -++ if (attr->dynWidth == 0) { -++ if (lastState != STAT_WIDTH) { -++ attr->fldWidth = 0; -++ } -++ if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->fldWidth)) { -++ return -1; -++ } -++ attr->fldWidth = (int)SECUREC_MUL_TEN((unsigned int)attr->fldWidth) + -++ (unsigned char)(ch - SECUREC_CHAR('0')); -++ } else { -++ if (attr->fldWidth < 0) { -++ attr->flags |= SECUREC_FLAG_LEFT; -++ attr->fldWidth = (-attr->fldWidth); -++ } -++ if (attr->fldWidth > SECUREC_MAX_WIDTH_LEN) { -++ return -1; -++ } -++ } -++ return 0; -++} -++ -++/* -++ * The sprintf_s function processes the wide character as a parameter for %C -++ * The swprintf_s function processes the multiple character as a parameter for %C -++ */ -++SECUREC_INLINE void SecUpdateWcharFlags(SecFormatAttr *attr) -++{ -++ if ((attr->flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) == 0) { -++#ifdef SECUREC_FOR_WCHAR -++ attr->flags |= SECUREC_FLAG_SHORT; -++#else -++ attr->flags |= SECUREC_FLAG_WIDECHAR; -++#endif -++ } -++} -++/* -++ * When encountering %S, current just same as %C -++ */ -++SECUREC_INLINE void SecUpdateWstringFlags(SecFormatAttr *attr) -++{ -++ SecUpdateWcharFlags(attr); -++} -++ -++#if SECUREC_IN_KERNEL -++SECUREC_INLINE void SecUpdatePointFlagsForKernel(SecFormatAttr *attr) -++{ -++ /* Width is not set */ -++ if (attr->fldWidth <= 0) { -++ attr->flags |= SECUREC_FLAG_LEADZERO; -++ attr->fldWidth = 2 * sizeof(void *); /* 2 x byte number is the length of hex */ -++ } -++ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { -++ /* Alternate form means '0x' prefix */ -++ attr->prefix[0] = SECUREC_CHAR('0'); -++ attr->prefix[1] = SECUREC_CHAR('x'); -++ attr->prefixLen = SECUREC_PREFIX_LEN; -++ } -++ attr->flags |= SECUREC_FLAG_LONG; /* Converting a long */ -++} -++#endif -++ -++SECUREC_INLINE void SecUpdatePointFlags(SecFormatAttr *attr) -++{ -++ attr->flags |= SECUREC_FLAG_POINTER; -++#if SECUREC_IN_KERNEL -++ SecUpdatePointFlagsForKernel(attr); -++#else -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) && (!defined(SECUREC_ON_UNIX)) -++#if defined(SECUREC_VXWORKS_PLATFORM) -++ attr->precision = 1; -++#else -++ attr->precision = 0; -++#endif -++ attr->flags |= SECUREC_FLAG_ALTERNATE; /* "0x" is not default prefix in UNIX */ -++ attr->digits = g_itoaLowerDigits; -++#else /* On unix or win */ -++#if defined(_AIX) || defined(SECUREC_ON_SOLARIS) -++ attr->precision = 1; -++#else -++ attr->precision = 2 * sizeof(void *); /* 2 x byte number is the length of hex */ -++#endif -++#if defined(SECUREC_ON_UNIX) -++ attr->digits = g_itoaLowerDigits; -++#else -++ attr->digits = g_itoaUpperDigits; -++#endif -++#endif -++ -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ attr->flags &= ~SECUREC_FLAG_LEADZERO; -++#endif -++ -++#ifdef SECUREC_ON_64BITS -++ attr->flags |= SECUREC_FLAG_I64; /* Converting an int64 */ -++#else -++ attr->flags |= SECUREC_FLAG_LONG; /* Converting a long */ -++#endif -++ /* Set up for %#p on different system */ -++ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { -++ /* Alternate form means '0x' prefix */ -++ attr->prefix[0] = SECUREC_CHAR('0'); -++#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) -++ attr->prefix[1] = SECUREC_CHAR('x'); -++#else -++ attr->prefix[1] = (SecChar)(attr->digits[SECUREC_NUMBER_OF_X]); -++#endif -++#if defined(_AIX) || defined(SECUREC_ON_SOLARIS) -++ attr->prefixLen = 0; -++#else -++ attr->prefixLen = SECUREC_PREFIX_LEN; -++#endif -++ } -++#endif -++} -++ -++SECUREC_INLINE void SecUpdateXpxFlags(SecFormatAttr *attr, SecChar ch) -++{ -++ /* Use unsigned lower hex output for 'x' */ -++ attr->digits = g_itoaLowerDigits; -++ attr->radix = SECUREC_RADIX_HEX; -++ switch (ch) { -++ case SECUREC_CHAR('p'): -++ /* Print a pointer */ -++ SecUpdatePointFlags(attr); -++ break; -++ case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */ -++ /* Unsigned upper hex output */ -++ attr->digits = g_itoaUpperDigits; -++ /* fall-through */ /* FALLTHRU */ -++ default: -++ /* For %#x or %#X */ -++ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { -++ /* Alternate form means '0x' prefix */ -++ attr->prefix[0] = SECUREC_CHAR('0'); -++ attr->prefix[1] = (SecChar)(attr->digits[SECUREC_NUMBER_OF_X]); -++ attr->prefixLen = SECUREC_PREFIX_LEN; -++ } -++ break; -++ } -++} -++ -++SECUREC_INLINE void SecUpdateOudiFlags(SecFormatAttr *attr, SecChar ch) -++{ -++ /* Do not set digits here */ -++ switch (ch) { -++ case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */ -++ /* For signed decimal output */ -++ attr->flags |= SECUREC_FLAG_SIGNED; -++ /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('u'): -++ attr->radix = SECUREC_RADIX_DECIMAL; -++ attr->digits = g_itoaLowerDigits; -++ break; -++ case SECUREC_CHAR('o'): -++ /* For unsigned octal output */ -++ attr->radix = SECUREC_RADIX_OCTAL; -++ attr->digits = g_itoaLowerDigits; -++ if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { -++ /* Alternate form means force a leading 0 */ -++ attr->flags |= SECUREC_FLAG_FORCE_OCTAL; -++ } -++ break; -++ default: -++ /* Do nothing */ -++ break; -++ } -++} -++ -++#if SECUREC_ENABLE_SPRINTF_FLOAT -++SECUREC_INLINE void SecFreeFloatBuffer(SecFloatAdapt *floatAdapt) -++{ -++ if (floatAdapt->floatBuffer != NULL) { -++ SECUREC_FREE(floatAdapt->floatBuffer); -++ } -++ if (floatAdapt->allocatedFmtStr != NULL) { -++ SECUREC_FREE(floatAdapt->allocatedFmtStr); -++ } -++ floatAdapt->floatBuffer = NULL; -++ floatAdapt->allocatedFmtStr = NULL; -++ floatAdapt->fmtStr = NULL; -++ floatAdapt->bufferSize = 0; -++} -++ -++SECUREC_INLINE void SecSeekToFrontPercent(const SecChar **format) -++{ -++ const SecChar *fmt = *format; -++ while (*fmt != SECUREC_CHAR('%')) { /* Must meet '%' */ -++ --fmt; -++ } -++ *format = fmt; -++} -++ -++/* Init float format, return 0 is OK */ -++SECUREC_INLINE int SecInitFloatFmt(SecFloatAdapt *floatFmt, const SecChar *format) -++{ -++ const SecChar *fmt = format - 2; /* Sub 2 to the position before 'f' or 'g' */ -++ int fmtStrLen; -++ int i; -++ -++ SecSeekToFrontPercent(&fmt); -++ /* Now fmt point to '%' */ -++ fmtStrLen = (int)(size_t)(format - fmt) + 1; /* With ending terminator */ -++ if (fmtStrLen > (int)sizeof(floatFmt->buffer)) { -++ /* When buffer is NOT enough, alloc a new buffer */ -++ floatFmt->allocatedFmtStr = (char *)SECUREC_MALLOC((size_t)((unsigned int)fmtStrLen)); -++ if (floatFmt->allocatedFmtStr == NULL) { -++ return -1; -++ } -++ floatFmt->fmtStr = floatFmt->allocatedFmtStr; -++ } else { -++ floatFmt->fmtStr = floatFmt->buffer; -++ floatFmt->allocatedFmtStr = NULL; /* Must set to NULL, later code free memory based on this identity */ -++ } -++ -++ for (i = 0; i < fmtStrLen - 1; ++i) { -++ /* Convert wchar to char */ -++ floatFmt->fmtStr[i] = (char)(fmt[i]); /* Copy the format string */ -++ } -++ floatFmt->fmtStr[fmtStrLen - 1] = '\0'; -++ -++ return 0; -++} -++ -++/* Init float buffer and format, return 0 is OK */ -++SECUREC_INLINE int SecInitFloatBuffer(SecFloatAdapt *floatAdapt, const SecChar *format, SecFormatAttr *attr) -++{ -++ floatAdapt->allocatedFmtStr = NULL; -++ floatAdapt->fmtStr = NULL; -++ floatAdapt->floatBuffer = NULL; -++ /* Compute the precision value */ -++ if (attr->precision < 0) { -++ attr->precision = SECUREC_FLOAT_DEFAULT_PRECISION; -++ } -++ /* -++ * Calc buffer size to store double value -++ * The maximum length of SECUREC_MAX_WIDTH_LEN is enough -++ */ -++ if ((attr->flags & SECUREC_FLAG_LONG_DOUBLE) != 0) { -++ if (attr->precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE_LB)) { -++ return -1; -++ } -++ /* Long double needs to meet the basic print length */ -++ floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE_LB + attr->precision + SECUREC_FLOAT_BUF_EXT; -++ } else { -++ if (attr->precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE)) { -++ return -1; -++ } -++ /* Double needs to meet the basic print length */ -++ floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE + attr->precision + SECUREC_FLOAT_BUF_EXT; -++ } -++ if (attr->fldWidth > floatAdapt->bufferSize) { -++ floatAdapt->bufferSize = attr->fldWidth + SECUREC_FLOAT_BUF_EXT; -++ } -++ -++ if (floatAdapt->bufferSize > SECUREC_BUFFER_SIZE) { -++ /* The current value of SECUREC_BUFFER_SIZE could not store the formatted float string */ -++ floatAdapt->floatBuffer = (char *)SECUREC_MALLOC(((size_t)(unsigned int)floatAdapt->bufferSize)); -++ if (floatAdapt->floatBuffer == NULL) { -++ return -1; -++ } -++ attr->text.str = floatAdapt->floatBuffer; -++ } else { -++ attr->text.str = attr->buffer.str; /* Output buffer for float string with default size */ -++ } -++ -++ if (SecInitFloatFmt(floatAdapt, format) != 0) { -++ if (floatAdapt->floatBuffer != NULL) { -++ SECUREC_FREE(floatAdapt->floatBuffer); -++ floatAdapt->floatBuffer = NULL; -++ } -++ return -1; -++ } -++ return 0; -++} -++#endif -++ -++SECUREC_INLINE SecInt64 SecUpdateNegativeChar(SecFormatAttr *attr, char ch) -++{ -++ SecInt64 num64 = ch; /* Sign extend */ -++ if (num64 >= 128) { /* 128 on some platform, char is always unsigned */ -++ unsigned char tmp = (unsigned char)(~((unsigned char)ch)); -++ num64 = tmp + 1; -++ attr->flags |= SECUREC_FLAG_NEGATIVE; -++ } -++ return num64; -++} -++ -++/* -++ * If the precision is not satisfied, zero is added before the string -++ */ -++SECUREC_INLINE void SecNumberSatisfyPrecision(SecFormatAttr *attr) -++{ -++ int precision; -++ if (attr->precision < 0) { -++ precision = 1; /* Default precision 1 */ -++ } else { -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++ attr->flags &= ~SECUREC_FLAG_LEADZERO; -++#else -++ if ((attr->flags & SECUREC_FLAG_POINTER) == 0) { -++ attr->flags &= ~SECUREC_FLAG_LEADZERO; -++ } -++#endif -++ if (attr->precision > SECUREC_MAX_PRECISION) { -++ attr->precision = SECUREC_MAX_PRECISION; -++ } -++ precision = attr->precision; -++ } -++ while (attr->textLen < precision) { -++ --attr->text.str; -++ *(attr->text.str) = '0'; -++ ++attr->textLen; -++ } -++} -++ -++/* -++ * Add leading zero for %#o -++ */ -++SECUREC_INLINE void SecNumberForceOctal(SecFormatAttr *attr) -++{ -++ /* Force a leading zero if FORCEOCTAL flag set */ -++ if ((attr->flags & SECUREC_FLAG_FORCE_OCTAL) != 0 && -++ (attr->textLen == 0 || attr->text.str[0] != '0')) { -++ --attr->text.str; -++ *(attr->text.str) = '0'; -++ ++attr->textLen; -++ } -++} -++ -++SECUREC_INLINE void SecUpdateSignedNumberPrefix(SecFormatAttr *attr) -++{ -++ if ((attr->flags & SECUREC_FLAG_SIGNED) == 0) { -++ return; -++ } -++ if ((attr->flags & SECUREC_FLAG_NEGATIVE) != 0) { -++ /* Prefix is '-' */ -++ attr->prefix[0] = SECUREC_CHAR('-'); -++ attr->prefixLen = 1; -++ return; -++ } -++ if ((attr->flags & SECUREC_FLAG_SIGN) != 0) { -++ /* Prefix is '+' */ -++ attr->prefix[0] = SECUREC_CHAR('+'); -++ attr->prefixLen = 1; -++ return; -++ } -++ if ((attr->flags & SECUREC_FLAG_SIGN_SPACE) != 0) { -++ /* Prefix is ' ' */ -++ attr->prefix[0] = SECUREC_CHAR(' '); -++ attr->prefixLen = 1; -++ return; -++ } -++ return; -++} -++ -++SECUREC_INLINE void SecNumberCompatZero(SecFormatAttr *attr) -++{ -++#if SECUREC_IN_KERNEL -++ if ((attr->flags & SECUREC_FLAG_POINTER) != 0) { -++ static char strNullPointer[SECUREC_NULL_STRING_SIZE] = "(null)"; -++ attr->text.str = strNullPointer; -++ attr->textLen = 6; /* Length of (null) is 6 */ -++ attr->flags &= ~SECUREC_FLAG_LEADZERO; -++ attr->prefixLen = 0; -++ if (attr->precision >= 0 && attr->precision < attr->textLen) { -++ attr->textLen = attr->precision; -++ } -++ } -++ if ((attr->flags & SECUREC_FLAG_POINTER) == 0 && attr->radix == SECUREC_RADIX_HEX && -++ (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { -++ /* Add 0x prefix for %x or %X, the prefix string has been set before */ -++ attr->prefixLen = SECUREC_PREFIX_LEN; -++ } -++#elif defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX)) -++ if ((attr->flags & SECUREC_FLAG_POINTER) != 0) { -++ static char strNullPointer[SECUREC_NULL_STRING_SIZE] = "(nil)"; -++ attr->text.str = strNullPointer; -++ attr->textLen = 5; /* Length of (nil) is 5 */ -++ attr->flags &= ~SECUREC_FLAG_LEADZERO; -++ } -++#elif defined(SECUREC_VXWORKS_PLATFORM) || defined(__hpux) -++ if ((attr->flags & SECUREC_FLAG_POINTER) != 0 && (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) { -++ /* Add 0x prefix for %p, the prefix string has been set before */ -++ attr->prefixLen = SECUREC_PREFIX_LEN; -++ } -++#endif -++ (void)attr; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++} -++ -++/* -++ * Formatting output core function -++ */ -++SECUREC_INLINE int SecOutput(SecPrintfStream *stream, const SecChar *cFormat, va_list argList) -++{ -++ const SecChar *format = cFormat; -++ int charsOut; /* Characters written */ -++ int noOutput = 0; /* Must be initialized or compiler alerts */ -++ SecFmtState state; -++ SecFormatAttr formatAttr; -++ -++ formatAttr.flags = 0; -++ formatAttr.textIsWide = 0; /* Flag for buffer contains wide chars */ -++ formatAttr.fldWidth = 0; -++ formatAttr.precision = 0; -++ formatAttr.dynWidth = 0; -++ formatAttr.dynPrecision = 0; -++ formatAttr.digits = g_itoaUpperDigits; -++ formatAttr.radix = SECUREC_RADIX_DECIMAL; -++ formatAttr.padding = 0; -++ formatAttr.textLen = 0; -++ formatAttr.text.str = NULL; -++ formatAttr.prefixLen = 0; -++ formatAttr.prefix[0] = SECUREC_CHAR('\0'); -++ formatAttr.prefix[1] = SECUREC_CHAR('\0'); -++ charsOut = 0; -++ state = STAT_NORMAL; /* Starting state */ -++ -++ /* Loop each format character */ -++ while (*format != SECUREC_CHAR('\0') && charsOut >= 0) { -++ SecFmtState lastState = state; -++ SecChar ch = *format; /* Currently read character */ -++ ++format; -++ state = SecDecodeState(ch, lastState); -++ switch (state) { -++ case STAT_NORMAL: -++ SecWriteChar(stream, ch, &charsOut); -++ continue; -++ case STAT_PERCENT: -++ /* Set default values */ -++ noOutput = 0; -++ formatAttr.prefixLen = 0; -++ formatAttr.textLen = 0; -++ formatAttr.flags = 0; -++ formatAttr.fldWidth = 0; -++ formatAttr.precision = -1; -++ formatAttr.textIsWide = 0; -++ formatAttr.dynWidth = 0; -++ formatAttr.dynPrecision = 0; -++ break; -++ case STAT_FLAG: -++ /* Set flag based on which flag character */ -++ SecDecodeFlags(ch, &formatAttr); -++ break; -++ case STAT_WIDTH: -++ /* Update width value */ -++ if (ch == SECUREC_CHAR('*')) { -++ /* get width from arg list */ -++ formatAttr.fldWidth = (int)va_arg(argList, int); -++ formatAttr.dynWidth = 1; -++ } -++ if (SecDecodeWidth(ch, &formatAttr, lastState) != 0) { -++ return -1; -++ } -++ break; -++ case STAT_DOT: -++ formatAttr.precision = 0; -++ break; -++ case STAT_PRECIS: -++ /* Update precision value */ -++ if (ch == SECUREC_CHAR('*')) { -++ /* Get precision from arg list */ -++ formatAttr.precision = (int)va_arg(argList, int); -++ formatAttr.dynPrecision = 1; -++ } -++ if (SecDecodePrecision(ch, &formatAttr) != 0) { -++ return -1; -++ } -++ break; -++ case STAT_SIZE: -++ /* Read a size specifier, set the formatAttr.flags based on it, and skip format to next character */ -++ if (SecDecodeSize(ch, &formatAttr, &format) != 0) { -++ /* Compatibility code for "%I" just print I */ -++ SecWriteChar(stream, ch, &charsOut); -++ state = STAT_NORMAL; -++ continue; -++ } -++ break; -++ case STAT_TYPE: -++ switch (ch) { -++ case SECUREC_CHAR('C'): /* Wide char */ -++ SecUpdateWcharFlags(&formatAttr); -++ /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('c'): { -++ unsigned int cValue = (unsigned int)va_arg(argList, int); -++ SecDecodeTypeC(&formatAttr, cValue); -++ break; -++ } -++ case SECUREC_CHAR('S'): /* Wide char string */ -++ SecUpdateWstringFlags(&formatAttr); -++ /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('s'): { -++ char *argPtr = (char *)va_arg(argList, char *); -++ SecDecodeTypeS(&formatAttr, argPtr); -++ break; -++ } -++ case SECUREC_CHAR('G'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('g'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('E'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('e'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('f'): { -++#if SECUREC_ENABLE_SPRINTF_FLOAT -++ /* Add following code to call system sprintf API for float number */ -++ SecFloatAdapt floatAdapt; -++ noOutput = 1; /* It's no more data needs to be written */ -++ -++ /* Now format is pointer to the next character of 'f' */ -++ if (SecInitFloatBuffer(&floatAdapt, format, &formatAttr) != 0) { -++ break; -++ } -++ -++ if ((formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) != 0) { -++#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && SECUREC_ENABLE_SPRINTF_LONG_DOUBLE -++ long double tmp = (long double)va_arg(argList, long double); -++ SecFormatLongDouble(&formatAttr, &floatAdapt, tmp); -++#else -++ double tmp = (double)va_arg(argList, double); -++ SecFormatDouble(&formatAttr, &floatAdapt, tmp); -++#endif -++ } else { -++ double tmp = (double)va_arg(argList, double); -++ SecFormatDouble(&formatAttr, &floatAdapt, tmp); -++ } -++ -++ /* Only need write formatted float string */ -++ SecWriteFloatText(stream, &formatAttr, &charsOut); -++ SecFreeFloatBuffer(&floatAdapt); -++ break; -++#else -++ return -1; -++#endif -++ } -++ case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('p'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('x'): /* fall-through */ /* FALLTHRU */ -++ SecUpdateXpxFlags(&formatAttr, ch); -++ /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('u'): /* fall-through */ /* FALLTHRU */ -++ case SECUREC_CHAR('o'): { -++ SecInt64 num64; -++ SecUpdateOudiFlags(&formatAttr, ch); -++ /* Read argument into variable num64. Be careful, depend on the order of judgment */ -++ if ((formatAttr.flags & SECUREC_FLAG_I64) != 0 || -++ (formatAttr.flags & SECUREC_FLAG_LONGLONG) != 0) { -++ num64 = (SecInt64)va_arg(argList, SecInt64); /* Maximum Bit Width sign bit unchanged */ -++ } else if ((formatAttr.flags & SECUREC_FLAG_LONG) != 0) { -++ num64 = SECUREC_GET_LONG_FROM_ARG(formatAttr); -++ } else if ((formatAttr.flags & SECUREC_FLAG_CHAR) != 0) { -++ num64 = SECUREC_GET_CHAR_FROM_ARG(formatAttr); -++ } else if ((formatAttr.flags & SECUREC_FLAG_SHORT) != 0) { -++ num64 = SECUREC_GET_SHORT_FROM_ARG(formatAttr); -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++ } else if ((formatAttr.flags & SECUREC_FLAG_PTRDIFF) != 0) { -++ num64 = (ptrdiff_t)va_arg(argList, ptrdiff_t); /* Sign extend */ -++ } else if ((formatAttr.flags & SECUREC_FLAG_SIZE) != 0) { -++ num64 = SECUREC_GET_SIZE_FROM_ARG(formatAttr); -++ } else if ((formatAttr.flags & SECUREC_FLAG_INTMAX) != 0) { -++ num64 = (SecInt64)va_arg(argList, SecInt64); -++#endif -++ } else { -++ num64 = SECUREC_GET_INT_FROM_ARG(formatAttr); -++ } -++ -++ /* The order of the following calls must be correct */ -++ SecNumberToBuffer(&formatAttr, num64); -++ SecNumberSatisfyPrecision(&formatAttr); -++ SecNumberForceOctal(&formatAttr); -++ SecUpdateSignedNumberPrefix(&formatAttr); -++ if (num64 == 0) { -++ SecNumberCompatZero(&formatAttr); -++ } -++ break; -++ } -++ default: -++ /* Do nothing */ -++ break; -++ } -++ -++ if (noOutput == 0) { -++ /* Calculate amount of padding */ -++ formatAttr.padding = (formatAttr.fldWidth - formatAttr.textLen) - formatAttr.prefixLen; -++ -++ /* Put out the padding, prefix, and text, in the correct order */ -++ SecWriteLeftPadding(stream, &formatAttr, &charsOut); -++ SecWritePrefix(stream, &formatAttr, &charsOut); -++ SecWriteLeadingZero(stream, &formatAttr, &charsOut); -++ SecWriteText(stream, &formatAttr, &charsOut); -++ SecWriteRightPadding(stream, &formatAttr, &charsOut); -++ } -++ break; -++ case STAT_INVALID: /* fall-through */ /* FALLTHRU */ -++ default: -++ return -1; /* Input format is wrong(STAT_INVALID), directly return */ -++ } -++ } -++ -++ if (state != STAT_NORMAL && state != STAT_TYPE) { -++ return -1; -++ } -++ -++ return charsOut; /* The number of characters written */ -++} -++ -++/* -++ * Output one zero character zero into the SecPrintfStream structure -++ * If there is not enough space, make sure f->count is less than 0 -++ */ -++SECUREC_INLINE int SecPutZeroChar(SecPrintfStream *stream) -++{ -++ --stream->count; -++ if (stream->count >= 0) { -++ *(stream->cur) = SECUREC_CHAR('\0'); -++ ++stream->cur; -++ return 0; -++ } -++ return -1; -++} -++ -++/* -++ * Multi character formatted output implementation -++ */ -++#ifdef SECUREC_FOR_WCHAR -++int SecVswprintfImpl(wchar_t *string, size_t count, const wchar_t *format, va_list argList) -++#else -++int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList) -++#endif -++{ -++ SecPrintfStream stream; -++ int retVal; -++ -++ stream.count = (int)count; /* The count include \0 character, must be greater than zero */ -++ stream.cur = string; -++ -++ retVal = SecOutput(&stream, format, argList); -++ if (retVal >= 0) { -++ if (SecPutZeroChar(&stream) == 0) { -++ return retVal; -++ } -++ } -++ if (stream.count < 0) { -++ /* The buffer was too small, then truncate */ -++ string[count - 1] = SECUREC_CHAR('\0'); -++ return SECUREC_PRINTF_TRUNCATE; -++ } -++ string[0] = SECUREC_CHAR('\0'); /* Empty the dest string */ -++ return -1; -++} -++#endif /* OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 */ -++ -+diff --git a/lib/securec/src/scanf_s.c b/lib/securec/src/scanf_s.c -+new file mode 100755 -+index 000000000..dc575714e -+--- /dev/null -++++ b/lib/securec/src/scanf_s.c -+@@ -0,0 +1,51 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: scanf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "linux/securec.h" -++ -++/* -++ * -++ * The scanf_s function is equivalent to fscanf_s with the argument stdin interposed before the arguments to scanf_s -++ * The scanf_s function reads data from the standard input stream stdin and -++ * writes the data into the location that's given by argument. Each argument -++ * must be a pointer to a variable of a type that corresponds to a type specifier -++ * in format. If copying occurs between strings that overlap, the behavior is -++ * undefined. -++ * -++ * -++ * format Format control string. -++ * ... Optional arguments. -++ * -++ * -++ * ... The converted value stored in user assigned address -++ * -++ * -++ * Returns the number of fields successfully converted and assigned; -++ * the return value does not include fields that were read but not assigned. -++ * A return value of 0 indicates that no fields were assigned. -++ * return -1 if an error occurs. -++ */ -++int scanf_s(const char *format, ...) -++{ -++ int ret; /* If initialization causes e838 */ -++ va_list argList; -++ -++ va_start(argList, format); -++ ret = vscanf_s(format, argList); -++ va_end(argList); -++ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ -++ return ret; -++} -++ -+diff --git a/lib/securec/src/secinput.h b/lib/securec/src/secinput.h -+new file mode 100755 -+index 000000000..176ee05d9 -+--- /dev/null -++++ b/lib/securec/src/secinput.h -+@@ -0,0 +1,181 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: Define macro, data struct, and declare function prototype, -++ * which is used by input.inl, secureinput_a.c and secureinput_w.c. -++ * Create: 2014-02-25 -++ */ -++ -++#ifndef SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C -++#define SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C -++#include "securecutil.h" -++ -++#define SECUREC_SCANF_EINVAL (-1) -++#define SECUREC_SCANF_ERROR_PARA (-2) -++ -++/* For internal stream flag */ -++#define SECUREC_MEM_STR_FLAG 0x01U -++#define SECUREC_FILE_STREAM_FLAG 0x02U -++#define SECUREC_PIPE_STREAM_FLAG 0x04U -++#define SECUREC_LOAD_FILE_TO_MEM_FLAG 0x08U -++ -++#define SECUREC_UCS_BOM_HEADER_SIZE 2U -++#define SECUREC_UCS_BOM_HEADER_BE_1ST 0xfeU -++#define SECUREC_UCS_BOM_HEADER_BE_2ST 0xffU -++#define SECUREC_UCS_BOM_HEADER_LE_1ST 0xffU -++#define SECUREC_UCS_BOM_HEADER_LE_2ST 0xfeU -++#define SECUREC_UTF8_BOM_HEADER_SIZE 3U -++#define SECUREC_UTF8_BOM_HEADER_1ST 0xefU -++#define SECUREC_UTF8_BOM_HEADER_2ND 0xbbU -++#define SECUREC_UTF8_BOM_HEADER_3RD 0xbfU -++#define SECUREC_UTF8_LEAD_1ST 0xe0U -++#define SECUREC_UTF8_LEAD_2ND 0x80U -++ -++#define SECUREC_BEGIN_WITH_UCS_BOM(s, len) ((len) == SECUREC_UCS_BOM_HEADER_SIZE && \ -++ (((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_LE_1ST && \ -++ (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_LE_2ST) || \ -++ ((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_BE_1ST && \ -++ (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_BE_2ST))) -++ -++#define SECUREC_BEGIN_WITH_UTF8_BOM(s, len) ((len) == SECUREC_UTF8_BOM_HEADER_SIZE && \ -++ (unsigned char)((s)[0]) == SECUREC_UTF8_BOM_HEADER_1ST && \ -++ (unsigned char)((s)[1]) == SECUREC_UTF8_BOM_HEADER_2ND && \ -++ (unsigned char)((s)[2]) == SECUREC_UTF8_BOM_HEADER_3RD) -++ -++#ifdef SECUREC_FOR_WCHAR -++#define SECUREC_BOM_HEADER_SIZE SECUREC_UCS_BOM_HEADER_SIZE -++#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UCS_BOM((s), (len)) -++#else -++#define SECUREC_BOM_HEADER_SIZE SECUREC_UTF8_BOM_HEADER_SIZE -++#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UTF8_BOM((s), (len)) -++#endif -++ -++typedef struct { -++ unsigned int flag; /* Mark the properties of input stream */ -++ char *base; /* The pointer to the header of buffered string */ -++ const char *cur; /* The pointer to next read position */ -++ size_t count; /* The size of buffered string in bytes */ -++#if SECUREC_ENABLE_SCANF_FILE -++ FILE *pf; /* The file pointer */ -++ size_t fileRealRead; -++ long oriFilePos; /* The original position of file offset when fscanf is called */ -++#endif -++} SecFileStream; -++ -++#if SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) do { \ -++ (stream)->pf = (fp); \ -++ (stream)->fileRealRead = 0; \ -++ (stream)->oriFilePos = 0; \ -++} SECUREC_WHILE_ZERO -++#else -++/* Disable file */ -++#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) -++#endif -++ -++/* This initialization for eliminating redundant initialization. */ -++#define SECUREC_FILE_STREAM_FROM_STRING(stream, buf, cnt) do { \ -++ (stream)->flag = SECUREC_MEM_STR_FLAG; \ -++ (stream)->base = NULL; \ -++ (stream)->cur = (buf); \ -++ (stream)->count = (cnt); \ -++ SECUREC_FILE_STREAM_INIT_FILE((stream), NULL); \ -++} SECUREC_WHILE_ZERO -++ -++/* This initialization for eliminating redundant initialization. */ -++#define SECUREC_FILE_STREAM_FROM_FILE(stream, fp) do { \ -++ (stream)->flag = SECUREC_FILE_STREAM_FLAG; \ -++ (stream)->base = NULL; \ -++ (stream)->cur = NULL; \ -++ (stream)->count = 0; \ -++ SECUREC_FILE_STREAM_INIT_FILE((stream), (fp)); \ -++} SECUREC_WHILE_ZERO -++ -++/* This initialization for eliminating redundant initialization. */ -++#define SECUREC_FILE_STREAM_FROM_STDIN(stream) do { \ -++ (stream)->flag = SECUREC_PIPE_STREAM_FLAG; \ -++ (stream)->base = NULL; \ -++ (stream)->cur = NULL; \ -++ (stream)->count = 0; \ -++ SECUREC_FILE_STREAM_INIT_FILE((stream), SECUREC_STREAM_STDIN); \ -++} SECUREC_WHILE_ZERO -++ -++#ifdef __cplusplus -++extern "C" { -++#endif -++int SecInputS(SecFileStream *stream, const char *cFormat, va_list argList); -++void SecClearDestBuf(const char *buffer, const char *format, va_list argList); -++#ifdef SECUREC_FOR_WCHAR -++int SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList); -++void SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList); -++#endif -++ -++/* 20150105 For software and hardware decoupling,such as UMG */ -++#ifdef SECUREC_SYSAPI4VXWORKS -++#ifdef feof -++#undef feof -++#endif -++extern int feof(FILE *stream); -++#endif -++ -++#if defined(SECUREC_SYSAPI4VXWORKS) || defined(SECUREC_CTYPE_MACRO_ADAPT) -++#ifndef isspace -++#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n')) -++#endif -++#ifndef iswspace -++#define iswspace(c) (((c) == L' ') || ((c) == L'\t') || ((c) == L'\r') || ((c) == L'\n')) -++#endif -++#ifndef isascii -++#define isascii(c) (((unsigned char)(c)) <= 0x7f) -++#endif -++#ifndef isupper -++#define isupper(c) ((c) >= 'A' && (c) <= 'Z') -++#endif -++#ifndef islower -++#define islower(c) ((c) >= 'a' && (c) <= 'z') -++#endif -++#ifndef isalpha -++#define isalpha(c) (isupper(c) || (islower(c))) -++#endif -++#ifndef isdigit -++#define isdigit(c) ((c) >= '0' && (c) <= '9') -++#endif -++#ifndef isxupper -++#define isxupper(c) ((c) >= 'A' && (c) <= 'F') -++#endif -++#ifndef isxlower -++#define isxlower(c) ((c) >= 'a' && (c) <= 'f') -++#endif -++#ifndef isxdigit -++#define isxdigit(c) (isdigit(c) || isxupper(c) || isxlower(c)) -++#endif -++#endif -++ -++#ifdef __cplusplus -++} -++#endif -++/* Reserved file operation macro interface, s is FILE *, i is fileno zero. */ -++#ifndef SECUREC_LOCK_FILE -++#define SECUREC_LOCK_FILE(s) -++#endif -++ -++#ifndef SECUREC_UNLOCK_FILE -++#define SECUREC_UNLOCK_FILE(s) -++#endif -++ -++#ifndef SECUREC_LOCK_STDIN -++#define SECUREC_LOCK_STDIN(i, s) -++#endif -++ -++#ifndef SECUREC_UNLOCK_STDIN -++#define SECUREC_UNLOCK_STDIN(i, s) -++#endif -++#endif -++ -+diff --git a/lib/securec/src/securecutil.c b/lib/securec/src/securecutil.c -+new file mode 100755 -+index 000000000..7518eb300 -+--- /dev/null -++++ b/lib/securec/src/securecutil.c -+@@ -0,0 +1,81 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: Provides internal functions used by this library, such as memory -++ * copy and memory move. Besides, include some helper function for -++ * printf family API, such as SecVsnprintfImpl -++ * Create: 2014-02-25 -++ */ -++ -++/* Avoid duplicate header files,not include securecutil.h */ -++#include "securecutil.h" -++ -++#if defined(ANDROID) && !defined(SECUREC_CLOSE_ANDROID_HANDLE) && (SECUREC_HAVE_WCTOMB || SECUREC_HAVE_MBTOWC) -++#include -++#if SECUREC_HAVE_WCTOMB -++/* -++ * Convert wide characters to narrow multi-bytes -++ */ -++int wctomb(char *s, wchar_t wc) -++{ -++ return (int)wcrtomb(s, wc, NULL); -++} -++#endif -++ -++#if SECUREC_HAVE_MBTOWC -++/* -++ * Converting narrow multi-byte characters to wide characters -++ * mbrtowc returns -1 or -2 upon failure, unlike mbtowc, which only returns -1 -++ * When the return value is less than zero, we treat it as a failure -++ */ -++int mbtowc(wchar_t *pwc, const char *s, size_t n) -++{ -++ return (int)mbrtowc(pwc, s, n, NULL); -++} -++#endif -++#endif -++ -++/* The V100R001C01 version num is 0x5 (High 8 bits) */ -++#define SECUREC_C_VERSION 0x500U -++#define SECUREC_SPC_VERSION 0xbU -++#define SECUREC_VERSION_STR "V100R001C01SPC011B003" -++ -++/* -++ * Get version string and version number. -++ * The rules for version number are as follows: -++ * 1) SPC verNumber<->verStr like: -++ * 0x201<->C01 -++ * 0x202<->C01SPC001 Redefine numbers after this version -++ * 0x502<->C01SPC002 -++ * 0x503<->C01SPC003 -++ * ... -++ * 0X50a<->SPC010 -++ * 0X50b<->SPC011 -++ * ... -++ * 0x700<->C02 -++ * 0x701<->C01SPC001 -++ * 0x702<->C02SPC002 -++ * ... -++ * 2) CP verNumber<->verStr like: -++ * 0X601<->CP0001 -++ * 0X602<->CP0002 -++ * ... -++ */ -++const char *GetHwSecureCVersion(unsigned short *verNumber) -++{ -++ if (verNumber != NULL) { -++ *verNumber = (unsigned short)(SECUREC_C_VERSION | SECUREC_SPC_VERSION); -++ } -++ return SECUREC_VERSION_STR; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(GetHwSecureCVersion); -++#endif -++ -+diff --git a/lib/securec/src/securecutil.h b/lib/securec/src/securecutil.h -+new file mode 100755 -+index 000000000..35112a248 -+--- /dev/null -++++ b/lib/securec/src/securecutil.h -+@@ -0,0 +1,574 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: Define macro, data struct, and declare internal used function prototype, -++ * which is used by secure functions. -++ * Create: 2014-02-25 -++ */ -++ -++#ifndef SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F -++#define SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F -++#include "linux/securec.h" -++ -++#if (defined(_MSC_VER)) && (_MSC_VER >= 1400) -++/* Shield compilation alerts using discarded functions and Constant expression to maximize code compatibility */ -++#define SECUREC_MASK_MSVC_CRT_WARNING __pragma(warning(push)) \ -++ __pragma(warning(disable : 4996 4127)) -++#define SECUREC_END_MASK_MSVC_CRT_WARNING __pragma(warning(pop)) -++#else -++#define SECUREC_MASK_MSVC_CRT_WARNING -++#define SECUREC_END_MASK_MSVC_CRT_WARNING -++#endif -++#define SECUREC_WHILE_ZERO SECUREC_MASK_MSVC_CRT_WARNING while (0) SECUREC_END_MASK_MSVC_CRT_WARNING -++ -++/* Automatically identify the platform that supports strnlen function, and use this function to improve performance */ -++#ifndef SECUREC_HAVE_STRNLEN -++#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L) -++#if SECUREC_IN_KERNEL -++#define SECUREC_HAVE_STRNLEN 0 -++#else -++#if defined(__GLIBC__) && __GLIBC__ >= 2 && defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ >= 10 -++#define SECUREC_HAVE_STRNLEN 1 -++#else -++#define SECUREC_HAVE_STRNLEN 0 -++#endif -++#endif -++#else -++#define SECUREC_HAVE_STRNLEN 0 -++#endif -++#endif -++ -++#if SECUREC_IN_KERNEL -++/* In kernel disable functions */ -++#ifndef SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_SCANF_FILE 0 -++#endif -++#ifndef SECUREC_ENABLE_SCANF_FLOAT -++#define SECUREC_ENABLE_SCANF_FLOAT 0 -++#endif -++#ifndef SECUREC_ENABLE_SPRINTF_FLOAT -++#define SECUREC_ENABLE_SPRINTF_FLOAT 0 -++#endif -++#ifndef SECUREC_HAVE_MBTOWC -++#define SECUREC_HAVE_MBTOWC 0 -++#endif -++#ifndef SECUREC_HAVE_WCTOMB -++#define SECUREC_HAVE_WCTOMB 0 -++#endif -++#ifndef SECUREC_HAVE_WCHART -++#define SECUREC_HAVE_WCHART 0 -++#endif -++#else /* Not in kernel */ -++/* Systems that do not support file, can define this macro to 0. */ -++#ifndef SECUREC_ENABLE_SCANF_FILE -++#define SECUREC_ENABLE_SCANF_FILE 1 -++#endif -++#ifndef SECUREC_ENABLE_SCANF_FLOAT -++#define SECUREC_ENABLE_SCANF_FLOAT 0 -++#endif -++/* Systems that do not support float, can define this macro to 0. */ -++#ifndef SECUREC_ENABLE_SPRINTF_FLOAT -++#define SECUREC_ENABLE_SPRINTF_FLOAT 1 -++#endif -++#ifndef SECUREC_HAVE_MBTOWC -++#define SECUREC_HAVE_MBTOWC 0 -++#endif -++#ifndef SECUREC_HAVE_WCTOMB -++#define SECUREC_HAVE_WCTOMB 0 -++#endif -++#ifndef SECUREC_HAVE_WCHART -++#define SECUREC_HAVE_WCHART 1 -++#endif -++#endif -++ -++#ifndef SECUREC_ENABLE_INLINE -++#define SECUREC_ENABLE_INLINE 0 -++#endif -++ -++#ifndef SECUREC_INLINE -++#if SECUREC_ENABLE_INLINE -++#define SECUREC_INLINE static inline -++#else -++#define SECUREC_INLINE static -++#endif -++#endif -++ -++#ifndef SECUREC_WARP_OUTPUT -++#if SECUREC_IN_KERNEL -++#define SECUREC_WARP_OUTPUT 1 -++#else -++#define SECUREC_WARP_OUTPUT 0 -++#endif -++#endif -++ -++#ifndef SECUREC_STREAM_STDIN -++#define SECUREC_STREAM_STDIN stdin -++#endif -++ -++#define SECUREC_MUL_SIXTEEN(x) ((x) << 4U) -++#define SECUREC_MUL_EIGHT(x) ((x) << 3U) -++#define SECUREC_MUL_TEN(x) ((((x) << 2U) + (x)) << 1U) -++/* Limited format input and output width, use signed integer */ -++#define SECUREC_MAX_WIDTH_LEN_DIV_TEN 21474836 -++#define SECUREC_MAX_WIDTH_LEN (SECUREC_MAX_WIDTH_LEN_DIV_TEN * 10) -++/* Is the x multiplied by 10 greater than */ -++#define SECUREC_MUL_TEN_ADD_BEYOND_MAX(x) (((x) > SECUREC_MAX_WIDTH_LEN_DIV_TEN)) -++ -++#define SECUREC_FLOAT_BUFSIZE (309 + 40) /* Max length of double value */ -++#define SECUREC_FLOAT_BUFSIZE_LB (4932 + 40) /* Max length of long double value */ -++#define SECUREC_FLOAT_DEFAULT_PRECISION 6 -++ -++/* This macro does not handle pointer equality or integer overflow */ -++#define SECUREC_MEMORY_NO_OVERLAP(dest, src, count) \ -++ (((src) < (dest) && ((const char *)(src) + (count)) <= (char *)(dest)) || \ -++ ((dest) < (src) && ((char *)(dest) + (count)) <= (const char *)(src))) -++ -++#define SECUREC_MEMORY_IS_OVERLAP(dest, src, count) \ -++ (((src) < (dest) && ((const char *)(src) + (count)) > (char *)(dest)) || \ -++ ((dest) < (src) && ((char *)(dest) + (count)) > (const char *)(src))) -++ -++/* -++ * Check whether the strings overlap, len is the length of the string not include terminator -++ * Length is related to data type char or wchar , do not force conversion of types -++ */ -++#define SECUREC_STRING_NO_OVERLAP(dest, src, len) \ -++ (((src) < (dest) && ((src) + (len)) < (dest)) || \ -++ ((dest) < (src) && ((dest) + (len)) < (src))) -++ -++/* -++ * Check whether the strings overlap for strcpy wcscpy function, dest len and src Len are not include terminator -++ * Length is related to data type char or wchar , do not force conversion of types -++ */ -++#define SECUREC_STRING_IS_OVERLAP(dest, src, len) \ -++ (((src) < (dest) && ((src) + (len)) >= (dest)) || \ -++ ((dest) < (src) && ((dest) + (len)) >= (src))) -++ -++/* -++ * Check whether the strings overlap for strcat wcscat function, dest len and src Len are not include terminator -++ * Length is related to data type char or wchar , do not force conversion of types -++ */ -++#define SECUREC_CAT_STRING_IS_OVERLAP(dest, destLen, src, srcLen) \ -++ (((dest) < (src) && ((dest) + (destLen) + (srcLen)) >= (src)) || \ -++ ((src) < (dest) && ((src) + (srcLen)) >= (dest))) -++ -++#if SECUREC_HAVE_STRNLEN -++#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \ -++ *(outLen) = strnlen((str), (maxLen)); \ -++} SECUREC_WHILE_ZERO -++#define SECUREC_CALC_STR_LEN_OPT(str, maxLen, outLen) do { \ -++ if ((maxLen) > 8) { \ -++ /* Optimization or len less then 8 */ \ -++ if (*((str) + 0) == '\0') { \ -++ *(outLen) = 0; \ -++ } else if (*((str) + 1) == '\0') { \ -++ *(outLen) = 1; \ -++ } else if (*((str) + 2) == '\0') { \ -++ *(outLen) = 2; \ -++ } else if (*((str) + 3) == '\0') { \ -++ *(outLen) = 3; \ -++ } else if (*((str) + 4) == '\0') { \ -++ *(outLen) = 4; \ -++ } else if (*((str) + 5) == '\0') { \ -++ *(outLen) = 5; \ -++ } else if (*((str) + 6) == '\0') { \ -++ *(outLen) = 6; \ -++ } else if (*((str) + 7) == '\0') { \ -++ *(outLen) = 7; \ -++ } else if (*((str) + 8) == '\0') { \ -++ /* Optimization with a length of 8 */ \ -++ *(outLen) = 8; \ -++ } else { \ -++ /* The offset is 8 because the performance of 8 byte alignment is high */ \ -++ *(outLen) = 8 + strnlen((str) + 8, (maxLen) - 8); \ -++ } \ -++ } else { \ -++ SECUREC_CALC_STR_LEN((str), (maxLen), (outLen)); \ -++ } \ -++} SECUREC_WHILE_ZERO -++#else -++#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \ -++ const char *strEnd_ = (const char *)(str); \ -++ size_t availableSize_ = (size_t)(maxLen); \ -++ while (availableSize_ > 0 && *strEnd_ != '\0') { \ -++ --availableSize_; \ -++ ++strEnd_; \ -++ } \ -++ *(outLen) = (size_t)(strEnd_ - (str)); \ -++} SECUREC_WHILE_ZERO -++#define SECUREC_CALC_STR_LEN_OPT SECUREC_CALC_STR_LEN -++#endif -++ -++#define SECUREC_CALC_WSTR_LEN(str, maxLen, outLen) do { \ -++ const wchar_t *strEnd_ = (const wchar_t *)(str); \ -++ size_t len_ = 0; \ -++ while (len_ < (maxLen) && *strEnd_ != L'\0') { \ -++ ++len_; \ -++ ++strEnd_; \ -++ } \ -++ *(outLen) = len_; \ -++} SECUREC_WHILE_ZERO -++ -++/* -++ * Performance optimization, product may disable inline function. -++ * Using function pointer for MEMSET to prevent compiler optimization when cleaning up memory. -++ */ -++#ifdef SECUREC_USE_ASM -++#define SECUREC_MEMSET_FUNC_OPT memset_opt -++#define SECUREC_MEMCPY_FUNC_OPT memcpy_opt -++#else -++#define SECUREC_MEMSET_FUNC_OPT memset -++#define SECUREC_MEMCPY_FUNC_OPT memcpy -++#endif -++ -++#define SECUREC_MEMCPY_WARP_OPT(dest, src, count) (void)SECUREC_MEMCPY_FUNC_OPT((dest), (src), (count)) -++ -++#ifndef SECUREC_MEMSET_BARRIER -++#if defined(__GNUC__) -++/* Can be turned off for scenarios that do not use memory barrier */ -++#define SECUREC_MEMSET_BARRIER 1 -++#else -++#define SECUREC_MEMSET_BARRIER 0 -++#endif -++#endif -++ -++#ifndef SECUREC_MEMSET_INDIRECT_USE -++/* Can be turned off for scenarios that do not allow pointer calls */ -++#define SECUREC_MEMSET_INDIRECT_USE 1 -++#endif -++ -++#if SECUREC_MEMSET_BARRIER -++#define SECUREC_MEMORY_BARRIER(dest) __asm__ __volatile__("": : "r"(dest) : "memory") -++#else -++#define SECUREC_MEMORY_BARRIER(dest) -++#endif -++ -++#if SECUREC_MEMSET_BARRIER -++#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) do { \ -++ (void)SECUREC_MEMSET_FUNC_OPT(dest, value, count); \ -++ SECUREC_MEMORY_BARRIER(dest); \ -++} SECUREC_WHILE_ZERO -++#elif SECUREC_MEMSET_INDIRECT_USE -++#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) do { \ -++ void *(* const volatile fn_)(void *s_, int c_, size_t n_) = SECUREC_MEMSET_FUNC_OPT; \ -++ (void)(*fn_)((dest), (value), (count)); \ -++} SECUREC_WHILE_ZERO -++#else -++#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count) (void)SECUREC_MEMSET_FUNC_OPT((dest), (value), (count)) -++#endif -++ -++#ifdef SECUREC_FORMAT_OUTPUT_INPUT -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) || defined(__ARMCC_VERSION) -++typedef __int64 SecInt64; -++typedef unsigned __int64 SecUnsignedInt64; -++#if defined(__ARMCC_VERSION) -++typedef unsigned int SecUnsignedInt32; -++#else -++typedef unsigned __int32 SecUnsignedInt32; -++#endif -++#else -++typedef unsigned int SecUnsignedInt32; -++typedef long long SecInt64; -++typedef unsigned long long SecUnsignedInt64; -++#endif -++ -++#ifdef SECUREC_FOR_WCHAR -++#if 1//defined(SECUREC_VXWORKS_PLATFORM) && !defined(__WINT_TYPE__) -++typedef wchar_t wint_t; -++#endif -++#ifndef WEOF -++#define WEOF ((wchar_t)(-1)) -++#endif -++#define SECUREC_CHAR(x) L ## x -++typedef wchar_t SecChar; -++typedef wchar_t SecUnsignedChar; -++typedef wint_t SecInt; -++typedef wint_t SecUnsignedInt; -++#else /* no SECUREC_FOR_WCHAR */ -++#define SECUREC_CHAR(x) (x) -++typedef char SecChar; -++typedef unsigned char SecUnsignedChar; -++typedef int SecInt; -++typedef unsigned int SecUnsignedInt; -++#endif -++#endif -++ -++/* -++ * Determine whether the address is 8-byte aligned -++ * Some systems do not have uintptr_t type, so use NULL to clear tool alarm 507 -++ */ -++#define SECUREC_ADDR_ALIGNED_8(addr) ((((size_t)(addr)) & 7U) == 0) /* Use 7 to check aligned 8 */ -++ -++/* -++ * If you define the memory allocation function, you need to define the function prototype. -++ * You can define this macro as a header file. -++ */ -++#if defined(SECUREC_MALLOC_PROTOTYPE) -++SECUREC_MALLOC_PROTOTYPE -++#endif -++ -++#ifndef SECUREC_MALLOC -++#define SECUREC_MALLOC(x) malloc((size_t)(x)) -++#endif -++ -++#ifndef SECUREC_FREE -++#define SECUREC_FREE(x) free((void *)(x)) -++#endif -++ -++/* Improve performance with struct assignment, buf1 is not defined to avoid tool false positive */ -++#define SECUREC_COPY_VALUE_BY_STRUCT(dest, src, n) do { \ -++ *(SecStrBuf##n *)(void *)(dest) = *(const SecStrBuf##n *)(const void *)(src); \ -++} SECUREC_WHILE_ZERO -++ -++typedef struct { -++ unsigned char buf[2]; /* Performance optimization code structure assignment length 2 bytes */ -++} SecStrBuf2; -++typedef struct { -++ unsigned char buf[3]; /* Performance optimization code structure assignment length 3 bytes */ -++} SecStrBuf3; -++typedef struct { -++ unsigned char buf[4]; /* Performance optimization code structure assignment length 4 bytes */ -++} SecStrBuf4; -++typedef struct { -++ unsigned char buf[5]; /* Performance optimization code structure assignment length 5 bytes */ -++} SecStrBuf5; -++typedef struct { -++ unsigned char buf[6]; /* Performance optimization code structure assignment length 6 bytes */ -++} SecStrBuf6; -++typedef struct { -++ unsigned char buf[7]; /* Performance optimization code structure assignment length 7 bytes */ -++} SecStrBuf7; -++typedef struct { -++ unsigned char buf[8]; /* Performance optimization code structure assignment length 8 bytes */ -++} SecStrBuf8; -++typedef struct { -++ unsigned char buf[9]; /* Performance optimization code structure assignment length 9 bytes */ -++} SecStrBuf9; -++typedef struct { -++ unsigned char buf[10]; /* Performance optimization code structure assignment length 10 bytes */ -++} SecStrBuf10; -++typedef struct { -++ unsigned char buf[11]; /* Performance optimization code structure assignment length 11 bytes */ -++} SecStrBuf11; -++typedef struct { -++ unsigned char buf[12]; /* Performance optimization code structure assignment length 12 bytes */ -++} SecStrBuf12; -++typedef struct { -++ unsigned char buf[13]; /* Performance optimization code structure assignment length 13 bytes */ -++} SecStrBuf13; -++typedef struct { -++ unsigned char buf[14]; /* Performance optimization code structure assignment length 14 bytes */ -++} SecStrBuf14; -++typedef struct { -++ unsigned char buf[15]; /* Performance optimization code structure assignment length 15 bytes */ -++} SecStrBuf15; -++typedef struct { -++ unsigned char buf[16]; /* Performance optimization code structure assignment length 16 bytes */ -++} SecStrBuf16; -++typedef struct { -++ unsigned char buf[17]; /* Performance optimization code structure assignment length 17 bytes */ -++} SecStrBuf17; -++typedef struct { -++ unsigned char buf[18]; /* Performance optimization code structure assignment length 18 bytes */ -++} SecStrBuf18; -++typedef struct { -++ unsigned char buf[19]; /* Performance optimization code structure assignment length 19 bytes */ -++} SecStrBuf19; -++typedef struct { -++ unsigned char buf[20]; /* Performance optimization code structure assignment length 20 bytes */ -++} SecStrBuf20; -++typedef struct { -++ unsigned char buf[21]; /* Performance optimization code structure assignment length 21 bytes */ -++} SecStrBuf21; -++typedef struct { -++ unsigned char buf[22]; /* Performance optimization code structure assignment length 22 bytes */ -++} SecStrBuf22; -++typedef struct { -++ unsigned char buf[23]; /* Performance optimization code structure assignment length 23 bytes */ -++} SecStrBuf23; -++typedef struct { -++ unsigned char buf[24]; /* Performance optimization code structure assignment length 24 bytes */ -++} SecStrBuf24; -++typedef struct { -++ unsigned char buf[25]; /* Performance optimization code structure assignment length 25 bytes */ -++} SecStrBuf25; -++typedef struct { -++ unsigned char buf[26]; /* Performance optimization code structure assignment length 26 bytes */ -++} SecStrBuf26; -++typedef struct { -++ unsigned char buf[27]; /* Performance optimization code structure assignment length 27 bytes */ -++} SecStrBuf27; -++typedef struct { -++ unsigned char buf[28]; /* Performance optimization code structure assignment length 28 bytes */ -++} SecStrBuf28; -++typedef struct { -++ unsigned char buf[29]; /* Performance optimization code structure assignment length 29 bytes */ -++} SecStrBuf29; -++typedef struct { -++ unsigned char buf[30]; /* Performance optimization code structure assignment length 30 bytes */ -++} SecStrBuf30; -++typedef struct { -++ unsigned char buf[31]; /* Performance optimization code structure assignment length 31 bytes */ -++} SecStrBuf31; -++typedef struct { -++ unsigned char buf[32]; /* Performance optimization code structure assignment length 32 bytes */ -++} SecStrBuf32; -++typedef struct { -++ unsigned char buf[33]; /* Performance optimization code structure assignment length 33 bytes */ -++} SecStrBuf33; -++typedef struct { -++ unsigned char buf[34]; /* Performance optimization code structure assignment length 34 bytes */ -++} SecStrBuf34; -++typedef struct { -++ unsigned char buf[35]; /* Performance optimization code structure assignment length 35 bytes */ -++} SecStrBuf35; -++typedef struct { -++ unsigned char buf[36]; /* Performance optimization code structure assignment length 36 bytes */ -++} SecStrBuf36; -++typedef struct { -++ unsigned char buf[37]; /* Performance optimization code structure assignment length 37 bytes */ -++} SecStrBuf37; -++typedef struct { -++ unsigned char buf[38]; /* Performance optimization code structure assignment length 38 bytes */ -++} SecStrBuf38; -++typedef struct { -++ unsigned char buf[39]; /* Performance optimization code structure assignment length 39 bytes */ -++} SecStrBuf39; -++typedef struct { -++ unsigned char buf[40]; /* Performance optimization code structure assignment length 40 bytes */ -++} SecStrBuf40; -++typedef struct { -++ unsigned char buf[41]; /* Performance optimization code structure assignment length 41 bytes */ -++} SecStrBuf41; -++typedef struct { -++ unsigned char buf[42]; /* Performance optimization code structure assignment length 42 bytes */ -++} SecStrBuf42; -++typedef struct { -++ unsigned char buf[43]; /* Performance optimization code structure assignment length 43 bytes */ -++} SecStrBuf43; -++typedef struct { -++ unsigned char buf[44]; /* Performance optimization code structure assignment length 44 bytes */ -++} SecStrBuf44; -++typedef struct { -++ unsigned char buf[45]; /* Performance optimization code structure assignment length 45 bytes */ -++} SecStrBuf45; -++typedef struct { -++ unsigned char buf[46]; /* Performance optimization code structure assignment length 46 bytes */ -++} SecStrBuf46; -++typedef struct { -++ unsigned char buf[47]; /* Performance optimization code structure assignment length 47 bytes */ -++} SecStrBuf47; -++typedef struct { -++ unsigned char buf[48]; /* Performance optimization code structure assignment length 48 bytes */ -++} SecStrBuf48; -++typedef struct { -++ unsigned char buf[49]; /* Performance optimization code structure assignment length 49 bytes */ -++} SecStrBuf49; -++typedef struct { -++ unsigned char buf[50]; /* Performance optimization code structure assignment length 50 bytes */ -++} SecStrBuf50; -++typedef struct { -++ unsigned char buf[51]; /* Performance optimization code structure assignment length 51 bytes */ -++} SecStrBuf51; -++typedef struct { -++ unsigned char buf[52]; /* Performance optimization code structure assignment length 52 bytes */ -++} SecStrBuf52; -++typedef struct { -++ unsigned char buf[53]; /* Performance optimization code structure assignment length 53 bytes */ -++} SecStrBuf53; -++typedef struct { -++ unsigned char buf[54]; /* Performance optimization code structure assignment length 54 bytes */ -++} SecStrBuf54; -++typedef struct { -++ unsigned char buf[55]; /* Performance optimization code structure assignment length 55 bytes */ -++} SecStrBuf55; -++typedef struct { -++ unsigned char buf[56]; /* Performance optimization code structure assignment length 56 bytes */ -++} SecStrBuf56; -++typedef struct { -++ unsigned char buf[57]; /* Performance optimization code structure assignment length 57 bytes */ -++} SecStrBuf57; -++typedef struct { -++ unsigned char buf[58]; /* Performance optimization code structure assignment length 58 bytes */ -++} SecStrBuf58; -++typedef struct { -++ unsigned char buf[59]; /* Performance optimization code structure assignment length 59 bytes */ -++} SecStrBuf59; -++typedef struct { -++ unsigned char buf[60]; /* Performance optimization code structure assignment length 60 bytes */ -++} SecStrBuf60; -++typedef struct { -++ unsigned char buf[61]; /* Performance optimization code structure assignment length 61 bytes */ -++} SecStrBuf61; -++typedef struct { -++ unsigned char buf[62]; /* Performance optimization code structure assignment length 62 bytes */ -++} SecStrBuf62; -++typedef struct { -++ unsigned char buf[63]; /* Performance optimization code structure assignment length 63 bytes */ -++} SecStrBuf63; -++typedef struct { -++ unsigned char buf[64]; /* Performance optimization code structure assignment length 64 bytes */ -++} SecStrBuf64; -++ -++/* -++ * User can change the error handler by modify the following definition, -++ * such as logging the detail error in file. -++ */ -++#if defined(_DEBUG) || defined(DEBUG) -++#if defined(SECUREC_ERROR_HANDLER_BY_ASSERT) -++#define SECUREC_ERROR_INVALID_PARAMTER(msg) assert(msg "invalid argument" == NULL) -++#define SECUREC_ERROR_INVALID_RANGE(msg) assert(msg "invalid dest buffer size" == NULL) -++#define SECUREC_ERROR_BUFFER_OVERLAP(msg) assert(msg "buffer overlap" == NULL) -++#elif defined(SECUREC_ERROR_HANDLER_BY_PRINTF) -++#if SECUREC_IN_KERNEL -++#define SECUREC_ERROR_INVALID_PARAMTER(msg) printk("%s invalid argument\n", msg) -++#define SECUREC_ERROR_INVALID_RANGE(msg) printk("%s invalid dest buffer size\n", msg) -++#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printk("%s buffer overlap\n", msg) -++#else -++#define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg) -++#define SECUREC_ERROR_INVALID_RANGE(msg) printf("%s invalid dest buffer size\n", msg) -++#define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg) -++#endif -++#elif defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) -++#define SECUREC_ERROR_INVALID_PARAMTER(msg) LogSecureCRuntimeError(msg " EINVAL\n") -++#define SECUREC_ERROR_INVALID_RANGE(msg) LogSecureCRuntimeError(msg " ERANGE\n") -++#define SECUREC_ERROR_BUFFER_OVERLAP(msg) LogSecureCRuntimeError(msg " EOVERLAP\n") -++#endif -++#endif -++ -++/* Default handler is none */ -++#ifndef SECUREC_ERROR_INVALID_PARAMTER -++#define SECUREC_ERROR_INVALID_PARAMTER(msg) -++#endif -++#ifndef SECUREC_ERROR_INVALID_RANGE -++#define SECUREC_ERROR_INVALID_RANGE(msg) -++#endif -++#ifndef SECUREC_ERROR_BUFFER_OVERLAP -++#define SECUREC_ERROR_BUFFER_OVERLAP(msg) -++#endif -++ -++#ifdef __cplusplus -++extern "C" { -++#endif -++ -++/* Assembly language memory copy and memory set for X86 or MIPS ... */ -++#ifdef SECUREC_USE_ASM -++void *memcpy_opt(void *dest, const void *src, size_t n); -++void *memset_opt(void *s, int c, size_t n); -++#endif -++ -++#if defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG) -++void LogSecureCRuntimeError(const char *errDetail); -++#endif -++ -++#ifdef __cplusplus -++} -++#endif /* __cplusplus */ -++#endif -++ -+diff --git a/lib/securec/src/secureinput_a.c b/lib/securec/src/secureinput_a.c -+new file mode 100755 -+index 000000000..e79868f45 -+--- /dev/null -++++ b/lib/securec/src/secureinput_a.c -+@@ -0,0 +1,38 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: By defining data type for ANSI string and including "input.inl", -++ * this file generates real underlying function used by scanf family API. -++ * Create: 2014-02-25 -++ */ -++ -++#define SECUREC_FORMAT_OUTPUT_INPUT 1 -++#ifdef SECUREC_FOR_WCHAR -++#undef SECUREC_FOR_WCHAR -++#endif -++ -++#include "secinput.h" -++ -++#include "input.inl" -++ -++SECUREC_INLINE int SecIsDigit(SecInt ch) -++{ -++ /* SecInt to unsigned char clear 571, use bit mask to clear negative return of ch */ -++ return isdigit((int)((unsigned int)(unsigned char)(ch) & 0xffU)); -++} -++SECUREC_INLINE int SecIsXdigit(SecInt ch) -++{ -++ return isxdigit((int)((unsigned int)(unsigned char)(ch) & 0xffU)); -++} -++SECUREC_INLINE int SecIsSpace(SecInt ch) -++{ -++ return isspace((int)((unsigned int)(unsigned char)(ch) & 0xffU)); -++} -++ -+diff --git a/lib/securec/src/secureprintoutput.h b/lib/securec/src/secureprintoutput.h -+new file mode 100755 -+index 000000000..a00b10dff -+--- /dev/null -++++ b/lib/securec/src/secureprintoutput.h -+@@ -0,0 +1,146 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: Define macro, enum, data struct, and declare internal used function -++ * prototype, which is used by output.inl, secureprintoutput_w.c and -++ * secureprintoutput_a.c. -++ * Create: 2014-02-25 -++ */ -++ -++#ifndef SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C -++#define SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C -++#include "securecutil.h" -++ -++/* Shield compilation alerts about using sprintf without format attribute to format float value. */ -++#ifndef SECUREC_HANDLE_WFORMAT -++#define SECUREC_HANDLE_WFORMAT 1 -++#endif -++ -++#if SECUREC_HANDLE_WFORMAT && defined(__GNUC__) && ((__GNUC__ >= 5) || \ -++ (defined(__GNUC_MINOR__) && (__GNUC__ == 4 && __GNUC_MINOR__ > 7))) -++#if defined(__clang__) -++#define SECUREC_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic push") \ -++ _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") -++#else -++#define SECUREC_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic push") \ -++ _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") \ -++ _Pragma("GCC diagnostic ignored \"-Wmissing-format-attribute\"") \ -++ _Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"") -++#endif -++#define SECUREC_END_MASK_WFORMAT_WARNING _Pragma("GCC diagnostic pop") -++#else -++#define SECUREC_MASK_WFORMAT_WARNING -++#define SECUREC_END_MASK_WFORMAT_WARNING -++#endif -++ -++#define SECUREC_MASK_VSPRINTF_WARNING SECUREC_MASK_WFORMAT_WARNING \ -++ SECUREC_MASK_MSVC_CRT_WARNING -++ -++#define SECUREC_END_MASK_VSPRINTF_WARNING SECUREC_END_MASK_WFORMAT_WARNING \ -++ SECUREC_END_MASK_MSVC_CRT_WARNING -++ -++/* -++ * Flag definitions. -++ * Using macros instead of enumerations is because some of the enumerated types under the compiler are 16bit. -++ */ -++#define SECUREC_FLAG_SIGN 0x00001U -++#define SECUREC_FLAG_SIGN_SPACE 0x00002U -++#define SECUREC_FLAG_LEFT 0x00004U -++#define SECUREC_FLAG_LEADZERO 0x00008U -++#define SECUREC_FLAG_LONG 0x00010U -++#define SECUREC_FLAG_SHORT 0x00020U -++#define SECUREC_FLAG_SIGNED 0x00040U -++#define SECUREC_FLAG_ALTERNATE 0x00080U -++#define SECUREC_FLAG_NEGATIVE 0x00100U -++#define SECUREC_FLAG_FORCE_OCTAL 0x00200U -++#define SECUREC_FLAG_LONG_DOUBLE 0x00400U -++#define SECUREC_FLAG_WIDECHAR 0x00800U -++#define SECUREC_FLAG_LONGLONG 0x01000U -++#define SECUREC_FLAG_CHAR 0x02000U -++#define SECUREC_FLAG_POINTER 0x04000U -++#define SECUREC_FLAG_I64 0x08000U -++#define SECUREC_FLAG_PTRDIFF 0x10000U -++#define SECUREC_FLAG_SIZE 0x20000U -++#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT -++#define SECUREC_FLAG_INTMAX 0x40000U -++#endif -++ -++/* State definitions. Identify the status of the current format */ -++typedef enum { -++ STAT_NORMAL, -++ STAT_PERCENT, -++ STAT_FLAG, -++ STAT_WIDTH, -++ STAT_DOT, -++ STAT_PRECIS, -++ STAT_SIZE, -++ STAT_TYPE, -++ STAT_INVALID -++} SecFmtState; -++ -++#ifndef SECUREC_BUFFER_SIZE -++#if SECUREC_IN_KERNEL -++#define SECUREC_BUFFER_SIZE 32 -++#elif defined(SECUREC_STACK_SIZE_LESS_THAN_1K) -++/* -++ * SECUREC BUFFER SIZE Can not be less than 23 -++ * The length of the octal representation of 64-bit integers with zero lead -++ */ -++#define SECUREC_BUFFER_SIZE 256 -++#else -++#define SECUREC_BUFFER_SIZE 512 -++#endif -++#endif -++#if SECUREC_BUFFER_SIZE < 23 -++#error SECUREC_BUFFER_SIZE Can not be less than 23 -++#endif -++/* Buffer size for wchar, use 4 to make the compiler aligns as 8 bytes as possible */ -++#define SECUREC_WCHAR_BUFFER_SIZE 4 -++ -++#define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE -++/* Max. # bytes in multibyte char,see MB_LEN_MAX */ -++#define SECUREC_MB_LEN 16 -++/* The return value of the internal function, which is returned when truncated */ -++#define SECUREC_PRINTF_TRUNCATE (-2) -++ -++#define SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, maxLimit) \ -++ ((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) -++ -++#define SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, maxLimit) do { \ -++ if ((strDest) != NULL && (destMax) > 0 && (destMax) <= (maxLimit)) { \ -++ *(strDest) = '\0'; \ -++ } \ -++} SECUREC_WHILE_ZERO -++ -++#ifdef SECUREC_COMPATIBLE_WIN_FORMAT -++#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \ -++ (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \ -++ ((count) > (SECUREC_STRING_MAX_LEN - 1) && (count) != (size_t)(-1))) -++ -++#else -++#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \ -++ (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \ -++ ((count) > (SECUREC_STRING_MAX_LEN - 1))) -++#endif -++ -++#ifdef __cplusplus -++extern "C" { -++#endif -++#ifdef SECUREC_FOR_WCHAR -++int SecVswprintfImpl(wchar_t *string, size_t count, const wchar_t *format, va_list argList); -++#else -++int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList); -++#endif -++#ifdef __cplusplus -++} -++#endif -++ -++#endif -++ -+diff --git a/lib/securec/src/secureprintoutput_a.c b/lib/securec/src/secureprintoutput_a.c -+new file mode 100755 -+index 000000000..b2b4b6a65 -+--- /dev/null -++++ b/lib/securec/src/secureprintoutput_a.c -+@@ -0,0 +1,112 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: By defining corresponding macro for ANSI string and including "output.inl", -++ * this file generates real underlying function used by printf family API. -++ * Create: 2014-02-25 -++ */ -++ -++#define SECUREC_FORMAT_OUTPUT_INPUT 1 -++ -++#ifdef SECUREC_FOR_WCHAR -++#undef SECUREC_FOR_WCHAR -++#endif -++ -++#include "secureprintoutput.h" -++#if SECUREC_WARP_OUTPUT -++#define SECUREC_FORMAT_FLAG_TABLE_SIZE 128 -++SECUREC_INLINE const char *SecSkipKnownFlags(const char *format) -++{ -++ static const unsigned char flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = { -++ /* -++ * Known flag is "0123456789 +-#hlLwZzjqt*I$" -++ */ -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, -++ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, -++ 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 -++ }; -++ const char *fmt = format; -++ while (*fmt != '\0') { -++ char fmtChar = *fmt; -++ if ((unsigned char)fmtChar > 0x7f) { /* 0x7f is upper limit of format char value */ -++ break; -++ } -++ if (flagTable[(unsigned char)fmtChar] == 0) { -++ break; -++ } -++ ++fmt; -++ } -++ return fmt; -++} -++ -++SECUREC_INLINE int SecFormatContainN(const char *format) -++{ -++ const char *fmt = format; -++ while (*fmt != '\0') { -++ ++fmt; -++ /* Skip normal char */ -++ if (*(fmt - 1) != '%') { -++ continue; -++ } -++ /* Meet %% */ -++ if (*fmt == '%') { -++ ++fmt; /* Point to the character after the %. Correct handling %%xx */ -++ continue; -++ } -++ /* Now parse %..., fmt point to the character after the % */ -++ fmt = SecSkipKnownFlags(fmt); -++ if (*fmt == 'n') { -++ return 1; -++ } -++ } -++ return 0; -++} -++/* -++ * Multi character formatted output implementation, the count include \0 character, must be greater than zero -++ */ -++int SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList) -++{ -++ int retVal; -++ if (SecFormatContainN(format) != 0) { -++ string[0] = '\0'; -++ return -1; -++ } -++ SECUREC_MASK_VSPRINTF_WARNING -++ retVal = vsnprintf(string, count, format, argList); -++ SECUREC_END_MASK_VSPRINTF_WARNING -++ if (retVal >= (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */ -++ /* The buffer was too small; we return truncation */ -++ string[count - 1] = '\0'; -++ return SECUREC_PRINTF_TRUNCATE; -++ } -++ if (retVal < 0) { -++ string[0] = '\0'; /* Empty the dest strDest */ -++ return -1; -++ } -++ return retVal; -++} -++#else -++#if SECUREC_IN_KERNEL -++#include -++#endif -++ -++#ifndef EOF -++#define EOF (-1) -++#endif -++ -++#include "output.inl" -++ -++#endif -++ -+diff --git a/lib/securec/src/snprintf_s.c b/lib/securec/src/snprintf_s.c -+new file mode 100755 -+index 000000000..ec18328e3 -+--- /dev/null -++++ b/lib/securec/src/snprintf_s.c -+@@ -0,0 +1,110 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: snprintf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "linux/securec.h" -++ -++#if SECUREC_ENABLE_SNPRINTF -++/* -++ * -++ * The snprintf_s function is equivalent to the snprintf function -++ * except for the parameter destMax/count and the explicit runtime-constraints violation -++ * The snprintf_s function formats and stores count or fewer characters in -++ * strDest and appends a terminating null. Each argument (if any) is converted -++ * and output according to the corresponding format specification in format. -++ * The formatting is consistent with the printf family of functions; If copying -++ * occurs between strings that overlap, the behavior is undefined. -++ * -++ * -++ * strDest Storage location for the output. -++ * destMax The size of the storage location for output. Size -++ * in bytes for snprintf_s or size in words for snwprintf_s. -++ * count Maximum number of character to store. -++ * format Format-control string. -++ * ... Optional arguments. -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * return the number of characters written, not including the terminating null -++ * return -1 if an error occurs. -++ * return -1 if count < destMax and the output string has been truncated -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ * -++ */ -++int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, ...) -++{ -++ int ret; /* If initialization causes e838 */ -++ va_list argList; -++ -++ va_start(argList, format); -++ ret = vsnprintf_s(strDest, destMax, count, format, argList); -++ va_end(argList); -++ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ -++ return ret; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(snprintf_s); -++#endif -++#endif -++ -++#if SECUREC_SNPRINTF_TRUNCATED -++/* -++ * -++ * The snprintf_truncated_s function is equivalent to the snprintf function -++ * except for the parameter destMax/count and the explicit runtime-constraints violation -++ * The snprintf_truncated_s function formats and stores count or fewer characters in -++ * strDest and appends a terminating null. Each argument (if any) is converted -++ * and output according to the corresponding format specification in format. -++ * The formatting is consistent with the printf family of functions; If copying -++ * occurs between strings that overlap, the behavior is undefined. -++ * -++ * -++ * strDest Storage location for the output. -++ * destMax The size of the storage location for output. Size -++ * in bytes for snprintf_truncated_s or size in words for snwprintf_s. -++ * format Format-control string. -++ * ... Optional arguments. -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * return the number of characters written, not including the terminating null -++ * return -1 if an error occurs. -++ * return destMax-1 if output string has been truncated -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ * -++ */ -++int snprintf_truncated_s(char *strDest, size_t destMax, const char *format, ...) -++{ -++ int ret; /* If initialization causes e838 */ -++ va_list argList; -++ -++ va_start(argList, format); -++ ret = vsnprintf_truncated_s(strDest, destMax, format, argList); -++ va_end(argList); -++ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ -++ return ret; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(snprintf_truncated_s); -++#endif -++ -++#endif -++ -+diff --git a/lib/securec/src/sprintf_s.c b/lib/securec/src/sprintf_s.c -+new file mode 100755 -+index 000000000..1f25f8399 -+--- /dev/null -++++ b/lib/securec/src/sprintf_s.c -+@@ -0,0 +1,58 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: sprintf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "linux/securec.h" -++ -++/* -++ * -++ * The sprintf_s function is equivalent to the sprintf function -++ * except for the parameter destMax and the explicit runtime-constraints violation -++ * The sprintf_s function formats and stores a series of characters and values -++ * in strDest. Each argument (if any) is converted and output according to -++ * the corresponding format specification in format. The format consists of -++ * ordinary characters and has the same form and function as the format argument -++ * for printf. A null character is appended after the last character written. -++ * If copying occurs between strings that overlap, the behavior is undefined. -++ * -++ * -++ * strDest Storage location for output. -++ * destMax Maximum number of characters to store. -++ * format Format-control string. -++ * ... Optional arguments -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * return the number of bytes stored in strDest, not counting the terminating null character. -++ * return -1 if an error occurred. -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++int sprintf_s(char *strDest, size_t destMax, const char *format, ...) -++{ -++ int ret; /* If initialization causes e838 */ -++ va_list argList; -++ -++ va_start(argList, format); -++ ret = vsprintf_s(strDest, destMax, format, argList); -++ va_end(argList); -++ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ -++ return ret; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(sprintf_s); -++#endif -++ -+diff --git a/lib/securec/src/sscanf_s.c b/lib/securec/src/sscanf_s.c -+new file mode 100755 -+index 000000000..a8141ed25 -+--- /dev/null -++++ b/lib/securec/src/sscanf_s.c -+@@ -0,0 +1,58 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: sscanf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "linux/securec.h" -++ -++/* -++ * -++ * The sscanf_s function is equivalent to fscanf_s, -++ * except that input is obtained from a string (specified by the argument buffer) rather than from a stream -++ * The sscanf function reads data from buffer into the location given by each -++ * argument. Every argument must be a pointer to a variable with a type that -++ * corresponds to a type specifier in format. The format argument controls the -++ * interpretation of the input fields and has the same form and function as -++ * the format argument for the scanf function. -++ * If copying takes place between strings that overlap, the behavior is undefined. -++ * -++ * -++ * buffer Stored data. -++ * format Format control string, see Format Specifications. -++ * ... Optional arguments. -++ * -++ * -++ * ... The converted value stored in user assigned address -++ * -++ * -++ * Each of these functions returns the number of fields successfully converted -++ * and assigned; the return value does not include fields that were read but -++ * not assigned. -++ * A return value of 0 indicates that no fields were assigned. -++ * return -1 if an error occurs. -++ */ -++int sscanf_s(const char *buffer, const char *format, ...) -++{ -++ int ret; /* If initialization causes e838 */ -++ va_list argList; -++ -++ va_start(argList, format); -++ ret = vsscanf_s(buffer, format, argList); -++ va_end(argList); -++ (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */ -++ -++ return ret; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(sscanf_s); -++#endif -++ -+diff --git a/lib/securec/src/strcat_s.c b/lib/securec/src/strcat_s.c -+new file mode 100755 -+index 000000000..f835e7bc9 -+--- /dev/null -++++ b/lib/securec/src/strcat_s.c -+@@ -0,0 +1,101 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: strcat_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "securecutil.h" -++ -++/* -++ * Befor this function, the basic parameter checking has been done -++ */ -++SECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax, const char *strSrc) -++{ -++ size_t destLen; -++ size_t srcLen; -++ size_t maxSrcLen; -++ SECUREC_CALC_STR_LEN(strDest, destMax, &destLen); -++ /* Only optimize strSrc, do not apply this function to strDest */ -++ maxSrcLen = destMax - destLen; -++ SECUREC_CALC_STR_LEN_OPT(strSrc, maxSrcLen, &srcLen); -++ -++ if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { -++ strDest[0] = '\0'; -++ if (strDest + destLen <= strSrc && destLen == destMax) { -++ SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); -++ return EINVAL_AND_RESET; -++ } -++ SECUREC_ERROR_BUFFER_OVERLAP("strcat_s"); -++ return EOVERLAP_AND_RESET; -++ } -++ if (srcLen + destLen >= destMax || strDest == strSrc) { -++ strDest[0] = '\0'; -++ if (destLen == destMax) { -++ SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); -++ return EINVAL_AND_RESET; -++ } -++ SECUREC_ERROR_INVALID_RANGE("strcat_s"); -++ return ERANGE_AND_RESET; -++ } -++ SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen + 1); /* Single character length include \0 */ -++ return EOK; -++} -++ -++/* -++ * -++ * The strcat_s function appends a copy of the string pointed to by strSrc (including the terminating null character) -++ * to the end of the string pointed to by strDest. -++ * The initial character of strSrc overwrites the terminating null character of strDest. -++ * strcat_s will return EOVERLAP_AND_RESET if the source and destination strings overlap. -++ * -++ * Note that the second parameter is the total size of the buffer, not the -++ * remaining size. -++ * -++ * -++ * strDest Null-terminated destination string buffer. -++ * destMax Size of the destination string buffer. -++ * strSrc Null-terminated source string buffer. -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * EOK Success -++ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN -++ * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid) or -++ * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN) -++ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN -++ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap -++ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc) -++{ -++ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { -++ SECUREC_ERROR_INVALID_RANGE("strcat_s"); -++ return ERANGE; -++ } -++ if (strDest == NULL || strSrc == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("strcat_s"); -++ if (strDest != NULL) { -++ strDest[0] = '\0'; -++ return EINVAL_AND_RESET; -++ } -++ return EINVAL; -++ } -++ return SecDoCat(strDest, destMax, strSrc); -++} -++ -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(strcat_s); -++#endif -++ -+diff --git a/lib/securec/src/strcpy_s.c b/lib/securec/src/strcpy_s.c -+new file mode 100755 -+index 000000000..ca1b2ddb1 -+--- /dev/null -++++ b/lib/securec/src/strcpy_s.c -+@@ -0,0 +1,353 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: strcpy_s function -++ * Create: 2014-02-25 -++ */ -++/* -++ * [Standardize-exceptions] Use unsafe function: Performance-sensitive -++ * [reason] Always used in the performance critical path, -++ * and sufficient input validation is performed before calling -++ */ -++ -++#include "securecutil.h" -++ -++#ifndef SECUREC_STRCPY_WITH_PERFORMANCE -++#define SECUREC_STRCPY_WITH_PERFORMANCE 1 -++#endif -++ -++#define SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc) ((destMax) > 0 && \ -++ (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && (strDest) != (strSrc)) -++ -++#if (!SECUREC_IN_KERNEL) && SECUREC_STRCPY_WITH_PERFORMANCE -++#ifndef SECUREC_STRCOPY_THRESHOLD_SIZE -++#define SECUREC_STRCOPY_THRESHOLD_SIZE 32UL -++#endif -++/* The purpose of converting to void is to clean up the alarm */ -++#define SECUREC_SMALL_STR_COPY(strDest, strSrc, lenWithTerm) do { \ -++ if (SECUREC_ADDR_ALIGNED_8(strDest) && SECUREC_ADDR_ALIGNED_8(strSrc)) { \ -++ /* Use struct assignment */ \ -++ switch (lenWithTerm) { \ -++ case 1: \ -++ *(strDest) = *(strSrc); \ -++ break; \ -++ case 2: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 2); \ -++ break; \ -++ case 3: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 3); \ -++ break; \ -++ case 4: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 4); \ -++ break; \ -++ case 5: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 5); \ -++ break; \ -++ case 6: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 6); \ -++ break; \ -++ case 7: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 7); \ -++ break; \ -++ case 8: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 8); \ -++ break; \ -++ case 9: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 9); \ -++ break; \ -++ case 10: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 10); \ -++ break; \ -++ case 11: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 11); \ -++ break; \ -++ case 12: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 12); \ -++ break; \ -++ case 13: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 13); \ -++ break; \ -++ case 14: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 14); \ -++ break; \ -++ case 15: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 15); \ -++ break; \ -++ case 16: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 16); \ -++ break; \ -++ case 17: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 17); \ -++ break; \ -++ case 18: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 18); \ -++ break; \ -++ case 19: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 19); \ -++ break; \ -++ case 20: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 20); \ -++ break; \ -++ case 21: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 21); \ -++ break; \ -++ case 22: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 22); \ -++ break; \ -++ case 23: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 23); \ -++ break; \ -++ case 24: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 24); \ -++ break; \ -++ case 25: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 25); \ -++ break; \ -++ case 26: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 26); \ -++ break; \ -++ case 27: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 27); \ -++ break; \ -++ case 28: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 28); \ -++ break; \ -++ case 29: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 29); \ -++ break; \ -++ case 30: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 30); \ -++ break; \ -++ case 31: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 31); \ -++ break; \ -++ case 32: \ -++ SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 32); \ -++ break; \ -++ default: \ -++ /* Do nothing */ \ -++ break; \ -++ } /* END switch */ \ -++ } else { \ -++ char *tmpStrDest_ = (char *)(strDest); \ -++ const char *tmpStrSrc_ = (const char *)(strSrc); \ -++ switch (lenWithTerm) { \ -++ case 32: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 31: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 30: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 29: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 28: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 27: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 26: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 25: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 24: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 23: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 22: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 21: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 20: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 19: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 18: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 17: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 16: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 15: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 14: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 13: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 12: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 11: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 10: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 9: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 8: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 7: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 6: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 5: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 4: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 3: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 2: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ case 1: \ -++ *(tmpStrDest_++) = *(tmpStrSrc_++); \ -++ /* fall-through */ /* FALLTHRU */ \ -++ default: \ -++ /* Do nothing */ \ -++ break; \ -++ } \ -++ } \ -++} SECUREC_WHILE_ZERO -++#endif -++ -++#if SECUREC_IN_KERNEL || (!SECUREC_STRCPY_WITH_PERFORMANCE) -++#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)) -++#else -++/* -++ * Performance optimization. lenWithTerm include '\0' -++ */ -++#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) do { \ -++ if ((lenWithTerm) > SECUREC_STRCOPY_THRESHOLD_SIZE) { \ -++ SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)); \ -++ } else { \ -++ SECUREC_SMALL_STR_COPY((dest), (src), (lenWithTerm)); \ -++ } \ -++} SECUREC_WHILE_ZERO -++#endif -++ -++/* -++ * Check Src Range -++ */ -++SECUREC_INLINE errno_t CheckSrcRange(char *strDest, size_t destMax, const char *strSrc) -++{ -++ size_t tmpDestMax = destMax; -++ const char *tmpSrc = strSrc; -++ /* Use destMax as boundary checker and destMax must be greater than zero */ -++ while (*tmpSrc != '\0' && tmpDestMax > 0) { -++ ++tmpSrc; -++ --tmpDestMax; -++ } -++ if (tmpDestMax == 0) { -++ strDest[0] = '\0'; -++ SECUREC_ERROR_INVALID_RANGE("strcpy_s"); -++ return ERANGE_AND_RESET; -++ } -++ return EOK; -++} -++ -++/* -++ * Handling errors -++ */ -++errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc) -++{ -++ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { -++ SECUREC_ERROR_INVALID_RANGE("strcpy_s"); -++ return ERANGE; -++ } -++ if (strDest == NULL || strSrc == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("strcpy_s"); -++ if (strDest != NULL) { -++ strDest[0] = '\0'; -++ return EINVAL_AND_RESET; -++ } -++ return EINVAL; -++ } -++ return CheckSrcRange(strDest, destMax, strSrc); -++} -++ -++/* -++ * -++ * The strcpy_s function copies the string pointed to strSrc -++ * (including the terminating null character) into the array pointed to by strDest -++ * The destination string must be large enough to hold the source string, -++ * including the terminating null character. strcpy_s will return EOVERLAP_AND_RESET -++ * if the source and destination strings overlap. -++ * -++ * -++ * strDest Location of destination string buffer -++ * destMax Size of the destination string buffer. -++ * strSrc Null-terminated source string buffer. -++ * -++ * -++ * strDest is updated. -++ * -++ * -++ * EOK Success -++ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN -++ * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN -++ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN -++ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap -++ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc) -++{ -++ if (SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc)) { -++ size_t srcStrLen; -++ SECUREC_CALC_STR_LEN(strSrc, destMax, &srcStrLen); -++ ++srcStrLen; /* The length include '\0' */ -++ -++ if (srcStrLen <= destMax) { -++ /* Use mem overlap check include '\0' */ -++ if (SECUREC_MEMORY_NO_OVERLAP(strDest, strSrc, srcStrLen)) { -++ /* Performance optimization srcStrLen include '\0' */ -++ SECUREC_STRCPY_OPT(strDest, strSrc, srcStrLen); -++ return EOK; -++ } else { -++ strDest[0] = '\0'; -++ SECUREC_ERROR_BUFFER_OVERLAP("strcpy_s"); -++ return EOVERLAP_AND_RESET; -++ } -++ } -++ } -++ return strcpy_error(strDest, destMax, strSrc); -++} -++ -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(strcpy_s); -++#endif -++ -+diff --git a/lib/securec/src/strncat_s.c b/lib/securec/src/strncat_s.c -+new file mode 100755 -+index 000000000..6686d2994 -+--- /dev/null -++++ b/lib/securec/src/strncat_s.c -+@@ -0,0 +1,119 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: strncat_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "securecutil.h" -++ -++/* -++ * Befor this function, the basic parameter checking has been done -++ */ -++SECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax, const char *strSrc, size_t count) -++{ -++ size_t destLen; -++ size_t srcLen; -++ SECUREC_CALC_STR_LEN(strDest, destMax, &destLen); -++ /* -++ * The strSrc is no longer optimized. The reason is that when count is small, -++ * the efficiency of strnlen is higher than that of self realization. -++ */ -++ SECUREC_CALC_STR_LEN(strSrc, count, &srcLen); -++ -++ if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) { -++ strDest[0] = '\0'; -++ if (strDest + destLen <= strSrc && destLen == destMax) { -++ SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); -++ return EINVAL_AND_RESET; -++ } -++ SECUREC_ERROR_BUFFER_OVERLAP("strncat_s"); -++ return EOVERLAP_AND_RESET; -++ } -++ if (srcLen + destLen >= destMax || strDest == strSrc) { -++ strDest[0] = '\0'; -++ if (destLen == destMax) { -++ SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); -++ return EINVAL_AND_RESET; -++ } -++ SECUREC_ERROR_INVALID_RANGE("strncat_s"); -++ return ERANGE_AND_RESET; -++ } -++ SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen); /* No terminator */ -++ *(strDest + destLen + srcLen) = '\0'; -++ return EOK; -++} -++ -++/* -++ * -++ * The strncat_s function appends not more than n successive characters -++ * (not including the terminating null character) -++ * from the array pointed to by strSrc to the end of the string pointed to by strDest -++ * The strncat_s function try to append the first D characters of strSrc to -++ * the end of strDest, where D is the lesser of count and the length of strSrc. -++ * If appending those D characters will fit within strDest (whose size is given -++ * as destMax) and still leave room for a null terminator, then those characters -++ * are appended, starting at the original terminating null of strDest, and a -++ * new terminating null is appended; otherwise, strDest[0] is set to the null -++ * character. -++ * -++ * -++ * strDest Null-terminated destination string. -++ * destMax Size of the destination buffer. -++ * strSrc Null-terminated source string. -++ * count Number of character to append, or truncate. -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * EOK Success -++ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN -++ * EINVAL_AND_RESET (strDest unterminated and all other parameters are valid)or -++ * (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN) -++ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN -++ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap -++ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count) -++{ -++ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { -++ SECUREC_ERROR_INVALID_RANGE("strncat_s"); -++ return ERANGE; -++ } -++ -++ if (strDest == NULL || strSrc == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("strncat_s"); -++ if (strDest != NULL) { -++ strDest[0] = '\0'; -++ return EINVAL_AND_RESET; -++ } -++ return EINVAL; -++ } -++ if (count > SECUREC_STRING_MAX_LEN) { -++#ifdef SECUREC_COMPATIBLE_WIN_FORMAT -++ if (count == (size_t)(-1)) { -++ /* Windows internal functions may pass in -1 when calling this function */ -++ return SecDoCatLimit(strDest, destMax, strSrc, destMax); -++ } -++#endif -++ strDest[0] = '\0'; -++ SECUREC_ERROR_INVALID_RANGE("strncat_s"); -++ return ERANGE_AND_RESET; -++ } -++ return SecDoCatLimit(strDest, destMax, strSrc, count); -++} -++ -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(strncat_s); -++#endif -++ -+diff --git a/lib/securec/src/strncpy_s.c b/lib/securec/src/strncpy_s.c -+new file mode 100755 -+index 000000000..5f4c5b709 -+--- /dev/null -++++ b/lib/securec/src/strncpy_s.c -+@@ -0,0 +1,145 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: strncpy_s function -++ * Create: 2014-02-25 -++ */ -++/* -++ * [Standardize-exceptions] Use unsafe function: Performance-sensitive -++ * [reason] Always used in the performance critical path, -++ * and sufficient input validation is performed before calling -++ */ -++ -++#include "securecutil.h" -++ -++#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) -++#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \ -++ (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \ -++ ((count) <= SECUREC_STRING_MAX_LEN || (count) == ((size_t)(-1))) && (count) > 0)) -++#else -++#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \ -++ (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \ -++ (count) <= SECUREC_STRING_MAX_LEN && (count) > 0)) -++#endif -++ -++/* -++ * Check Src Count Range -++ */ -++SECUREC_INLINE errno_t CheckSrcCountRange(char *strDest, size_t destMax, const char *strSrc, size_t count) -++{ -++ size_t tmpDestMax = destMax; -++ size_t tmpCount = count; -++ const char *endPos = strSrc; -++ -++ /* Use destMax and count as boundary checker and destMax must be greater than zero */ -++ while (*(endPos) != '\0' && tmpDestMax > 0 && tmpCount > 0) { -++ ++endPos; -++ --tmpCount; -++ --tmpDestMax; -++ } -++ if (tmpDestMax == 0) { -++ strDest[0] = '\0'; -++ SECUREC_ERROR_INVALID_RANGE("strncpy_s"); -++ return ERANGE_AND_RESET; -++ } -++ return EOK; -++} -++ -++/* -++ * Handling errors, when dest equal src return EOK -++ */ -++errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count) -++{ -++ if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) { -++ SECUREC_ERROR_INVALID_RANGE("strncpy_s"); -++ return ERANGE; -++ } -++ if (strDest == NULL || strSrc == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("strncpy_s"); -++ if (strDest != NULL) { -++ strDest[0] = '\0'; -++ return EINVAL_AND_RESET; -++ } -++ return EINVAL; -++ } -++ if (count > SECUREC_STRING_MAX_LEN) { -++ strDest[0] = '\0'; /* Clear dest string */ -++ SECUREC_ERROR_INVALID_RANGE("strncpy_s"); -++ return ERANGE_AND_RESET; -++ } -++ if (count == 0) { -++ strDest[0] = '\0'; -++ return EOK; -++ } -++ return CheckSrcCountRange(strDest, destMax, strSrc, count); -++} -++ -++/* -++ * -++ * The strncpy_s function copies not more than n successive characters (not including the terminating null character) -++ * from the array pointed to by strSrc to the array pointed to by strDest. -++ * -++ * -++ * strDest Destination string. -++ * destMax The size of the destination string, in characters. -++ * strSrc Source string. -++ * count Number of characters to be copied. -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * EOK Success -++ * EINVAL strDest is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN -++ * EINVAL_AND_RESET strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN -++ * ERANGE destMax is 0 and destMax > SECUREC_STRING_MAX_LEN -++ * ERANGE_AND_RESET strDest have not enough space and all other parameters are valid and not overlap -++ * EOVERLAP_AND_RESET dest buffer and source buffer are overlapped and all parameters are valid -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count) -++{ -++ if (SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count)) { -++ size_t minCpLen; /* Use it to store the maxi length limit */ -++ if (count < destMax) { -++ SECUREC_CALC_STR_LEN(strSrc, count, &minCpLen); /* No ending terminator */ -++ } else { -++ size_t tmpCount = destMax; -++#ifdef SECUREC_COMPATIBLE_WIN_FORMAT -++ if (count == ((size_t)(-1))) { -++ tmpCount = destMax - 1; -++ } -++#endif -++ SECUREC_CALC_STR_LEN(strSrc, tmpCount, &minCpLen); /* No ending terminator */ -++ if (minCpLen == destMax) { -++ strDest[0] = '\0'; -++ SECUREC_ERROR_INVALID_RANGE("strncpy_s"); -++ return ERANGE_AND_RESET; -++ } -++ } -++ if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, minCpLen) || strDest == strSrc) { -++ /* Not overlap */ -++ SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, minCpLen); /* Copy string without terminator */ -++ strDest[minCpLen] = '\0'; -++ return EOK; -++ } else { -++ strDest[0] = '\0'; -++ SECUREC_ERROR_BUFFER_OVERLAP("strncpy_s"); -++ return EOVERLAP_AND_RESET; -++ } -++ } -++ return strncpy_error(strDest, destMax, strSrc, count); -++} -++ -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(strncpy_s); -++#endif -++ -+diff --git a/lib/securec/src/strtok_s.c b/lib/securec/src/strtok_s.c -+new file mode 100755 -+index 000000000..cd5dcd2cd -+--- /dev/null -++++ b/lib/securec/src/strtok_s.c -+@@ -0,0 +1,116 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: strtok_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "securecutil.h" -++ -++SECUREC_INLINE int SecIsInDelimit(char ch, const char *strDelimit) -++{ -++ const char *ctl = strDelimit; -++ while (*ctl != '\0' && *ctl != ch) { -++ ++ctl; -++ } -++ return (int)(*ctl != '\0'); -++} -++ -++/* -++ * Find beginning of token (skip over leading delimiters). -++ * Note that there is no token if this loop sets string to point to the terminal null. -++ */ -++SECUREC_INLINE char *SecFindBegin(char *strToken, const char *strDelimit) -++{ -++ char *token = strToken; -++ while (*token != '\0') { -++ if (SecIsInDelimit(*token, strDelimit) != 0) { -++ ++token; -++ continue; -++ } -++ /* Don't find any delimiter in string header, break the loop */ -++ break; -++ } -++ return token; -++} -++ -++/* -++ * Find rest of token -++ */ -++SECUREC_INLINE char *SecFindRest(char *strToken, const char *strDelimit) -++{ -++ /* Find the rest of the token. If it is not the end of the string, put a null there */ -++ char *token = strToken; -++ while (*token != '\0') { -++ if (SecIsInDelimit(*token, strDelimit) != 0) { -++ /* Find a delimiter, set string terminator */ -++ *token = '\0'; -++ ++token; -++ break; -++ } -++ ++token; -++ } -++ return token; -++} -++ -++/* -++ * Find the final position pointer -++ */ -++SECUREC_INLINE char *SecUpdateToken(char *strToken, const char *strDelimit, char **context) -++{ -++ /* Point to updated position. Record string position for next search in the context */ -++ *context = SecFindRest(strToken, strDelimit); -++ /* Determine if a token has been found. */ -++ if (*context == strToken) { -++ return NULL; -++ } -++ return strToken; -++} -++ -++/* -++ * -++ * The strtok_s function parses a string into a sequence of strToken, -++ * replace all characters in strToken string that match to strDelimit set with 0. -++ * On the first call to strtok_s the string to be parsed should be specified in strToken. -++ * In each subsequent call that should parse the same string, strToken should be NULL -++ * -++ * strToken String containing token or tokens. -++ * strDelimit Set of delimiter characters. -++ * context Used to store position information between calls -++ * to strtok_s -++ * -++ * context is updated -++ * -++ * On the first call returns the address of the first non \0 character, otherwise NULL is returned. -++ * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call, -++ * return NULL if the *context string length is equal 0, otherwise return *context. -++ */ -++char *strtok_s(char *strToken, const char *strDelimit, char **context) -++{ -++ char *orgToken = strToken; -++ /* Validate delimiter and string context */ -++ if (context == NULL || strDelimit == NULL) { -++ return NULL; -++ } -++ /* Valid input string and string pointer from where to search */ -++ if (orgToken == NULL && *context == NULL) { -++ return NULL; -++ } -++ /* If string is null, continue searching from previous string position stored in context */ -++ if (orgToken == NULL) { -++ orgToken = *context; -++ } -++ orgToken = SecFindBegin(orgToken, strDelimit); -++ return SecUpdateToken(orgToken, strDelimit, context); -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(strtok_s); -++#endif -++ -+diff --git a/lib/securec/src/vscanf_s.c b/lib/securec/src/vscanf_s.c -+new file mode 100755 -+index 000000000..61480a697 -+--- /dev/null -++++ b/lib/securec/src/vscanf_s.c -+@@ -0,0 +1,63 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: vscanf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "secinput.h" -++ -++/* -++ * -++ * The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList, -++ * The vscanf_s function reads data from the standard input stream stdin and -++ * writes the data into the location that's given by argument. Each argument -++ * must be a pointer to a variable of a type that corresponds to a type specifier -++ * in format. If copying occurs between strings that overlap, the behavior is -++ * undefined. -++ * -++ * -++ * format Format control string. -++ * argList pointer to list of arguments -++ * -++ * -++ * argList the converted value stored in user assigned address -++ * -++ * -++ * Returns the number of fields successfully converted and assigned; -++ * the return value does not include fields that were read but not assigned. -++ * A return value of 0 indicates that no fields were assigned. -++ * return -1 if an error occurs. -++ */ -++int vscanf_s(const char *format, va_list argList) -++{ -++ int retVal; /* If initialization causes e838 */ -++ SecFileStream fStr; -++ SECUREC_FILE_STREAM_FROM_STDIN(&fStr); -++ /* -++ * The "va_list" has different definition on different platform, so we can't use argList == NULL -++ * To determine it's invalid. If you has fixed platform, you can check some fields to validate it, -++ * such as "argList == NULL" or argList.xxx != NULL or *(size_t *)&argList != 0. -++ */ -++ if (format == NULL || fStr.pf == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("vscanf_s"); -++ return SECUREC_SCANF_EINVAL; -++ } -++ -++ SECUREC_LOCK_STDIN(0, fStr.pf); -++ retVal = SecInputS(&fStr, format, argList); -++ SECUREC_UNLOCK_STDIN(0, fStr.pf); -++ if (retVal < 0) { -++ SECUREC_ERROR_INVALID_PARAMTER("vscanf_s"); -++ return SECUREC_SCANF_EINVAL; -++ } -++ return retVal; -++} -++ -+diff --git a/lib/securec/src/vsnprintf_s.c b/lib/securec/src/vsnprintf_s.c -+new file mode 100755 -+index 000000000..35caaa220 -+--- /dev/null -++++ b/lib/securec/src/vsnprintf_s.c -+@@ -0,0 +1,138 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: vsnprintf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "secureprintoutput.h" -++ -++#if SECUREC_ENABLE_VSNPRINTF -++/* -++ * -++ * The vsnprintf_s function is equivalent to the vsnprintf function -++ * except for the parameter destMax/count and the explicit runtime-constraints violation -++ * The vsnprintf_s function takes a pointer to an argument list, then formats -++ * and writes up to count characters of the given data to the memory pointed -++ * to by strDest and appends a terminating null. -++ * -++ * -++ * strDest Storage location for the output. -++ * destMax The size of the strDest for output. -++ * count Maximum number of character to write(not including -++ * the terminating NULL) -++ * format Format-control string. -++ * argList pointer to list of arguments. -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * return the number of characters written, not including the terminating null -++ * return -1 if an error occurs. -++ * return -1 if count < destMax and the output string has been truncated -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, va_list argList) -++{ -++ int retVal; -++ -++ if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, SECUREC_STRING_MAX_LEN)) { -++ SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); -++ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); -++ return -1; -++ } -++ -++ if (destMax > count) { -++ retVal = SecVsnprintfImpl(strDest, count + 1, format, argList); -++ if (retVal == SECUREC_PRINTF_TRUNCATE) { /* To keep dest buffer not destroyed 2014.2.18 */ -++ /* The string has been truncated, return -1 */ -++ return -1; /* To skip error handler, return strlen(strDest) or -1 */ -++ } -++ } else { -++ retVal = SecVsnprintfImpl(strDest, destMax, format, argList); -++#ifdef SECUREC_COMPATIBLE_WIN_FORMAT -++ if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)(-1)) { -++ return -1; -++ } -++#endif -++ } -++ -++ if (retVal < 0) { -++ strDest[0] = '\0'; /* Empty the dest strDest */ -++ if (retVal == SECUREC_PRINTF_TRUNCATE) { -++ /* Buffer too small */ -++ SECUREC_ERROR_INVALID_RANGE("vsnprintf_s"); -++ } -++ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s"); -++ return -1; -++ } -++ -++ return retVal; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(vsnprintf_s); -++#endif -++#endif -++ -++#if SECUREC_SNPRINTF_TRUNCATED -++/* -++ * -++ * The vsnprintf_truncated_s function is equivalent to the vsnprintf function -++ * except for the parameter destMax/count and the explicit runtime-constraints violation -++ * The vsnprintf_truncated_s function takes a pointer to an argument list, then formats -++ * and writes up to count characters of the given data to the memory pointed -++ * to by strDest and appends a terminating null. -++ * -++ * -++ * strDest Storage location for the output. -++ * destMax The size of the strDest for output. -++ * the terminating NULL) -++ * format Format-control string. -++ * argList pointer to list of arguments. -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * return the number of characters written, not including the terminating null -++ * return -1 if an error occurs. -++ * return destMax-1 if output string has been truncated -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, va_list argList) -++{ -++ int retVal; -++ -++ if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) { -++ SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); -++ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); -++ return -1; -++ } -++ -++ retVal = SecVsnprintfImpl(strDest, destMax, format, argList); -++ if (retVal < 0) { -++ if (retVal == SECUREC_PRINTF_TRUNCATE) { -++ return (int)(destMax - 1); /* To skip error handler, return strlen(strDest) */ -++ } -++ strDest[0] = '\0'; /* Empty the dest strDest */ -++ SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_truncated_s"); -++ return -1; -++ } -++ -++ return retVal; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(vsnprintf_truncated_s); -++#endif -++#endif -++ -+diff --git a/lib/securec/src/vsprintf_s.c b/lib/securec/src/vsprintf_s.c -+new file mode 100755 -+index 000000000..f50fa4a98 -+--- /dev/null -++++ b/lib/securec/src/vsprintf_s.c -+@@ -0,0 +1,67 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: vsprintf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "secureprintoutput.h" -++ -++/* -++ * -++ * The vsprintf_s function is equivalent to the vsprintf function -++ * except for the parameter destMax and the explicit runtime-constraints violation -++ * The vsprintf_s function takes a pointer to an argument list, and then formats -++ * and writes the given data to the memory pointed to by strDest. -++ * The function differ from the non-secure versions only in that the secure -++ * versions support positional parameters. -++ * -++ * -++ * strDest Storage location for the output. -++ * destMax Size of strDest -++ * format Format specification. -++ * argList pointer to list of arguments -++ * -++ * -++ * strDest is updated -++ * -++ * -++ * return the number of characters written, not including the terminating null character, -++ * return -1 if an error occurs. -++ * -++ * If there is a runtime-constraint violation, strDest[0] will be set to the '\0' when strDest and destMax valid -++ */ -++int vsprintf_s(char *strDest, size_t destMax, const char *format, va_list argList) -++{ -++ int retVal; /* If initialization causes e838 */ -++ -++ if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) { -++ SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN); -++ SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s"); -++ return -1; -++ } -++ -++ retVal = SecVsnprintfImpl(strDest, destMax, format, argList); -++ if (retVal < 0) { -++ strDest[0] = '\0'; -++ if (retVal == SECUREC_PRINTF_TRUNCATE) { -++ /* Buffer is too small */ -++ SECUREC_ERROR_INVALID_RANGE("vsprintf_s"); -++ } -++ SECUREC_ERROR_INVALID_PARAMTER("vsprintf_s"); -++ return -1; -++ } -++ -++ return retVal; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(vsprintf_s); -++#endif -++ -+diff --git a/lib/securec/src/vsscanf_s.c b/lib/securec/src/vsscanf_s.c -+new file mode 100755 -+index 000000000..a19abe2b9 -+--- /dev/null -++++ b/lib/securec/src/vsscanf_s.c -+@@ -0,0 +1,87 @@ -++/* -++ * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. -++ * Licensed under Mulan PSL v2. -++ * You can use this software according to the terms and conditions of the Mulan PSL v2. -++ * You may obtain a copy of Mulan PSL v2 at: -++ * http://license.coscl.org.cn/MulanPSL2 -++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -++ * See the Mulan PSL v2 for more details. -++ * Description: vsscanf_s function -++ * Create: 2014-02-25 -++ */ -++ -++#include "secinput.h" -++#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL && \ -++ (!defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT)) -++#include -++#endif -++ -++/* -++ * -++ * vsscanf_s -++ * -++ * -++ * -++ * The vsscanf_s function is equivalent to sscanf_s, with the variable argument list replaced by argList -++ * The vsscanf_s function reads data from buffer into the location given by -++ * each argument. Every argument must be a pointer to a variable with a type -++ * that corresponds to a type specifier in format. The format argument controls -++ * the interpretation of the input fields and has the same form and function -++ * as the format argument for the scanf function. -++ * If copying takes place between strings that overlap, the behavior is undefined. -++ * -++ * -++ * buffer Stored data -++ * format Format control string, see Format Specifications. -++ * argList pointer to list of arguments -++ * -++ * -++ * argList the converted value stored in user assigned address -++ * -++ * -++ * Each of these functions returns the number of fields successfully converted -++ * and assigned; the return value does not include fields that were read but -++ * not assigned. A return value of 0 indicates that no fields were assigned. -++ * return -1 if an error occurs. -++ */ -++int vsscanf_s(const char *buffer, const char *format, va_list argList) -++{ -++ size_t count; /* If initialization causes e838 */ -++ int retVal; -++ SecFileStream fStr; -++ -++ /* Validation section */ -++ if (buffer == NULL || format == NULL) { -++ SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); -++ return SECUREC_SCANF_EINVAL; -++ } -++ count = strlen(buffer); -++ if (count == 0 || count > SECUREC_STRING_MAX_LEN) { -++ SecClearDestBuf(buffer, format, argList); -++ SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); -++ return SECUREC_SCANF_EINVAL; -++ } -++#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL -++ /* -++ * On vxworks platform when buffer is white string, will set first %s argument to zero.Like following usage: -++ * " \v\f\t\r\n", "%s", str, strSize -++ * Do not check all character, just first and last character then consider it is white string -++ */ -++ if (isspace((int)(unsigned char)buffer[0]) != 0 && isspace((int)(unsigned char)buffer[count - 1]) != 0) { -++ SecClearDestBuf(buffer, format, argList); -++ } -++#endif -++ SECUREC_FILE_STREAM_FROM_STRING(&fStr, buffer, count); -++ retVal = SecInputS(&fStr, format, argList); -++ if (retVal < 0) { -++ SECUREC_ERROR_INVALID_PARAMTER("vsscanf_s"); -++ return SECUREC_SCANF_EINVAL; -++ } -++ return retVal; -++} -++#if SECUREC_EXPORT_KERNEL_SYMBOL -++EXPORT_SYMBOL(vsscanf_s); -++#endif -++ -+diff --git a/mm/slab_common.c b/mm/slab_common.c -+index 5f1a1c38a..ea444c5d2 100644 -+--- a/mm/slab_common.c -++++ b/mm/slab_common.c -+@@ -405,6 +405,11 @@ kmem_cache_create(const char *name, unsigned int size, unsigned int align, -+ } -+ EXPORT_SYMBOL(kmem_cache_create); -+ -++#ifdef CONFIG_ARCH_BSP -++#ifdef CONFIG_SYSFS_SLAB_MINI_OPT -++#undef SLAB_SUPPORTS_SYSFS -++#endif -++#endif -+ static void slab_caches_to_rcu_destroy_workfn(struct work_struct *work) -+ { -+ LIST_HEAD(to_destroy); -+diff --git a/mm/slub.c b/mm/slub.c -+index ec1c3a376..091a26f96 100644 -+--- a/mm/slub.c -++++ b/mm/slub.c -+@@ -4927,8 +4927,10 @@ static void __init resiliency_test(void) -+ } -+ #else -+ #ifdef CONFIG_SYSFS -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_SLAB_MINI_OPT) -+ static void resiliency_test(void) {}; -+ #endif -++#endif -+ #endif /* SLUB_RESILIENCY_TEST */ -+ -+ #ifdef CONFIG_SYSFS -+@@ -5754,6 +5756,7 @@ static int sysfs_slab_alias(struct kmem_cache *s, const char *name) -+ return 0; -+ } -+ -++#if !defined(CONFIG_ARCH_BSP) || !defined(CONFIG_SYSFS_SLAB_MINI_OPT) -+ static int __init slab_sysfs_init(void) -+ { -+ struct kmem_cache *s; -+@@ -5792,7 +5795,12 @@ static int __init slab_sysfs_init(void) -+ resiliency_test(); -+ return 0; -+ } -+- -++#else -++static int __init slab_sysfs_init(void) -++{ -++ return 0; -++} -++#endif -+ __initcall(slab_sysfs_init); -+ #endif /* CONFIG_SYSFS */ -+ -+diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -+index 941337088..585a86747 100644 -+--- a/scripts/Makefile.lib -++++ b/scripts/Makefile.lib -+@@ -211,6 +211,11 @@ cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ -+ ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) -+ -+ DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes -++#ifdef CONFIG_ARCH_BSP -++ifneq ($(CONFIG_SYNC_OPTEE_MEMORY_LAYOUT),) -++ DTC_INCLUDE += $(CONFIG_OPTEE_DIR)/core/arch/arm/dts/ -++endif -++#endif -+ -+ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ -+ $(addprefix -I,$(DTC_INCLUDE)) \ -+diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost -+index 42154b6df..82aa01377 100644 -+--- a/scripts/Makefile.modpost -++++ b/scripts/Makefile.modpost -+@@ -47,7 +47,7 @@ MODPOST = scripts/mod/modpost \ -+ $(if $(CONFIG_MODVERSIONS),-m) \ -+ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ -+ $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ -+- $(if $(KBUILD_MODPOST_WARN),-w) \ -++ $(if $(if $(CONFIG_ARCH_BSP),$(KBUILD_EXTMOD))$(KBUILD_MODPOST_WARN),-w) \ -+ -o $@ -+ -+ ifdef MODPOST_VMLINUX -+diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh -+index a18b47695..20593eeb2 100755 -+--- a/scripts/checksyscalls.sh -++++ b/scripts/checksyscalls.sh -+@@ -260,6 +260,7 @@ syscall_list() { -+ echo "#endif" -+ done -+ } -+- -++#ifndef CONFIG_ARCH_BSP -+ (ignore_list && syscall_list $(dirname $0)/../arch/x86/entry/syscalls/syscall_32.tbl) | \ -+ $* -E -x c - > /dev/null -++#endif -+-- -+2.34.1 -+ -diff --git a/bsp/meta-hisilicon/recipes-kernel/linux/linux-hipico.inc b/bsp/meta-hisilicon/recipes-kernel/linux/linux-hipico.inc -new file mode 100644 -index 00000000000..07ac78e5f18 ---- /dev/null -+++ b/bsp/meta-hisilicon/recipes-kernel/linux/linux-hipico.inc -@@ -0,0 +1,42 @@ -+# add recipes-kernel path to find patch and defconfig -+FILESEXTRAPATHS:append := "${THISDIR}/files/:" -+ -+# for mkimage -+DEPENDS += "u-boot-tools-native dtc-native" -+ -+OPENEULER_REPO_NAMES = "kernel-5.10-tag626 src-kernel-5.10-tag626" -+ -+OPENEULER_KERNEL_CONFIG = "file://config/hipico/hipico_debug_defconfig" -+ -+SRC_URI:append = "file://kernel-5.10-tag626 \ -+ file://patch/0001-hipico-kernel-510-patch-d8e3bcbbe.patch \ -+ file://config/hipico/hipico_debug_defconfig \ -+ file://dtbs/hipico.dts \ -+ file://its/linux_image.its \ -+" -+ -+S = "${WORKDIR}/kernel-5.10-tag626" -+ -+# add method to do_compile task to produce bootable Image -+do_compile:append(){ -+ cp ${KERNEL_OUTPUT_DIR}/zImage ${WORKDIR}/its/zImage -+ dtc -I dts -O dtb ${WORKDIR}/dtbs/hipico.dts -o ${WORKDIR}/its/devicetree.dtb -+ mkimage -f ${WORKDIR}/its/linux_image.its uImage -+ cp uImage ${KERNEL_OUTPUT_DIR}/uImage -+} -+ -+# uImage as bl33, we need to use it to build the fip.bin. So add uImage to SYSROOT_DIR -+# Since sysroot_stage_all() is rewritten as empty in meta/classes/kernel.bbclass, -+# we can't use "SYSROOT_DIRS" directly, here we write a SYSROOT_PREPROCESS_FUNCS to add uImage -+SYSROOT_DIRS += "/linux-img" -+FILES:${KERNEL_PACKAGE_NAME} += "/linux-img" -+do_install:append() { -+ install -d ${D}/linux-img -+ install -m 0644 ${KERNEL_OUTPUT_DIR}/uImage ${D}/linux-img/uImage -+} -+ -+SYSROOT_PREPROCESS_FUNCS += "additional_populate_sysroot" -+additional_populate_sysroot() { -+ sysroot_stage_dir ${D}/linux-img ${SYSROOT_DESTDIR}/linux-img -+} -+ -diff --git a/bsp/meta-hisilicon/recipes-kernel/linux/linux-openeuler.bbappend b/bsp/meta-hisilicon/recipes-kernel/linux/linux-openeuler.bbappend -index 87721b69fb8..3a719c99d94 100644 ---- a/bsp/meta-hisilicon/recipes-kernel/linux/linux-openeuler.bbappend -+++ b/bsp/meta-hisilicon/recipes-kernel/linux/linux-openeuler.bbappend -@@ -1,4 +1,4 @@ - # add COMPATIBLE_MACHINE --COMPATIBLE_MACHINE = "hi3093|hieulerpi1|hiedge1" -+COMPATIBLE_MACHINE = "hi3093|hieulerpi1|hiedge1|hipico" - - require recipes-kernel/linux/${@bb.utils.contains('DISTRO_FEATURES', 'mpu_solution', 'linux-hi3093-mpu.inc', 'linux-${MACHINE}.inc', d)} --- -2.34.1 - diff --git "a/CV610 OpenEuler\346\236\204\345\273\272\347\254\224\350\256\260.md" "b/CV610 OpenEuler\346\236\204\345\273\272\347\254\224\350\256\260.md" deleted file mode 100644 index 32e15deb07a6f8a1bba01400e15c44a2c645d7d2..0000000000000000000000000000000000000000 --- "a/CV610 OpenEuler\346\236\204\345\273\272\347\254\224\350\256\260.md" +++ /dev/null @@ -1,86 +0,0 @@ -* 参考文档: - -``` -https://gitee.com/openeuler/yocto-meta-openeuler/pulls/2248/files - -https://embedded.pages.openeuler.org/master/getting_started/index.html -``` - -## 注意: - -* 在执行下面步骤之前,请确保你Ubuntu版本为ubuntu22.04 x86_64 >32G内存,如果有服务器会更好,如果内存太小,构建一次需要挺长时间。 - -## 步骤1:安装必要的软件包 - -``` -# 安装必要的软件包 -sudo apt-get install python3 python3-pip docker docker.io -pip install oebuild - -# 配置docker环境 -sudo usermod -a -G docker $(whoami) -sudo systemctl daemon-reload && sudo systemctl restart docker -sudo chmod o+rw /var/run/docker.sock -``` - -![image-20240902163303232](pic/image-20240902163303232.png) - -## 步骤2:初始化oebuild构建环境 - -* 运行 oebuild 完成初始化工作,包括创建工作目录、拉取构建容器等,之后的构建都需要在 `` 下进行: - -``` -# 为要创建的工作目录 -oebuild init - -# 切换到工作目录 -cd - -# 拉取构建容器、yocto-meta-openeuler 项目代码 -oebuild update -``` - -![image-20240902163956232](pic/image-20240902163956232.png) - -## 步骤3:开始构建 - -* 复制0001-add-hipico-image.patch到oebuild/src/的文件夹中,执行下面的命令,将patch合入代码中。 - -``` -cd /home/hispark/euler_cv610/src/yocto-meta-openeuler - -patch -p1 < ../../0001-yotco-add-hipico-image.patch -``` - -![image-20240902170041821](pic/image-20240902170041821.png) - -* 继续执行以下命令进行 `hipico` 镜像的构建,`build_arm64` 为该镜像的构建目录: - -``` -# 所有的构建工作都需要在 oebuild 工作目录下进行 -cd - -# 为 openeuler-image-qemu-arm64 镜像创建配置文件 compile.yaml -oebuild generate -p hipico -d build_arm64 - -# 切换到包含 compile.yaml 的编译空间目录,如 build/build_arm64/ -cd build/build_arm64/ - -# 根据提示进入 build_arm64 构建目录,并开始构建 -oebuild bitbake openeuler-image -``` - -![image-20240902170248415](pic/image-20240902170248415.png) - -* 构建成功之后,会在output目录下生成如下的文件。其中openeuler-image-hipico-20240902090336.rootfs.cpio.gz为文件系统rootfs,zImage-5.10.0-openeuler为内核zImages。 - -![image-20240902213941083](pic/image-20240902213941083.png) - -* 如果在构建过程中出现如下截图错误,可以执行下面的命令,清理一下镜像缓存再编就行了 - -``` -bitbake openeuler-image -c cleanall; bitbake openeuler-image -``` - -![image-20240903092950422](pic/image-20240903092950422.png) - diff --git "a/HiPico-OpenEuler\346\236\204\345\273\272\346\211\213\345\206\214.md" "b/HiPico-OpenEuler\346\236\204\345\273\272\346\211\213\345\206\214.md" new file mode 100644 index 0000000000000000000000000000000000000000..5d31830ef3785938085c6f2eaeb1cdd70582df37 --- /dev/null +++ "b/HiPico-OpenEuler\346\236\204\345\273\272\346\211\213\345\206\214.md" @@ -0,0 +1,99 @@ +# HiPico-OpenEuler构建手册 + +## 相关文档 + +1. [openeuler官方文档](https://embedded.pages.openeuler.org/master/getting_started/index.html) + +## 一、检查基本开发环境 + +开发建议使用ubuntu系统,可参考[《基础开发环境搭建》](./开发工具使用/基础开发环境搭建.md)安装ubuntu系统并配置基本的ubuntu开发环境。 + +openeuler的构建都在docker中进行,因此对系统的依赖只有docker和python。其中python版本最低为**python3.8及以上**,建议python版本越新越好。若当前系统中没有指定版本的python,建议使用**conda**创建虚拟的python环境([《conda使用手册》](./开发工具使用/conda使用手册.md))。 + +```shell +# 安装docker +sudo apt-get install docker docker.io +# 配置docker环境 +sudo usermod -a -G docker $(whoami) +sudo systemctl daemon-reload && sudo systemctl restart docker +sudo chmod o+rw /var/run/docker.sock +``` + +```shell +# 若当前主机包含python3.8及以上版本的python可直接执行以下命令安装oebuild +# 若不包含指定版本,参考conda使用手册安装虚拟环境后在虚拟环境中安装oebuild +pip install oebuild +``` + +## 二、初始化构建环境 + +oebuild是openeuler构建开发环境的工具,可以根据配置自动拉取docker镜像、源码、初始化构建环境等操作。 + +```shell +# 创建工作目录 +oebuild init +# 切换到工作目录 +cd +# 拉取构建容器、yocto-meta-openeuler 项目代码 +oebuild update + +# 创建hipico构建环境 +oebuild generate -p hipico -d build_arm64 +``` + +## 三、构建openeuler镜像 + +``` + + ├── build + │   └── build_arm64 # 构建目录 + └── src + ├── yocto-meta-openeuler # openeuler主仓库 + ├── ... # 其它源码仓库 +``` + +构建openeuler系统需要切换到**构建目录**,再执行命令。 + +> oebuild和bitbake的使用可参考[《oebuild&bitbake使用笔记》](./开发工具使用/oebuild&bitbake使用笔记.md) + +```shell +# 切换到构建目录 +cd /build/build_arm64 +# 编译openeuler镜像 +oebuild bitbake openeuler-image +``` + +构建完成后,在`/build/build_arm64/output/<构建时间戳>`目录中生成构建产物。 + +``` +-rwxr-xr-x 1 cxcc cxcc 8600124 Oct 22 13:12 Image +-rw-r--r-- 1 cxcc cxcc 8600124 Oct 24 15:02 Image-5.10.0-openeuler +-rw-r--r-- 1 cxcc cxcc 38615170 Oct 24 15:02 openeuler-image-hipico-20241024150144.rootfs.cpio.gz +-rw-r--r-- 1 cxcc cxcc 133066752 Oct 24 15:02 openeuler-image-hipico-20241024150144.rootfs.ext4 +-rw-r--r-- 1 cxcc cxcc 57671680 Oct 24 15:02 openeuler-image-hipico-20241024150144.rootfs.ubi +-rw-r--r-- 1 cxcc cxcc 3635101 Oct 22 13:13 uImage +-rwxr-xr-x 1 cxcc cxcc 9456744 Oct 22 13:12 vmlinux +-rw-r--r-- 1 cxcc cxcc 6140008 Oct 24 15:02 vmlinux-5.10.0-openeuler +lrwxrwxrwx 1 cxcc cxcc 23 Oct 24 15:02 zImage -> zImage-5.10.0-openeuler +-rwxr-xr-x 1 cxcc cxcc 3618248 Oct 22 13:13 zImage-5.10.0-openeuler +``` + +其中`uImage`和`openeuler-image-hipico-20241024150144.rootfs.ubi`分别是内核和根文件系统的部署件,可通过烧录工具直接烧录到系统中。 + +> **怎么获取u-boot?** +> +> 可在以下仓库链接中获取u-boot源码:https://gitee.com/hieuler-pico/u-boot +> +> 若对u-boot功能没有特殊要求可直接下载最新的releases版本:https://gitee.com/hieuler-pico/u-boot/releases + +> **怎么烧录固件?** +> +> 首先需要获取所有的部署件: +> +> 1. burn_table.xml: 烧录分区表 +> 1. boot_image.bin: u-boot镜像 +> 1. nand_env.bin: u-boot环境变量 +> 1. uImage: Linux内核镜像 +> 1. openeuler-image-hipico-*.rootfs.ubi: 根文件系统镜像 +> +> 参考[《HiPico镜像烧录指南》](./开发工具使用/HiPico镜像烧录指南.md)烧录固件 \ No newline at end of file diff --git a/pic/image-20240902163303232.png b/pic/image-20240902163303232.png deleted file mode 100644 index a68b27d80fcd79b262c15a6f8618f3d9b32574bd..0000000000000000000000000000000000000000 Binary files a/pic/image-20240902163303232.png and /dev/null differ diff --git a/pic/image-20240902163956232.png b/pic/image-20240902163956232.png deleted file mode 100644 index ed24c0ba56528bdbef54ffc9cd0babaa34af8ea1..0000000000000000000000000000000000000000 Binary files a/pic/image-20240902163956232.png and /dev/null differ diff --git a/pic/image-20240902170041821.png b/pic/image-20240902170041821.png deleted file mode 100644 index 6a17408103e54b8d0b6187ab0ffe599583342f7c..0000000000000000000000000000000000000000 Binary files a/pic/image-20240902170041821.png and /dev/null differ diff --git a/pic/image-20240902170248415.png b/pic/image-20240902170248415.png deleted file mode 100644 index 5ff08e9d490ebf8967c94a7d41c80dbaa66d286c..0000000000000000000000000000000000000000 Binary files a/pic/image-20240902170248415.png and /dev/null differ diff --git a/pic/image-20240902213941083.png b/pic/image-20240902213941083.png deleted file mode 100644 index 7c61a6c18a9c9eebb9cf671bc236ba26cd6bd851..0000000000000000000000000000000000000000 Binary files a/pic/image-20240902213941083.png and /dev/null differ diff --git a/pic/image-20240903092950422.png b/pic/image-20240903092950422.png deleted file mode 100644 index a02fa803857abc96e1aafdf717161f0a408a039f..0000000000000000000000000000000000000000 Binary files a/pic/image-20240903092950422.png and /dev/null differ diff --git a/pic/image-20241027214656594.png b/pic/image-20241027214656594.png new file mode 100644 index 0000000000000000000000000000000000000000..e88d5e5380cf7e398b854854f0b240d2fa5fcf87 Binary files /dev/null and b/pic/image-20241027214656594.png differ diff --git a/pic/image-20241027214854749.png b/pic/image-20241027214854749.png new file mode 100644 index 0000000000000000000000000000000000000000..92357d3d74bf71a525364a5231fe6f0aeabc65ea Binary files /dev/null and b/pic/image-20241027214854749.png differ diff --git a/pic/image-20241027220855071.png b/pic/image-20241027220855071.png new file mode 100644 index 0000000000000000000000000000000000000000..52b6d88d714d14208e3635ccbaf11f5a554dfbc0 Binary files /dev/null and b/pic/image-20241027220855071.png differ diff --git a/pic/image-20241027221257451.png b/pic/image-20241027221257451.png new file mode 100644 index 0000000000000000000000000000000000000000..46f140be4257609f18dcb8cee0115d36d25ecd41 Binary files /dev/null and b/pic/image-20241027221257451.png differ diff --git a/pic/image-20241027221410263.png b/pic/image-20241027221410263.png new file mode 100644 index 0000000000000000000000000000000000000000..93dca008e58127cdaa46ce4ae6522ec3418bdad0 Binary files /dev/null and b/pic/image-20241027221410263.png differ diff --git a/pic/image-20241027221445335.png b/pic/image-20241027221445335.png new file mode 100644 index 0000000000000000000000000000000000000000..bda24ef65758d1f1fd3dd3632db6f5f9377c2605 Binary files /dev/null and b/pic/image-20241027221445335.png differ diff --git a/pic/image-20241027222134378.png b/pic/image-20241027222134378.png new file mode 100644 index 0000000000000000000000000000000000000000..8a0cdf582f53e98663351ee93c3d4df0071596a4 Binary files /dev/null and b/pic/image-20241027222134378.png differ diff --git a/pic/image-20241027222240284.png b/pic/image-20241027222240284.png new file mode 100644 index 0000000000000000000000000000000000000000..2c09737fb71409a4e382c1c4bbe8db4686d57632 Binary files /dev/null and b/pic/image-20241027222240284.png differ diff --git a/pic/image-20241027222610538.png b/pic/image-20241027222610538.png new file mode 100644 index 0000000000000000000000000000000000000000..2e7c5da7a410d151d7e99678010cbf23a6e8b0a7 Binary files /dev/null and b/pic/image-20241027222610538.png differ diff --git a/pic/image-20241027223022906.png b/pic/image-20241027223022906.png new file mode 100644 index 0000000000000000000000000000000000000000..ad397a40071e6237a33b15e0d9563e52df7f2db3 Binary files /dev/null and b/pic/image-20241027223022906.png differ diff --git a/pic/image-20241027223052428.png b/pic/image-20241027223052428.png new file mode 100644 index 0000000000000000000000000000000000000000..7244ce0907953ee72623c0f1324ddcb18487e0f4 Binary files /dev/null and b/pic/image-20241027223052428.png differ diff --git a/pic/image-20241027223453489.png b/pic/image-20241027223453489.png new file mode 100644 index 0000000000000000000000000000000000000000..694afd99cb332bc85f244da025323beb4aab0968 Binary files /dev/null and b/pic/image-20241027223453489.png differ diff --git a/pic/image-20241027223542816.png b/pic/image-20241027223542816.png new file mode 100644 index 0000000000000000000000000000000000000000..bb60a4442b6401a7e4334e382de57db79827a104 Binary files /dev/null and b/pic/image-20241027223542816.png differ diff --git a/pic/image-20241027223742358.png b/pic/image-20241027223742358.png new file mode 100644 index 0000000000000000000000000000000000000000..0d7f97294e5028ba31d9e903d704574e04e944b8 Binary files /dev/null and b/pic/image-20241027223742358.png differ diff --git "a/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/HiPico\351\225\234\345\203\217\347\203\247\345\275\225\346\214\207\345\215\227.md" "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/HiPico\351\225\234\345\203\217\347\203\247\345\275\225\346\214\207\345\215\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..c241cc37adae14da6bbe814829cd424e9d984f44 --- /dev/null +++ "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/HiPico\351\225\234\345\203\217\347\203\247\345\275\225\346\214\207\345\215\227.md" @@ -0,0 +1,78 @@ +# HiPico镜像烧录指南 + +HiPico使用hitools工具烧录HiPico开发板 + +[点此跳转下载烧录工具]() + +## 烧录工具 + +解压ToolPlatform-CAM-5.6.58-win32-x86_64.zip之后,双击目录中**ToolPlatform.exe**即可使用 + +## 安装USB驱动 + +hitools工具可使用**串口、网络、USB**接口进行烧录。若不使用USB烧录则不需要进行安装USB驱动的步骤。 + +1. 运行**zadig_2.5.exe**文件 + + ![image-20241027214656594](../pic/image-20241027214656594.png) + +2. 选择 Options->List All Devices,将 List All Devices 勾上 + + ![image-20241027214854749](../pic/image-20241027214854749.png) + +3. 进入update模式:按下update按键不松手,随后**重新上下电**或者**按下并松开reset按键**,随后可松开update按键 + +4. 在红色方框位置选择正确的设备(USBBurn),然后方框内选择驱动(libusbK)。点击“Install Driver”(未安装过)或者“Replace Driver”(已安装过) + + ![image-20241027220855071](../pic/image-20241027220855071.png) + + ![image-20241027221410263](../pic/image-20241027221410263.png) + + ![image-20241027221445335](../pic/image-20241027221445335.png) + +5. 重新进入update模式按照上述的方式继续安装**libusb-win32** + + ![image-20241027221257451](../pic/image-20241027221257451.png) + +## 镜像包内容 + +烧录镜像前需要准备好镜像包,包括以下文件: + +1. burn_table.xml: 烧录分区表 +1. boot_image.bin: u-boot镜像 +1. nand_env.bin: u-boot环境变量 +1. uImage: Linux内核镜像 +1. openeuler-image-hipico-*.rootfs.ubi: 根文件系统镜像 + +## 烧录镜像(USB方式) + +1. 打开烧录工具,第一次打开时会提示选择芯片,选择**Hi3516CV610** + + ![image-20241027222134378](../pic/image-20241027222134378.png) + +2. 点击BurnTool进入烧录界面 + + ![image-20241027222240284](../pic/image-20241027222240284.png) + +3. 选择烧录方式及镜像包 + + ![image-20241027222610538](../pic/image-20241027222610538.png) + +4. 选择rootfs镜像 + + ![image-20241027223022906](../pic/image-20241027223022906.png) + + ![image-20241027223052428](../pic/image-20241027223052428.png) + +5. 开始烧录 + + ![image-20241027223453489](../pic/image-20241027223453489.png) + +6. 下方的控制台会显示烧录的详细过程,烧录错误时可根据控制台中的信息判断错误原因 + + ![image-20241027223542816](../pic/image-20241027223542816.png) + +7. 烧录成功 + + ![image-20241027223742358](../pic/image-20241027223742358.png) + diff --git "a/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/conda\344\275\277\347\224\250\346\211\213\345\206\214.md" "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/conda\344\275\277\347\224\250\346\211\213\345\206\214.md" new file mode 100644 index 0000000000000000000000000000000000000000..4767668ba73f7d966ddc6492e1cba0af13a64af9 --- /dev/null +++ "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/conda\344\275\277\347\224\250\346\211\213\345\206\214.md" @@ -0,0 +1,68 @@ +# conda使用手册 + +系统版本:Ubuntu 18.04.6 LTS (Bionic Beaver) + +## 安装Anaconda + +[Anaconda官网](https://www.anaconda.com/) + +[Anaconda3-2024.02-1-Linux-x86_64](https://repo.anaconda.com/archive/Anaconda3-2024.02-1-Linux-x86_64.sh) + +[所有版本](https://repo.anaconda.com/archive/) + +首先下载Anaconda3安装脚本 + +```shell +# 添加可执行权限 +chmod +x Anaconda3-2024.02-1-Linux-x86_64.sh +# 安装 +# 首先会显示检查协议,点击回车检查协议 +# 点击q停止查看协议,此时输入yes同意协议 +# 输入安装路径回车 +# 确认是否在开启一个shell时自动激活conda(yes/no) 选择yes +./Anaconda3-2024.02-1-Linux-x86_64.sh +# 重新开启一个终端可以看到在命令提示符之前多了一段,例如下面这样 +(base) compile_04@compile +``` + +## 虚拟环境的使用 + +安装conda之后,可创建虚拟环境,在虚拟环境中配置python环境不影响系统中的python环境。使用虚拟环境时通过`conda activate`激活环境。 + +```shell +# -n 指定虚拟环境的名称后续会用到 +# 后续跟虚拟环境中要装的软件包,也可以为空,此处以python3.11为例 +# conda create -n [依赖...] +conda create -n python=3.11 + +# 激活虚拟环境 +conda activate + +# 查看现有的虚拟环境 +conda info -e + +# 删除虚拟环境 +conda remove -n --all + +# 退出环境,不加环境名称直接退出当前环境到base +conda deactivate +``` + +## 虚拟环境中软件包的安装 + +```shell +# 列出已安装的软件包 +conda list +# 搜索指定软件包 +conda search package_name +# 安装软件包,大部分使用pip的软件包,可以使用conda安装 +conda install package_name +# 安装指定版本(不建议,大部分时候conda可自动解决依赖) +conda install package_name=1.5.0 +# 更新软件包 +conda update package_name +# 删除软件包 +conda remove package_name +``` + +除了使用conda安装之外pip也可正常使用 diff --git "a/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/oebuild&bitbake\344\275\277\347\224\250\347\254\224\350\256\260.md" "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/oebuild&bitbake\344\275\277\347\224\250\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..0a4ae0318a8615517d43a51381a79076bd17c026 --- /dev/null +++ "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/oebuild&bitbake\344\275\277\347\224\250\347\254\224\350\256\260.md" @@ -0,0 +1,79 @@ +# oebuild&bitbake使用笔记 + +## oebuild + +oebuild是openeuler开发环境构建的工具。主要在创建、进入开发环境时使用。 + +> oebuild对python的版本要求比较高,至少为python3.8及以上,版本越高越好。 + +```shell +# 创建开发环境 +oebuild init + +# 更新oebuild环境,拉取最新镜像、源码等 +oebuild update + +# 显示帮助信息 +oebuild generate --help + +# 显示支持的平台和特性 +oebuild generate --list + +# 创建镜像构建环境 +oebuild generate -p <平台> -d <构建目录> [-f <特性> ...] + +# 进入构建环境 +oebuild bitbake + +# 不进入构建环境,仅执行bitbake命令 +oebuild bitbake <命令> +``` + +## bitbake + +bitbake是构建镜像使用的命令,bitbake按照指定的**配方**进行构建。 + +```shell +# 构建指定配方中的指定任务 +bitbake <配方名> [-c <任务>] +``` + +例子: + +```shell +# 构建openeuler镜像 +bitbake openeuler-image +``` + +其中openeuler-image就是配方名,配方名中一般不包含_下划线,对应的文件为<配方名>.bb,openeuler-image对应的配方路径为`yocto-meta-openeuler/meta-openeuler/recipes-core/images/openeuler-image.bb` + +每个配方可包含多个任务,若执行bitbake时不使用-c指定需要执行的任务,则会执行默认的任务`do_build`,若想查看配方有哪些可执行的任务,可以执行`bitbake <配方名> -c listtasks`查看可执行的任务。 + +当一个任务因为系统卡顿、网络错误等原因出现错误时,可根据日志中的错误信息,定位对应的配方。使用`bitbake <配方名> -c clean`清空对应配方的构建,重新构建即可。 + +``` +| make[2]: Leaving directory '/home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/binutils-2.41/build.arm-openeuler-linux-gnueabi.arm-openeuler-linux-gnueabi/gold' +| make[1]: *** [Makefile:6884: all-gold] Error 2 +| make[1]: Leaving directory '/home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/binutils-2.41/build.arm-openeuler-linux-gnueabi.arm-openeuler-linux-gnueabi' +| make: *** [Makefile:1005: all] Error 2 +| ERROR: oe_runmake failed +| WARNING: /home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/temp/run.do_compile.1334057:189 exit 1 from 'exit 1' +| WARNING: Backtrace (BB generated script): +| #1: bbfatal_log, /home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/temp/run.do_compile.1334057, line 189 +| #2: die, /home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/temp/run.do_compile.1334057, line 173 +| #3: oe_runmake, /home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/temp/run.do_compile.1334057, line 168 +| #4: autotools_do_compile, /home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/temp/run.do_compile.1334057, line 163 +| #5: do_compile, /home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/temp/run.do_compile.1334057, line 158 +| #6: main, /home/openeuler/build/build_arm64/tmp/work/armv7a-vfp-openeuler-linux-gnueabi/binutils/2.41-r0/temp/run.do_compile.1334057, line 202 +ERROR: Task (/usr1/openeuler/src/yocto-poky/../yocto-meta-openeuler/meta-openeuler/recipes-devtools/binutils/binutils_2.41.bb:do_compile) failed with exit code '1' +NOTE: Tasks Summary: Attempted 2143 tasks of which 0 didn't need to be rerun and 1 failed. + +Summary: 1 task failed: + /usr1/openeuler/src/yocto-poky/../yocto-meta-openeuler/meta-openeuler/recipes-devtools/binutils/binutils_2.41.bb:do_compile +Summary: There were 6 WARNING messages. +Summary: There were 2 ERROR messages, returning a non-zero exit code. +``` + +以上面的错误为例,出错的配方为`/usr1/openeuler/src/yocto-poky/../yocto-meta-openeuler/meta-openeuler/recipes-devtools/binutils/binutils_2.41.bb:do_compile`,binutils为配方名,2.41为版本号,do_compile是出错的任务。 + +此时可以清除binutils重新编译`bitbake binutils -c clean` \ No newline at end of file diff --git "a/\345\237\272\347\241\200\345\274\200\345\217\221\347\216\257\345\242\203\346\220\255\345\273\272.md" "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/\345\237\272\347\241\200\345\274\200\345\217\221\347\216\257\345\242\203\346\220\255\345\273\272.md" similarity index 74% rename from "\345\237\272\347\241\200\345\274\200\345\217\221\347\216\257\345\242\203\346\220\255\345\273\272.md" rename to "\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/\345\237\272\347\241\200\345\274\200\345\217\221\347\216\257\345\242\203\346\220\255\345\273\272.md" index 537c06a9e1af29f86cb3db17a91577a58e8626e6..23fb4b9851497ec07ee468d92d6815d54341db09 100644 --- "a/\345\237\272\347\241\200\345\274\200\345\217\221\347\216\257\345\242\203\346\220\255\345\273\272.md" +++ "b/\345\274\200\345\217\221\345\267\245\345\205\267\344\275\277\347\224\250/\345\237\272\347\241\200\345\274\200\345\217\221\347\216\257\345\242\203\346\220\255\345\273\272.md" @@ -4,23 +4,23 @@ 1.1 打开VMware Workstation 17,选择创建新的虚拟机 -![img](./pic/wps1.jpg) +![img](../pic/wps1.jpg) 1.2 选择典型,点击下一步 -![img](./pic/wps2.jpg) +![img](../pic/wps2.jpg) 1.3 选择稍后安装操作系统,点击下一步。 -![img](./pic/wps3.jpg) +![img](../pic/wps3.jpg) 1.4 选择Linux系统,Ubuntu 64位版本,点击下一步。 -![img](./pic/wps4.jpg) +![img](../pic/wps4.jpg) 1.5 设置虚拟机名称以及存储位置,点击下一步。 -![img](./pic/wps5.jpg) +![img](../pic/wps5.jpg) 1.6 指定处理器数量,点击下一步。 @@ -30,155 +30,155 @@ 用户需根据自己的电脑配置(CPU 配置)情况来为虚拟机分配处理器数量以及每个处理器的内核数量,只需满足如下要求: **虚拟机处理器内核总数小于或等于(<=)CPU实际线程数;** -![img](./pic/wps6.jpg) +![img](../pic/wps6.jpg) 1.7 分配内存,点击下一步。 虚拟机的内存大小也需要根据用户的电脑配置(内存配置)情况以及开发需求来设置。 -![img](./pic/wps7.jpg) +![img](../pic/wps7.jpg) 1.8 网络连接,控制器类型,磁盘类型无其他需求默认即可,点击下一步。 -![img](./pic/wps8.jpg) +![img](../pic/wps8.jpg) -![img](./pic/wps9.jpg) +![img](../pic/wps9.jpg) -![img](./pic/wps10.jpg) +![img](../pic/wps10.jpg) -![img](./pic/wps11.jpg) +![img](../pic/wps11.jpg) 1.9 设置磁盘容量,一般开发设置不低于200GB,此设置不意味着马上会占用实际的硬盘容量,而是随着虚拟机中的文件大小变化而变化,选择将虚拟磁盘拆分成多个文件,点击下一步。 -![img](./pic/wps12.jpg) +![img](../pic/wps12.jpg) 1.10 点击自定义硬件,进行其他设置。 -![img](./pic/wps13.jpg) +![img](../pic/wps13.jpg) 1.11 根据电脑配置选择合适的内存和处理器,同时网络适配器需选择桥接模式。 -![img](./pic/wps14.jpg) +![img](../pic/wps14.jpg) 1.12 CD/DVD需设置使用的Ubuntu 22.04镜像ISO文件。 -![img](./pic/wps15.jpg) +![img](../pic/wps15.jpg) 1.13 设置完以上参数后,点击完成。 -![img](./pic/wps16.jpg) +![img](../pic/wps16.jpg) 1.14 完成后的虚拟机设置,暂不开启虚拟机。 -![img](./pic/wps17.jpg) +![img](../pic/wps17.jpg) 1.15 点击菜单栏的编辑,选择虚拟网络编辑器。 -![img](./pic/wps18.jpg) +![img](../pic/wps18.jpg) 1.16 点击右下角的更改设置。 -![img](./pic/wps19.jpg) +![img](../pic/wps19.jpg) 1.17 选择VMnet0,设置为桥接模式,并选择桥接至当前正在使用的网口(无线网卡或者有线网卡)。 -![img](./pic/wps20.jpg) +![img](../pic/wps20.jpg) 1.18 此时即可点击开启此虚拟机。 -![img](./pic/wps21.jpg) +![img](../pic/wps21.jpg) 1.19 开启虚拟机后会进入Ubuntu的安装菜单,选择Try or Install Ubuntu。 -![img](./pic/wps22.jpg) +![img](../pic/wps22.jpg) - 如果没有出现以上菜单而是提示没有操作系统,按以下操作,先点击①挂载CD/DVD,在点击②选择重启虚拟机。 -![img](./pic/wps23.jpg) +![img](../pic/wps23.jpg) 1.20 进入安装流程,建议选择英文,点击Install Ubuntu。 -![img](./pic/wps24.jpg) +![img](../pic/wps24.jpg) 1.21 选择输入法,点击Continue。 -![img](./pic/wps25.jpg) +![img](../pic/wps25.jpg) 1.22 选择最小安装Minimal installation,后续再根据需要安装其他软件,去掉安装时下载更新,加快安装流程,点击Continue。 -![img](./pic/wps26.jpg) +![img](../pic/wps26.jpg) 1.23 点击擦除整个磁盘安装Ubuntu,此时只是擦除虚拟机磁盘,不是对实际物理磁盘进行擦除,点击Install Now。 -![img](./pic/wps27.jpg) +![img](../pic/wps27.jpg) 1.24 弹窗窗口选择Continue。 -![img](./pic/wps28.jpg) +![img](../pic/wps28.jpg) 1.25 选择时区。 -![img](./pic/wps29.jpg) +![img](../pic/wps29.jpg) 1.26 设置用户名和密码。 -![img](./pic/wps30.jpg) +![img](../pic/wps30.jpg) 1.27 等待安装完成。 -![img](./pic/wps31.jpg) +![img](../pic/wps31.jpg) 1.28 安装完成后点击Restart Now。 -![img](./pic/wps32.jpg) +![img](../pic/wps32.jpg) - 注意:如果重启后还是安装程序(右下角有Install Ubuntu图标),此时需要先关机,移除安装镜像后再重启。 -![img](./pic/wps33.jpg) +![img](../pic/wps33.jpg) - 右上角点击关机图标,选择关机Power Off。 -![img](./pic/wps34.jpg) +![img](../pic/wps34.jpg) - 遇到此页面直接按Enter。 -![img](./pic/wps35.jpg) +![img](../pic/wps35.jpg) - 点击编辑虚拟机设置。 -![img](./pic/wps36.jpg) +![img](../pic/wps36.jpg) - CD/DVD设置项中去掉使用ISO映像文件。 -![img](./pic/wps37.jpg) +![img](../pic/wps37.jpg) ## **2.基础配置** ### 2.1 开机引导,根据个人需求选择,无特别需求可参考下面的选项选择 -![img](./pic/wps38.jpg) +![img](../pic/wps38.jpg) -![img](./pic/wps39.jpg) +![img](../pic/wps39.jpg) -![img](./pic/wps40.jpg) +![img](../pic/wps40.jpg) -![img](./pic/wps41.jpg) +![img](../pic/wps41.jpg) -![img](./pic/wps42.jpg) +![img](../pic/wps42.jpg) ### **2.2 安装VMware tools** 在创建好的虚拟机上点击“**虚拟机(M)**"打开虚拟机设置界面: -![img](./pic/wps43.jpg) +![img](../pic/wps43.jpg) -![img](./pic/wps44.jpg) +![img](../pic/wps44.jpg) 点击DVD图标,打开后找到VMware Tools压缩文件,并将其复制到桌面。 -![img](./pic/wps45.jpg) +![img](../pic/wps45.jpg) - ![img](./pic/wps46.jpg) + ![img](../pic/wps46.jpg) 使用快捷键ctrl+alt+t打开终端,解压后切换至VMwareTool目录 @@ -186,21 +186,21 @@ sudo ./vmware-install.pl ``` -![img](./pic/wps47.jpg) +![img](../pic/wps47.jpg) -![img](./pic/wps48.jpg) +![img](../pic/wps48.jpg) -![img](./pic/wps49.jpg) +![img](../pic/wps49.jpg) ### **2.3 修改软件更新源阿里** -![img](./pic/wps50.jpg) +![img](../pic/wps50.jpg) -![img](./pic/wps51.jpg) +![img](../pic/wps51.jpg) -![img](./pic/wps52.jpg) +![img](../pic/wps52.jpg) -![img](./pic/wps53.jpg) +![img](../pic/wps53.jpg) **2.4 打开命令行,安装vim** @@ -209,9 +209,9 @@ sudo apt-get upgrade sudo apt-get install vim ``` -![img](./pic/wps54.jpg) +![img](../pic/wps54.jpg) -![img](./pic/wps55.jpg) +![img](../pic/wps55.jpg) - 修改VIM配置 @@ -235,7 +235,7 @@ set ts=4 "设置tab键为4个空格 <一个tab键的长度> set showmatch "括号匹配高亮显示 ``` -![img](./pic/wps56.jpg) +![img](../pic/wps56.jpg) ### **2.5 NFS安装** @@ -246,15 +246,15 @@ sudo apt-get install rpm sudo apt-get install net-tools ``` -![img](./pic/wps57.jpg) +![img](../pic/wps57.jpg) -![img](./pic/wps58.jpg) +![img](../pic/wps58.jpg) -![img](./pic/wps59.jpg) +![img](../pic/wps59.jpg) - 创建NFS路径以及配置环境变量 -![img](./pic/wps60.jpg) +![img](../pic/wps60.jpg) ```bash #添加NFS路径 @@ -266,9 +266,9 @@ mount -t nfs -o nolock -o tcp -o rsize=32768,wsize=32768 192.168.2.52:/home/ebai sudo systemctl restart nfs-kernel-server ``` -![img](./pic/wps61.jpg) +![img](../pic/wps61.jpg) -![img](./pic/wps62.jpg) +![img](../pic/wps62.jpg) ### **2.6 SSH安装** @@ -277,15 +277,15 @@ sudo apt install openssh-server -y sudo systemctl enable --now ssh ``` -![img](./pic/wps63.jpg) +![img](../pic/wps63.jpg) - 电脑SSH连接虚拟机配置 -![img](./pic/wps64.jpg) +![img](../pic/wps64.jpg) -![img](./pic/wps65.jpg) +![img](../pic/wps65.jpg) -![img](./pic/wps66.jpg) +![img](../pic/wps66.jpg) ### **2.7 SMB安装** @@ -295,9 +295,9 @@ sudo smbpasswd -a ebaina sudo vi /etc/samba/smb.conf ``` -![img](./pic/wps67.jpg) +![img](../pic/wps67.jpg) -![img](./pic/wps68.jpg) +![img](../pic/wps68.jpg) - 配置SMB环境变量 @@ -317,7 +317,7 @@ available = yes writable = yes ``` -![img](./pic/wps69.jpg) +![img](../pic/wps69.jpg) ```bash sudo service smbd restart @@ -325,18 +325,18 @@ sudo service smbd restart - 电脑端映射SMB -![img](./pic/wps70.jpg) +![img](../pic/wps70.jpg) -![img](./pic/wps71.jpg) +![img](../pic/wps71.jpg) -![img](./pic/wps72.jpg) +![img](../pic/wps72.jpg) -![img](./pic/wps73.jpg) +![img](../pic/wps73.jpg) -![img](./pic/wps74.jpg) +![img](../pic/wps74.jpg) -![img](./pic/wps75.jpg) +![img](../pic/wps75.jpg) -![img](./pic/wps76.jpg) +![img](../pic/wps76.jpg) \ No newline at end of file