loongson:2k1000:dts:Correct desc

loongson: ls2kmci: fix deponds dma error option and disable redundant code about cd-gpio setup
loongson: i2c: support clock and bus freq from dts or acpi, support multi bus clock generate mode
loongson: 2k1000: dts: add aliases and  clock desc and other fix
rtc: sd2078: add sd2078 rtc driver
This commit is contained in:
tao89959
2026-08-24 10:50:26 +08:00
committed by maoxiaochuan
parent 55a9dbec94
commit 18294facf4
24 changed files with 1701 additions and 322 deletions
+96 -69
View File
@@ -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";
};
+4 -8
View File
@@ -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>;
};
};
};
+4 -2
View File
@@ -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>;
@@ -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>;
};
@@ -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>;
};
};
};
@@ -144,6 +144,7 @@
motorcomm,led0_cfg = <0x40>; //千兆常亮
motorcomm,led1_cfg = <0x30>; //百兆 十兆常亮
motorcomm,led2_cfg = <0x2600>; //有数据时闪烁
motorcomm,keep-pll-enabled = <1>;
};
};
};
@@ -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
@@ -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
@@ -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
@@ -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
+2
View File
@@ -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)
{
+88 -7
View File
@@ -25,6 +25,7 @@
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/units.h>
#include <linux/clk.h>
/* 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;
+1 -1
View File
@@ -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
+33 -23
View File
@@ -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");
+1
View File
@@ -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 {
+5 -2
View File
@@ -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;
}
+436 -196
View File
@@ -1,312 +1,552 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Author: zhanghongchen <zhanghongchen@loongson.cn>
* Yinbo Zhu <zhuyinbo@loongson.cn>
* Copyright (C) 2022-2023 Loongson Technology Corporation Limited
*/
// SPDX-License-Identifier: GPL-2.0
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <asm/io.h>
#include <linux/seq_file.h>
#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);
+10
View File
@@ -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
+1
View File
@@ -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
+229
View File
@@ -0,0 +1,229 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Real Time Clock (RTC) Driver for SD2068
* Copyright (C) 2018 Zoro Li
*/
#include <linux/bcd.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
#include <linux/slab.h>
#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, &regmap_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 <long17.cool@163.com>");
MODULE_DESCRIPTION("SD2068 RTC driver");
MODULE_LICENSE("GPL v2");
+8 -4
View File
@@ -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 |
+9
View File
@@ -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
+2
View File
@@ -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;
+4
View File
@@ -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);
}