diff --git a/arch/loongarch/boot/dts/loongson2k1000.dtsi b/arch/loongarch/boot/dts/loongson2k1000.dtsi index ed44b5495..1b1938d0a 100644 --- a/arch/loongarch/boot/dts/loongson2k1000.dtsi +++ b/arch/loongarch/boot/dts/loongson2k1000.dtsi @@ -13,6 +13,26 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + serial5 = &uart5; + serial6 = &uart6; + serial7 = &uart7; + serial8 = &uart8; + serial9 = &uart9; + serial10 = &uart10; + serial11 = &uart11; + i2c0 = &i2c2; + i2c1 = &i2c3; + spi0 = &spi0; + ethernet0 = &gmac0; + ethernet1 = &gmac1; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -312,6 +332,13 @@ }; }; + sdio_default:sdio_as_default { + mux { + groups = "sdio"; + function = "sdio"; + }; + }; + lio_default:lio { mux { groups = "dvo0_lio_uart"; @@ -355,7 +382,7 @@ interrupts = <28 IRQ_TYPE_LEVEL_HIGH>, <29 IRQ_TYPE_LEVEL_HIGH>, <30 IRQ_TYPE_LEVEL_HIGH>, - <30 IRQ_TYPE_LEVEL_HIGH>, + <31 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, <26 IRQ_TYPE_LEVEL_HIGH>, @@ -426,54 +453,16 @@ #thermal-sensor-cells = <1>; }; - apbdma0: dma-controller@1fe00c00 { - compatible = "loongson,ls2k1000-apbdma"; - reg = <0x0 0x1fe00c00 0x0 0x8>; + dma: dma@0x1fe00c00 { + compatible = "loongson,lsia-dma"; + reg = <0x0 0x1fe00c00 0x0 0x100>; + #config-nr = <5>; interrupt-parent = <&liointc1>; - interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk LOONGSON2_APB_CLK>; - #dma-cells = <1>; - status = "disabled"; - }; - - apbdma1: dma-controller@1fe00c10 { - compatible = "loongson,ls2k1000-apbdma"; - reg = <0x0 0x1fe00c10 0x0 0x8>; - interrupt-parent = <&liointc1>; - interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk LOONGSON2_APB_CLK>; - #dma-cells = <1>; - status = "disabled"; - }; - - apbdma2: dma-controller@1fe00c20 { - compatible = "loongson,ls2k1000-apbdma"; - reg = <0x0 0x1fe00c20 0x0 0x8>; - interrupt-parent = <&liointc1>; - interrupts = <14 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk LOONGSON2_APB_CLK>; - #dma-cells = <1>; - status = "disabled"; - }; - - apbdma3: dma-controller@1fe00c30 { - compatible = "loongson,ls2k1000-apbdma"; - reg = <0x0 0x1fe00c30 0x0 0x8>; - interrupt-parent = <&liointc1>; - interrupts = <15 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk LOONGSON2_APB_CLK>; - #dma-cells = <1>; - status = "disabled"; - }; - - dma-controller@1fe00c40 { - compatible = "loongson,ls2k1000-apbdma"; - reg = <0x0 0x1fe00c40 0x0 0x8>; - interrupt-parent = <&liointc1>; - interrupts = <16 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk LOONGSON2_APB_CLK>; - #dma-cells = <1>; - status = "disabled"; + interrupts = <12 IRQ_TYPE_LEVEL_HIGH>, <13 IRQ_TYPE_LEVEL_HIGH>, + <14 IRQ_TYPE_LEVEL_HIGH>, <15 IRQ_TYPE_LEVEL_HIGH>, + <16 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <2>; + dma-channels = <5>; }; uart0: serial@1fe20000 { @@ -482,6 +471,8 @@ clock-frequency = <125000000>; interrupt-parent = <&liointc0>; interrupts = <0x0 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_4_default>; no-loopback-test; status = "okay"; }; @@ -605,6 +596,11 @@ reg = <0x0 0x1fe21000 0x0 0x8>; interrupt-parent = <&liointc0>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk LOONGSON2_APB_CLK>; + clock-names = "i2c-clk"; + bus_div_mode = <0>; status = "disabled"; }; @@ -613,29 +609,58 @@ reg = <0x0 0x1fe21800 0x0 0x8>; interrupt-parent = <&liointc0>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk LOONGSON2_APB_CLK>; + clock-names = "i2c-clk"; + bus_div_mode = <0>; status = "disabled"; }; - pmc: power-management@1fe27000 { - compatible = "loongson,ls2k1000-pmc", "loongson,ls2k0500-pmc", "syscon"; + sdio0: sdio@0x1fe2c000 { + #address-cells = <2>; + compatible = "loongson,ls2k_sdio_1.1"; + reg = <0 0x1fe2c000 0 0x100>; + interrupt-parent = <&liointc0>; + interrupts = <31 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "ls2k_mci_irq"; + dma-mask = <0xffffffff 0xffffffff>; + clock-frequency = <0 125000000>; + dmas = <&dma 3 0xaae>; + dma-names = "sdio_rw"; + bus-width = <4>; + max-frequency = <25000000>; + pinctrl-0 = <&sdio_default>; + pinctrl-names = "default"; + status = "disabled"; + }; + + pmc: syscon@0x1fe27000 { + compatible = "syscon"; reg = <0x0 0x1fe27000 0x0 0x58>; - interrupt-parent = <&liointc1>; - interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; - loongson,suspend-address = <0x0 0x1c000500>; + }; - syscon-reboot { - compatible = "syscon-reboot"; - offset = <0x30>; - mask = <0x1>; - }; + reboot { + compatible ="syscon-reboot"; + regmap = <&pmc>; + offset = <0x30>; + mask = <0x1>; + }; - syscon-poweroff { - compatible = "syscon-poweroff"; - regmap = <&pmc>; - offset = <0x14>; - mask = <0x3c00>; - value = <0x3c00>; - }; + poweroff { + compatible ="syscon-poweroff"; + regmap = <&pmc>; + offset = <0x14>; + mask = <0x3c00>; + value = <0x3c00>; + }; + + wdt:watchdog@1fe27030{ + compatible = "loongson,ls2x-wdt"; + reg = <0 0x1fe27030 0 0xC>; + clocks = <&clk LOONGSON2_APB_CLK>; + clock-names = "wdt-clk"; + status = "okay"; }; rtc0: rtc@1fe27800 { @@ -654,13 +679,15 @@ interrupt-parent = <&liointc0>; interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk LOONGSON2_APB_CLK>; - dmas = <&apbdma2 0>, <&apbdma3 0>; + dmas = <&dma 2 0xaae>, <&dma 1 0xaae>; dma-names = "tx", "rx"; #sound-dai-cells = <0>; status = "disabled"; }; spi0: spi@1fff0220 { + #address-cells = <1>; + #size-cells = <0>; compatible = "loongson,ls2k1000-spi"; reg = <0x0 0x1fff0220 0x0 0x10>; clocks = <&clk LOONGSON2_BOOT_CLK>; @@ -676,8 +703,7 @@ interrupt-parent = <&liointc0>; interrupts = <20 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "nand_irq"; - - dmas = <&apbdma0 1>; + dmas = <&dma 0 0xaae>; dma-names = "nand_rw"; dma-mask = <0xffffffff 0xffffffff>; @@ -789,7 +815,7 @@ }; otg: usb@40000000 { - compatible = "loongson,dwc2-otg"; + compatible = "loongson,loongson2-dwc2"; reg = <0 0x40000000 0 0x40000>; interrupt-parent = <&liointc1>; interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; @@ -830,6 +856,7 @@ reg = <0 0x400e0000 0 0x10000>; interrupt-parent = <&liointc0>; interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; + dma-mask = <0xffffffff 0xffffffff>; status = "disabled"; }; diff --git a/arch/loongarch/boot/dts/ls2k1000_dp.dts b/arch/loongarch/boot/dts/ls2k1000_dp.dts index c2edefe31..6c6f470ba 100644 --- a/arch/loongarch/boot/dts/ls2k1000_dp.dts +++ b/arch/loongarch/boot/dts/ls2k1000_dp.dts @@ -12,12 +12,6 @@ / { model = "LS2K1000-DP-V10"; - aliases { - serial0 = &uart0; - ethernet0 = &gmac0; - ethernet1 = &gmac1; - }; - chosen { stdout-path = "serial0:115200n8"; bootargs = "earlycon"; @@ -193,10 +187,10 @@ status = "okay"; #address-cells = <1>; - #size-cells = <0>; + #size-cells = <0>; spi-flash@0 { compatible = "jedec,spi-nor"; - spi-max-frequency = <30000000>; + spi-max-frequency = <25000000>; reg = <0>; /* CS0 */ partitions { @@ -302,6 +296,7 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; @@ -320,6 +315,7 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; diff --git a/arch/loongarch/boot/dts/ls2k300_alientek.dts b/arch/loongarch/boot/dts/ls2k300_alientek.dts index 470896166..2aa08f95d 100644 --- a/arch/loongarch/boot/dts/ls2k300_alientek.dts +++ b/arch/loongarch/boot/dts/ls2k300_alientek.dts @@ -30,7 +30,7 @@ gpios = <&gpio 70 GPIO_ACTIVE_LOW>; linux,default-trigger = "none"; default-state = "on"; - status = "okay"; + status = "okay"; }; }; @@ -145,6 +145,7 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; @@ -163,6 +164,7 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; @@ -251,7 +253,7 @@ loongson,sound-card-name = "ES8388"; }; -&pinmux{ +&pinmux{ /*/驱动GPIO子系统实验 pinctrl_gpio_62: pinmux_G62_as_gpio { pinctrl-single,bits = <0xc 0x00000000 0x30000000>; diff --git a/arch/loongarch/boot/dts/ls2k300_g2k03z0_core_v10.dtsi b/arch/loongarch/boot/dts/ls2k300_g2k03z0_core_v10.dtsi index 84fce005f..86eb11564 100644 --- a/arch/loongarch/boot/dts/ls2k300_g2k03z0_core_v10.dtsi +++ b/arch/loongarch/boot/dts/ls2k300_g2k03z0_core_v10.dtsi @@ -64,10 +64,12 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; -// &emmc { -// mmc-hs200-1_8v; -// }; +&emmc { + // mmc-hs200-1_8v; + clk-need-stable = <0>; +}; diff --git a/arch/loongarch/boot/dts/ls2k300_gongkong_gbkpgk0.dts b/arch/loongarch/boot/dts/ls2k300_gongkong_gbkpgk0.dts index 212b0be30..4e42d229f 100644 --- a/arch/loongarch/boot/dts/ls2k300_gongkong_gbkpgk0.dts +++ b/arch/loongarch/boot/dts/ls2k300_gongkong_gbkpgk0.dts @@ -156,6 +156,7 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; @@ -174,6 +175,7 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; diff --git a/arch/loongarch/boot/dts/ls2k300_vanguard_pi_common.dtsi b/arch/loongarch/boot/dts/ls2k300_vanguard_pi_common.dtsi index 389ca5a69..6ba1b7211 100644 --- a/arch/loongarch/boot/dts/ls2k300_vanguard_pi_common.dtsi +++ b/arch/loongarch/boot/dts/ls2k300_vanguard_pi_common.dtsi @@ -144,6 +144,7 @@ motorcomm,led0_cfg = <0x40>; //千兆常亮 motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮 motorcomm,led2_cfg = <0x2600>; //有数据时闪烁 + motorcomm,keep-pll-enabled = <1>; }; }; }; diff --git a/arch/loongarch/configs/loongson_2k1000_defconfig b/arch/loongarch/configs/loongson_2k1000_defconfig index 9b0ca55fe..530905964 100644 --- a/arch/loongarch/configs/loongson_2k1000_defconfig +++ b/arch/loongarch/configs/loongson_2k1000_defconfig @@ -6,7 +6,7 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y -CONFIG_PREEMPT_RT=y +CONFIG_PREEMPT=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -43,8 +43,8 @@ CONFIG_CMDLINE="fbcon=logo-pos:center fbcon=logo-count:1" CONFIG_CMDLINE_EXTEND=y CONFIG_BUILTIN_DTB=y # CONFIG_SCHED_SMT is not set -CONFIG_SMP=y CONFIG_NR_CPUS=2 +CONFIG_NUMA=y # CONFIG_SUSPEND is not set CONFIG_PM=y # CONFIG_ACPI_AC is not set @@ -75,12 +75,10 @@ CONFIG_ZSWAP=y CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y CONFIG_ZBUD=y # CONFIG_COMPAT_BRK is not set -CONFIG_SPARSEMEM_MANUAL=y CONFIG_PAGE_REPORTING=y CONFIG_KSM=y CONFIG_CMA=y CONFIG_CMA_SYSFS=y -CONFIG_CMA_AREAS=20 CONFIG_USERFAULTFD=y CONFIG_NET=y CONFIG_PACKET=y @@ -352,7 +350,6 @@ CONFIG_EFI_ZBOOT=y CONFIG_EFI_BOOTLOADER_CONTROL=m CONFIG_EFI_CAPSULE_LOADER=m CONFIG_EFI_TEST=m -# CONFIG_EFI_DISABLE_RUNTIME is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y @@ -545,6 +542,7 @@ CONFIG_I2C_GPIO=y CONFIG_I2C_LS2X=y CONFIG_SPI=y CONFIG_SPI_LOONGSON_PLATFORM=y +CONFIG_SPI_SPIDEV=y CONFIG_PINCTRL=y CONFIG_PINCTRL_LOONGSON2=y CONFIG_PINCTRL_SINGLE=y @@ -552,16 +550,18 @@ CONFIG_GPIO_SYSFS=y CONFIG_GPIO_LOONGSON_IRQCHIP=y CONFIG_GPIO_LOONGSON_64BIT=y CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_PCA953X_IRQ=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_RESTART=y CONFIG_POWER_RESET_SYSCON=y CONFIG_POWER_RESET_SYSCON_POWEROFF=y CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_SENSORS_GPIO_FAN=y CONFIG_SENSORS_W83795=m CONFIG_SENSORS_W83627HF=m CONFIG_THERMAL=y CONFIG_LOONGSON2_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_LOONGSON2_WDT=y # CONFIG_MEDIA_CEC_SUPPORT is not set CONFIG_MEDIA_SUPPORT=y # CONFIG_DVB_CORE is not set @@ -694,7 +694,6 @@ CONFIG_RTC_DRV_DS1307=y CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_LOONGSON=y CONFIG_DMADEVICES=y -CONFIG_LOONGSON2_APB_DMA=y CONFIG_LSIA_DMA=y CONFIG_UDMABUF=y CONFIG_DMABUF_HEAPS=y diff --git a/arch/loongarch/configs/loongson_2k1000_no_dc_defconfig b/arch/loongarch/configs/loongson_2k1000_no_dc_defconfig new file mode 100644 index 000000000..1f119d63d --- /dev/null +++ b/arch/loongarch/configs/loongson_2k1000_no_dc_defconfig @@ -0,0 +1,752 @@ +CONFIG_LOCALVERSION=".lsgd" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_PREEMPT=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_RDMA=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_MISC=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PERF_EVENTS=y +CONFIG_KEXEC=y +CONFIG_LOONGSON_2K1000=y +CONFIG_HZ_1000=y +CONFIG_CMDLINE="fbcon=logo-pos:center fbcon=logo-count:1" +CONFIG_CMDLINE_EXTEND=y +CONFIG_BUILTIN_DTB=y +# CONFIG_SCHED_SMT is not set +CONFIG_SMP=y +CONFIG_NR_CPUS=2 +# CONFIG_SUSPEND is not set +CONFIG_PM=y +# CONFIG_ACPI_AC is not set +# CONFIG_ACPI_BATTERY is not set +# CONFIG_ACPI_BUTTON is not set +# CONFIG_ACPI_FAN is not set +# CONFIG_ACPI_PROCESSOR is not set +# CONFIG_ACPI_TABLE_UPGRADE is not set +CONFIG_JUMP_LABEL=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_ZONED=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_BLK_WBT=y +CONFIG_BLK_CGROUP_IOLATENCY=y +CONFIG_BLK_CGROUP_IOCOST=y +CONFIG_BLK_CGROUP_IOPRIO=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_BSD_DISKLABEL=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_ZSWAP=y +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y +CONFIG_ZBUD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_PAGE_REPORTING=y +CONFIG_KSM=y +CONFIG_CMA=y +CONFIG_CMA_SYSFS=y +CONFIG_CMA_AREAS=20 +CONFIG_USERFAULTFD=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_TLS=m +CONFIG_TLS_DEVICE=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=y +CONFIG_XDP_SOCKETS=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_ESP_OFFLOAD=m +CONFIG_INET_ESPINTCP=y +CONFIG_INET_IPCOMP=m +CONFIG_INET_UDP_DIAG=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BBR=m +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_ESP_OFFLOAD=y +CONFIG_INET6_ESPINTCP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_MROUTE=y +CONFIG_MPTCP=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NFT_CT=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_FIB_INET=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NETFILTER_XT_SET=m +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_NFCT=y +CONFIG_NFT_DUP_IPV4=m +CONFIG_NFT_FIB_IPV4=m +CONFIG_NF_TABLES_ARP=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_SYNPROXY=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_NFT_FIB_IPV6=m +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_SRH=m +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_SYNPROXY=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NF_CONNTRACK_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_IP_SCTP=m +CONFIG_RDS=y +CONFIG_L2TP=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +CONFIG_LLC2=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_CLS_BPF=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_BPF=m +CONFIG_OPENVSWITCH=m +CONFIG_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_NETLINK_DIAG=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_BPF_STREAM_PARSER=y +CONFIG_CAN=y +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y +CONFIG_BT_HCIBTUSB_MTK=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_ATH3K=m +CONFIG_BT_VIRTIO=m +CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=y +# CONFIG_PCIEASPM is not set +# CONFIG_VGA_ARB is not set +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_SW_SWITCHTEC=m +CONFIG_UEVENT_HELPER=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_ZSTD=y +CONFIG_EFI_ZBOOT=y +CONFIG_EFI_BOOTLOADER_CONTROL=m +CONFIG_EFI_CAPSULE_LOADER=m +CONFIG_EFI_TEST=m +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_RAW_NAND=y +# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set +CONFIG_MTD_SPI_NOR=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_VIRTIO_BLK=y +CONFIG_EEPROM_AT24=m +CONFIG_BLK_DEV_SD=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_AHCI_DWC=y +CONFIG_NETDEVICES=y +CONFIG_BONDING=m +CONFIG_DUMMY=y +CONFIG_WIREGUARD=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_IPVLAN=m +CONFIG_VXLAN=y +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +# 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_ASIX is not set +# CONFIG_NET_VENDOR_ATHEROS 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_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_CORTINA is not set +# CONFIG_NET_VENDOR_DAVICOM 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_ENGLEDER is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FUNGIBLE is not set +# CONFIG_NET_VENDOR_GOOGLE is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_ADI is not set +# CONFIG_NET_VENDOR_LITEX is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_META 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_MICROSOFT is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NI 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_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_VENDOR_PENSANDO is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_BROCADE 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_SILAN is not set +# CONFIG_NET_VENDOR_SIS 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_STMMAC_ETH=y +# CONFIG_DWMAC_LOONGSON 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_VERTEXCOM is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WANGXUN is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_MOTORCOMM_PHY=y +CONFIG_REALTEK_PHY=m +CONFIG_CAN_SJA1000=y +CONFIG_CAN_SJA1000_PLATFORM=y +CONFIG_CAN_LSCANFD=y +CONFIG_CAN_LSCANFD_PLATFORM=y +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +# CONFIG_WLAN_VENDOR_ADMTEK is not set +# CONFIG_WLAN_VENDOR_ATH is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +# CONFIG_WLAN_VENDOR_BROADCOM is not set +# CONFIG_WLAN_VENDOR_INTEL is not set +# CONFIG_WLAN_VENDOR_INTERSIL is not set +# CONFIG_WLAN_VENDOR_MARVELL is not set +# CONFIG_WLAN_VENDOR_MEDIATEK is not set +# CONFIG_WLAN_VENDOR_MICROCHIP is not set +# CONFIG_WLAN_VENDOR_PURELIFI is not set +CONFIG_RT2X00=m +CONFIG_RT2800USB=m +# CONFIG_RT2800USB_RT33XX is not set +# CONFIG_RT2800USB_RT35XX is not set +CONFIG_RTL8187=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +CONFIG_RTL8192EE=m +CONFIG_RTL8821AE=m +CONFIG_RTL8192CU=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8XXXU=m +CONFIG_RTW88=m +CONFIG_RTW88_8822BU=m +CONFIG_RTW88_8822CU=m +CONFIG_RTW88_8723DU=m +CONFIG_RTW88_8821CU=m +# CONFIG_WLAN_VENDOR_RSI is not set +# CONFIG_WLAN_VENDOR_SILABS is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +# CONFIG_WLAN_VENDOR_QUANTENNA is not set +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_XTKBD=m +# CONFIG_MOUSE_PS2 is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GOODIX=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m +CONFIG_SERIO=m +CONFIG_SERIO_LIBPS2=m +CONFIG_SERIO_RAW=m +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=16 +CONFIG_SERIAL_8250_RUNTIME_UARTS=16 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_RSA=y +# CONFIG_SERIAL_8250_PERICOM is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_I2C=y +# CONFIG_ACPI_I2C_OPREGION is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_GPIO=y +CONFIG_I2C_LS2X=y +CONFIG_SPI=y +CONFIG_SPI_LOONGSON_PLATFORM=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_LOONGSON2=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_LOONGSON_IRQCHIP=y +CONFIG_GPIO_LOONGSON_64BIT=y +CONFIG_GPIO_PCA953X=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_RESTART=y +CONFIG_POWER_RESET_SYSCON=y +CONFIG_POWER_RESET_SYSCON_POWEROFF=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_SENSORS_W83795=m +CONFIG_SENSORS_W83627HF=m +CONFIG_THERMAL=y +CONFIG_LOONGSON2_THERMAL=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_BT87X=m +CONFIG_SND_BT87X_OVERCLOCK=y +CONFIG_SND_HDA_INTEL=y +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_LOONGSON=y +CONFIG_SND_LS=y +CONFIG_SND_LS_PCM=y +CONFIG_SND_LS_PCM_GENERIC_DMA=y +CONFIG_SND_SOC_ES8328_I2C=y +CONFIG_SND_VIRTIO=m +CONFIG_HIDRAW=y +CONFIG_UHID=m +CONFIG_HID_A4TECH=m +CONFIG_HID_CHERRY=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_LOGITECH_DJ=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_SUNPLUS=m +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +# CONFIG_USB_PCI is not set +CONFIG_USB_OTG=y +CONFIG_USB_MON=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=y +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_GADGET=y +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_ACPI=m +CONFIG_MMC=y +# CONFIG_PWRSEQ_EMMC is not set +CONFIG_MMC_LS2K=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_EFI=y +CONFIG_RTC_DRV_LOONGSON=y +CONFIG_DMADEVICES=y +CONFIG_LSIA_DMA=y +CONFIG_SYNC_FILE=y +CONFIG_UDMABUF=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=y +CONFIG_UIO_DMEM_GENIRQ=y +# CONFIG_VIRTIO_MENU is not set +# CONFIG_VHOST_MENU is not set +# CONFIG_LOONGARCH_PLATFORM_DEVICES is not set +CONFIG_COMMON_CLK_LOONGSON2=y +# CONFIG_COMMON_CLK_LOONGSON2X is not set +CONFIG_IOMMU_DEBUGFS=y +CONFIG_LOONGSON2_GUTS=y +CONFIG_LOONGSON2_PM=y +CONFIG_IIO=y +CONFIG_LS_2K300_ADC=y +CONFIG_PWM=y +CONFIG_PWM_LOONGSON=y +CONFIG_GENERIC_PHY=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_EXPORTFS_BLOCK_OPS=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_AUTOFS_FS=y +CONFIG_OVERLAY_FS=y +CONFIG_OVERLAY_FS_INDEX=y +CONFIG_OVERLAY_FS_XINO_AUTO=y +CONFIG_OVERLAY_FS_METACOPY=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_FAT_DEFAULT_IOCHARSET="gb2312" +CONFIG_EXFAT_FS=y +CONFIG_NTFS3_FS=y +CONFIG_NTFS3_64BIT_CLUSTER=y +CONFIG_NTFS3_LZX_XPRESS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_UTF8=y +CONFIG_KEY_DH_OPERATIONS=y +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_YAMA=y +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_CRYPTO_USER=m +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_ESSIV=m +CONFIG_CRYPTO_BLAKE2B=m +CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XXHASH=y +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRC_ITU_T=m +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_SPARC is not set +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=0 +CONFIG_IRQ_POLL=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +# CONFIG_FTRACE is not set +CONFIG_UNWINDER_ORC=y diff --git a/arch/loongarch/configs/loongson_2k300_defconfig b/arch/loongarch/configs/loongson_2k300_defconfig index 851c3a072..03a42abc2 100644 --- a/arch/loongarch/configs/loongson_2k300_defconfig +++ b/arch/loongarch/configs/loongson_2k300_defconfig @@ -689,6 +689,7 @@ CONFIG_LEDS_PWM=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_SD2078=y CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_LOONGSON=y CONFIG_DMADEVICES=y diff --git a/arch/loongarch/configs/loongson_2k300_rt_defconfig b/arch/loongarch/configs/loongson_2k300_rt_defconfig index 962d5b769..9c08252ce 100644 --- a/arch/loongarch/configs/loongson_2k300_rt_defconfig +++ b/arch/loongarch/configs/loongson_2k300_rt_defconfig @@ -686,6 +686,7 @@ CONFIG_LEDS_PWM=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_SD2078=y CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_LOONGSON=y CONFIG_DMADEVICES=y diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c index 242f9a698..49ab1d21c 100644 --- a/arch/loongarch/mm/init.c +++ b/arch/loongarch/mm/init.c @@ -72,6 +72,7 @@ void __init paging_init(void) free_area_init(max_zone_pfns); } +#ifndef CONFIG_NUMA void __init mem_init(void) { max_mapnr = max_low_pfn; @@ -79,6 +80,7 @@ void __init mem_init(void) memblock_free_all(); } +#endif void __ref free_initmem(void) { diff --git a/drivers/i2c/busses/i2c-ls2x.c b/drivers/i2c/busses/i2c-ls2x.c index b475dd27b..47faffdc8 100644 --- a/drivers/i2c/busses/i2c-ls2x.c +++ b/drivers/i2c/busses/i2c-ls2x.c @@ -25,6 +25,7 @@ #include #include #include +#include /* I2C Registers */ #define I2C_LS2X_PRER_LO 0x0 /* Freq Division Low Byte Register */ @@ -63,11 +64,18 @@ /* The default bus frequency, which is an empirical value */ #define LS2X_I2C_FREQ_STD (33 * HZ_PER_KHZ) +#define I2C_BUS_FREQ_DIV_MODE_D4 (0) +#define I2C_BUS_FREQ_DIV_MODE_D5 (1) +#define I2C_BUS_FREQ_DIV_MODE_INVAILD (I2C_BUS_FREQ_DIV_MODE_D5 + 1) + struct ls2x_i2c_priv { + u8 i2c_bus_freq_div_mode; struct i2c_adapter adapter; void __iomem *base; struct i2c_timings i2c_t; struct completion cmd_complete; + u32 bus_frequency; + u64 clock_frequency; }; /* @@ -98,21 +106,20 @@ static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv) u16 val; struct i2c_timings *t = &priv->i2c_t; struct device *dev = priv->adapter.dev.parent; - u32 acpi_speed = i2c_acpi_find_bus_speed(dev); i2c_parse_fw_timings(dev, t, false); - if (acpi_speed || t->bus_freq_hz) - t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed); - else - t->bus_freq_hz = LS2X_I2C_FREQ_STD; - + t->bus_freq_hz = priv->bus_frequency; /* * According to the chip manual, we can only access the registers as bytes, * otherwise the high bits will be truncated. * So set the I2C frequency with a sequential writeb() instead of writew(). */ - val = LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1; + if (priv->i2c_bus_freq_div_mode == I2C_BUS_FREQ_DIV_MODE_D4) + val = priv->clock_frequency / (4 * t->bus_freq_hz) - 1; + else if ((priv->i2c_bus_freq_div_mode == I2C_BUS_FREQ_DIV_MODE_D5)) + val = priv->clock_frequency / (5 * t->bus_freq_hz) - 1; + writeb(FIELD_GET(GENMASK(7, 0), val), priv->base + I2C_LS2X_PRER_LO); writeb(FIELD_GET(GENMASK(15, 8), val), priv->base + I2C_LS2X_PRER_HI); } @@ -284,6 +291,73 @@ static const struct i2c_algorithm ls2x_i2c_algo = { .functionality = ls2x_i2c_func, }; +static void clock_frequency_get(struct platform_device *pdev, struct device *dev, struct ls2x_i2c_priv *priv) +{ + int err; + u32 clk; + struct clk *clk_unit; + + if (!(device_property_read_u32(dev, "clock-frequency", &clk))) + priv->clock_frequency = clk; + else { + clk_unit = devm_clk_get(&pdev->dev, "i2c-clk"); + + if(IS_ERR(clk_unit)) + goto err_def; + + err = clk_prepare_enable(clk_unit); + if (err) + goto err_def; + + clk = clk_get_rate(clk_unit); + if (!clk) { + clk_disable_unprepare(clk_unit); + goto err_def; + } + + priv->clock_frequency = clk; + clk_unit = NULL; + return; +err_def: + pr_info("i2c-ls2x %s warning: cant get i2c input clock, default value 125000000", pdev->name); + priv->clock_frequency = 125000000; + clk_unit = NULL; + } +} + +static void bus_frequency_get(struct platform_device *pdev, struct device *dev, struct ls2x_i2c_priv *priv) +{ + u32 bus_freq; + + priv->bus_frequency = 0; + + if (!(device_property_read_u32(dev, "bus_freq", &bus_freq))) + priv->bus_frequency = bus_freq; + else + priv->bus_frequency = i2c_acpi_find_bus_speed(dev); + + if (!(priv->bus_frequency)) + priv->bus_frequency = 100000; // default 100KHz +} + +static void bus_frequency_div_mode_get(struct platform_device *pdev, struct device *dev, struct ls2x_i2c_priv *priv) +{ + u32 mode; + + priv->i2c_bus_freq_div_mode = 255; + + if (!(device_property_read_u32(dev, "bus_div_mode", &mode))) + priv->i2c_bus_freq_div_mode = mode; + else + priv->i2c_bus_freq_div_mode = I2C_BUS_FREQ_DIV_MODE_D5; + + if (mode >= I2C_BUS_FREQ_DIV_MODE_INVAILD) + priv->i2c_bus_freq_div_mode = I2C_BUS_FREQ_DIV_MODE_D4; + + if (priv->i2c_bus_freq_div_mode == 255) + priv->i2c_bus_freq_div_mode = I2C_BUS_FREQ_DIV_MODE_D4; +} + static int ls2x_i2c_probe(struct platform_device *pdev) { int ret, irq; @@ -304,6 +378,13 @@ static int ls2x_i2c_probe(struct platform_device *pdev) if (irq < 0) return irq; + clock_frequency_get(pdev, dev, priv); + dev_info(dev, "i2c dev input clock is %lld Hz\n", priv->clock_frequency); + bus_frequency_get(pdev, dev, priv); + dev_info(dev, "i2c dev bus clock is %d Hz\n", priv->bus_frequency); + bus_frequency_div_mode_get(pdev, dev, priv); + dev_info(dev, "i2c dev bus clock generate mode is %d\n", priv->i2c_bus_freq_div_mode); + /* Add the i2c adapter */ adap = &priv->adapter; adap->retries = 5; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4dbfae874..74085f524 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -1118,7 +1118,7 @@ config MMC_LITEX config MMC_LS2K tristate "loongson 2k SD/MMC Card Interface support" - depends on LOONGARCH && LOONGSON2_APB_DMA + depends on LOONGARCH help This selects a driver for the MCI interface found in loongson 2k CPU.If you have a board based on it and a MMC/SD diff --git a/drivers/mmc/host/ls2kmci.c b/drivers/mmc/host/ls2kmci.c index 35a4af5de..cdb9f2811 100644 --- a/drivers/mmc/host/ls2kmci.c +++ b/drivers/mmc/host/ls2kmci.c @@ -70,7 +70,7 @@ static const int dbgmap_err = dbg_fail; static const int dbgmap_info = dbg_info | dbg_conf; static const int dbgmap_debug = dbg_err | dbg_debug; -static void __iomem *cd_gpio_inten_base; +// static void __iomem *cd_gpio_inten_base; #define dbg(host, channels, args...) \ do { \ if (dbgmap_err & channels) \ @@ -694,8 +694,8 @@ static void ls2k_mci_send_request(struct mmc_host *mmc) if (retry_n < 500) udelay(10); } - if (retry_n < 0) - printk("Warning: may losing int when tx fifo is not full\n"); + // if (retry_n < 0) + // printk("Warning: may losing int when tx fifo is not full\n"); } #endif @@ -726,14 +726,16 @@ static void ls2k_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* Set the power state */ mci_con = readl(host->base + SDICON); u32 dll; + u32 clk_stable_delay; int ret; + clk_stable_delay = host->clk_need_stable ? 100 : 1; ls2k_mci_disable_irq(host, true); switch (ios->power_mode) { case MMC_POWER_ON: case MMC_POWER_UP: writel(SDICON_RESET, host->base + SDICON); - mdelay(100); + mdelay(clk_stable_delay); writel(0x3, host->base + SDICON); if (host->pdata->version >= LOONGSON_SDIO_EMMC_VER_1_1) writel(SDIINT_CLEARALL, host->base + SDIINTMSK); @@ -765,7 +767,7 @@ static void ls2k_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ret = of_property_read_u32(pdev->dev.of_node, "dll", &dll); if (ret == 0) ls2k_mci_set_dll(host, dll); - mdelay(100); + mdelay(clk_stable_delay); ls2k_mci_enable_irq(host, true); } @@ -866,8 +868,8 @@ static int ls2k_mci_probe(struct platform_device *pdev) struct dma_chan *chan; __be32 *of_property = NULL; struct mmc_gpio *ctx; - int cd_gpio_num; - u64 val; + // int cd_gpio_num; + // u64 val; if (dev_fwnode(&pdev->dev)) { if (!device_property_read_u64(&pdev->dev, "dma-mask", @@ -915,12 +917,12 @@ static int ls2k_mci_probe(struct platform_device *pdev) } host->phys_base = r->start; - if (r->start == LS2K1000_SDIO_REG_BASE) - cd_gpio_inten_base = (void *)LS2K1000_GPIO_INTEN_BASE; - else if (r->start == LS2K0500_SDIO0_REG_BASE) - cd_gpio_inten_base = (void *)LS2K0500_SDIO0_GPIO_INTEN_BASE; - else if (r->start == LS2K0500_SDIO1_REG_BASE) - cd_gpio_inten_base = (void *)LS2K0500_SDIO1_GPIO_INTEN_BASE; + // if (r->start == LS2K1000_SDIO_REG_BASE) + // cd_gpio_inten_base = (void *)LS2K1000_GPIO_INTEN_BASE; + // else if (r->start == LS2K0500_SDIO0_REG_BASE) + // cd_gpio_inten_base = (void *)LS2K0500_SDIO0_GPIO_INTEN_BASE; + // else if (r->start == LS2K0500_SDIO1_REG_BASE) + // cd_gpio_inten_base = (void *)LS2K0500_SDIO1_GPIO_INTEN_BASE; host->base = ioremap(r->start, r->end - r->start + 1); @@ -983,6 +985,14 @@ static int ls2k_mci_probe(struct platform_device *pdev) device_property_read_u64(&pdev->dev, "clock-frequency", (u64 *)&host->clk_rate); } + host->clk_need_stable = 1; + if (dev_fwnode(&pdev->dev)) { + if (device_property_read_u32(&pdev->dev, "clk-need-stable", (u32 *)&host->clk_need_stable)) + host->clk_need_stable = 1; + } + host->clk_need_stable = !!(host->clk_need_stable); + dev_info(&pdev->dev, "clk_need_stable: %d\n", host->clk_need_stable); + mmc->ops = &ls2k_mci_ops; mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; @@ -1008,16 +1018,16 @@ static int ls2k_mci_probe(struct platform_device *pdev) ctx = mmc->slot.handler_priv; - if (!(mmc->caps & MMC_CAP_NONREMOVABLE) && - !(mmc->caps & MMC_CAP_NEEDS_POLL) && cd_gpio_inten_base) { - cd_gpio_num = desc_to_gpio(ctx->cd_gpio); - local_irq_save(flags); - val = readq((void *)cd_gpio_inten_base); - val |= (0x1 << cd_gpio_num); - writeq(val, (void *)cd_gpio_inten_base); - local_irq_restore(flags); - ls2k_mci_gpio_get_cd(mmc); - } + // if (!(mmc->caps & MMC_CAP_NONREMOVABLE) && + // !(mmc->caps & MMC_CAP_NEEDS_POLL) && cd_gpio_inten_base) { + // cd_gpio_num = desc_to_gpio(ctx->cd_gpio); + // local_irq_save(flags); + // val = readq((void *)cd_gpio_inten_base); + // val |= (0x1 << cd_gpio_num); + // writeq(val, (void *)cd_gpio_inten_base); + // local_irq_restore(flags); + // ls2k_mci_gpio_get_cd(mmc); + // } ret = mmc_add_host(mmc); if (ret) { dev_err(&pdev->dev, "failed to add mmc host.\n"); diff --git a/drivers/mmc/host/ls2kmci.h b/drivers/mmc/host/ls2kmci.h index 5340d0556..8df06c129 100644 --- a/drivers/mmc/host/ls2kmci.h +++ b/drivers/mmc/host/ls2kmci.h @@ -266,6 +266,7 @@ struct ls2k_mci_host { #endif struct dma_chan *chan; unsigned int app_cmd; + unsigned int clk_need_stable; }; struct ls2k_mci_pdata { diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 9581c86f8..7e8d29bd6 100644 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -1731,9 +1731,12 @@ static int yt8531_config_init(struct phy_device *phydev) if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) { /* enable RXC clock when no wire plug */ + ret = ytphy_write_ext(phydev, 0xa000, 0); + ret = ytphy_modify_ext_with_lock(phydev, - YT8521_CLOCK_GATING_REG, - YT8521_CGR_RX_CLK_EN, 0); + YT8521_CLOCK_GATING_REG, + (1 << 12 | 0x1 << 1 | 0x1 << 2 | 0xf << 4), + (0x1 << 1 | 0x1 << 2 | 0x8 << 4)); if (ret < 0) return ret; } diff --git a/drivers/pinctrl/pinctrl-loongson2.c b/drivers/pinctrl/pinctrl-loongson2.c index 4d4fbeada..91f59be9b 100644 --- a/drivers/pinctrl/pinctrl-loongson2.c +++ b/drivers/pinctrl/pinctrl-loongson2.c @@ -1,312 +1,552 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Author: zhanghongchen - * Yinbo Zhu - * Copyright (C) 2022-2023 Loongson Technology Corporation Limited - */ - +// SPDX-License-Identifier: GPL-2.0 #include #include #include -#include +#include #include #include -#include -#include -#include +#include #include - #include "core.h" #include "pinctrl-utils.h" -#define PMX_GROUP(name, offset, bitv) \ +/* + useful groups: + "sata_led", "gmac1", "dvo0_lio_uart", "dvo1_camera", "can0", "can1", + "hda_i2s", "i2c0", "i2c1", "uart0", "uart1", "uart2", "nand", + "pwm0", "pwm1", "pwm2", "pwm3", "sdio" + */ + +/* + useful functions: + "sata_led", "gpio", "gmac1", "dvo0", "lio", + "uart1_4", "uart1_2", "uart1_1", "uart2_4", "uart2_2", "uart2_1", + "dvo1", "camera", "can0", "can1", "hda", "i2s", "i2c0", "i2c1", + "uart0_4", "uart0_2", "uart0_1", + "nand", "pwm0", "pwm1", "pwm2", "pwm3", "sdio" + */ + +/* + * usage: + uart2_4_default:uart2_4 { + mux { + groups = "uart2"; + function = "uart2_4"; + }; + }; + + ---------------------------------- + + uart_group1: bus1 { + compatible = "simple-pm-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pinctrl-names = "default"; + pinctrl-0 = <&uart1_4_default>; + groups 能用什么 functions 见于 使用FUNCTION_GROUP_MAP_CREATE宏的代码 + 一份dts里面理论上不能出现同样的 groups的使用。像上面的声明可以有相同的组 + 但是在 类似 uart_group1: bus1 里面 pinctrl-0这样就不能用到同样的 groups + */ + +#define PMX_GROUP(group_name) \ { \ - .grp = PINCTRL_PINGROUP((#name), (name ## _pins), \ - ARRAY_SIZE((name ## _pins))), \ - .reg = offset, \ - .bit = bitv, \ + .name = #group_name, \ + .pins = group_name ## _pins, \ + .num_pins = ARRAY_SIZE(group_name ## _pins), \ + .bit_size = ARRAY_SIZE(group_name ## _reg), \ + .reg = group_name ## _reg, \ + .bit = group_name ## _bit, \ + .bit_width = group_name ## _bit_width, \ } -#define SPECIFIC_GROUP(group) \ - static const char * const group##_groups[] = { \ - #group \ +#define FUNCTION_GROUP_MAP_CREATE(function, single_groups) \ + static const char * const function##_function_groups[] = { \ + single_groups \ } -#define FUNCTION(fn) \ +#define FUNCTION(fn, handle_func, value, mask) \ { \ .name = #fn, \ - .groups = fn ## _groups, \ - .num_groups = ARRAY_SIZE(fn ## _groups), \ + .groups = fn ## _function_groups, \ + .num_groups = ARRAY_SIZE(fn ## _function_groups), \ + .mul_bit_zone_handle_func = handle_func, \ + .bit_value = value,\ + .bit_mask = mask,\ } -struct loongson2_pinctrl { +struct ls2k_pinctrl { struct device *dev; struct pinctrl_dev *pcdev; struct pinctrl_desc desc; struct device_node *of_node; - spinlock_t lock; - void __iomem *reg_base; + raw_spinlock_t lock; + void * __iomem reg_base; }; -struct loongson2_pmx_group { - struct pingroup grp; - unsigned int reg; - unsigned int bit; +struct ls2k_pmx_group { + const char *name; + const unsigned int *pins; + unsigned int num_pins; + unsigned char bit_size; + unsigned int* reg; + unsigned int* bit; + unsigned char* bit_width; }; -struct loongson2_pmx_func { +struct ls2k_pmx_func { const char *name; const char * const *groups; unsigned int num_groups; + + int (*mul_bit_zone_handle_func)(unsigned long, unsigned int); + unsigned int* bit_value; + unsigned char* bit_mask; }; -#define LOONGSON2_PIN(x) PINCTRL_PIN(x, "gpio"#x) -static const struct pinctrl_pin_desc loongson2_pctrl_pins[] = { - LOONGSON2_PIN(0), LOONGSON2_PIN(1), LOONGSON2_PIN(2), LOONGSON2_PIN(3), - LOONGSON2_PIN(4), LOONGSON2_PIN(5), LOONGSON2_PIN(6), LOONGSON2_PIN(7), - LOONGSON2_PIN(8), LOONGSON2_PIN(9), LOONGSON2_PIN(10), LOONGSON2_PIN(11), - LOONGSON2_PIN(12), LOONGSON2_PIN(13), LOONGSON2_PIN(14), - LOONGSON2_PIN(16), LOONGSON2_PIN(17), LOONGSON2_PIN(18), LOONGSON2_PIN(19), - LOONGSON2_PIN(20), LOONGSON2_PIN(21), LOONGSON2_PIN(22), LOONGSON2_PIN(23), - LOONGSON2_PIN(24), LOONGSON2_PIN(25), LOONGSON2_PIN(26), LOONGSON2_PIN(27), - LOONGSON2_PIN(28), LOONGSON2_PIN(29), LOONGSON2_PIN(30), - LOONGSON2_PIN(32), LOONGSON2_PIN(33), LOONGSON2_PIN(34), LOONGSON2_PIN(35), - LOONGSON2_PIN(36), LOONGSON2_PIN(37), LOONGSON2_PIN(38), LOONGSON2_PIN(39), - LOONGSON2_PIN(40), LOONGSON2_PIN(41), - LOONGSON2_PIN(44), LOONGSON2_PIN(45), LOONGSON2_PIN(46), LOONGSON2_PIN(47), - LOONGSON2_PIN(48), LOONGSON2_PIN(49), LOONGSON2_PIN(50), LOONGSON2_PIN(51), - LOONGSON2_PIN(52), LOONGSON2_PIN(53), LOONGSON2_PIN(54), LOONGSON2_PIN(55), - LOONGSON2_PIN(56), LOONGSON2_PIN(57), LOONGSON2_PIN(58), LOONGSON2_PIN(59), - LOONGSON2_PIN(60), LOONGSON2_PIN(61), LOONGSON2_PIN(62), LOONGSON2_PIN(63), +/* + * register pin desc but not so important + * because ls2k1000 pin No is compilcate such as Y22 + * so dont match to all pin + */ +#define LS2K_PIN(pin_num, groups) PINCTRL_PIN(pin_num, groups) +static const struct pinctrl_pin_desc ls2k_pctrl_pins[] = { + LS2K_PIN(1, "SATA_LEDN"), + LS2K_PIN(2, "GMAC1_14_pin"), + LS2K_PIN(17, "uart1_dvo0_pin"), + LS2K_PIN(3, "uart2_dvo0_pin"), + LS2K_PIN(4, "dvo1_camera_pin"), + LS2K_PIN(5, "can0"), LS2K_PIN(6, "can1"), + LS2K_PIN(7, "hda_i2s"), + LS2K_PIN(8, "i2c0"), LS2K_PIN(9, "i2c1"), + LS2K_PIN(10, "uart0"), + LS2K_PIN(11, "nand"), + LS2K_PIN(12, "pwm0"), LS2K_PIN(13, "pwm1"), LS2K_PIN(14, "pwm2"), LS2K_PIN(15, "pwm3"), + LS2K_PIN(16, "sdio"), }; -static const unsigned int gpio_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 46, 55, - 56, 57, 58, 59, 60, 61, 62, 63}; -static const unsigned int sdio_pins[] = {36, 37, 38, 39, 40, 41}; -static const unsigned int can1_pins[] = {34, 35}; -static const unsigned int can0_pins[] = {32, 33}; -static const unsigned int pwm3_pins[] = {23}; -static const unsigned int pwm2_pins[] = {22}; -static const unsigned int pwm1_pins[] = {21}; -static const unsigned int pwm0_pins[] = {20}; -static const unsigned int i2c1_pins[] = {18, 19}; -static const unsigned int i2c0_pins[] = {16, 17}; -static const unsigned int nand_pins[] = {44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63}; -static const unsigned int sata_led_pins[] = {14}; -static const unsigned int i2s_pins[] = {24, 25, 26, 27, 28}; -static const unsigned int hda_pins[] = {24, 25, 26, 27, 28, 29, 30}; +/* + * 下面的数组 可以观测得知 一共分为 _pins _reg _bit _bit_width四大组 + * 然后每个数组的前缀都是groups里面的一个 比如 sata_led uart等等 + * 如果需要添加,那么希望按照这个规则添加 + * 因为这些都是为了契合 PMX_GROUP 这个宏 + * 而这个宏的目的 就是为了 填充 ls2k_pmx_group 变量 + * group_name ## _pins 这样是把宏参数和_pins拼接,那么就明白为什么数组的名字要这样命名。 + * _pins 数组是groups包括的引脚的物理编号的集合,呼应ls2k_pctrl_pins,事实上如果为空或者乱填也没关系。 + * _reg 数组是配置寄存器相对于基地址的偏移值的集合 有多少个要设置的位域就要有多少个元素 + * _bit 数组是配置寄存器中要设置的位域的最低位的偏移值 从0开始算,芯片手册的配置寄存器可知。 + * _bit_width 数组是配置寄存器中要设置的位域的位宽,和 _bit 数组就能描述这个位域的位置。 + */ +static const unsigned int sata_led_pins[]={1}; +static const unsigned int gmac1_pins[]={2}; +static const unsigned int dvo0_lio_uart_pins[]={3, 17}; +static const unsigned int uart1_pins[]={17}; +static const unsigned int uart2_pins[]={3}; +static const unsigned int dvo1_camera_pins[]={4}; +static const unsigned int can0_pins[]={5}; +static const unsigned int can1_pins[]={6}; +static const unsigned int hda_i2s_pins[]={7}; +static const unsigned int i2c0_pins[]={8}; +static const unsigned int i2c1_pins[]={9}; +static const unsigned int uart0_pins[]={10}; +static const unsigned int nand_pins[]={11}; +static const unsigned int pwm0_pins[]={12}; +static const unsigned int pwm1_pins[]={13}; +static const unsigned int pwm2_pins[]={14}; +static const unsigned int pwm3_pins[]={15}; +static const unsigned int sdio_pins[]={16}; -static struct loongson2_pmx_group loongson2_pmx_groups[] = { - PMX_GROUP(gpio, 0x0, 64), - PMX_GROUP(sdio, 0x0, 20), - PMX_GROUP(can1, 0x0, 17), - PMX_GROUP(can0, 0x0, 16), - PMX_GROUP(pwm3, 0x0, 15), - PMX_GROUP(pwm2, 0x0, 14), - PMX_GROUP(pwm1, 0x0, 13), - PMX_GROUP(pwm0, 0x0, 12), - PMX_GROUP(i2c1, 0x0, 11), - PMX_GROUP(i2c0, 0x0, 10), - PMX_GROUP(nand, 0x0, 9), - PMX_GROUP(sata_led, 0x0, 8), - PMX_GROUP(i2s, 0x0, 6), - PMX_GROUP(hda, 0x0, 4), +static unsigned int sata_led_reg[] = {0}; +static unsigned int gmac1_reg[] = {0}; +static unsigned int dvo0_lio_uart_reg[] = {0x10, 0x8, 0x8, 0, 0x8, 0x8}; +static unsigned int uart1_reg[] = {0x10, 0x8, 0x8, 0, 0x8, 0x8}; +static unsigned int uart2_reg[] = {0x10, 0x8, 0x8, 0, 0x8, 0x8}; +static unsigned int dvo1_camera_reg[] = {0x10, 0x10}; +static unsigned int can0_reg[] = {0}; +static unsigned int can1_reg[] = {0}; +static unsigned int hda_i2s_reg[] = {0, 0}; +static unsigned int i2c0_reg[] = {0}; +static unsigned int i2c1_reg[] = {0}; +static unsigned int uart0_reg[] = {0x8}; +static unsigned int nand_reg[] = {0}; +static unsigned int pwm0_reg[] = {0}; +static unsigned int pwm1_reg[] = {0}; +static unsigned int pwm2_reg[] = {0}; +static unsigned int pwm3_reg[] = {0}; +static unsigned int sdio_reg[] = {0}; + +static unsigned int sata_led_bit[] = {8}; +static unsigned int gmac1_bit[] = {3}; +static unsigned int dvo0_lio_uart_bit[] = {1, 12, 13, 7, 4, 8}; +static unsigned int uart1_bit[] = {1, 12, 13, 7, 4, 8}; +static unsigned int uart2_bit[] = {1, 12, 13, 7, 4, 8}; +static unsigned int dvo1_camera_bit[] = {4, 5}; +static unsigned int can0_bit[] = {16}; +static unsigned int can1_bit[] = {17}; +static unsigned int hda_i2s_bit[] = {6, 4}; +static unsigned int i2c0_bit[] = {10}; +static unsigned int i2c1_bit[] = {11}; +static unsigned int uart0_bit[] = {0}; +static unsigned int nand_bit[] = {9}; +static unsigned int pwm0_bit[] = {12}; +static unsigned int pwm1_bit[] = {13}; +static unsigned int pwm2_bit[] = {14}; +static unsigned int pwm3_bit[] = {15}; +static unsigned int sdio_bit[] = {20}; + +static unsigned char sata_led_bit_width[] = {1}; +static unsigned char gmac1_bit_width[] = {1}; +static unsigned char dvo0_lio_uart_bit_width[] = {1, 1, 1, 1, 4, 4}; +static unsigned char uart1_bit_width[] = {1, 1, 1, 1, 4, 4}; +static unsigned char uart2_bit_width[] = {1, 1, 1, 1, 4, 4}; +static unsigned char dvo1_camera_bit_width[] = {1, 1}; +static unsigned char can0_bit_width[] = {1}; +static unsigned char can1_bit_width[] = {1}; +static unsigned char hda_i2s_bit_width[] = {1, 1}; +static unsigned char i2c0_bit_width[] = {1}; +static unsigned char i2c1_bit_width[] = {1}; +static unsigned char uart0_bit_width[] = {4}; +static unsigned char nand_bit_width[] = {1}; +static unsigned char pwm0_bit_width[] = {1}; +static unsigned char pwm1_bit_width[] = {1}; +static unsigned char pwm2_bit_width[] = {1}; +static unsigned char pwm3_bit_width[] = {1}; +static unsigned char sdio_bit_width[] = {1}; + +//上面的数组就是在这里用的。 +static struct ls2k_pmx_group ls2k_pmx_groups[] = { + PMX_GROUP(sata_led), + PMX_GROUP(gmac1), + PMX_GROUP(dvo0_lio_uart), + PMX_GROUP(uart1), + PMX_GROUP(uart2), + PMX_GROUP(dvo1_camera), + PMX_GROUP(can0), + PMX_GROUP(can1), + PMX_GROUP(hda_i2s), + PMX_GROUP(i2c0), + PMX_GROUP(i2c1), + PMX_GROUP(uart0), + PMX_GROUP(nand), + PMX_GROUP(pwm0), + PMX_GROUP(pwm1), + PMX_GROUP(pwm2), + PMX_GROUP(pwm3), + PMX_GROUP(sdio), }; -SPECIFIC_GROUP(sdio); -SPECIFIC_GROUP(can1); -SPECIFIC_GROUP(can0); -SPECIFIC_GROUP(pwm3); -SPECIFIC_GROUP(pwm2); -SPECIFIC_GROUP(pwm1); -SPECIFIC_GROUP(pwm0); -SPECIFIC_GROUP(i2c1); -SPECIFIC_GROUP(i2c0); -SPECIFIC_GROUP(nand); -SPECIFIC_GROUP(sata_led); -SPECIFIC_GROUP(i2s); -SPECIFIC_GROUP(hda); +/* + * 这里管理的是function + * 包括 function所属的groups(这个groups可以设置的functions) 和 怎么设置配置寄存器让function生效 + * FUNCTION_GROUP_MAP_CREATE 做的工作其实就是声明一个 _function_groups数组 + * 这个数组里面的字符串就是宏参数。 + * 数组前缀是function的名字 数组里面的内容是groups的名字 + * 这里的含义就是 function所属的groups(这个groups可以设置的functions) 的声明 + * 接着下面的那些数字的数组,就是functions生效的那些配置寄存器的位域的值 + * 那些数组还要对应上面的_bit _bit_width 数组 见芯片手册 + * 比如 dvo0 lio uart12 这样的复用 要控制6个位域 所以对应有6个值 + * 但是uart1 和 uart2 是能共存的 所以在 uart1_4_bit_mask 和类似的数组 里面 会有0 + * 0 代表对应的位域不设置,这样就能实现共存。 + * + * FUNCTION 宏代表的是 ls2k_pmx_func 变量的填充 + * 第1个参数是 fucntion的名字 会用在填充 对应 _function_groups 数组到对应的变量中 + * 第2个 是指代function有多个 groups的情况 比如 gpio 这个function + * 可以发现很多个groups都是可以用的,那么如果还是用给定数组来设置位域,那么将会多很多代码 + * 所以把这个过程 使用一个回调函数来实现 见于 ls2k_pmx_set_mux_handle_gpio 的实现 + * 如果 满足通用的设置方法 那么 填入 NULL 并 写好 第3 4参数 + * 第 3 和 第4个参数 就是 位域的值的数组填充,使用另外一套生效办法 这套办法是通用的。 + */ -static const char * const gpio_groups[] = { - "sdio", - "can1", "can0", - "pwm3", "pwm2", "pwm1", "pwm0", - "i2c1", "i2c0", - "nand", - "sata_led", - "i2s", - "hda", +//create const char * const[] name {func}_function_groups to use in ls2k_pmx_functions +FUNCTION_GROUP_MAP_CREATE(sata_led, "sata_led"); +static const char * const gpio_function_groups[] = { + "sdio", "can1", "can0", "pwm3", "pwm2", "pwm1", "pwm0", "i2c1", + "i2c0", "nand", "sata_led", "hda_i2s" +}; +FUNCTION_GROUP_MAP_CREATE(gmac1, "gmac1"); +FUNCTION_GROUP_MAP_CREATE(dvo0, "dvo0_lio_uart"); +FUNCTION_GROUP_MAP_CREATE(lio, "dvo0_lio_uart"); +FUNCTION_GROUP_MAP_CREATE(uart1_4, "uart1"); +FUNCTION_GROUP_MAP_CREATE(uart1_2, "uart1"); +FUNCTION_GROUP_MAP_CREATE(uart1_1, "uart1"); +FUNCTION_GROUP_MAP_CREATE(uart2_4, "uart2"); +FUNCTION_GROUP_MAP_CREATE(uart2_2, "uart2"); +FUNCTION_GROUP_MAP_CREATE(uart2_1, "uart2"); +FUNCTION_GROUP_MAP_CREATE(dvo1, "dvo1_camera"); +FUNCTION_GROUP_MAP_CREATE(camera, "dvo1_camera"); +FUNCTION_GROUP_MAP_CREATE(can0, "can0"); +FUNCTION_GROUP_MAP_CREATE(can1, "can1"); +FUNCTION_GROUP_MAP_CREATE(hda, "hda_i2s"); +FUNCTION_GROUP_MAP_CREATE(i2s, "hda_i2s"); +FUNCTION_GROUP_MAP_CREATE(i2c0, "i2c0"); +FUNCTION_GROUP_MAP_CREATE(i2c1, "i2c1"); +FUNCTION_GROUP_MAP_CREATE(uart0_4, "uart0"); +FUNCTION_GROUP_MAP_CREATE(uart0_2, "uart0"); +FUNCTION_GROUP_MAP_CREATE(uart0_1, "uart0"); +FUNCTION_GROUP_MAP_CREATE(nand, "nand"); +FUNCTION_GROUP_MAP_CREATE(pwm0, "pwm0"); +FUNCTION_GROUP_MAP_CREATE(pwm1, "pwm1"); +FUNCTION_GROUP_MAP_CREATE(pwm2, "pwm2"); +FUNCTION_GROUP_MAP_CREATE(pwm3, "pwm3"); +FUNCTION_GROUP_MAP_CREATE(sdio, "sdio"); + +static unsigned int single_bit_1_on_value[] = {1}; +static unsigned int dvo0_bit_value[] = {1, 0, 0, 0, 0, 0}; +static unsigned int lio_bit_value[] = {0, 0, 0, 1, 0, 0}; +static unsigned int uart1_4_bit_value[] = {0, 1, 0, 0, 0xf, 0}; +static unsigned int uart1_2_bit_value[] = {0, 1, 0, 0, 0x3, 0}; +static unsigned int uart1_1_bit_value[] = {0, 1, 0, 0, 0x1, 0}; +static unsigned int uart2_4_bit_value[] = {0, 0, 1, 0, 0, 0xf}; +static unsigned int uart2_2_bit_value[] = {0, 0, 1, 0, 0, 0x3}; +static unsigned int uart2_1_bit_value[] = {0, 0, 1, 0, 0, 0x1}; +static unsigned int dvo1_bit_value[] = {1, 0}; +static unsigned int camera_bit_value[] = {0, 1}; +static unsigned int hda_bit_value[] = {0, 1}; +static unsigned int i2s_bit_value[] = {1, 0}; +static unsigned int gen_uart_mode4_value[] = {0xf}; +static unsigned int gen_uart_mode2_value[] = {0x3}; +static unsigned int gen_uart_mode1_value[] = {0x1}; + +static unsigned char dvo0_bit_mask[] = {1, 1, 1, 1, 0, 0}; +static unsigned char lio_bit_mask[] = {1, 1, 1, 1, 0, 0}; +static unsigned char uart1_4_bit_mask[] = {1, 1, 0, 1, 1, 0}; +static unsigned char uart1_2_bit_mask[] = {1, 1, 0, 1, 1, 0}; +static unsigned char uart1_1_bit_mask[] = {1, 1, 0, 1, 1, 0}; +static unsigned char uart2_4_bit_mask[] = {1, 0, 1, 1, 0, 1}; +static unsigned char uart2_2_bit_mask[] = {1, 0, 1, 1, 0, 1}; +static unsigned char uart2_1_bit_mask[] = {1, 0, 1, 1, 0, 1}; + +static int ls2k_pmx_set_mux_handle_gpio(unsigned long reg_base, unsigned int group_num); +static struct ls2k_pmx_func ls2k_pmx_functions[] = { + FUNCTION(sata_led, NULL, single_bit_1_on_value, NULL), + FUNCTION(gmac1, NULL, single_bit_1_on_value, NULL), + FUNCTION(gpio, ls2k_pmx_set_mux_handle_gpio, NULL, NULL), + FUNCTION(dvo0, NULL, dvo0_bit_value, dvo0_bit_mask), + FUNCTION(lio, NULL, lio_bit_value, lio_bit_mask), + FUNCTION(uart1_4, NULL, uart1_4_bit_value, uart1_4_bit_mask), + FUNCTION(uart1_2, NULL, uart1_2_bit_value, uart1_2_bit_mask), + FUNCTION(uart1_1, NULL, uart1_1_bit_value, uart1_1_bit_mask), + FUNCTION(uart2_4, NULL, uart2_4_bit_value, uart2_4_bit_mask), + FUNCTION(uart2_2, NULL, uart2_2_bit_value, uart2_2_bit_mask), + FUNCTION(uart2_1, NULL, uart2_1_bit_value, uart2_1_bit_mask), + FUNCTION(dvo1, NULL, dvo1_bit_value, NULL), + FUNCTION(camera, NULL, camera_bit_value, NULL), + FUNCTION(can0, NULL, single_bit_1_on_value, NULL), + FUNCTION(can1, NULL, single_bit_1_on_value, NULL), + FUNCTION(hda, NULL, hda_bit_value, NULL), + FUNCTION(i2s, NULL, i2s_bit_value, NULL), + FUNCTION(i2c0, NULL, single_bit_1_on_value, NULL), + FUNCTION(i2c1, NULL, single_bit_1_on_value, NULL), + FUNCTION(uart0_4, NULL, gen_uart_mode4_value, NULL), + FUNCTION(uart0_2, NULL, gen_uart_mode2_value, NULL), + FUNCTION(uart0_1, NULL, gen_uart_mode1_value, NULL), + FUNCTION(nand, NULL, single_bit_1_on_value, NULL), + FUNCTION(pwm0, NULL, single_bit_1_on_value, NULL), + FUNCTION(pwm1, NULL, single_bit_1_on_value, NULL), + FUNCTION(pwm2, NULL, single_bit_1_on_value, NULL), + FUNCTION(pwm3, NULL, single_bit_1_on_value, NULL), + FUNCTION(sdio, NULL, single_bit_1_on_value, NULL), }; -static const struct loongson2_pmx_func loongson2_pmx_functions[] = { - FUNCTION(gpio), - FUNCTION(sdio), - FUNCTION(can1), - FUNCTION(can0), - FUNCTION(pwm3), - FUNCTION(pwm2), - FUNCTION(pwm1), - FUNCTION(pwm0), - FUNCTION(i2c1), - FUNCTION(i2c0), - FUNCTION(nand), - FUNCTION(sata_led), - FUNCTION(i2s), - FUNCTION(hda), -}; - -static int loongson2_get_groups_count(struct pinctrl_dev *pcdev) +static int ls2k_get_groups_count(struct pinctrl_dev *pcdev) { - return ARRAY_SIZE(loongson2_pmx_groups); + return ARRAY_SIZE(ls2k_pmx_groups); } -static const char *loongson2_get_group_name(struct pinctrl_dev *pcdev, +static const char *ls2k_get_group_name(struct pinctrl_dev *pcdev, unsigned int selector) { - return loongson2_pmx_groups[selector].grp.name; + return ls2k_pmx_groups[selector].name; } -static int loongson2_get_group_pins(struct pinctrl_dev *pcdev, unsigned int selector, +static int ls2k_get_group_pins(struct pinctrl_dev *pcdev, unsigned int selector, const unsigned int **pins, unsigned int *num_pins) { - *pins = loongson2_pmx_groups[selector].grp.pins; - *num_pins = loongson2_pmx_groups[selector].grp.npins; + *pins = ls2k_pmx_groups[selector].pins; + *num_pins = ls2k_pmx_groups[selector].num_pins; return 0; } -static void loongson2_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s, +static void ls2k_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s, unsigned int offset) { seq_printf(s, " %s", dev_name(pcdev->dev)); } -static const struct pinctrl_ops loongson2_pctrl_ops = { - .get_groups_count = loongson2_get_groups_count, - .get_group_name = loongson2_get_group_name, - .get_group_pins = loongson2_get_group_pins, +static const struct pinctrl_ops ls2k_pctrl_ops = { + .get_groups_count = ls2k_get_groups_count, + .get_group_name = ls2k_get_group_name, + .get_group_pins = ls2k_get_group_pins, .dt_node_to_map = pinconf_generic_dt_node_to_map_all, .dt_free_map = pinctrl_utils_free_map, - .pin_dbg_show = loongson2_pin_dbg_show, + .pin_dbg_show = ls2k_pin_dbg_show, }; -static int loongson2_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned int func_num, - unsigned int group_num) +static int ls2k_pmx_set_mux_handle_gpio(unsigned long reg_base, unsigned int group_num) { - struct loongson2_pinctrl *pctrl = pinctrl_dev_get_drvdata(pcdev); - void __iomem *reg = pctrl->reg_base + - loongson2_pmx_groups[group_num].reg; - unsigned int mux_bit = loongson2_pmx_groups[group_num].bit; + int i; + unsigned char bit_size = ls2k_pmx_groups[group_num].bit_size; + unsigned int* reg_offset = ls2k_pmx_groups[group_num].reg; + unsigned int* bit = ls2k_pmx_groups[group_num].bit; + + unsigned long reg_temp; + unsigned int val; - unsigned long flags; - spin_lock_irqsave(&pctrl->lock, flags); - val = readl(reg); - if (func_num == 0) - val &= ~BIT(mux_bit); - else - val |= BIT(mux_bit); - writel(val, reg); - spin_unlock_irqrestore(&pctrl->lock, flags); + for(i = 0; i < bit_size; ++i) { + reg_temp = reg_base + reg_offset[i]; + val = readl((void *)reg_temp); + val &= ~(1 << bit[i]); //gpio always be bit-0 + writel(val, (void *)reg_temp); + } return 0; } -static int loongson2_pmx_get_funcs_count(struct pinctrl_dev *pcdev) +static int ls2k_pmx_set_mux(struct pinctrl_dev *pcdev, unsigned int func_num, + unsigned int group_num) { - return ARRAY_SIZE(loongson2_pmx_functions); + int ret; + int i; + struct ls2k_pinctrl *pctrl = pinctrl_dev_get_drvdata(pcdev); + + int (*handle_func)(unsigned long, unsigned int) = ls2k_pmx_functions[func_num].mul_bit_zone_handle_func; + unsigned int* bit_value = ls2k_pmx_functions[func_num].bit_value; + unsigned char* bit_mask = ls2k_pmx_functions[func_num].bit_mask; + + unsigned char bit_size = ls2k_pmx_groups[group_num].bit_size; + unsigned int* reg_offset = ls2k_pmx_groups[group_num].reg; + unsigned int* bit = ls2k_pmx_groups[group_num].bit; + unsigned char* bit_width = ls2k_pmx_groups[group_num].bit_width; + + unsigned long reg_base = (unsigned long)pctrl->reg_base; + unsigned long reg_temp; + unsigned int bit_value_temp; + + unsigned int val; + unsigned int val_mask; + + unsigned long flags; + + raw_spin_lock_irqsave(&pctrl->lock, flags); + if(handle_func) + ret = handle_func(reg_base, group_num); + else { + for(i = 0; i < bit_size; ++i) { + reg_temp = reg_base + reg_offset[i]; + if(!bit_mask || bit_mask[i]) { + bit_value_temp = bit_value[i]; + bit_value_temp <<= bit[i]; + + //make bit filed mask + val_mask = 1 << bit_width[i]; + --val_mask; + val_mask <<= bit[i]; + + val = readl((void *)reg_temp); + val &= ~val_mask; //use mask clear bit filed + val |= bit_value_temp; //value fix bit filed + writel(val, (void *)reg_temp); + } + } + ret = 0; + } + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + + return ret; } -static const char *loongson2_pmx_get_func_name(struct pinctrl_dev *pcdev, +static int ls2k_pmx_get_funcs_count(struct pinctrl_dev *pcdev) +{ + return ARRAY_SIZE(ls2k_pmx_functions); +} + +static const char *ls2k_pmx_get_func_name(struct pinctrl_dev *pcdev, unsigned int selector) { - return loongson2_pmx_functions[selector].name; + return ls2k_pmx_functions[selector].name; } -static int loongson2_pmx_get_groups(struct pinctrl_dev *pcdev, - unsigned int selector, +static int ls2k_pmx_get_groups(struct pinctrl_dev *pcdev, unsigned int selector, const char * const **groups, unsigned int * const num_groups) { - *groups = loongson2_pmx_functions[selector].groups; - *num_groups = loongson2_pmx_functions[selector].num_groups; + *groups = ls2k_pmx_functions[selector].groups; + *num_groups = ls2k_pmx_functions[selector].num_groups; return 0; } -static const struct pinmux_ops loongson2_pmx_ops = { - .set_mux = loongson2_pmx_set_mux, - .get_functions_count = loongson2_pmx_get_funcs_count, - .get_function_name = loongson2_pmx_get_func_name, - .get_function_groups = loongson2_pmx_get_groups, +const struct pinmux_ops ls2k_pmx_ops = { + .set_mux = ls2k_pmx_set_mux, + .get_functions_count = ls2k_pmx_get_funcs_count, + .get_function_name = ls2k_pmx_get_func_name, + .get_function_groups = ls2k_pmx_get_groups, }; -static int loongson2_pinctrl_probe(struct platform_device *pdev) +static int ls2k_pinctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct loongson2_pinctrl *pctrl; + struct ls2k_pinctrl *pctrl; + struct resource *res; - pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); + pctrl = devm_kzalloc(dev, sizeof(struct ls2k_pinctrl), GFP_KERNEL); if (!pctrl) return -ENOMEM; - pctrl->reg_base = devm_platform_ioremap_resource(pdev, 0); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pctrl->reg_base = devm_ioremap_resource(dev, res); if (IS_ERR(pctrl->reg_base)) return PTR_ERR(pctrl->reg_base); - spin_lock_init(&pctrl->lock); + raw_spin_lock_init(&pctrl->lock); pctrl->dev = dev; - pctrl->desc.name = "pinctrl-loongson2"; + pctrl->desc.name = "pinctrl-ls2k"; pctrl->desc.owner = THIS_MODULE; - pctrl->desc.pctlops = &loongson2_pctrl_ops; - pctrl->desc.pmxops = &loongson2_pmx_ops; - pctrl->desc.pins = loongson2_pctrl_pins; - pctrl->desc.npins = ARRAY_SIZE(loongson2_pctrl_pins); + pctrl->desc.pctlops = &ls2k_pctrl_ops; + pctrl->desc.pmxops = &ls2k_pmx_ops; + pctrl->desc.confops = NULL; + pctrl->desc.pins = ls2k_pctrl_pins; + pctrl->desc.npins = ARRAY_SIZE(ls2k_pctrl_pins); pctrl->pcdev = devm_pinctrl_register(pctrl->dev, &pctrl->desc, pctrl); - if (IS_ERR(pctrl->pcdev)) - return dev_err_probe(pctrl->dev, PTR_ERR(pctrl->pcdev), - "can't register pinctrl device"); + if (IS_ERR(pctrl->pcdev)) { + dev_err(pctrl->dev, "can't register pinctrl device"); + return PTR_ERR(pctrl->pcdev); + } return 0; } -static const struct of_device_id loongson2_pinctrl_dt_match[] = { +static const struct of_device_id ls2k_pinctrl_dt_match[] = { + { + .compatible = "loongson,2k1000-pinctrl", + }, { .compatible = "loongson,ls2k-pinctrl", }, - { } + { }, }; -MODULE_DEVICE_TABLE(of, loongson2_pinctrl_dt_match); -static struct platform_driver loongson2_pinctrl_driver = { - .probe = loongson2_pinctrl_probe, +static struct platform_driver ls2k_pinctrl_driver = { + .probe = ls2k_pinctrl_probe, .driver = { - .name = "loongson2-pinctrl", - .of_match_table = loongson2_pinctrl_dt_match, + .name = "ls2k-pinctrl", + .of_match_table = ls2k_pinctrl_dt_match, }, }; -static int __init loongson2_pinctrl_init(void) +static int __init ls2k_pinctrl_init(void) { - return platform_driver_register(&loongson2_pinctrl_driver); + return platform_driver_register(&ls2k_pinctrl_driver); } -arch_initcall(loongson2_pinctrl_init); +arch_initcall(ls2k_pinctrl_init); -static void __exit loongson2_pinctrl_exit(void) +static void __exit ls2k_pinctrl_exit(void) { - platform_driver_unregister(&loongson2_pinctrl_driver); + platform_driver_unregister(&ls2k_pinctrl_driver); } -module_exit(loongson2_pinctrl_exit); - -MODULE_DESCRIPTION("Loongson2 Pinctrl driver"); -MODULE_LICENSE("GPL"); +module_exit(ls2k_pinctrl_exit); diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 66eb11222..b86e81139 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -753,6 +753,16 @@ config RTC_DRV_SD2405AL This driver can also be built as a module. If so, the module will be called rtc-sd2405al. +config RTC_DRV_SD2078 + tristate "ZXW Shenzhen whwave SD2078" + select REGMAP_I2C + help + If you say yes here you get support for the ZXW Shenzhen whwave + SD2078 RTC chips. + + This driver can also be built as a module. If so, the module + will be called rtc-sd2078 + config RTC_DRV_SD3078 tristate "ZXW Shenzhen whwave SD3078" select REGMAP_I2C diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index f62340ecc..32a124e35 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -164,6 +164,7 @@ obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o obj-$(CONFIG_RTC_DRV_SD2405AL) += rtc-sd2405al.o +obj-$(CONFIG_RTC_DRV_SD2078) += rtc-sd2078.o obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o diff --git a/drivers/rtc/rtc-sd2078.c b/drivers/rtc/rtc-sd2078.c new file mode 100644 index 000000000..655d9f767 --- /dev/null +++ b/drivers/rtc/rtc-sd2078.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Real Time Clock (RTC) Driver for SD2068 + * Copyright (C) 2018 Zoro Li + */ + +#include +#include +#include +#include +#include +#include + +#define SD2068_REG_SC 0x00 +#define SD2068_REG_MN 0x01 +#define SD2068_REG_HR 0x02 +#define SD2068_REG_DW 0x03 +#define SD2068_REG_DM 0x04 +#define SD2068_REG_MO 0x05 +#define SD2068_REG_YR 0x06 + +#define SD2068_REG_CTRL1 0x0f +#define SD2068_REG_CTRL2 0x10 +#define SD2068_REG_CTRL3 0x11 + +#define KEY_WRITE1 0x80 +#define KEY_WRITE2 0x04 +#define KEY_WRITE3 0x80 + +#define NUM_TIME_REGS (SD2068_REG_YR - SD2068_REG_SC + 1) + +/* + * The SD2068 has write protection + * and we can choose whether or not to use it. + * Write protection is turned off by default. + */ +#define WRITE_PROTECT_EN 0 + +struct sd2068 { + struct rtc_device *rtc; + struct regmap *regmap; +}; + +/* + * In order to prevent arbitrary modification of the time register, + * when modification of the register, + * the "write" bit needs to be written in a certain order. + * 1. set WRITE1 bit + * 2. set WRITE2 bit + * 3. set WRITE3 bit + */ +static void sd2068_enable_reg_write(struct sd2068 *sd2068) +{ + regmap_update_bits(sd2068->regmap, SD2068_REG_CTRL2, + KEY_WRITE1, KEY_WRITE1); + regmap_update_bits(sd2068->regmap, SD2068_REG_CTRL1, + KEY_WRITE2, KEY_WRITE2); + regmap_update_bits(sd2068->regmap, SD2068_REG_CTRL1, + KEY_WRITE3, KEY_WRITE3); +} + +#if WRITE_PROTECT_EN +/* + * In order to prevent arbitrary modification of the time register, + * we should disable the write function. + * when disable write, + * the "write" bit needs to be clear in a certain order. + * 1. clear WRITE2 bit + * 2. clear WRITE3 bit + * 3. clear WRITE1 bit + */ +static void sd2068_disable_reg_write(struct sd2068 *sd2068) +{ + regmap_update_bits(sd2068->regmap, SD2068_REG_CTRL1, + KEY_WRITE2, 0); + regmap_update_bits(sd2068->regmap, SD2068_REG_CTRL1, + KEY_WRITE3, 0); + regmap_update_bits(sd2068->regmap, SD2068_REG_CTRL2, + KEY_WRITE1, 0); +} +#endif + +static int sd2068_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + unsigned char hour; + unsigned char rtc_data[NUM_TIME_REGS] = {0}; + struct i2c_client *client = to_i2c_client(dev); + struct sd2068 *sd2068 = i2c_get_clientdata(client); + int ret; + + ret = regmap_bulk_read(sd2068->regmap, SD2068_REG_SC, rtc_data, + NUM_TIME_REGS); + if (ret < 0) { + dev_err(dev, "reading from RTC failed with err:%d\n", ret); + return ret; + } + + tm->tm_sec = bcd2bin(rtc_data[SD2068_REG_SC] & 0x7F); + tm->tm_min = bcd2bin(rtc_data[SD2068_REG_MN] & 0x7F); + + /* + * The SD2068 supports 12/24 hour mode. + * When getting time, + * we need to convert the 12 hour mode to the 24 hour mode. + */ + hour = rtc_data[SD2068_REG_HR]; + if (hour & 0x80) /* 24H MODE */ + tm->tm_hour = bcd2bin(rtc_data[SD2068_REG_HR] & 0x3F); + else if (hour & 0x20) /* 12H MODE PM */ + tm->tm_hour = bcd2bin(rtc_data[SD2068_REG_HR] & 0x1F) + 12; + else /* 12H MODE AM */ + tm->tm_hour = bcd2bin(rtc_data[SD2068_REG_HR] & 0x1F); + + tm->tm_mday = bcd2bin(rtc_data[SD2068_REG_DM] & 0x3F); + tm->tm_wday = rtc_data[SD2068_REG_DW] & 0x07; + tm->tm_mon = bcd2bin(rtc_data[SD2068_REG_MO] & 0x1F) - 1; + tm->tm_year = bcd2bin(rtc_data[SD2068_REG_YR]) + 100; + + return 0; +} + +static int sd2068_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + unsigned char rtc_data[NUM_TIME_REGS]; + struct i2c_client *client = to_i2c_client(dev); + struct sd2068 *sd2068 = i2c_get_clientdata(client); + int ret; + + rtc_data[SD2068_REG_SC] = bin2bcd(tm->tm_sec); + rtc_data[SD2068_REG_MN] = bin2bcd(tm->tm_min); + rtc_data[SD2068_REG_HR] = bin2bcd(tm->tm_hour) | 0x80; + rtc_data[SD2068_REG_DM] = bin2bcd(tm->tm_mday); + rtc_data[SD2068_REG_DW] = tm->tm_wday & 0x07; + rtc_data[SD2068_REG_MO] = bin2bcd(tm->tm_mon) + 1; + rtc_data[SD2068_REG_YR] = bin2bcd(tm->tm_year - 100); + +#if WRITE_PROTECT_EN + sd2068_enable_reg_write(sd2068); +#endif + + ret = regmap_bulk_write(sd2068->regmap, SD2068_REG_SC, rtc_data, + NUM_TIME_REGS); + if (ret < 0) { + dev_err(dev, "writing to RTC failed with err:%d\n", ret); + return ret; + } + +#if WRITE_PROTECT_EN + sd2068_disable_reg_write(sd2068); +#endif + + return 0; +} + +static const struct rtc_class_ops sd2068_rtc_ops = { + .read_time = sd2068_rtc_read_time, + .set_time = sd2068_rtc_set_time, +}; + +static const struct regmap_config regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x11, +}; + +static int sd2068_probe(struct i2c_client *client) +{ + int ret; + struct sd2068 *sd2068; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; + + sd2068 = devm_kzalloc(&client->dev, sizeof(*sd2068), GFP_KERNEL); + if (!sd2068) + return -ENOMEM; + + sd2068->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(sd2068->regmap)) { + dev_err(&client->dev, "regmap allocation failed\n"); + return PTR_ERR(sd2068->regmap); + } + + i2c_set_clientdata(client, sd2068); + + sd2068->rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(sd2068->rtc)) + return PTR_ERR(sd2068->rtc); + + sd2068->rtc->ops = &sd2068_rtc_ops; + sd2068->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + sd2068->rtc->range_max = RTC_TIMESTAMP_END_2099; + + ret = devm_rtc_register_device(sd2068->rtc); + if (ret) + return ret; + + sd2068_enable_reg_write(sd2068); + + return 0; +} + +static const struct i2c_device_id sd2068_id[] = { + {"sd2068", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, sd2068_id); + +static const struct of_device_id rtc_dt_match[] = { + { .compatible = "whwave,sd2068" }, + {}, +}; +MODULE_DEVICE_TABLE(of, rtc_dt_match); + +static struct i2c_driver sd2068_driver = { + .driver = { + .name = "sd2068", + .of_match_table = of_match_ptr(rtc_dt_match), + }, + .probe = sd2068_probe, + .id_table = sd2068_id, +}; + +module_i2c_driver(sd2068_driver); + +MODULE_AUTHOR("Dianlong Li "); +MODULE_DESCRIPTION("SD2068 RTC driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/spi/spi-loongson-core.c b/drivers/spi/spi-loongson-core.c index f34eb10da..3de7e9016 100644 --- a/drivers/spi/spi-loongson-core.c +++ b/drivers/spi/spi-loongson-core.c @@ -42,12 +42,16 @@ static void loongson_spi_set_clk(struct loongson_spi *loongson_spi, unsigned int { unsigned char val; unsigned int div, div_tmp; - static const char rdiv[12] = {0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10, 11}; + // 第一个元素是无效的,肯定不会进来的 + static const char spre[13] = {0, 0, 0, 1, 0, 0, 1, 1, 1, 2, 2, 2, 2}; + static const char spr[13] = {0, 0, 1, 0, 2, 3, 1, 2, 3, 0, 1, 2, 3}; div = clamp_val(DIV_ROUND_UP_ULL(loongson_spi->clk_rate, hz), 2, 4096); - div_tmp = rdiv[fls(div - 1)]; - loongson_spi->spcr = (div_tmp & GENMASK(1, 0)) >> 0; - loongson_spi->sper = (div_tmp & GENMASK(3, 2)) >> 2; + div_tmp = fls(div - 1); + + loongson_spi->spcr = spr[div_tmp]; + loongson_spi->sper = spre[div_tmp]; + val = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPCR_REG); val &= ~GENMASK(1, 0); loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPCR_REG, val | diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 20eee9b05..b6f2c5965 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -47,6 +47,15 @@ config WATCHDOG_NOWAYOUT get killed. If you say Y here, the watchdog cannot be stopped once it has been started. +config WATCHDOG_TIMEOUT_ON_CLOSE + int "Timeout value for opening watchdog device" + default 5 + depends on !WATCHDOG_NOWAYOUT + help + if not WATCHDOG_NOWAYOUT, mean setup watchdog daemon when poweroff + so this option is second about watchdog timeout. + if setup <= 0 mean not setup watchdog timeout. but ping watchdog also will exec + config WATCHDOG_HANDLE_BOOT_ENABLED bool "Update boot-enabled watchdog until userspace takes over" default y diff --git a/drivers/watchdog/loongson2_wdt.c b/drivers/watchdog/loongson2_wdt.c index 83252edf3..3648e8c1c 100644 --- a/drivers/watchdog/loongson2_wdt.c +++ b/drivers/watchdog/loongson2_wdt.c @@ -29,7 +29,9 @@ struct ls2x_wdt_drvdata { static int ls2x_wdt_ping(struct watchdog_device *wdt_dev) { struct ls2x_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev); + u8 wd_en = 1; + writel((1 << wd_en), drvdata->base + RST_CTR); writel(0x1, drvdata->base + WD_CR); return 0; diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 4190cb800..615838d1f 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -966,6 +966,10 @@ static int watchdog_release(struct inode *inode, struct file *file) /* If the watchdog was not stopped, send a keepalive ping */ if (err < 0) { pr_crit("watchdog%d: watchdog did not stop!\n", wdd->id); +#ifdef CONFIG_WATCHDOG_TIMEOUT_ON_CLOSE + if (wdd->ops->set_timeout && CONFIG_WATCHDOG_TIMEOUT_ON_CLOSE > 0) + wdd->ops->set_timeout(wdd, CONFIG_WATCHDOG_TIMEOUT_ON_CLOSE); +#endif watchdog_ping(wdd); }